I am creating a simple text editor similiar to Notepad.
It would insert the time and date to the file if the user presses F5.
I browsed about mnemonics and accelerators but they are used in combination with Alt and Ctrl respectively.
Should I use an EventListener or is there any other solution?
You could simply use:
JMenuItem menuItem = new JMenuItem("Refresh");
KeyStroke f5 = KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0);
menuItem.setAccelerator(f5);
with KeyStroke having 0 specifying no modifiers as described in the docs.
An ActionListener is the appropriate listener for menu item events.
As partly already mentioned in some comments, the recommended approach is
use an action to configure a menuItem
configure the action with an accelerator
add the action to the menu
Some code:
Action doLog = new AbstractAction("Dummny log!") {
#Override
public void actionPerformed(ActionEvent e) {
LOG.info("doing: " + getValue(Action.NAME));
}
};
doLog.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("F5"));
JMenu menu = new JMenu("dummy");
menu.add(doLog);
frame.getJMenuBar().add(menu);
You can add a KeyBinding to your JMenuItem like this:
Action sayHello = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null,"Hello World, From JMenuItem :)");
}
};
jMenuItem.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("F5"),"sayHello");//4.The WHEN_IN_FOCUSED_WINDOW input maps of all the enabled components in the focused window are searched.
jMenuItem.getActionMap().put("sayHello",sayHello);
References:
http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html
http://docs.oracle.com/javase/7/docs/api/javax/swing/JComponent.html#getInputMap(int)
http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html#howto
Related
I am adding a JMenuItem (Show History) that will toggle the appearance of a JPanel upon click. But after doing so, I want to change the title of that menu item to state the opposite action (Hide History). Is there a way to change just the text for that menu item, or must I remove the old JMenuItem and add a new one?
JMenuItem history = new JMenuItem("Show History");
history.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//code here to show the history
//history.changeText("Hide History") OR viewMenu.remove(history) and create/add new one
}
});
viewMenu.add(history);
So this is what you do:
history.setText("Hide History");
And make history final.
I created a menu in the menu bar in which I'd like to create a JCheckBoxMenuItem to set a condition for highlighting remaining menu items.
Something like the following pseudo-code:
if login(true)
then highlight remaining menuitems
else
un-highlight the menuitems
I think for highlighting you mean enable/disable a JMenuItem. That's possible.
Use setEnabled:
JMenuItem item;
item.setEnabled(false); //to disable
Like suggested by kleopatra, the best way of doing that is to implement your own action for each JMenuItem, and let your action to enable/disable the button accordingly to the state:
For example:
public class AMenuAction extends AbstractAction {
#override
public void actionPerformed(ActionEvent e) {
//implement your action behavior here
}
}
Then construct your JMenuItem with such action:
AMenuAction afterLoginAction = new AMenuAction();
JMenuItem item = new JMenuItem(afterLoginAction );
When the user logged in/out call setEnabled method on the desired actions.
void Login()
{
afterLoginAction.setEnabled(true);
}
Enabling and disabling menu items is done in the same way as for any other JComponent by using the setEnabled( boolean ) method
Create a JCheckBoxMenuItem as userlogin menu item
JCheckBoxMenuItem jCheckBoxMenuItem = new JCheckBoxMenuItem();
then
add action listener to it
//unhighlite other menu items before login
jMenuFileOpen.setEnabled(false);
//...
jCheckBoxMenuItem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
if (login(true)){
jCheckBoxMenuItem.setSelected(true);
//highlite other menu items
jMenuFileOpen.setEnabled(true);
//...
} else {
jCheckBoxMenuItem.setSelected(false);
//unhighlite other menu items
jMenuFileOpen.setEnabled(false);
//...
}
}
});
once login(true) is successful the checkbox is checked on menu and other menu items are enabled.
menuBar = new JMenuBar();
// File Menu
JMenu fileMenu = new JMenu("File");
menuBar.add(fileMenu);
// File->New
JMenuItem newMenuItem = new JMenuItem("New");
frame.setJMenuBar(menuBar);
newMenuItem.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent arg0) {
btnExample.setText("Clicked");
btnExample.doClick();
//---------->SOME HOW TO EXECUTE btnExample<---------//
}
});
fileMenu.add(newMenuItem);
final JButton btnExample = new JButton("SD");
frame.getContentPane().add(btnExample, "cell 4 0,growx,aligny top");
btnExample.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
spinnerForVar.setValue(4);//default value for spinner
spinnerForFunc.setValue(4);//default value for spinner
...
}
});
Hello! I hope someone can help me. Here it is the problem: I have Menu item "New" and have button btnExample. I want the following: When i click on "File->New" it executes btnExample. My code is able only to change the button title and show visual affect of clicking. But how can I actually execute it?
I have only one advice - don't do that. Don't bind GUI components in this way.
If you want two components to execute the same operation, simply pack this operation in a method and call the method from both components.
Also, use ActionListener - are you sure the user is going to press it using mouse and not keyboard? what if you add shortcuts to those buttons/components?
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
//My button to click on it
jButton1ActionPerformed(evt);//this is the call for the other button to execut it
}
You should not be using a MouseListener for this.
You should be using Actions. Then you can add the Action to both the JButton and the JMemuItem.
Read the section from the Swing tutorial on How to Use Actions.
Amazing, I found my solution in your codes!
btnExample.doClick();
This did the job for me
I've tried using getInputMap() + getActionMap() on a JComboBox and it seems to have no effect.
I've tried addActionListener() / addItemListener() on a JComboBox and I can't seem to distinguish a change of selection from someone pressing the Return/Enter key.
Any suggestions? In my application, I want the Return/Enter key to be stronger than just selecting, it's a selecting + applying action.
Here's my code to setup the key binding. It works fine (e.g. note("hit ENTER") is called) when component is a JList, but doesn't work when component is a JComboBox.
private void setupApplyProfile(final JComponent component, final MyComboBoxModel mcbm)
{
String enterAction = "applyItem";
KeyStroke enterKey = KeyStroke.getKeyStroke("ENTER");
component.getInputMap().put(enterKey, enterAction);
component.getActionMap().put(enterAction, new AbstractAction()
{
#Override public void actionPerformed(ActionEvent e) {
note("hit ENTER");
applySelectedProfile(mcbm);
}
});
}
Aha, this seems to work: note("cb editor action") gets called when I hit Enter in the combo box field.
comboBox.getEditor().addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent arg0) {
note("cb editor action");
}
});
In my application, I want the Return/Enter key to be stronger than just selecting, it's a selecting + applying action.
If I understand the question you can use the following:
comboBox.putClientProperty("JComboBox.isTableCellEditor", Boolean.TRUE);
The ActionEvent and ItemEvents will only be fired when an item is selected from the drop down list when you use the mouse or the enter key. The eEvents will not be fired if you navigate the drop down list using the up/down arrow keys.
I have code like this:
jTextArea1.add(jPopupMenu1);
jTextArea1.setComponentPopupMenu(jPopupMenu1);
jTextField1.add(jPopupMenu2);
jTextField1.setComponentPopupMenu(jPopupMenu2);
and for menu items I have actions:
private void CopyActionPerformed(java.awt.event.ActionEvent evt) {
jTextArea1.copy();
}
private void Copy1ActionPerformed(java.awt.event.ActionEvent evt) {
jTextField1.copy();
}
Now I think it would be better to use one popup for all text components, how to pass info about which component was clicked to copy text? Maybe there is some more general solution for such case?
Actions should be created by extending TextAction. The TextAction class has a method that will return the text component that last has focus. This action can then be used on a popup menu or on a menu added to the menu bar. So the basic code to create the menu item would be:
JMenuItem copy = new JMenuItem( new CustomAction() );
However, its even easier than that because the DefaultEditorKit already provides a default copy action so all you need to do is:
JMenuItem copy = new JMenuItem( new DefaultEditorKit.CopyAction() );
the Event class has a getSource() method that tells you what component was the cause of the event.