How to clear results using JMenuItem - java

What code do I use for the JMenuItem Clear in order to clear results from the memory in Java GUI appliation? I know how to clear from a JText field, by using the object.setText("");, but how do I clear results using a JMenuItem?

Your question is a bit vague, so I'll try and answer what I think your asking...
Removing from a List using JMenuItems
Remove things from somewhere else in response to clicking on the JMenuItem:
Item class:
public class Item {
public static final String name;
public static int cost;
public Item(String name, int cost) {
this.name = name;
this.int = int;
}
}
Main class:
public class Main {
public static void main() {
List<Item> list = new LinkedList<>();
JMenu menu = new JMenu();
menu.add( new JMenuItem(
new AbstractAction("Add Carwash") {
public void actionPerformed(ActionEvent e) {
list.add( new Item("CarWash", 10) );
}
}
);
menu.add( new JMenuItem(
new AbstractAction("Oil Change") {
public void actionPerformed(ActionEvent e) {
list.add( new Item("Oil Change", 10) );
}
}
);
menu.add( new JMenuItem(
new AbstractAction("Clear") {
public void actionPerformed(ActionEvent e) {
list.clear();
}
}
);
menu.add( new JMenuItem(
new AbstractAction("Total") {
public void actionPerformed(ActionEvent e) {
System.out.println(
list.stream().mapToInt().sum()
);
}
}
);
}
}
Note that this is not complete, may not not compile, and does not actually display anything yet (add the menu to a JFrame).

Related

Change variables in ChangeListener?

I am making a matching card program and I want to make sure the user only selects two card. So I have made Changelisteners and inside those changelisteners I would like to have an integer that would increase when there is a change in the state of the button. I have tried to use int, but it gave me the error where it says to use a final or effectively final. Is there some way that I can use an int inside of the changelistener method.
Here is an example:
card1Button.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
//int increases here
}
});
You have two basic choices to solve the immediate issue
You could...
Make the counter an instance field
public class MyAwesomeCardGame extends ... {
private int counter;
//...
public MyAwesomeCardGame() {
//...
card1Button.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
counter++;
}
});
}
}
You could...
Make the counter a instance of field of the anonymous class
public class MyAwesomeCardGame extends ... {
//...
public MyAwesomeCardGame() {
//...
card1Button.addChangeListener(new ChangeListener() {
private int counter;
public void stateChanged(ChangeEvent e) {
counter++;
}
});
}
}
Alternatively
Depending on what you're doing, you could use two ButtonGroups instead, it would ensure that only one button from each group can be selected at a time
You could change the scope of your variable
public class CardGame {
private int x;
public CardGame() {
card1Button.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
x++;
}
});
}
}
Here is an example that shows how you can do this when using a JCheckBox:
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class CheckBoxGroup
{
private Set<GroupButtonModel> models = new HashSet<GroupButtonModel>();
private int groupSize;
public CheckBoxGroup(int groupSize)
{
this.groupSize = groupSize;
}
public void register(JCheckBox checkBox)
{
ButtonModel groupModel = new GroupButtonModel();
groupModel.setSelected ( checkBox.getModel().isSelected() );
checkBox.setModel( groupModel );
}
private class GroupButtonModel extends JToggleButton.ToggleButtonModel
{
#Override
public void setSelected(boolean selected)
{
if (!selected)
{
models.remove( this );
super.setSelected( selected );
return;
}
// Check number of currently selected check boxes
if (models.size() == groupSize)
{
System.out.println("Only " + groupSize + " items can be selected");
}
else
{
models.add( this );
super.setSelected( selected );
}
}
}
private static void createAndShowGUI()
{
JPanel panel = new JPanel();
CheckBoxGroup group = new CheckBoxGroup(3);
for (int i = 0; i < 10; i++)
{
JCheckBox checkBox = new JCheckBox( String.valueOf(i) );
panel.add( checkBox );
group.register( checkBox );
}
JFrame frame = new JFrame("Check Box Group");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( panel );
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
It adds a custom model to the component to check the number of currently selected components before allowing you to select another component.
It will also work for a JToggleButton. Just change the register(...) method to register toggle buttons.

How to add custom SWT context menu for Text box control

I would like to modify the right click context menu for some some SWT Text boxes.
I would like to still have some of the default options like Copy, Cut, Paste, but would also like to have a custom action 'Generate Random' to fill the text box with a UUID.
How can I add such a menu to the control?
here's what I came up with to add some of the standard functions (cut, copy, paste, select all) as well as a custom action (generate UUID)
public static void addContextMenuWithUUID(final Text control)
{
Menu menu = new Menu(control);
MenuItem item = new MenuItem(menu, SWT.PUSH);
item.setText("Cut");
item.addListener(SWT.Selection, new Listener()
{
#Override
public void handleEvent(Event event)
{
control.cut();
}
});
item = new MenuItem(menu, SWT.PUSH);
item.setText("Copy");
item.addListener(SWT.Selection, new Listener()
{
#Override
public void handleEvent(Event event)
{
control.copy();
}
});
item = new MenuItem(menu, SWT.PUSH);
item.setText("Paste");
item.addListener(SWT.Selection, new Listener()
{
#Override
public void handleEvent(Event event)
{
control.paste();
}
});
item = new MenuItem(menu, SWT.PUSH);
item.setText("Select All");
item.addListener(SWT.Selection, new Listener()
{
#Override
public void handleEvent(Event event)
{
control.selectAll();
}
});
item = new MenuItem(menu, SWT.PUSH);
item.setText("Generate UUID");
item.addListener(SWT.Selection, new Listener()
{
#Override
public void handleEvent(Event event)
{
control.setText(UUID.randomUUID().toString());
}
});
control.setMenu(menu);
}
When I had to do something similar a while ago, this is what I did,
I adopted the TextActionHandler class provided by eclipse and modified the code to suit my needs.
public final class TextActionHandler {
enum TextAction {
CUT (WorkbenchMessages.Workbench_cut, IWorkbenchCommandConstants.EDIT_CUT),
COPY (WorkbenchMessages.Workbench_copy, IWorkbenchCommandConstants.EDIT_COPY),
PASTE (WorkbenchMessages.Workbench_paste, IWorkbenchCommandConstants.EDIT_PASTE),
DELETE (WorkbenchMessages.Workbench_delete, null),
SELECT_ALL(WorkbenchMessages.Workbench_selectAll, WorkbenchCommandConstants.EDIT_SELECT_ALL);
private String text;
private String commandId;
private TextAction(String text, String commandId ) {
this.text = text;
this.commandId = commandId;
}
public String getCommandId() {
return commandId;
}
public String getText() {
return text;
}
}
public TextActionHandler(Text text) {
addText(text);
}
public TextActionHandler() {
super();
}
public void addText(Text textControl) {
if (textControl == null) {
return;
}
textControl.addDisposeListener(new DisposeListener() {
#Override
public void widgetDisposed(DisposeEvent e) {
removeText(activeTextControl);
}
});
textControl.addListener(SWT.Activate, textControlListener);
textControl.addListener(SWT.Deactivate, textControlListener);
textControl.addKeyListener(keyAdapter);
textControl.addMouseListener(mouseAdapter);
activeTextControl = textControl;
updateActionsEnableState();
}
public void hookContextMenu() {
final MenuManager menuMgr = new MenuManager("#PMPopupMenu");
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
addContextMenuOptions(menuMgr);
}
});
Menu menu = menuMgr.createContextMenu(activeTextControl);
activeTextControl.setMenu(menu);
}
private void addContextMenuOptions(MenuManager manager) {
manager.removeAll();
manager.add(textCutAction);
manager.add(textCopyAction);
manager.add(textPasteAction);
manager.add(textDeleteAction);
manager.add(new Separator());
manager.add(textSelectAllAction);
// add your own action handlers here
}
...
// example.
private final class CutActionHandler extends Action {
private CutActionHandler() {
setProperties(this, TextAction.CUT);
setEnabled(false);
}
#Override
public void runWithEvent(Event event) {
if (activeTextControl != null && !activeTextControl.isDisposed()) {
activeTextControl.cut();
updateActionsEnableState();
}
}
#Override
public boolean isEnabled() {
return activeTextControl != null && !activeTextControl.isDisposed()
&& activeTextControl.getEditable()
&& activeTextControl.getSelectionCount() > 0;
}
public void updateEnabledState() {
setEnabled(isEnabled());
}
}
private void setProperties(Action action, TextAction actionEnum){
action.setText(actionEnum.getText());
action.setActionDefinitionId(actionEnum.getCommandId());
action.setImageDescriptor(getImageDescriptor(actionEnum));
action.setDisabledImageDescriptor(getDisabledImageDescriptor(actionEnum));
}
}
Likewise, you can have your own ActionHandlers added. e.g, RandomGeneratorHandler.
To hook this to your textboxes, do
Text text = new Text(parent, SWT.NONE);
...
TextActionHandler handler = new TextActionHandler();
handler.addText(text);
handler.hookContextMenu();
Note - I have not provided the complete class here, for other actions like copy, paste, delete and select all etc, you will have to do something similar as Cut. I have used the same code defined in the TextActionHandler class.

