I have a text area that I would like to become blank when the enter button is pressed. I know this would normally be done with a setText method. However when I do this, the text is removed but the new line function created by the return key being pressed. My question is, is the anyway of stopping this default action from happening?
thanks
Are you listening for the ENTER key on the text area and then clearing it? The following works for me:
final JTextArea ta = new JTextArea();
ta.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER){
ta.setText("");
}
}
#Override
public void keyPressed(KeyEvent e) {
}
});
Hi
I have a text area that I would like to become blank when the enter button is pressed.
This, I understand. Here's how you can do that:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Main {
public static void main(String[]args) {
final JFrame frame = new JFrame();
final JTextArea area = new JTextArea();
area.setPreferredSize(new Dimension(200, 200));
area.addKeyListener(new KeyAdapter(){
#Override
public void keyReleased(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER) {
area.setText("");
}
}
});
frame.add(area);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
I know this would normally be done with a setText method. However when I do this, the text is removed but the new line function created by the return key being pressed. My question is, is the anyway of stopping this default action from happening?
That, I don't understand.
The problem is probably that you are not consuming the keystroke event, and although the text area is cleared, the normal processing of the keystroke ends up inserting a newline.
Rather than trapping the keystroke event (which isn't necessarily portable) I would recommend using a DocumentFilter. There is a tutorial here that shows you how to write one. Implement the filter so that when there is a 'newline' in the insert or replace string, replace the entire contents of the document with "".
However this approach can't tell the difference between a newline typed at the keyboard and one pasted into the text area.
Before you clear the text you need to remove the new line code the return button left. You do that with the consume() method.
So to clear your text:
yourkeyevent.consume();
yourTextObject.setText("");
Instead, you can also use:
yourTextarea.setText(null);
yourTextarea.setCaretPosition(-1);
I solved your problem overriding the code in the method "public void keyTyped(KeyEvent e)" instead of "public void keyPressed(KeyEvent e)" and it works.
Here the code:
package versione1;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class WhiteEnter {
final JFrame frame = new JFrame();
private JTextArea area = new JTextArea();
public static void main(String[]args) {
WhiteEnter prova = new WhiteEnter();
prova.run();
}
public void run(){
area.setPreferredSize(new Dimension(200, 200));
area.addKeyListener(new PressEnterKeyListener());
frame.add(area);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public class PressEnterKeyListener implements KeyListener{
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
}
#Override
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() == (KeyEvent.VK_ENTER)){
try{
area.setText(null);
area.setCaretPosition(0);
} catch(Exception ex){
ex.printStackTrace();
}
}
}
}
}
Related
I want to know how to be able to change a JLabel in java Swing to the button I press but I don't know what I'm missing something. Please help.
What it should end up looking like is on the top of the screen it will show the key being pressed and will update the JLabel as you press it. Don't worry about the Imports, I have them all in the actual code. Thanks :)
public class RandomFrame extends JFrame{
Dimension Size = new Dimension(800,800);
ListenForKeys LFK = new ListenForKeys();
JLabel JInput = new JLabel("");
JPanel P1 = new JPanel();
public static void main(String[] args) {
new RandomFrame();
}
public RandomFrame() {
super("RandomFrame");
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setSize(Size);
P1.add(JInput);
this.add(P1);
this.setVisible(true);
}
private class ListenForKeys implements KeyListener {
#Override
public void keyPressed(KeyEvent e) {
String Key = String.valueOf(e.getKeyChar());
JInput.setText(Key);
}
#Override
public void keyReleased(KeyEvent e) {}
#Override
public void keyTyped(KeyEvent e) {}
}
}
Austin pointed out that LFK wasn't attached to anything and sure enough, I added it to the JFrame using the line this.addKeyListener(LFK) and sure enough it worked. Thank you :)
I want to write a live search using Swing components. I am using a keyListener to keep track of the input. Basically i dont want the keyListener to take action every time a button is pressed but instead wait (for some period of time) for more incoming input. This period of time is refreshed every time a button is pressed and the input gets evaluated when it eventually times out (e.g. no button is being pressed within the period meaning that the input is complete). How do I implement that into my keyListener?
Code snippet of main method:
static JTextField nameTextField = new JTextField();
public static void main(String args[]) throws Exception {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(nameTextField, BorderLayout.NORTH);
nameTextField.addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent keyEvent) {
//
}
#Override
public void keyPressed(KeyEvent e) {
//
}
#Override
public void keyReleased(KeyEvent e) {
if(waitForMoreInput(50)) {
doSomething(nameTextField.getText());
}
}
}
}
}
);
frame.setSize(250, 100);
frame.setVisible(true);
}
Thanks in advance
Much better is for you to use a DocumentListener or DocumentFilter, depending on if you want to listen before or after text has been fully registered with the text component.
The DocumentListener will register any time the text has changed, be it via a key press, via a copy and paste, via a deletion of text. The Timer will then wait however long you wish to do whatever action is required on the text. For example:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
public class DocListenerFoo extends JPanel {
private JTextField nameTextField = new JTextField(20);
public DocListenerFoo() {
add(new JLabel("Add Text:"));
add(nameTextField);
int timerDelay = 1000; // one second
nameTextField.getDocument().addDocumentListener(new MyDocListener(timerDelay));
}
private class MyDocListener implements DocumentListener {
private Timer docTimer;
private int timerDelay;
public MyDocListener(int timerDelay) {
this.timerDelay = timerDelay;
}
#Override
public void changedUpdate(DocumentEvent e) {
textChangedAction(e);
}
#Override
public void insertUpdate(DocumentEvent e) {
textChangedAction(e);
}
#Override
public void removeUpdate(DocumentEvent e) {
textChangedAction(e);
}
private void textChangedAction(DocumentEvent e) {
Document doc = e.getDocument();
try {
String text = doc.getText(0, doc.getLength());
if (docTimer != null && docTimer.isRunning()) {
docTimer.stop();
}
docTimer = new Timer(timerDelay, new TimerListener(text));
docTimer.setRepeats(false);
docTimer.start();
} catch (BadLocationException e1) {
e1.printStackTrace();
}
}
}
private class TimerListener implements ActionListener {
private String text;
public TimerListener(String text) {
this.text = text;
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO do check on text here
System.out.println("Checking text here: " + text);
}
}
private static void createAndShowGui() {
DocListenerFoo mainPanel = new DocListenerFoo();
JFrame frame = new JFrame("DocListenerFoo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Don't wait inside the key or document event, it just blocks the program from being processed further. Instead save the current time or (re)start a timer in the event and execute your action later somewhere else.
I'm guessing that you're trying to use a KeyListener with a Swing text component such as a JTextField (I have to guess since you don't tell or show us). If so, then the best solution is don't. Using a KeyListener with these components can mess up the functionality of the components. Much better is for you to use a DocumentListener or DocumentFilter, depending on if you want to listen before or after text has been fully registered with the text component.
For a better more complete answer, post a better more complete question, including your minimal code example and details about your problem.
I have looked at many sites and did not get a result. I have some JTextFields that only accept one character. What I need is that when I press BACKSPACE that character is cleared and the focus returns to the previous JTextField and so on. I added a KeyListener to all JTextFields and try KeyTyped, KeyReleased and KeyPressed events but none worked. The code below:
jt.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent evt) {
char c = evt.getKeyChar();
if(Character.isLetter(c) || Character.isISOControl(c))
{
evt = evt;
} else
evt.consume();
}
public void keyReleased(KeyEvent evt) {
if(evt.getKeyChar() == KeyEvent.VK_BACK_SPACE)
{
robot.keyPress(KeyEvent.VK_BACK_SPACE);
robot.keyRelease(KeyEvent.VK_BACK_SPACE);
robot.keyPress(KeyEvent.VK_SHIFT);
robot.keyPress(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_TAB);
robot.keyRelease(KeyEvent.VK_SHIFT);
}
}
});
Thanks for any help.
Don't use a KeyListener. Swing was designed to be used with Key Bindings.
Don't use the Robot. The API has a method that allows you to transfer focus.
Here is the basic code for the Key Binding:
textField.getInputMap().put(KeyStroke.getKeyStroke("BACK_SPACE"), "backspace");
textField.getActionMap().put("backspace", new AbstractAction()
{
#Override
public void actionPerformed(ActionEvent e)
{
Component c = (Component)e.getSource();
c.transferFocusBackward();
}
});
I have some JTextFields that only accept one character.
You may also want to look at Text Field Auto Tab. It is a class that will allow you to automatically tab to the next text field when a character is entered.
I've quickly made a small app that hopefully solved your problem, here's the entire code:
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import javax.swing.GroupLayout;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class BackspaceTest extends JFrame implements KeyListener {
// In this example I've used 4 Text Fields, each of which takes 1 character
private JTextField text1, text2, text3, text4;
// I've stored the Text Fields in a ArrayList so we can easily shuffle trough them later
private ArrayList<JTextField> fieldList = new ArrayList<>();
// Numerical value for tracking the currently focused TextField
private int focusIndex;
// This constructor is the first thing that gets called from main
public BackspaceTest() {
init();
}
private void init() {
// Initialize the text fields with 1 character column size
text1 = new JTextField(1);
text2 = new JTextField(1);
text3 = new JTextField(1);
text4 = new JTextField(1);
// Key listeners for implementing 1 character limitations and Backspace functionality
text1.addKeyListener(this);
text2.addKeyListener(this);
text3.addKeyListener(this);
text4.addKeyListener(this);
// The focus listener keeps track of currently focused Text Fields
text1.addFocusListener(new TextFocusListener());
text2.addFocusListener(new TextFocusListener());
text3.addFocusListener(new TextFocusListener());
text4.addFocusListener(new TextFocusListener());
// The default focus is on the first field
text1.requestFocus();
fieldList.add(text1);
fieldList.add(text2);
fieldList.add(text3);
fieldList.add(text4);
// Puts the items on the screen
createLayout(text1, text2, text3, text4);
setTitle("Backspace Test");
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
private void createLayout(JComponent... arg) {
JPanel panel = (JPanel) getContentPane();
GroupLayout gl = new GroupLayout(panel);
panel.setLayout(gl);
gl.setAutoCreateContainerGaps(true);
gl.setAutoCreateGaps(true);
gl.setHorizontalGroup(gl.createSequentialGroup()
.addComponent(arg[0])
.addComponent(arg[1])
.addComponent(arg[2])
.addComponent(arg[3])
);
gl.setVerticalGroup(gl.createParallelGroup()
.addComponent(arg[0])
.addComponent(arg[1])
.addComponent(arg[2])
.addComponent(arg[3])
);
gl.linkSize(text1, text2, text3, text4);
pack();
}
class TextFocusListener implements FocusListener {
#Override
public void focusGained(FocusEvent e) {
focusIndex = fieldList.indexOf(getFocusOwner());
System.out.println(focusIndex);
}
#Override
public void focusLost(FocusEvent e) { }
}
#Override
public void keyTyped(KeyEvent e) { }
#Override
public void keyPressed(KeyEvent e) {
JTextField focusedText = fieldList.get(focusIndex);
// Check if BACKSPACE is pressed and if Text Field is empty and if it's not the first field
if (e.getKeyCode() == KeyEvent.VK_BACK_SPACE &&
focusedText.getText().equals("") &&
focusIndex > 0) {
fieldList.get(--focusIndex).requestFocus();
}
}
#Override
public void keyReleased(KeyEvent e) {
// This limits the amount of characteres to 1. I'm not fully pleased with it but it works for this demonstration
if (text1.getText().length() >= 1)
text1.setText(text1.getText().substring(0, 1));
if (text2.getText().length() >= 1)
text2.setText(text2.getText().substring(0, 1));
if (text3.getText().length() >= 1)
text3.setText(text3.getText().substring(0, 1));
if (text4.getText().length() >= 1)
text4.setText(text4.getText().substring(0, 1));
}
// Here's where the program starts
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new BackspaceTest().setVisible(true);
}
});
}
});
If you don't have time to run it, look at the line 96, I think the Focus Listener is a good way to solve your problem. Hope this helps you out, good luck!
i have to check if i pressed left, right or both buttons on my mouse, here is a sample code:
package sandbox;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Sandbox extends JFrame {
public static void main(String[] args) {
Sandbox s = new Sandbox();
s.setVisible(true);
}
public Sandbox() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(300, 200);
setResizable(false);
setTitle("Frame");
setLayout(null);
JButton but = new JButton("click me");
but.setBounds(0, 0, 120, 50);
but.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
if(SwingUtilities.isLeftMouseButton(e) | SwingUtilities.isRightMouseButton(e))
System.out.println("both");
else if(SwingUtilities.isLeftMouseButton(e))
System.out.println("left");
else if(SwingUtilities.isRightMouseButton(e))
System.out.println("right");
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
});
add(but);
}
}
i have to make it using SwingUtilities, but there is a problem if i press left or right single button it will print "both", not "left" or "right", if i used MouseEvent class it was working properly but i need it with SwingUtilities class if it's possible, thanks.
EDIT: using MouseEvent class it's working right:
if(e.getModifiersEx() == (MouseEvent.BUTTON1_DOWN_MASK | MouseEvent.BUTTON3_DOWN_MASK))
...
Don't check using OR (|) but use AND (& or better the short cut version &&) instead:
if(SwingUtilities.isLeftMouseButton(e) && SwingUtilities.isRightMouseButton(e))
...
Update:
For checking if both buttons are pressed, SwingUtilities doesn't seem to be the right tool. The isXxxxMouseButton(...) methods do the same as you do, they check the button masks, but use different masks which seem not be set when both buttons are pressed.
As an example, isRightMouseButton() is implemented as follows:
public static boolean isRightMouseButton(MouseEvent anEvent) {
return ((anEvent.getModifiers() & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK);
}
As you can see, the implementation isn't that complext, so you might be better off to just do the mask check yourself.
mouse listene event on button
but.addMouseListener(new MouseListener() {
mouse listener event on fame.
this.addMouseListener(new MouseListener() {
Please check with '||' not '|', don't use the && because it is not possible to press both buttons at the same time
if(SwingUtilities.isLeftMouseButton(e) || SwingUtilities.isRightMouseButton(e))
You will get result
both
left
both
left
both
right
I have 2 textfields in my project. The first textfield is txtNumA and the second is txtNumB. I disabled txtNumB. When txtNumA is not empty, txtNumB will be enabled.
Well, this is part of code I've tried:
private void txtNumKeyTyped(java.awt.event.KeyEvent evt) {
if(!(txtNumA.getText().trim().equals(""))){
txtNumB.setEnabled(true);
}
else {
txtNumB.setText(null);
txtNumB.setEnabled(false);
}
}
Actually it works, but not perfect. It works only if I typed 2 or more characters in txtNumA. What I need is when I typed one character and more, txtNumB will be enabled.
What's wrong with my code?
What is happening here is,
In case of KeyTyped and KeyPressed events the input is not still given to the TextField.That's why it is not working and works after you type the second character and by that time first character must have reached the TextField.So use KeyReleased method to handle this case.
t is the first TextField and t1 is second.
t.addKeyListener(new KeyListener(){
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
JTextField bt = (JTextField)e.getSource();
if(bt.getText().trim().length()>0){
t1.setEnabled(true);
}
else
t1.setEnabled(false);
}
});
The correct way is to add a DocumentListener to the Document of your JTextField:
public final class TextFieldListener implements DocumentListener {
public static void main(final String... args) {
SwingUtilities.invokeLater(() -> new TextFieldListener().go());
}
private final JFrame frame = new JFrame();
private final JTextField field = new JTextField();
private final JTextField field2 = new JTextField();
private TextFieldListener() {
field.getDocument().addDocumentListener(this);
frame.setLayout(new GridLayout(2, 0));
frame.add(field);
frame.add(field2);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
onFieldUpdated();
}
private void go() {
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void onFieldUpdated() {
setField2Enabled(!field.getText().isEmpty());
}
private void setField2Enabled(final boolean enabled) {
field2.setEnabled(enabled);
}
#Override
public void insertUpdate(final DocumentEvent e) {
onFieldUpdated();
}
#Override
public void removeUpdate(final DocumentEvent e) {
onFieldUpdated();
}
#Override
public void changedUpdate(final DocumentEvent e) {}
}
It is not correct to add a KeyListener to your text field if you are interested in changes to its content.
Further reading:
JTextComponent
Document
Text Component Features
How to Use Text Fields
How to Write a Document Listener
I think the problem with this working for 2 characters is because getText() method returns not updated value, i.e. it returns the value BEFORE the change. What you need to do is somehow update that value before you compare it to empty string.
You may need to investigate KeyEvent to see if user adds another character or is it e.g. backspace...