I have a swing application with multiple jtextfield on it. How do you replace the function of the enter key wherein when you press the Enter key, it will transfer to the nextfocusable component just like the tab key? I dont want to put a keylistener on each jtextfield.
You're looking for Container.setFocusTraversalKeys:
Container root = ...
// pressed TAB, control pressed TAB
Set<AWTKeyStroke> defaultKeys = root.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS);
// since defaultKeys is unmodifiable
Set<AWTKeyStroke> newKeys = new HashSet<>(defaultKeys);
newKeys.add(KeyStroke.getKeyStroke("pressed ENTER"));
root.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, newKeys);
For more information, take a look at the Focus Subsystem tutorial.
You can call:
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.focusNextComponent();
but you will have to register a single ActionListener with all your JTextFields.
Related
How can I add a function key (i.e. the F1 to F12 keys) for shortcut key in JavaFX?
I use save button. I don’t need to click save button and it make easy to system
If you are using a Button, let's say saveButton and it is in Scene scene then you can set accelerator(shortcut key) to button as following:
Button saveButton = new Button("save");
scene.getAccelerators().put(new KeyCodeCombination(KeyCode.F1), saveButton::fire);
KeyCodeCombination in above code is used to set accelerators to javaFX contols and It takes, as argument, KeyCode e.g. KeyCode.K, KeyCode.F3 etc. and/or KeyCombination like KeyCombination.SHORTCUT_DOWN etc.
and if you are using MenuItem let's say saveMenu then you can set accelerator(shortcut key) to it as following:
MenuItem saveMenu = new MenuItem("save");
saveMenu.setAccelerator(new KeyCodeCombination(KeyCode.F1));
I have a Java application that contains a lot of features, and to make life easier for the user, I have set up numerous mnemonics and accelerators. For instance, I have a JMenuItem that allows the user to save the state of the application, witht he following code:
JMenuItem saveItem = new JMenuItem("Save");
saveItem.setMnemonic('S');
saveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK));
This works as desired, but now I would like to give the user an option to change the hot keys. While CTRL + s would seem like a fairly obvious hot key to stick with, there are many features that use these short cuts, and simply picked Save as an example.
I have a JButton that I have arranged for testing purposes that allows the user to enter in a new shortcut when clicked. I was thinking that I would simply try and capture the keys that the user holds down (InputEvent) and presses (KeyEvent). I also though it might be smart to force the use of an InputMask to avoid complications in Text Fields and the like.
What I am wondering is: What is the best way to capture the new input that the user enters? I have looked up information regarding KeyBindings and they look right for the job, but the main issue I see is actually capturing the keys and saving them.
Sounds like you need to setup a KeyListener. When the user presses/releases a key, it triggers a KeyEvent from which you can retrieve the main key pressed (e.g. S) and the mask/modifiers (e.g. CTRL+SHIFT).
From there you can create a KeyStroke object and set this as the new accelerator of your menu.
public void keyReleased(KeyEvent e){
KeyStroke ks = KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers());
menuItem.setAccelerator(ks);
}
The thing is you probably want this key listener to be removed right after the key released event, to avoid multiple keystrokes to be captured. So you could have this kind of logic:
JButton captureKeyButton = new JButton("Capture key");
JLabel captureText = new JLabel("");
KeyListener keyListener = new KeyAdapter(){
public void keyReleased(KeyEvent e){
KeyStroke ks = KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers());
menuItem.setAccelerator(ks);
captureText.setText("Key captured: "+ks.toString());
captureKeyButton.removeKeyListener(this);
}
};
ActionListener buttonClicked = new ActionListener(){
public void actionPerformed(ActionEvent e){
captureKeyButton.addKeyListener(keyListener);
captureText.setText("Please type a menu shortcut");
}
};
captureKeyButton.addActionListener(buttonClicked);
I wrote a autocomplete combobox program in which I search for the words entered by the user inside a file. The program works fine, however, the combobox editor doesn't return anything when something is typed in it. I don't know why is that.. Here is the chunk of code that deals with the problem.
// in GUI class constructor
InstantSearchBox = new JComboBox();
InstantSearchBox.setEditable(true);
/*****/
KeyHandler handle = new KeyHandler();
InstantSearchBox.getEditor().getEditorComponent().addKeyListener(handle);
// Keylistener class (KeyPressed method)
try
{
dataTobeSearched = InstantSearchBox.getEditor ().getItem ().toString ();
// the string variable is empty for some reason
System.out.println ("Data to be searched " + dataTobeSearched);
}
catch (NullPointerException e)
{
e.printStackTrace ();
}
Regards
Don't use a KeyListener. The text typed has not beeen added to the text field when at the time a keyPressed event is generated.
The better way to check for changes to the text field is to add a DocumentListener to the Document of the text field. See the section from the Swing tutorial on How to Write a Document Listener for more information.
You should use dataTobeSearched = (String) InstantSearchBox.getSelectedItem();
Despite its name, for editable comboboxes, this method just returns what text is entered.
The editor is only used internally by JComboBox to temporarily capture the input as they are typing. Once they have typed, the editor is cleared down and the text transferred back to the combobox model.
This allows editors to be shared amongst multiple comboboxes all at once - they just jump in when they are needed, capture input, jump back out again and clear down when editing is finished.
Use InstantSearchBox.getSelectedItem() instead of InstantSearchBox.getEditor().getItem().
I am using my predefined inherited Focus Traversal Class For My JFrame
I have defined the key press event for one of my button with some action on pressing Tab key to select other tab of my jTabbed Pane . This button is not responding only for the tab key .
int index=1;
if(evt.getKeyCode() == KeyEvent.VK_TAB)
{
// wrap around
if(evt.isShiftDown())
{
KeyboardFocusManager.getCurrentKeyboardFocusManager().focusPreviousComponent();
}
else
{
System.out.print("Shift Up");
KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent();
jtabPaneProducts.setSelectedIndex(index);
}
}
Please guide me how can i made jbutton to respond to the TAB key press in addition to focus traversal functionality.
You should be interested to read How to Write a Key Listener:
Alternatively, you can use the KeyEventDispatcher class to pre-listen to all key events. The focus page has detailed information on the focus subsystem.
And consequently: Interface KeyEventDispatcher
I am trying to make a program to manage a group of sports players. Each player has an enum Sport, and SportManager has convenient factory methods. What I am trying to do is open a dialog that has a JTextField for a name and a combo box to choose a sport. However, I want to stop the user from closing the dialog while the text field is blank, so I wrote a PropertyChangeListener so that when the text field is blank, it would beep to let the user know. However, if the user puts in something in the text after setting off the beep, it doesn't trigger the listener and you can't close the dialog without pressing cancel because the value is already JOptionPane.OK_OPTION, and cancel is the only way to change JOptionPane.VALUE_PROPERTY. So I tried to add
message.setValue(JOptionPane.UNITIALIZED_VALUE);
within the listener. However this just closes the window right away without giving the user a chance to fill in the text field, presumably because it triggers the listener I just registered. How do I make it so that it will beep more than once and give the user a chance to fill in the field?
FYI newPlayer is the component I'm registering the action to.
Code:
newPlayer.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
Object[] msg = new Object [4];
msg[0] = new JLabel("Name:");
final JTextField nameField = new JTextField();
msg[1]=nameField;
msg[2] = new JLabel("Sport: ");
JComboBox<Sport> major = new JComboBox<Sport>(SportManager.getAllSports());
msg[3]=major;
final JOptionPane message = new JOptionPane();
message.setMessage(msg);
message.setMessageType(JOptionPane.PLAIN_MESSAGE);
message.setOptionType(JOptionPane.OK_CANCEL_OPTION);
final JDialog query = new JDialog(gui,"Create a new player",true);
query.setContentPane(message);
query.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
message.addPropertyChangeListener(
new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e) {
String prop = e.getPropertyName();
if (query.isVisible()&& (e.getSource() == message)&& (prop.equals(JOptionPane.VALUE_PROPERTY))) {
if(nameField.getText().equals("")&&message.getValue().equals(JOptionPane.OK_OPTION)){
Toolkit.getDefaultToolkit().beep();
message.setValue(JOptionPane.UNINITIALIZED_VALUE);
return;
}
query.dispose();
}
}
});
query.pack();
query.setVisible(true);
if(Integer.parseInt(message.getValue().toString())==JOptionPane.OK_OPTION){
players.add(new Player(nameField.getText(),(Sport)major.getSelectedItem()));
edited=true;
}
gui.show(players);
}
});
I don't think you can do it with JOptionPane but you can using using TaskDialog framework and few others.
You can also create a dialog yourself, attach change listeners to your fields and enable/disable OK button based on content of your fields. This process is usually called "form validation"
However, I want to stop the user from closing the dialog while the
text field is blank
I get where you are going, but Java Swing is not very good at this. There is no way you can prevent the listener from being called. A solution would be to ignore the call, but this is complicated to implement.
The way I solved this issue is to let the pop-up disappear, check the returned value and if it is null/empty, beep and re-open it until user fills something.
JOptionPane does not internally support validation of inputs (Bug Reference). Your best bet is to create your own custom JDialog which supports disabling the OK button when the input data is invalid.
I'd recommend reading the bug report since other people talk about it and give workarounds.
However, I want to stop the user from closing the dialog while the text field is blank
The CustomDialog example from the section in the Swing tutorial on Stopping Automatic Dialog Closing has a working example that does this.
After taking a quick look at your code and the working example I think your code should be something like:
if (query.isVisible()
&& (e.getSource() == message)
&& (prop.equals(JOptionPane.VALUE_PROPERTY)))
{
if (message.getValue() == JOptionPane.UNINITIALIZED_VALUE)
return;
if (nameField.getText().equals("")
&& message.getValue().equals(JOptionPane.OK_OPTION))
{
Toolkit.getDefaultToolkit().beep();
message.setValue(JOptionPane.UNINITIALIZED_VALUE);
}
else
query.dispose();
}
Otherwise, I'll let you compare your code with the working code to see what the difference is.
One way to solve this problem is to add a Cancel and Ok button to your dialog. Then, disable closing the popup via the X in the corner, forcing the user to click either Cancel or Ok to finish/close the dialog. Now, simply add a listener to the text field that will disable the Ok button if the text field is blank.
Judging from your code I assume you can figure out how to implement these steps, but if you have trouble let us know! Good luck!