I would like the user to enter a value into the JTextField and use a listener to listen to the textfield and print the value to the console straightaway without pressing a key.
textfield1.addChangeListener(new ChangeListener() {
public void actionPerformed(ActionEvent e) {
System.out.println(textfield1);
}
});
error:
<anonymous textfield$2> is not abstract and does not override abstract method stateChanged(ChangeEvent) in ChangeListener
Put this private class into your public class. Just like a method.
private class textChangedListener implements KeyListener
{
public void keyPressed(KeyEvent e){}
public void keyReleased(KeyEvent e){}
public void keyTyped(KeyEvent e)
{
System.out.print(textField1.getText());
}
}
And then call it to your JTextField in your main method like so:
private JTextField textField1; // just showing the name of the JTextField
textField1.addKeyListener(new textChangedListener());
Yes, just use the KeyListener class, see the example below:
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class Main extends JFrame {
public Main() throws HeadlessException {
setSize(200, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout(FlowLayout.LEFT));
JLabel label = new JLabel("Write something: ");
JTextField input = new JTextField();
input.setPreferredSize(new Dimension(100, 20));
final JTextField output = new JTextField();
output.setPreferredSize(new Dimension(100, 20));
add(label);
add(input);
add(output);
input.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent e) {
JTextField textField = (JTextField) e.getSource();
String text = textField.getText();
output.setText(text);
}
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
}
});
}
public static void main(String[] args) {
new Main().setVisible(true);
}
}
You can set a addlistener to textproperty of the text field.
textField.textProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
System.out.println("textfield changed to "+ newValue);
}
});
Related
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class TheSize extends JFrame implements ActionListener, KeyListener {
static String inText="";
JPanel pane=new JPanel();
JLabel word0=new JLabel("I would like my grid to be 2^",JLabel.RIGHT);
JLabel word1=new JLabel("* 2^ "+inText,JLabel.RIGHT);
JButton finish=new JButton("I'm done");
JTextField size=new JTextField("",3);
public TheSize(){
super("size");
System.out.println("hi");
setLookAndFeel();
setSize(550,100);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
FlowLayout box=new FlowLayout();
setLayout(box);
pane.add(word0);
pane.add(size);
pane.add(word1);
pane.add(finish);
finish.addActionListener(this);
add(pane);
setVisible(true);
pack();
size. addKeyListener(this);
setFocusable(true);
}
private void setLookAndFeel() {
try {
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"
);
} catch (Exception exc) {
// ignore error
}
}
public void actionPerformed(ActionEvent e) {
}
#Override
public void keyPressed(KeyEvent arg0) {
}
#Override
public void keyReleased(KeyEvent arg0) {
}
#Override
public void keyTyped(KeyEvent e) {
inText=size.getText();
pane.revalidate();
pane.repaint();
}
public static void main(String[] args){
new TheSize();
}
}
a couple of things
I made sure the KeyListener is working, and it is not working as in no output, it didn't give me any error.
What should happen:
It should pop a frame which says I would like my grid to be 2^__(user input Textfield)____* 2^(what is in the textfield). (Button for I'm done).
however, (what is in the textfield) remains empty after I type something into the text field. I checked whether the program heard my keystrokes using System.out.println();, and it is working, so the revalidate(); and repaint() commands must not be(I also tested it out by putting a System.out.println(); in my constructor. Thanks in advance
Never use a KeyListener on a JTextField. Get rid of the KeyListener and the JTextField should likely accept text just fine. Instead, if you want to register user input, use a DocumentListener if you just want the text but won't filter it, or a DocumentFilter if you need to filter the text before it is displayed. This sort of question has been asked many times on this site.
Also note that your JLabel will never change, even if you do use a DocumentListener since you call setText(...) on your word1 JLabel but never re-call this method. Just changing the String that the inText String variable refers to of course will not magically change the JLabel's displayed text.
Note, that I'm not sure what you mean by the replicate() command as I've not heard of this method. Do you mean revalidate() if so, please clarify.
For example:
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Window;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
// Avoid extending JFrames if at all possible.
// and only extend other components if needed.
#SuppressWarnings("serial")
public class TheSize2 extends JPanel {
private static final String FORMAT = "* 2^ %s";
private static final int PREF_W = 550;
private static final int PREF_H = 100;
private String inText = "";
private JLabel word0 = new JLabel("I would like my grid to be 2^", JLabel.RIGHT);
private JLabel word1 = new JLabel(String.format(FORMAT, inText), JLabel.RIGHT);
private JButton finish = new JButton("I'm done");
private JTextField size = new JTextField("", 3);
public TheSize2() {
finish.setAction(new FinishAction("I'm Done"));
size.getDocument().addDocumentListener(new SizeListener());
add(word0);
add(size);
add(word1);
add(finish);
}
#Override // make JPanel bigger
public Dimension getPreferredSize() {
Dimension superSz = super.getPreferredSize();
if (isPreferredSizeSet()) {
return superSz;
}
int prefW = Math.max(superSz.width, PREF_W);
int prefH = Math.max(superSz.height, PREF_H);
return new Dimension(prefW, prefH);
}
private class SizeListener implements DocumentListener {
private void textUpdated(DocumentEvent e) {
try {
inText = e.getDocument().getText(0, e.getDocument().getLength());
word1.setText(String.format(FORMAT, inText));
} catch (BadLocationException e1) {
e1.printStackTrace();
}
}
#Override
public void changedUpdate(DocumentEvent e) {
textUpdated(e);
}
#Override
public void insertUpdate(DocumentEvent e) {
textUpdated(e);
}
#Override
public void removeUpdate(DocumentEvent e) {
textUpdated(e);
}
}
private class FinishAction extends AbstractAction {
public FinishAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
Component comp = (Component) e.getSource();
if (comp == null) {
return;
}
Window win = SwingUtilities.getWindowAncestor(comp);
if (win == null) {
return;
}
win.dispose();
}
}
private static void createAndShowGui() {
TheSize2 theSize2 = new TheSize2();
JFrame frame = new JFrame("The Size");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(theSize2);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
I found the solution with the help of Hovercraft Full Of Eels, all I missed was to re setSize. It is not the best solution, but it is simple enough for me to understand.
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class TheSize extends JFrame implements ActionListener, KeyListener {
static String inText="";
JPanel pane=new JPanel();
JLabel word0=new JLabel("I would like my grid to be 2^",JLabel.RIGHT);
JLabel word1=new JLabel("* 2^ "+inText,JLabel.RIGHT);
JButton finish=new JButton("I'm done");
JTextField size=new JTextField("",3);
public TheSize(){
super("size");
setLookAndFeel();
setSize(550,100);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
FlowLayout box=new FlowLayout();
setLayout(box);
pane.add(word0);
pane.add(size);
pane.add(word1);
pane.add(finish);
finish.addActionListener(this);
add(pane);
setVisible(true);
pack();
size.addKeyListener(this);
setFocusable(true);
}
private void setLookAndFeel() {
try {
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"
);
} catch (Exception exc) {
// ignore error
}
}
public void actionPerformed(ActionEvent e) {
}
public static void main(String[] args){
new TheSize();
}
#Override
public void keyPressed(KeyEvent arg0) {
}
#Override
public void keyReleased(KeyEvent arg0) {
inText=size.getText();
word1.setText("* 2^ "+inText);
pane.revalidate();
pane.repaint();
}
#Override
public void keyTyped(KeyEvent arg0) {
}
}
I have this code where I designed an editable JComboBox to listen to my keyPressed event and show a message that the key is pressed. But I have no idea why this not working. As a beginner I might have gone wrong logically/conceptually.
So, I would request for suggestions about how to construct the code, so that it works.
Code
import javax.swing.*;
import java.awt.*;
public class testEJCBX extends JFrame {
JComboBox jcbx = new JComboBox();
public testEJCBX() {
super("Editable JComboBox");
jcbx.setEditable(true);
getContentPane().setLayout(new FlowLayout());
getContentPane().add(jcbx);
jcbx.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyPressed(java.awt.event.KeyEvent evt)
{
jcbxKeyPressed(evt);
}
});
setSize(300, 170);
setVisible(true);
}
private void jcbxKeyPressed(java.awt.event.KeyEvent evt) {
JOptionPane.showMessageDialog(null, "Key Pressed");
}
public static void main(String argv[]) {
new testEJCBX();
}
}
You shouldn't be using a KeyListener for this sort of thing. Rather if you want to detect changes to the combo box's editor component, extract it and add a DocumentListener to it:
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
import java.awt.*;
public class TestEJCBX extends JFrame {
JComboBox<String> jcbx = new JComboBox<>();
public TestEJCBX() {
super("Editable JComboBox");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jcbx.setEditable(true);
getContentPane().setLayout(new FlowLayout());
getContentPane().add(jcbx);
JTextField editorComponent = (JTextField) jcbx.getEditor()
.getEditorComponent();
Document doc = editorComponent.getDocument();
doc.addDocumentListener(new DocumentListener() {
#Override
public void removeUpdate(DocumentEvent e) {
System.out.println("text changed");
}
#Override
public void insertUpdate(DocumentEvent e) {
System.out.println("text changed");
}
#Override
public void changedUpdate(DocumentEvent e) {
System.out.println("text changed");
}
});
pack();
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String argv[]) {
new TestEJCBX();
}
}
I'm making a small java program where I have two JTextFields labeled field1, field2. I have a calculate button as well which initially set to disabled. I want the button only to be enabled when the 2 text boxes have values in them. Currently what i have for the key listener is:
field1.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyReleased(java.awt.event.KeyEvent evt) {
if (field1.getDocument().getLength() > 0) {
bt1.setEnabled(true);
}
else {
bt1.setEnabled(false);
}
}
});
Is there a way to include field 2 into the above block? I've tried just copying and pasting the same code block twice but changing the field1 to field2 but that still doesn't work.
Thanks for the help
You really never want to use a KeyListener with a JTextField as this can mess up the JTextField's function. Much better is to use a DocumentListener and give it to both JTextField's Documents.
For example please check out this similar question
Or if you need to be notified of text changes before they are validated, use a DocumentFilter. For more on that, please see this question.
e.g.,
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class DocListenerEg extends JPanel {
private JTextField field1 = new JTextField(10);
private JTextField field2 = new JTextField(10);
private JButton button = new JButton("Button");
public DocListenerEg() {
add(field1);
add(field2);
add(button);
button.setEnabled(false);
DocumentListener docListener = new DocumentListener() {
#Override
public void removeUpdate(DocumentEvent e) {
checkForText();
}
#Override
public void insertUpdate(DocumentEvent e) {
checkForText();
}
#Override
public void changedUpdate(DocumentEvent e) {
checkForText();
}
private void checkForText() {
boolean textOK = !field1.getText().trim().isEmpty() && !field2.getText().trim().isEmpty();
button.setEnabled(textOK);
}
};
field1.getDocument().addDocumentListener(docListener);
field2.getDocument().addDocumentListener(docListener);
}
private static void createAndShowGui() {
DocListenerEg mainPanel = new DocListenerEg();
JFrame frame = new JFrame("DocListenerEg");
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();
}
});
}
}
You current requirement may be for only two text fields, but you should always design to be more flexible and allow any number of text fields. This also allows the code to be reusable.
Something like:
import java.awt.*;
import java.awt.event.*;
import java.util.List;
import java.util.ArrayList;
import javax.swing.*;
import javax.swing.event.*;
public class DataEntered implements DocumentListener
{
private JButton button;
private List<JTextField> textFields = new ArrayList<JTextField>();
public DataEntered(JButton button)
{
this.button = button;
}
public void addTextField(JTextField textField)
{
textFields.add( textField );
textField.getDocument().addDocumentListener( this );
}
public boolean isDataEntered()
{
for (JTextField textField : textFields)
{
if (textField.getText().trim().length() == 0)
return false;
}
return true;
}
#Override
public void insertUpdate(DocumentEvent e)
{
checkData();
}
#Override
public void removeUpdate(DocumentEvent e)
{
checkData();
}
#Override
public void changedUpdate(DocumentEvent e) {}
private void checkData()
{
button.setEnabled( isDataEntered() );
}
private static void createAndShowUI()
{
JButton submit = new JButton( "Submit" );
submit.setEnabled( false );
JTextField textField1 = new JTextField(10);
JTextField textField2 = new JTextField(10);
DataEntered de = new DataEntered( submit );
de.addTextField( textField1 );
de.addTextField( textField2 );
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(textField1, BorderLayout.WEST);
frame.add(textField2, BorderLayout.EAST);
frame.add(submit, BorderLayout.SOUTH);
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
When I press tab key on the keyboard I want to select my text fields in above order.how to do that?
Try this example....
package com.Demo;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
#SuppressWarnings("serial")
public class TabTest extends JFrame {
public TabTest() {
initialize();
}
private void initialize() {
setSize(300, 300);
setTitle("JTextArea TAB DEMO");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
JTextField textField = new JTextField();
JPasswordField passwordField = new JPasswordField();
final JTextArea textArea = new JTextArea();
JScrollPane scrollPane = new JScrollPane(textArea);
//
// Add key listener to change the TAB behaviour in
// JTextArea to transfer focus to other component forward
// or backward.
//
textArea.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_TAB) {
if (e.getModifiers() > 0) {
textArea.transferFocusBackward();
} else {
textArea.transferFocus();
}
e.consume();
}
}
});
getContentPane().add(textField, BorderLayout.NORTH);
getContentPane().add(scrollPane, BorderLayout.CENTER);
getContentPane().add(passwordField, BorderLayout.SOUTH);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TabTest().setVisible(true);
}
});
}
}
jTextField1.setNextFocusableComponent(jTextField2);
jTextField2.setNextFocusableComponent(jTextField3);
jTextField3.setNextFocusableComponent(jTextField4);
jTextField4.setNextFocusableComponent(jTextField5);
try this :)
Try this:
txtfld.addFocusListener(new FocusListener() {
#Override
public void focusGained(FocusEvent e) {
txtfld.setText("aaa");
}
#Override
public void focusLost(FocusEvent e) {
...
}
});
see more complete code.
This piece of code is a simplified version of a program I would convert to swing (using JTextField and DocumentListener). I have read some tutorials but I can't do it...
I shouldn't use global variables and I have to use some like getSource() (getDocument() in this case?), because in the original program the number of JTextField is variable (they are generated inside a for, so they haven't a "name"). This number depends on a value written in a text file.
import java.awt.*;
import java.awt.event.*;
class TestWindow extends Frame {
public TestWindow() {
Panel p = new Panel(new FlowLayout());
Label l = new Label("Temp");
TextField tf1 = new TextField();
TextField tf2 = new TextField();
tf1.addTextListener(new myTextListener(l));
tf2.addTextListener(new myTextListener(l));
p.add(tf1);
p.add(tf2);
tf1.setColumns(10);
tf2.setColumns(10);
p.add(l);
add(p);
pack();
setVisible(true);
}
class myTextListener implements TextListener {
Label input;
myTextListener(Label input) {
this.input = input;
}
public void textValueChanged(TextEvent e) {
input.setText(((TextField)(e.getSource())).getText());
}
}
}
public class Test {
public static void main(String[] args) {
new TestWindow();
}
}
This is a direct conversion of the code you posted to Swing that performs exactly the same task:
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import java.awt.FlowLayout;
public class TestWindow extends JFrame {
public TestWindow() {
JPanel p = new JPanel(new FlowLayout());
JLabel l = new JLabel("Temp");
JTextField tf1 = new JTextField(10);
JTextField tf2 = new JTextField(10);
tf1.getDocument().addDocumentListener(new MyDocumentListener(l));
tf2.getDocument().addDocumentListener(new MyDocumentListener(l));
p.add(tf1);
p.add(tf2);
p.add(l);
add(p);
pack();
setVisible(true);
}
class MyDocumentListener implements DocumentListener{
private JLabel label;
MyDocumentListener(JLabel label) {
this.label = label;
}
#Override
public void insertUpdate(DocumentEvent e) {
handleTextChange(e);
}
#Override
public void removeUpdate(DocumentEvent e) {
handleTextChange(e);
}
#Override
public void changedUpdate(DocumentEvent e) {
handleTextChange(e);
}
private void handleTextChange(DocumentEvent e) {
try {
label.setText(e.getDocument().getText(0,e.getDocument().getLength()));
} catch (BadLocationException ignored) {
//todo: handle exception properly although this should never happen
}
}
}
public static void main(String[] args) {
new TestWindow();
}
}
Please note that DocumentListener provides more control for handling text change events than the TextListener, but I chose to handle them with one single method in order to exactly match your example's functionality