Guys weird problem im facing
Basically i have 2 textAreas... (diplaybox and textbox)
while typing in textbox, the moment "Enter" is pressed i want all the text entered in textbox to go to displaybox... and textbox should be empty...
it all works fine, except...
after the text is transfered the cursor position of the textbox isnt on the topmost left side... it is somehow blinking on one line below that!(possibly because "ENTER" still got excecuted)... please see code
any ideas?
thanks in advance... just need the cursor to go back to the topmost left like how it is when we start typing ... without having to use KeyReleased event... something isnt feeling right... im sure this isnt he way it is actually done.. what say?
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_ENTER)// | (e.getKeyCode() == KeyEvent.VK_B))
{ //Toolkit.getDefaultToolkit().beep();
displaybox.append(textbox.getText() + "\n");
//textbox.setCaretPosition(0);
//textbox.setText("");
System.out.println(textbox.getCaretPosition());
}
}
public void keyTyped(KeyEvent e)
{}
public void keyReleased(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_ENTER)
{textbox.setCaretPosition(0);
textbox.setText("");
System.out.println(textbox.getCaretPosition());
}
}
All Swing components work by using Key Bindings. The default binding for the Enter key is to add a newline string to the text area. If you want to change the functionality of the Enter key then change the default Action. Don't attempt to use a KeyListener.
Check out Key Bindings for a program to list all the default bindings as well as a link to the Swinng tutorial on How to Use Key Bindings. If you run the program you will find that the Enter key invokes an Action identified by the "insert-break" tag in the ActionMap. So to replace the Action you can do something like:
Action enter = new AbstractAction()
{
#Override
public void actionPerformed(ActionEvent e)
{
displayBox.append( textBox.getText() + "\n" );
textBox.setText("");
}
};
textBox.getActionMap().put("insert-break", enter);
The problem with using the KeyListener is that the default Action is still invoked AFTER you process the KeyEvent.
Related
currently im trying to code a grid based game.
ive already managed to implement a key listener for general navigation.
but when pressing a certain key, a Jpopup Menu opens.
now i want to implement navigation for the menu aswell with a key listener. Pressing B is supposed to close the menu again.
KeyListener UnitActionMenuKeyListener = new KeyListener() {
#Override
public void keyPressed(KeyEvent evt)
{
if (evt.getKeyCode()==KeyEvent.VK_B)
menu.setVisible(false)
}
#Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
JPopupMenu menu = new JPopupMenu("UnitActionMenu");
JMenuItem bewegenItem = menu.add("test");
Using menu.show and menu.addKeyListener after this.
But no matter what i try, either my general navigation wont work anymore, or the general navigation will work, but my menu wont react to pressing B
so, how do i implement multiple key listeners for multiple elements?
i just want my main window to listen (and react) to some key differently than my menu
(sorry for bad writing, my english isnt that good and im frustrated by failing a simple task for more than 4 hours)
Swing key bindings are generally better than key listeners. Key listeners have issues related to the focus system. That's what the problem you're having sounds like. When the popup is active, it steals the focus. Only the focused component will send out key events.
There's a tutorial for key bindings here: https://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html
The API is a little more complicated but they're more robust and you can specify the focus behavior directly.
Here's a quick guide for converting key listeners to key bindings.
For a key listener, you have some code that's like this:
myComponent.addKeyListener(new KeyListener() {
...
#Override
public void keyTyped(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_Z)
performZAction();
}
});
Writing a key binding would be like this:
KeyStroke keystroke =
KeyStroke.getKeyStroke("typed Z");
myComponent.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(keystroke, "zAction");
myComponent.getActionMap()
.put("zAction", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
performZAction();
}
});
In other words, there are three steps:
Creating a javax.swing.KeyStroke object with KeyStroke.getKeyStroke.
Using the input map, bind the keystroke to a name for your action.
Using the action map, bind the name for your action to a javax.swing.Action.
The Action is your listener. You can extend javax.swing.AbstractAction and it's just like writing an ActionListener.
Im trying to get my KeyEvent working. Sadly the keyTyped(KeyEvent e) isnt responding at all. :)
I implemented the KeyEvnet to my class.
I assigned the listener like following:
JTextfield searchBar = new JTextField();
searchBar.addKeyListener( this );
My key event looks like this:
#Override
public void keyTyped(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
System.out.println("pressed");
try {
int browser = getSelectBrowser().getSelectedIndex();
logic.search( searchBar.getText(), searchInfo, browser, isURL );
} catch (InterruptedException ie) {
System.out.println( "Pressed fail" );
}
this.repaint();
}
}
I also tried the Listener in a second test Gui and were it also does not work.
:-)
use "keyPressed" instead of "keyTyped". keyTyped listens only on alphanumeric chars
You wont see this listener called when you press enter, so your println will never be called. Pressing enter on a JTextField will call the attached ActionListener, if there is one.
To get this working, add an ActionListener to the text field and put the code you want to run when enter is pressed in there.
You can read more about it here. Thanks to tak3shi for linking that in the comments.
I have an image here to explain my query
As you can see in the image I have many text fields,right now the cursor is on the text field(the cursor could be on any textfield).
As you can 3 out of the last 4 fields are disabled,once I press the enter those get enabled.This everything works fine.
My query is once I press enter how do I move my cursor to the position down there(marked in red)?
This is the small snippet of code for the once enter key pressed.
((JPanel)frame.getContentPane()).getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("ENTER"), "doSomething");
((JPanel)frame.getContentPane()).getActionMap ().put("doSomething", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("profit");
// disabledField.setEnabled(true);
textbox9.setEnabled(true);
textbox10.setEnabled(true);
textbox11.setEnabled(true);
}
});
You can request focus by using JComponent#requestFocusInWindow
For example...
public void actionPerformed(ActionEvent arg0) {
System.out.println("profit");
// disabledField.setEnabled(true);
textbox9.setEnabled(true);
textbox10.setEnabled(true);
textbox11.setEnabled(true);
textbox9.requestFocusInWindow();
}
Take a look at How to use the Focus Subsystem for more details
Having tried KeyEvents it was recommended that I switch to Key Bindings to activate certain events by the pushing of the arrow keys while one is in a TextArea
area.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke("VK_UP"),
"doEnterAction");
area.getActionMap().put("doEnterAction", new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e){
System.out.println("Event Handled");
oneRay[pick][0] = ("");
if(i>=4){
i=0;
area.setText("");
}
caller();
}
});
area.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke("VK_DOWN"),
"doEnterAction");
area.getActionMap().put("doEnterAction", new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e){
System.out.println("Event 2 Handled");
area.append("\n"+oneRay[pick][1]);
buton1.setEnabled(true);
buton2.setEnabled(true);
}
});
area.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke("VK_RIGHT"),
"doEnterAction");
area.getActionMap().put("doEnterAction", new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e){
if(i>=4){
i=0;
area.setText("");
}
caller();
}
This code covers three different Key Bindings, but none work, whether I press up down left right the cursor just moves in that direction in the TextArea.
What have I done wrong this time. Please help me!
whether I press up down left right the cursor just moves in that direction in the TextArea.
You are building the KeyStroke incorrectly. You should not be including the "VK_" in the Keystroke. So basically nothing is being added to the InputMap.
Also your code is updating the InputMap and ActionMap with a new identifier. I find is easier to just replace the Action in the ActionMap. See Key Bindings for a list of all the default Actions as well as the basic code for replacing the default Action (this is a different link than you got in your last posting).
Finally, in your other posting you suggested that you want to invoke the Action of a button. Well then your code should be creating an Action that can be used by the button and the Key Bindings. You create an Action the same way you create an ActionListener except you extend AbstractAction instead of implementing ActionListener.
Please do note that this is a different question,
I am writing a java program. I have a form with 10 JTextFields and a 'Submit' button.
How do I make the method for 'Submit' button to be called when the user presses the
enter key on ANY of the 10 text fields?
Should I add KeyListeners to all of the 10 or is there a more efficient way since the text fields and the button are inside a JPanel?
No, Create an common event handler like this ,And attach it to all
Below is a Mock code:
KeyAdapter event= new KeyAdapter() {
public void keyReleased(KeyEvent e) {
//do something
}
public void keyTyped(KeyEvent e) {
// TODO: Do something for the keyTyped event
}
public void keyPressed(KeyEvent e) {
// TODO: Do something for the keyPressed event
}
});
txtField1.addKeyListener(event);
txtField2.addKeyListener(event);
-----
may be a loop also :)