KeyPress handler is not working for first letter - java

I need to print something in the method on every key press event. I have tried the below code and the problem with that is, first key press in always returning null. Whereas, after typing the second letter, it prints the first key event. Key Press event is not capturing the letter on first event. Can you please help in resolving this ?
final StringComboBox searchGridTextBox = new StringComboBox();
searchGridTextBox.setEmptyText("Search Grid");
searchGridTextBox.addFocusHandler(new FocusHandler(){
#Override
public void onFocus(FocusEvent event){
if(searchGridTextBox.getStore().size() > 0)
searchGridTextBox.expand();
}
});
searchGridTextBox.addKeyPressHandler(new KeyPressHandler() {
#Override
public void onKeyPress(KeyPressEvent event) {
System.out.println("On key press event ") ;
}
});

For this scenario, you need to use KeyUpEvent. Please find the updated code below.
final StringComboBox searchGridTextBox = new StringComboBox();
searchGridTextBox.setEmptyText("Search Grid");
searchGridTextBox.addFocusHandler(new FocusHandler(){
#Override
public void onFocus(FocusEvent event){
if(searchGridTextBox.getStore().size() > 0)
searchGridTextBox.expand();
}
});
searchGridTextBox.addKeyUpHandler(new KeyUpHandler() {
#Override
public void onKeyUp(KeyUpEvent event) {
System.out.println("On key up event ") ;
}
});

There are 2 more handlers available keyUp and keyDown handler. Try using keyUp/keyDown handler and see if it fulfills your requirements.
There is a difference how keyPress behaves in a case of empty combo box which is explained in this post:
https://stackoverflow.com/a/42036960/3612019

Related

Java Swing: slightly modify existing keyboard behaviour? (right arrow should initially set cursor to position 0)

If a Java Swing JTextField gets the focus, all its text is marked.
Now, I would like to modify the behaviour, so that if the user now presses the right arrow, the cursor should be set to the texts beginning (position 0).
I'm able to get the RIGHT Key event and set the cursor to position 0,
but I don't know how to pass the RIGHT Key event to the original code so that it can handle the normal behaviour.
JTextField preisFieldEUR = new JTextField(…);
AbstractAction right = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
if (preisFieldEUR.getSelectionEnd() - preisFieldEUR.getSelectionStart() == preisFieldEUR.getText().length()) {
preisFieldEUR.setSelectionStart(0);
preisFieldEUR.setSelectionEnd(0);
} else {
// Todo: How to pass this event to the original keyboard handler to
// keep the normal behaviour?
}
}
};
preisFieldEUR.getInputMap().put(KeyStroke.getKeyStroke("RIGHT"), right);
Thanks a lot for any help!
You need something like this:
Action oldAction = preisFieldEUR.getActionMap().get("caret-forward"); // probably another parameter?
AbstractAction right = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
if (preisFieldEUR.getSelectionEnd() - preisFieldEUR.getSelectionStart() == preisFieldEUR.getText().length()) {
preisFieldEUR.setSelectionStart(0);
preisFieldEUR.setSelectionEnd(0);
} else {
oldAction.actionPeformed(e)
}
}
};

Java - Want getKeyCode to only register once

I'm currently working on a little game. I'm using getKeyCode to move my character but the thing is that I don't want you to be able to keep moving if you hold in the button. Is there anyway I can use getKeyCode to only register on the first click and then won't register until I release the button and press again?
else if (event.getKeyCode()== KeyEvent.VK_UP)
{
spelare1.setLocation(spelare1.getX(),spelare1.getY()-50);
}
This is how it currently looks like.
I think you are confusing KeyEvents. VK_UP is the up arrow key. Use KeyEvent.KEY_RELEASED to react on a released key.
You can keep a boolean indicating whether the key is currently pressed. Then you can react once after each press, like in this example:
public static void main(String[] args) {
JFrame f = new JFrame();
f.addKeyListener(new KeyAdapter() {
private boolean pressed;
#Override
public void keyReleased(KeyEvent e) {
pressed = false;
}
#Override
public void keyPressed(KeyEvent e) {
if (!pressed) {
System.out.println("Key pressed: " + e.getKeyCode());
pressed = true;
}
}
});
SwingUtilities.invokeLater(new Runnable() {
public void run() {
f.setVisible(true);
}
});
}
Depending on your needs, you might want to have a separate state for each key, or just one shared state.

Fire ActionEvent first

I have extended JTextField. There are multiple ActionListeners attached to my class, but I need one in particular to always fire first. Is there a way to ensure that a particular ActionEvent always first first?
Note that I do have a reference to my ActionListener. I am assuming I need to override a method, but I am not sure which one that is.
Is there a way to ensure that a particular ActionEvent always first first?
The Java spec does not guarantee the order in which events are fired.
However, I believe the default implementation is that the last ActionListener added to a component is first first.
Edit:
I use the mouse listener
Why are you using a MouseListener? What happens when the user tabs to/from the field? Don't assume mouse usage. A FocusListener will handle either keyboard or mouse activity in this case.
The problem comes into play when the user presses enter on the text field.
What happens if the user doesn't press enter and they just tab to the next field? That's what I would do.
This needs to happen before other action listners do their thing.
What other ActionListeners? A tgext field would only have a single listener.
Anyway do maybe answer your question you can effectively change the order of execution by using SwingUtilities.invokeLater(...) to place your code on the end of the Event Dispatch Thread so it executes after all other events:
public void actionPerformed(ActionEvent e)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
// add your code here
}
});
}
Again, any solution that depends on the order of events is not a good solution. The order of event could be different on different platforms.
Try to override fireActionPerformed from JTextField. Add custom ActionListener in new class and call him before call super.fireActionPerformed()
Ps: sorry for bad english.
Edit:
public class CustomTextField extends JTextField {
private List<ActionListener> listeners;
public synchronized void addPriorityActionListener(ActionListener l) {
if(l == null) {
return;
}
if(listeners == null) {
listeners = new ArrayList<>();
}
listeners.add(l);
}
public synchronized void removePriorityActionListener(ActionListener l) {
if(l == null || listeners == null) {
return;
}
listeners.remove(l);
}
protected void firePriorityActionPerformed() {
if(listeners == null) {
return;
}
ActionEvent event = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, getText());
for(ActionListener listener: listeners) {
listener.actionPerformed(event);
}
}
#Override
protected void fireActionPerformed() {
firePriorityActionPerformed();
super.fireActionPerformed();
}
}

