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.
Related
I successfully use postActionEvent() on a JTextField that has an ActionListener to simulate User action (pressing Enter key). I would like to create the same type of simulation for a JComboBox that has an ActionListener, but I don't find a postActionEvent() for a JComboBox. How could this (simulating User pressing Enter key) be accomplished?
How could this (simulating User pressing Enter key) be accomplished?
Combobox has an "enterPressed" Action. So you should be able to access the Action from the ActionMap of the combobox and then manually invoke the actionPerformed(...) method of the Action.
Check out Key Bindings for a program to list all the bindings for all Swing components.
You could also use a KeyListener:
addKeyListener(new KeyAdapter() {
#Override
public void keyReleased(KeyEvent event) {
if (event.getKeyChar() == KeyEvent.VK_ENTER) {
if (((JTextComponent) ((JComboBox) ((Component) event
.getSource()).getParent()).getEditor()
.getEditorComponent()).getText().isEmpty())
System.out.println("please dont make me blank");
}
}
});
See this question
I'm working on a JFrame which has a JTable and a few other elements within it. What I want the user to be able to do is tab through the table (with a set number of rows) and then when the focus is at the lower right hand side of the table, hitting tab again will jump to another component, in this case a JTextField.
I used a KeyListener to accomplish this for the case where the user just tabs through the table. The problem I'm having is that if the user is editing the cell and then presses tab, the TableCellEditor seems to have focus and the KeyListener I added to the table doesn't get called. From what I can tell in the docs, the CellEditor can only have a CellEditorListener which can only have a ChangeEvent, which is not going to work for what I'm trying to do here.
Anybody know of a workaround for this, or a trick I haven't thought of?
I used a KeyListener to accomplish this for the case where the user just tabs through the table.
Don't use a KeyListener. Swing was designed to be used with Key Bindings.
See Table Tabbing for an approach that shows how to reuse the existing tab action while providing your customization. Since this approach uses the default tab action hopefully it will fix your problem as well.
Try this:
table.setDefaultEditor(Object.class,new TableEditor());
class TableEditor extends DefaultCellEditor{
public TableEditor(){
super(new JTextField());
setClickCountToStart(1);
getComponent().addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e){
if(e.getKeyCode()==KeyEvent.VK_ENTER)
System.out.println("enter");
}
});
}
public Component getTableCellEditorComponent(JTable table,Object value,boolean isSelected,int row,int column){
JTextField com=(JTextField)super.getTableCellEditorComponent(table,value,isSelected,row,WIDTH);
com.setText((String)value);
return com;
}
}
And
table.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),"");
to remove standard reaction for the Enter key, if you need
Or:
editorComponent.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),"ent");
editorComponent.getActionMap().put("ent",new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e){
System.out.println("opp");
}
});
in the TableEditor constructor (instead of "getComponent" staff).
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
I'd like to add to a database, and my editable comboBoxModel when I enter a new name into the comboBox. I have the method for adding to the database down fine, I'm just trying to get it to somehow listen to an entry being added to the ComboBox.
What's the Best way to do this?
I've read the Java tutorial on Editable ComboBoxes, and noted where it said:
An editable combo box fires an action event when the user chooses an item from the menu and when the user types Enter. Note that the menu remains unchanged when the user enters a value into the combo box. If you want, you can easily write an action listener that adds a new item to the combo box's menu each time the user types in a unique value.
So I thought to myself, ok lets try this, and looked up some examples. Here is my attempt, essentially copy pasted out of the example I found, with my variable names:
playerNameComboBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("comboBoxEdited")) {
System.out.println("Adding new player!");
IController.Util.getInstance().addNewPlayer();
playerNameComboBox.insertItemAt(playerNameComboBox.getSelectedItem(), 0);
}
}
});
When I type in a new name, and press enter, it does nothing. No new database entry and no addtional option on the ComboBox. I haven't attached an action command to the ComboBox as I thought the example above assumed it would have that as default, and so did I.
But how do I get it to shout out that action command when I press enter, with the focus on the comboBox? I would have thought that comboBoxes would have had some sort of default behaviour to shout that out? Do I need to use an if(playerNameComboBox.hasFocus()) statement? Should I implement some kind of keylistener when my comboBox hasFocus()?
I'm very new at Java, so I'm unsure as to how this sort of thing should be done; any help is very much appreciated.
As requested, here is my short example in which names may be added to a JComboBox.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Test extends JFrame {
private JComboBox box;
public static void main(String[] args) {
new Test();
}
public Test()
{
super();
setSize(200, 100);
setDefaultCloseOperation(EXIT_ON_CLOSE);
box = new JComboBox();
box.setEditable(true);
getContentPane().add(box);
box.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("comboBoxEdited")) {
System.out.println("Adding new player!");
box.insertItemAt(box.getSelectedItem(), 0);
}
}
});
setVisible(true);
}
}
I'm quite new to Java Swing. And I'm stuck on trying to add a ListSelectionListener on a JComboBox instance. It seems only the ListSelectionModel interface has addListSelectionListener method. I kind of cannot figure it out...
Why I want to do add it is that I want program do something even the item in the combo box is not changes after selecting.
POTENTIAL ANSWER
I was simply thinking of attaching an actionListener on combobox not working. and i think it's bug of openjdk. I've reported it here
Thanks in advance.
Take a look at JComboBox#addItemListener:
JComboBox combo = createCombo();
combo.addItemListener(new ItemListener()
{
#Override
public void itemStateChanged(ItemEvent e)
{
if (e.getStateChange() == ItemEvent.SELECTED)
{
Object selectedItem = e.getItem();
// Do something with the selected item...
}
}
});
This event is fired for both mouse and keyboard interaction.
For JComboBox, you'll have to use ActionListener.
JComboBox jComboBox = new JComboBox();
jComboBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("combobox event");
}
});
AFAIK, actionPerformed is raised whenever the user makes a selection for the JComboBox even if it's the same item that was already selected.
It depends on your requirement. The ActionEvent is only fired when the keyboard is used, not when the selection changes as the mouse is moved over the items.
If you want to do some action when the item selection changes even if the mouse is moved then yes you will probably need access to the JList. You can access the JList used by the popup with the following code:
JComboBox comboBox = new JComboBox(...);
BasicComboPopup popup = (BasicComboPopup)comboBox.getAccessibleContext().getAccessibleChild(0);
JList list = popup.getList();
list.addListSelectionListener(...);
Use a PopupMenuListener. When the popup menu closes get the selected index and do your processing.