I have been trying to make a text changed event handling mechanism for my JTextArea. For my purposes an event has to be fired whenever there is a change in the text of the JTextArea. I tried using the KeyListener interface and here is my code for that.
txtArea.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent arg0) {
}
#Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyPressed(KeyEvent arg0) {
currentText = text.getText();
if (currentText == textString)
JOptionPane.showMessageDialog(null, "Correct");
}
});
Nothing happened when the textarea's text matched the hardcoded text. How can an event changed event be made for this.
Can this objective be achieved with a PropertyChangedListener? If it can, then how?
I would get the JTextArea's Document via getDocument() (a PlainDocument actually) and use a DocumentListener to listen for changes. This way you'd capture changes from key strokes and also from copy/paste/cut events.
Not the JTextArea, but the contained document receives updates, so you need:
jTextArea.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void removeUpdate(DocumentEvent e) {
}
#Override
public void insertUpdate(DocumentEvent e) {
}
#Override
public void changedUpdate(DocumentEvent arg0) {
}
});
You are comparing strings with ==
if (currentText == textString)
This will never be true. This compares if the strings are the same String object. You should use equals.
if (currentText.equals( textString) )
You might also want to check out DocumentListeners.
See also this How do I compare strings in Java?
Related
How can I make this ActionListener into a method for a specific JButton?
(im aware its possible to throw it all in an method but yeah..hm.)
myJButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e){
//do stuff
}
});
thx y'all,
edit: thanks everyone for the quick responses, my explanation wasn't very clear.
I looked into the use of lambdas and it was pretty much what I was thinking of, though the other ways are great to know aswell.
myButton.addActionListener(e -> myButtonMethod());
public void myButtonMethod() {
// code
}
Thank you again, everyone.
I'll try to be more clear and quicker next time.
Again, your question remains unclear. Your code above has a method, one that code can be put into:
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// you can call any code you want here
}
});
Or you could call a method of the outer class from that method:
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
button1Method();
}
});
// elsewhere
private void button1Method() {
// TODO fill with code
}
Or you could call a method of the inner anonymous class from that code
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
button1Method();
}
private void button1Method() {
// TODO fill with code
}
});
Or you could use lambdas:
button2.addActionListener(e -> button2Method());
// elsewhere
private void button2Method() {
// TODO fill with code
}
Or you could use a method reference:
button3.addActionListener(this::button3Method);
// elsewhere
private void button3Method(ActionEvent e) {
// TODO fill with code
}
Up to you to try to be clear on what exactly it is you're trying to do and what's preventing you from doing it.
I have a lot of different JFormattedTextFields with action and keylisteners. Every Field has a keylistener, so when I press enter I will focus the next JFormattedTextField. The Problem is, for some JFormattedTextFields my code is formatting the input and then sets the text new and for those selectAll() does not work.
JFormattedTextField a = new JFormattedTextField(someDouble);
JFormattedTextField b = new JFormattedTextField(someDouble2);
a.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
leasingfaktor1Field.selectAll();
if(...) {
//do something
a.setText(tausenderPunkt(someValue));
}
}
});
a.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 10) {
b.requestFocusInWindow();
}
}
});
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
leasingfaktor1Field.selectAll();
if(...) {
//do something
b.setText(tausenderPunkt(someValue));
}
}
});
b.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 10) {
c.requestFocusInWindow();
}
}
});
The function tausenderPunkt():
public String tausenderPunkt(double value) {
String s = String.format("%1$,.2f", value);
return s;
}
So when my cursor is in field a and i press enter the cursor goes to field b but does not select the text or values. When i do not use setText() i do not have the problem. Somebody has a solution?
Edit: For some JFormattedTextFields the solution was to add selectAll() to the keyAdapter, but not for all.
For example:
b.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 10) {
c.requestFocusInWindow();
c.selectAll();
}
}
});
Edit2:
The problem seems to be when i create the JFormattedTextFields.
When i do not create them with a value in the constructor it works.
But i have to do.
Before moving to your next text field you should consider handling all the required conditions for the text field you are currently focused on and this would of course include the formatting of values or text supplied to that field. Once all the desired conditions are met then move on to the next text field.
In reality this can all be accomplished through the keyPressed event for your particular situation. There is no need for the actionPerformed event on any of your text fields, for example:
a.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
checkConditions(a, b);
}
}
});
b.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
checkConditions(b, c);
}
}
});
//---------- and so on -------------
Here is a simple method so as to eliminate the need for repetitious code:
private void checkConditions(JFormattedTextField fieldA, JFormattedTextField fieldB) {
// Make sure something is contained within fieldA and
// that it's actually numerical text.
if(!fieldA.getText().isEmpty() &&
fieldA.getText().matches("([-]?)\\d+([,]\\d+)?(([.]\\d+)?)")) {
// Convert the supplied text to Double and
// ensure the desired numerical formating.
String res = (String)tausenderPunkt(Double.parseDouble(fieldA.getText().replace(",","")));
fieldA.setText(res);
// Set Focus to our next text fieldB.
fieldB.requestFocusInWindow();
// Highlight the contents (if any) within the
// next text fieldB.
fieldB.selectAll();
}
// If fieldA is empty or fieldA does not contain
// numerical text then inform User and re-highlight
// the entry in fieldA.
else {
JOptionPane.showMessageDialog (null, "Please Enter Numerical Values Only!",
"Incorrect Entry", JOptionPane.WARNING_MESSAGE);
fieldA.selectAll();
}
}
If you want the contents of your first text field to be highlighted as soon as focus has been established upon it (tabbed to or clicked on) then consider using a FocusGained event for that component or any other component where you desire the same effect.
I Hope this has helped in some way.
EDITED!
So as to handle OP's particular situation.
String str=this.getText();
this.setText(str);
this.selectAll();
You can get the focus owner and remove the focusable feature:
Component focusOwner = FocusManager.getCurrentManager().getFocusOwner();
When you get the component, put this sentence after load it:
component.setFocusable(false);
Hello guyz i am new to java swing and working on a project, I am unable to update the text which i was typed in text field to text area in java swing , I am using this Example as a reference , but i am making my GUI using Drag and Drop in Netbeans by using JFrame Form
Here is my code
private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
String s = this.jTextField1.getText();
jTextArea1.setEditable(false);
jTextField1.getDocument().addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent de) {
jTextArea1.setText(s);
}
#Override
public void removeUpdate(DocumentEvent de) {
jTextArea1.setText(s);
}
#Override
public void changedUpdate(DocumentEvent de) {
//Plain text components don't fire these events.
}
});
}
I am unable to do this by using Drag and drop method , whereas its working fine for me as like example which i have posted above.
Any help would be highly appreciate
Normally, we don't put a Listener inside another Listener, which makes the inner Listener to be called multiple times.
Clear out the following code.
jTextArea1.setEditable(false);
jTextField1.getDocument().addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent de) {
jTextArea1.setText(s);
}
#Override
public void removeUpdate(DocumentEvent de) {
jTextArea1.setText(s);
}
#Override
public void changedUpdate(DocumentEvent de) {
//Plain text components don't fire these events.
}
});
Then use your Netbeans GUI Builder to make the jTextArea1 non-editable ( in the Properties ) and also add a DocumentListener to the jTextField1 like what you did with its ActionListener.
Then update the text in the newly added methods created by the GUI Builder, which I believed to be:
public void jTextField1RemoveUpdate(DocumentEvent de)
public void jTextField1InsertUpdate(DocumentEvent de)
in each method, you make a call to jTextArea1.setText(jTextField1.getText());
I am working on a Java application and interfacing with an RFID reader that acts as a keyboard input device.
The application will be used for employee time tracking, so the employee should not see the code that his/her RFID tag contains.
Currently, the application opens a jFrame that asks the employee to scan their tag. This is where I would like to listen for the keyboard input.
All of the RFID tags are 10 digits, so I would like to use some kind of regex to detect when a card is scanned if possible.
If someone could point me in the right direction, or contribute some code I would be grateful.
Thanks in advance.
UPDATE:
I was able to read the input of the scanner by adding the following to the constructor of my JFrame.
addKeyListener(new KeyListener(){
#Override
public void keyPressed(KeyEvent e){ System.out.print(e.getKeyChar());}
#Override
public void keyReleased(KeyEvent e) { }
#Override
public void keyTyped(KeyEvent e) { }
});
So it is now confirmed that the Reader is just standard Keyboard input.
Here is an example of what I get for a tag: 0006459027
Now, the big question is, how do I take the characters that I got, and detect that it is a 10 digit string, and from there trigger an event to open a new frame?
First, I'd see if the RFID reader is triggering an ActionEvent to be fired when the tag is scanned. This would be the simplest approach.
Failing that, you would need to attach a DocumentListener to the fields underlying document and monitor for changes.
You'll need to decide how best to interrupt the results (as you're likely to get each letter of the RFID at a time). You could monitor the length of the document or have a javax.swing.Timer which triggers after a short delay (you'd reset the timer on each update event triggered by the DocumentListener)
Check out
JTextField.addActionListener
JTextField.getDocument().addDocumentListener
I'd suggest taking a look at DocumentFilter as well, but your interested in the final result, not modifying it.
UPDATED with DocumentListener Example
// In the classes variable decleration section...
private JTextField rfidField;
// In the classes constructor or UI init method...
rfidField = new JTextField(12);
rfidField.getDocument().addDocumentListener(new DocumentListener() {
public void handleUpdate(DocumentEvent e) {
if (e.getDocument().getLength() == 10) {
System.out.println("Trigger me happy...");
SwingUtilities.invokeLater(new Runnable() {
public void run() {
rfidField.setText(null);
}
});
}
}
#Override
public void insertUpdate(DocumentEvent e) {
handleUpdate(e);
}
#Override
public void removeUpdate(DocumentEvent e) {
handleUpdate(e);
}
#Override
public void changedUpdate(DocumentEvent e) {
handleUpdate(e);
}
});
// Now don't forget to add the field to your forms container ;)
//////
One of things I would be do when you "trigger" the code event is, once you've read it from the text field, is clear the text field (JTextField.setText(null)) - IMHO
If the RFID reader acts as a keyboard input device, try with key events:
JFrame frame = new JFrame();
// frame setup
frame.addKeyListener(new KeyAdapter(){
public void KeyPressed(KeyEvent ke)
{
System.out.println(ke);
}
});
Otherwise you have to check which kind of event it fires.
I was in a similar situation but with a bar-code scanner.
I really worked hard on a custom DocumentListener that would take care of all scenarios, and none of it worked.
Out of desperation, I added an ActionListener and it then worked very well.
Here is a code snap-shot :
try {
txtStockItemRef.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
System.out.println(txtStockItemRef.getText());
DatabaseManager.peformStockItemLookupByBarcodeRef(txtStockItemRef.getText());
}
});
} catch(Exception exc) {
LiveCityRetailTools.handleExceptionWithUserMessage(exc);
}
have tried a few different approaches to this but with no success so far. Just wondered if I'm missing anything. I have a JSpinner which is a component of a DateSelector widget alongside a Calendar. I am trying to fire a validation method if the user changes any text in the JSpinner instead of using the Calendar control or the JSpinner up and down arrows.
Here are the different approaches I have tried:
jSpinner1.addKeyListener(kl);
jSpinner1.getEditor().addKeyListener(kl);
((JSpinner.DefaultEditor) jSpinner1.getEditor().getTextField().addKeyListener(kl);
Anyone out there got any ideas as to what I'm doing wrong? Thanks
UPDATE
Apologies, I should have said that I have already added a ChangeListener to the JSpinnerDateModel which is attached to the JSpinner. Like so:
ChangeListener changeListener = new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
dateChanged();
}
};
jSpinnerDateModel.addChangeListener(changeListener);
KeyListener keyListener = new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyPressed(KeyEvent e) {
System.out.println(e.getKeyChar());
dateChanged();
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
};
((JSpinner.DefaultEditor) jSpinner1.getEditor()).getTextField().addKeyListener(
keyListener);
Thanks
Frank
If you want to disable keyboard editing do this:
JFormattedTextField tf = ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField();
tf.setEditable(false);
To listen for key events you need to add a listener to the text field. This works for me:
((JSpinner.DefaultEditor)spinner.getEditor()).getTextField().addKeyListener(new KeyListener(){
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
System.out.println("PRESSED!");
}
#Override
public void keyTyped(KeyEvent e) {
}
});
JSpinners handle KeyEvents themselves, but they fire ChangeEvents to the outside world. Adding a ChangeListener should allow you to perform the validation you wish.
See also: Detecting Spinner Value Changes (Java Tutorials)
This is a shortfall of swing, and in my opinion JSpinner should follow JComboBox in supplying the following access to the underlying text field:
JComboBox.getEditor().getEditorComponent()
From going through the source of J1.7 I found you can acheive pretty much the same thing with
JSpinner.getEditor().getComponent(0)
Therefore you can "hack" the listener in the following way:
JSpinner.getEditor().getComponent(0).addKeyListener(...)
Obviously this depends on the 'under the covers' implementation of swing and works as at J1.7 but there is no guarantee this works for other versions future or past.
Enjoy.
EDIT
or if the editor is an instance of DefaultEditor, you can cast it as such and use 'getTextField()'. It would be handy if this were defined in the interface.