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
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.
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.
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();
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.
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