GWT/ Textbox- single AND double click handler options? possible?

I have created a popup box that extends DialogBox and uses a cellTable that contains a list of values, one of which will be selected and inserted into a textBox.
-I have an onSelectionChange handler which is fired when one of the rows is clicked.
-I have an onDoubleClick handler which is fired when the same rows are double clicked.
both work when the other is commented out. But when they are both in the live code, whichever one is written first gets overwritten by the other one and no longer gets called.
Any way around this?
Code snipbit:
final SingleSelectionModel<popUpBoxContent> selectionModel= new <popUpBoxContent>();
cellTable.setSelectionModel(selectionModel);
selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler(){
public void onSelectionChange (selectionChangeEvent event){
//Do something
}});
final SingleSelectionModel<popUpBoxContent> selectionModel2= new <popUpBoxContent>();
cellTable.setSelectionModel(selectionMode2);
cellTable.addDomHandler(new DoubleClickHandler(){
public void onDoubleClick(final DoubleClickEvent event){
//Do something else
}},
DoubleClickEvent.getType());
Thank you!
Yes they get overwritten from what I can see in the snippet. Assuming "popUpBoxContent" is the data type with which the CellTable (I presume cellTable is a CellTable) is being populated you could try this and see if it works:
final SingleSelectionModel<PopUpBoxContent> selectionModel = new SingleSelectionModel<PopUpBoxContent>();
cellTable.setSelectionModel(selectionModel);
cellTable.addDomHandler(new DoubleClickHandler() {
public void onDoubleClick(final DoubleClickEvent event) {
PopUpBoxContent selected = selectionModel.getSelectedObject();
if (selected != null) {
System.out.println("double clicked");
}
}
},
DoubleClickEvent.getType());
selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
public void onSelectionChange(SelectionChangeEvent event) {
System.out.println("clicked");
}
});

JTextArea new line on shift + enter

I've added a keylistener to my JTextArea field, but it doesn't behave as I expected.
inputTextArea.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent k) {
//If the return button is hit, only set to a new line if shift is also down.
if(k.getKeyChar() == KeyEvent.VK_ENTER) {
if(k.isShiftDown()) {
inputTextArea.append(" \n");
} else {
//Send The Message...
boolean cleanTextField = false;
try {
sendMessage(inputTextArea.getText());
cleanTextField = true;
msgScrollPane.setAutoscrolls(true);
JScrollBar vbar = msgScrollPane.getVerticalScrollBar();
if ((vbar.getValue() + vbar.getVisibleAmount()) == vbar.getMaximum()) {
msgPane.setCaretPosition(msgDoc.getLength());
}
} catch (Exception ex) {
ex.printStackTrace();
cleanTextField = false;
} finally {
if(cleanTextField) {
inputTextArea.setText("");
}
}
}
}
}
});
I want this:
- If the return button is hit and shift is down: add a new line.
- If the return button is hit and the shift button isn't down: no new line, but submit.
Now it behaves like this:
- If I hit the return button and shift is down: no line added. Nothing happens.
- If I hit the return button and shift isn't down: submitted, but if I start typing again it begins on new line.
Does someone know how to do what I want?
EDIT:
I tried some other code to detect if the shift button is down:
if((k.getModifiersEx() == KeyEvent.SHIFT_DOWN_MASK) ||
(k.getModifiers() == KeyEvent.SHIFT_DOWN_MASK)) {
This doesn't work as well
You may use the InputMap and ActionMap of the JTextArea to map the key strokes to actions:
private static final String TEXT_SUBMIT = "text-submit";
private static final String INSERT_BREAK = "insert-break";
...
private void initialize() {
InputMap input = inputTextArea.getInputMap();
KeyStroke enter = KeyStroke.getKeyStroke("ENTER");
KeyStroke shiftEnter = KeyStroke.getKeyStroke("shift ENTER");
input.put(shiftEnter, INSERT_BREAK); // input.get(enter)) = "insert-break"
input.put(enter, TEXT_SUBMIT);
ActionMap actions = inputTextArea.getActionMap();
actions.put(TEXT_SUBMIT, new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
submitText();
}
});
}
...
private void submitText() {
// TODO
}
The original action for ENTER - "insert-break" - is used for shift ENTER.
Try using keyTyped and not keyPressed. I beleive keyPressed gives you an event for the shift and for the enter, whereas keyTyped gives you one combined event with a modifier.
Instead of doing the actions immediately on receiving the event, sequence them for later by posting them using SwingUtilities.invokeLater(). The code should look like:
if(k.isShiftDown()) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
inputTextArea.append(" \n");
}
});
} else {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//rest of the else body here
}
});
}
In my opinion, the problems seen here are because application-defined actions and internal actions are not being properly sequenced, leading to repaints happening before the text has been modified.

Categories