deleting menu items remotely

consider the following code:
mntmProfilesDelete.get(index).addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
JMenuItem eMntm = (JMenuItem) e.getSource();
String text = eMntm.getText();
Component[] mns = mnDelete.getParent().getComponents();
for(Component mn : mns)
{
System.err.println((String)(((JMenu)mn).getText()));
if(mn instanceof JMenu && ((JMenu)mn).getText().toLowerCase().equals("open"))
{
System.err.println((String)(((JMenu)mn).getText()));
Component[] mntms = ((JMenu) mn).getComponents();
for(Component mntm : mntms)
{
System.err.println((String)(((JMenu)mn).getText())+"\n"+(String)(((JMenuItem)mntm).getText()));
if(mntm instanceof JMenuItem && ((JMenuItem)mntm).getText().toLowerCase().equals(text.toLowerCase()))
{
System.err.println((String)(((JMenu)mn).getText())+"\n"+(String)(((JMenuItem)mntm).getText()));
((JMenu)mn).remove((JMenuItem)mntm);
}
}
}
}
mnDelete.remove(eMntm);
}
}
which I'm using to delete two menu items, like below:
(jmenu)father
(jmenu)open
(jmenuitem)item1
(jmenuitem)item2
etc
(jmenu)delete
(jmenuitem)item1
(jmenuitem)item2
etc
the action listener is attached to -item1- below -delete-
for some reason the -item1- below -open- doesn't get removed using the above code. I can't seem to understand why.
many thanks.
JMenu's remove(Component c) JavaDoc says: "Removes the component c from this menu."
AFAIC interpret from looking at the last line of your code (my weekend mind refused to dig through the casting galore[1] ;-) and your explanation: your this menu mnDelete is /father/delete. The item you're trying to remove (/father/open/item1) is not in this menu.
[1] Why the heck are you casting public String getText() to (String)?
So I would save off my menu that I want to modify so I can easily perform this change. As opposed to trying to wind through the hierarchy. This will make it much easier to read your code. For example:
public SomeApp {
JMenu openMenu;
JMenu deleteMenu;
public JMenu buildMenus(List<SomeObject> objsThatGoInMenu) {
openMenu = new JMenu("Open");
deleteMenu = new JMenu("Delete");
for( SomeObject so : objsThatGoInMenu ) {
addMenuOptions( so );
}
JMenu father = new JMenu("Father");
father.add( openMenu );
father.add( deleteMenu );
}
public addMenuOptions( final SomeObject so ) {
final JMenuItem openMenuItem = new JMenuItem( new AbstractAction( so.getName() ) {
public void actionPerformed(ActionEvent evt) {
// todo open
}
}));
final JMenuItem deleteMenuItem = new JMenuItem( new AbstractAction( so.getName() ) {
public void actionPerformed(ActionEvent evt) {
deleteMenu.remove( deleteMenuItem );
openMenu.remove( openMenuItem );
}
}));
openMenu.add( openMenuItem );
deleteMenu.add( deleteMenuItem );
}
}
solved it, every part of my code works as it should except:
Component[] mntms = ((JMenu) mn).getComponents();
which does not return any JMenuItems, it should be:
Component[] mntms = ((JMenu) mn).getMenuComponents();

How to use a variable which is used in an ActionListener?

as you can see in the picture I'm setting up a table which shows all files from a specific path (later I'll implement a filter for pdf files only). First, all files are simultaneously shown, but I want to see each single file of the path during the build up of the table. So I've changed it to a array list, but there a two errors which I really couldn't resolve...
Hope that you can help me ;-)
class FileModel extends AbstractTableModel implements FilenameFilter {
String titles[] = new String[] { "Path" };
Class<?> types[] = new Class[] { String.class, String.class };
private List<Object[]> data = new ArrayList<>();
public FileModel() {
this("C:\\");
}
public FileModel(String dir) {
File pwd = new File(dir);
setFileStats(pwd);
}
// Implement the methods of the TableModel interface we're interested
// in. Only getRowCount(), getColumnCount() and getValueAt() are
// required. The other methods tailor the look of the table.
#Override
public int getRowCount() {
return this.data.size();
}
#Override
public int getColumnCount() {
return this.titles.length;
}
#Override
public String getColumnName(int c) {
return this.titles[c];
}
#Override
public Class<?> getColumnClass(int c) {
return this.types[c];
}
#Override
public Object getValueAt(int r, int c) {
return this.data.get(r)[c];
}
// Our own method for setting/changing the current directory
// being displayed. This method fills the data set with file info
// from the given directory. It also fires an update event so this
// method could also be called after the table is on display.
public void setFileStats(File dir) {
System.out.println("SET MY DIR " + dir);
this.data = new ArrayList<>();
this.fireTableDataChanged();
String files[] = dir.list();
this.data = new Object[files.length][this.titles.length]; **// Here error #1**
for (int i = 0; i < files.length; i++) {
File tmp = new File(files[i]);
this.data[i][0] = tmp.getAbsolutePath(); **// Here error #2**
}
this.fireTableDataChanged();
}
#Override
public boolean accept(File dir, String name) {
// TODO Auto-generated method stub
return false;
}
}
Here's the code of the JFrame windows:
public class FileFrame extends JFrame {
protected FileModel fileModel = new FileModel();
{
this.setSize(500, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
JTable FileTable = new JTable(this.fileModel);
TableRowSorter<TableModel> TableRowSorter = new TableRowSorter<TableModel>(this.fileModel);
FileTable.setRowSorter(TableRowSorter);
FileTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
FileTable.setColumnSelectionAllowed(true);
FileTable.setDefaultRenderer(Number.class, new BigRenderer(1000));
JScrollPane JScrollPane = new JScrollPane(FileTable);
getContentPane().add(JScrollPane, BorderLayout.CENTER);
}
public static void main(String args[]) {
final FileFrame FileFrame = new FileFrame();
// Create menubar
JMenuBar menubar = new JMenuBar();
// Create JMenu object
JMenu menu = new JMenu("File");
// Create JMenuItem object
final JMenuItem openItem = new JMenuItem("Open");
JMenuItem exititem = new JMenuItem("Exit");
// Add JMenuItem to JMenu
menu.add(openItem);
menu.add(exititem);
// Add menu to menubar
menubar.add(menu);
// Add menubar to dialog
FileFrame.setJMenuBar(menubar);
// Show dialog
FileFrame.setVisible(true);
// Integrate ActionListener as anonymous class
openItem.addActionListener(new java.awt.event.ActionListener() {
public File savedPath;
public final JFileChooser FileChooser = new JFileChooser("C:\\");
// Initialize actionPerformed
#Override
public void actionPerformed(ActionEvent e) {
// Generate choose file
this.FileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
this.FileChooser.setDialogTitle("Selection of pdf directory");
this.FileChooser.setAcceptAllFileFilterUsed(false);
// Set the text
this.FileChooser.setApproveButtonText("Open directory");
// Set the tool tip
this.FileChooser.setApproveButtonToolTipText("Select pdf directory ");
if (this.savedPath != null)
this.FileChooser.setCurrentDirectory(this.savedPath);
int returnVal = this.FileChooser.showOpenDialog(openItem);
if (returnVal == JFileChooser.APPROVE_OPTION) {
this.savedPath = this.FileChooser.getSelectedFile();
FileFrame.fileModel.setFileStats(this.savedPath);
}
}
});
// Integrate ActionListener as anonymous class
exititem.addActionListener(new java.awt.event.ActionListener() {
// Initialize actionPerformed
#Override
public void actionPerformed(ActionEvent e) {
// Close program
System.exit(0);
}
});
}
}
The problem is you are trying to access data as though its an array
private List<Object[]> data = new ArrayList<>();
...
this.data = new Object[files.length][this.titles.length];
this.data[i][0] = tmp.getAbsolutePath();
But data is actually a List<Object[]>
So you might want to do
//data.add(new Object[files.length][this.titles.length]);
data.add(new Object[files.length]); // can only be one dimensional
and
((Object[])data.get(i))[0] = tmp.getAbsolutePath();
instead
See more on how to use Lists at The List Interface
UPDATE
Change your model code to this
String files[] = dir.list();
for (int i = 0; i < files.length; i++) {
File tmp = new File(files[i]);
data.add(new Object[] { tmp.getAbsolutePath()}) ;
}
All you need to do is add a new Object[] to the list (inside the loop) with just the file path, since that seems to be all you need. Don't add one before.

Event call doesn't work with key bind or click - what's the logical error?

I'm trying to call this event below; I create the frame with TabBuilder (since is part of my application) then it calls the Search screen which is popping up; but the event of the search with key bind or simple click on the button is not working and of course I'm doing something wrong but I don't know what since I'm a little bit new in Java. Please could anyone help me?
SearchScreen:
public class SearchScreen extends EventSearch{
public static void main (String[] args){
SearchScreen s= new SearchScreen();
}
public void SearchScreen(){
TabBuilder tb = new TabBuilder();
tb.searchTab();
}
}
EventSearch:
public class EventSearch extends TabBuilder{
String userQuery;
String key = "ENTER";
KeyStroke keyStroke = KeyStroke.getKeyStroke(key);
public EventSearch(){
btSearch.addActionListener(this);
txtSearch.getInputMap().put(keyStroke, key);
txtSearch.getActionMap().put(key, enterAction);
}
Action enterAction = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
try{
System.out.println("worked");
} catch (IOException e1) {
e1.printStackTrace(); //print failure
JOptionPane.showMessageDialog(null, "HTTP request failure.");
}
}
};
}
TabBuilder:
public class TabBuilder implements ActionListener {
protected JButton btSearch;
JMenuItem close, search;
protected JTextField txtSearch;
protected JFrame searchFrame = new JFrame();
public void TabBuilder(){
}
public void searchTab(){
JLabel lbSearch;
JPanel searchPane;
btSearch= new JButton("Search");
lbSearch= new JLabel("Type Keywords in english to be searched below:");
lbSearch.setHorizontalAlignment(SwingConstants.CENTER);
txtSearch= new JTextField();
searchPane=new JPanel();
searchPane.setBackground(Color.gray);
searchPane.add(lbSearch);
searchPane.add(txtSearch);
searchPane.add(btSearch);
searchPane.setLayout(new GridLayout(3,3));
btSearch.setEnabled(true);
searchFrame.add(searchPane);
searchFrame.setTitle("SHST");
searchFrame.setSize(400, 400);
searchFrame.setVisible(true);
searchFrame.setDefaultCloseOperation(1);
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==close){
System.exit(0);
}
if(e.getSource()==search){
SearchScreen s = new SearchSreen();
}
}
}
You write this actionListener
public void actionPerformed(ActionEvent e){
if(e.getSource()==close){
System.exit(0);
}
if(e.getSource()==search){
TabBuilder tb = new TabBuilder();
tb.searchTab();
}
}
and you added to btnSearch.addActionListener(this) , your actionListener never would do anything.
And for your KeyBinding happens something similar , you add the action to the txtSearch and then you are asking if the source is the e.getSource()==btSearch
And for KeyBindings you can use Constants to specify when they have to be binded.
JComponent.WHEN_FOCUSED, JComponent.WHEN_IN_FOCUSED_WINDOW , JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
For example :
txtSearch.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, key);
How to use KeyBindings

Categories