I'm tying to make a program that acts similar to the Windows Command Prompt, or a terminal. It's basically just a JFrame with a JTextArea as output, and a JTextField as input. It looks like this:
I want to be able to get input from the JTextField whenever my program calls a method that returns a String, something like:
public static String getInput() {
//Wait for user to enter something, then press the enter key
}
I added an AbstractAction so I can do stuff when the enter key is pressed, but I still could figure out how to return the input as a String whenever I call the method.
Action action = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e) {
//Clears the JTextField
input.setText("");
}
};
I could put something like userInput = input.getText() in public void actionPerformed(), so it would just set a variable to whatever has been entered every time, and use userInput whenever I want to, but I want the user to have time to read whats on the screen, then have the program wait for a response, instead of just using the last thing they entered right away.
I tried to use a userInput variable and a boolean variable like this:
private static String userInput = "";
private static boolean enterPressed = false;
Action action = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e) {
userInput = input.getText()
enterPressed = true;
input.setText("");
}
};
...
public static String getInput() {
enterPressed = false;
while(!enterPressed){
//Do Nothing
}
enterPressed = false;
return userInput;
}
When I called output.setText(getInput());, it worked like I wanted to, except that the while(!enterPressed){} made my processor work a lot harder than it should need to. I'm pretty sure there's probably a lot better way of doing this.
Here's my whole code right now:
public class ConsoleFrame {
//Objects for Console Frame
JFrame frame = new JFrame();
JTextArea output = new JTextArea();
JTextField input = new JTextField();
BoxLayout boxLayout = new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS);
JScrollPane scrollPane = new JScrollPane(output);
DefaultCaret caret = (DefaultCaret)output.getCaret();
Action action = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e) {
input.setText("");
}
};
ConsoleFrame(){
input.addActionListener(action);
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
frame.setLayout(boxLayout);
frame.add(scrollPane);
frame.add(input);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 250);
frame.setLocationRelativeTo(null);
input.setMaximumSize(new Dimension(Integer.MAX_VALUE, 10));
output.setEditable(false);
output.setAutoscrolls(true);
}
public static String getInput() {
return null;
}
}
So, how could I stop the program until the user presses enter, every time I call getInput();?
I want to be able to get input from the JTextField whenever my program
calls a method that returns a String, something like:
I added an AbstractAction so I can do stuff when the enter key is
pressed, but I still could figure out how to return the input as a
String whenever I call the method.
public String getInput() {
return input.getText();
}
So, how could I stop the program until the user presses enter, every time I call getInput();?
You don't. Swing, like most UI frame works is event driven, that is, something happens and your respond to it.
So, with that in mind you should consider using some kind Observer Pattern, where you use a call back to be notified of some kind of change which you are interested in, like your ActionListener for example.
Instead, you could provide some kind of listener, which interested parties would register with and when the field changes you would notify them, for example...
import java.util.EventListener;
import java.util.EventObject;
public class InputEvent extends EventObject {
private final String text;
public InputEvent(Object source, String text) {
super(source);
this.text = text;
}
public String getText() {
return text;
}
}
public interface InputObsever extends EventListener {
public void inputChanged(InputEvent evt);
}
So, we now have an observer who will be notified when ever the input is changed/updated.
Then we simply need a way to un/register and fire the event...
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.event.EventListenerList;
import javax.swing.text.DefaultCaret;
public class ConsoleFrame {
//Objects for Console Frame
JFrame frame = new JFrame();
JTextArea output = new JTextArea();
JTextField input = new JTextField();
BoxLayout boxLayout = new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS);
JScrollPane scrollPane = new JScrollPane(output);
DefaultCaret caret = (DefaultCaret) output.getCaret();
Action action = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
fireInputChanged(input.getText());
input.selectAll();
}
};
private EventListenerList listenerList = new EventListenerList();
ConsoleFrame() {
input.addActionListener(action);
caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
frame.setLayout(boxLayout);
frame.add(scrollPane);
frame.add(input);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 250);
frame.setLocationRelativeTo(null);
input.setMaximumSize(new Dimension(Integer.MAX_VALUE, 10));
output.setEditable(false);
output.setAutoscrolls(true);
}
public String getInput() {
return input.getText();
}
public void addInputObsever(InputObsever obsever) {
listenerList.add(InputObsever.class, obsever);
}
public void removeInputObsever(InputObsever obsever) {
listenerList.remove(InputObsever.class, obsever);
}
protected void fireInputChanged(String text) {
InputObsever[] listeners = listenerList.getListeners(InputObsever.class);
if (listeners.length > 0) {
InputEvent evt = new InputEvent(this, text);
for (InputObsever obsever : listeners) {
obsever.inputChanged(evt);
}
}
}
}
Now, the point here is, when you want to know when the text has been input/changed, you register an observer to the instance of the ConsoleFrame
console.addInputObsever(new InputObsever() {
#Override
public void inputChanged(InputEvent evt) {
// Do what ever you need to do...
}
});
EDIT: First half removed. It was brought to my attention that it was erroneous.
The best option is to enclose a call to whatever you need your computer to execute after the user inputs text inside your actionPerformed method. So when the user inputs text and presses enter, the program automatically continues from there.
Action action = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e) {
userInput = input.getText()
enterPressed = true;
input.setText("");
//call next method;
}
};
This requires some more formatting work on your behalf, but it could be helpful depending on your project. This link has more information on this strategy.
Hope this helped.
jTextField1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
yourFunction(jTextField1.getText());
jTextField1.setText("");
}
});
Btw just a tip, you may append the JTextArea to get the feel of a console window
Related
I am new to Java and have just tried out Java's swing, I tried making a log in form that would print the content of a JTextField to the console, but the console doesn't show anything when I tried it.
Here's my code:
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JButton;
public class JavaTextField {
private JFrame frame;
private JTextField text1;
private JTextField text2;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
JavaTextField window = new JavaTextField();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public JavaTextField() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
text1 = new JTextField();
text1.setBounds(114, 38, 122, 40);
frame.getContentPane().add(text1);
text1.setColumns(10);
String majorText = text1.getText();
text2 = new JTextField();
text2.setBounds(114, 117, 86, 20);
frame.getContentPane().add(text2);
text2.setColumns(10);
String minorText = text2.getText();
JButton btnButton = new JButton("Button");
btnButton.setBounds(132, 192, 159, 40);
frame.getContentPane().add(btnButton);
btnButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println(majorText);
System.out.println(minorText);
}
}
);
}
}
I'm glad if anyone could point me in the right direction, because I haven't seen the solution to this problem on the internet yet.
The issue here is, that you retrieve the content from the JTextFields at the wrong time. Currently you call getText() right when the components are being initialized. Of course, the content returned from getText() will be an empty String.
So to fix the issue in your logic, you should actually retrieve the majorText and minorText from the JTextFields only once your JButton has been pressed. Because at that point in time, when your button is pressed, the content of your text fields should be correct. To do that, move the retrieval of the text to the ActionListener.
The updated ActionListener should look as follows:
btnButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String majorText = text1.getText();
String minorText = text2.getText();
System.out.println(majorText);
System.out.println(minorText);
}
}
or simply:
btnButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println(text1.getText());
System.out.println(text2.getText());
}
}
Sidenote (as also mentioned by the other answer):
Using null layout is highly discouraged, as it is a frequent source for unnecessary errors. Have a look at the different LayoutManagers available and how and when to use them.
There are some improvements to do in your code:
Avoid the use of null-layout and setBounds(...), see why should you avoid it and a graphic example along with a suggestion to fix it by using layout managers
Your majorText is getting the text BEFORE you click on the button, and by that time it's empty and never update it, you need to get the text on button click, so move this line:
String majorText = text1.getText();
Inside your actionListener, same thing for minorText
And if you tagged your question with Java 8, then you could rewrite your listener using Java 8 lambdas
btnButton.addActionListener(e -> {
String majorText = text1.getText();
String minorText = text1.getText();
System.out.println(majorText);
System.out.println(minorText);
}
I want the user to type a name for player one and press enter and then for the textfield to be blank again so that the user can type in a name for player 2. so far I can only get player one's name as input but not player two. For some reason my code isn't working. Any help would be greatly appreciated. Thanks in advance.
import java.lang.*;
import java.util.*;
import java.util.List;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
public class mainClass extends JPanel implements ActionListener {
//constant variables to use
static String playerOneName;
static String playerTwoName;
static boolean playerOneNameSet;
static boolean playerTwoNameSet;
private static final long serialVersionUID = 1L;
public mainClass() {
}
public void paintComponent(Graphics g) {
//set background color to white
g.setColor(Color.white);
g.fillRect(0, 0, getWidth(), getHeight());
}
public static void initializeBoard() {
}
public static void main(String[] args) {
// title of frame
JFrame frame = new JFrame("Risk");
JTextField textField = new JTextField(20);
frame.add(textField, BorderLayout.SOUTH);
JLabel welcome = new JLabel("");
welcome.setText("Please Enter name for Player 1 in the text box at the bottom");
frame.add(welcome,BorderLayout.NORTH);
//action listener listens for enter key
textField.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
playerOneName= textField.getText();
System.out.println(playerOneName);
playerOneNameSet = true;
System.out.println(playerOneNameSet);
}
});
if(playerOneNameSet == true) {
JTextField textField2 = new JTextField(20);
frame.add(textField2, BorderLayout.SOUTH);
JLabel welcome2 = new JLabel("");
welcome2.setText("Please Enter name for Player 2 in the text box at the bottom");
frame.add(welcome2,BorderLayout.NORTH);
//action listener listens for enter key
textField2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
playerTwoName= textField2.getText();
System.out.println(playerTwoName);
playerTwoNameSet = true;
System.out.println(playerTwoNameSet);
}
});
}
// make sure it closes correctly
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//frame size in pixels
final int FRAME_WIDTH = 1000;
final int FRAME_HEIGHT = 700;
frame.setSize(FRAME_WIDTH,FRAME_HEIGHT);
// makes sure the frame is visible
frame.setVisible(true);
mainClass main = new mainClass();
frame.add(main);
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
There is one logical error in your code.
If you want to use only one JTextField for two inputs, you do not need to create
two JTextField. Just handle the ActionEvent and update only that JTextField. Here is the code for that:
textField.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt)
{
if (!playerOneNameSet)
{
playerOneName = textField.getText();
textField.setText("");
welcome.setText("Please Enter name for Player 2 in the text box at the
bottom");
playerOneNameSet = true;
}
else
{
playerTwoName = textField.getText();
textField.setText("");
}
}
});
The if part after that is not required. It will also eliminate the use of playerTwoNameSet.
If you want to use two JTextField, then you have to do it in the start properly without any logical flaw.
Logical Error in Detail:
Let me try to show you the flow of your program.
public static void main(String[] args)
{
// title of frame
JFrame frame = new JFrame("Risk");
.
.
.
.
//action listener listens for enter key
textField.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(java.awt.event.ActionEvent evt)
{
playerOneName= textField.getText();
System.out.println(playerOneName);
playerOneNameSet = true;
System.out.println(playerOneNameSet);
}
});
Your code is all good till here. After the above line, this happens
if(playerOneNameSet == true) //It is never executed
The reason this happens because playerOneNameSet is a static variable and its default value is false. This line is only executed once. Once your GUI is created, the main() method will not be called again until you run it again. After that, the control passes to the one JTextField that was created, that too when any ActionEvent is generated. It will never go to the if line after that.
I hope I have helped you. Do comment for any further problems.
I want to be able to pass user input from my GUI to one of my classes. However, the input is not passed over and immediately checks the if statement.
How do I get program to wait for the input and only checks after the button is clicked?
Main class
public class MainTest {
public static void main(String[] args) {
String weaponCategory;
//Create Java GUI
GUITest window = new GUITest();
if(window.getCategory() != "")
{
System.out.println("test");
}
}
}
GUITest class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GUITest implements ActionListener{
private JFrame frmInventorysystem;
private JPanel frameBottom;
private JComboBox equipList;
private String category = "";
private JButton confirmBtn, cancelBtn;
/**
* Create the application.
*/
public GUITest()
{
frmInventorysystem = new JFrame();
frmInventorysystem.setTitle("InventorySystem");
frmInventorysystem.setBounds(100, 100, 450, 300);
frmInventorysystem.getContentPane().setLayout(new BorderLayout(0, 0));
frmInventorysystem.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
/*JFrame inside another JFrame is not recommended. JPanels are used instead.
* Creating a flow layout for the bottom frame
*/
frameBottom = new JPanel();
frameBottom.setLayout(new FlowLayout());
//creates comboBox to find out which of the three items player is looking to insert
String[] weaponCategories = {"Weapon", "Armor", "Mod"};
equipList = new JComboBox(weaponCategories);
frmInventorysystem.getContentPane().add(equipList, BorderLayout.NORTH);
//Converting BorderLayout.south into a flow layout
frmInventorysystem.getContentPane().add(frameBottom, BorderLayout.SOUTH);
confirmBtn = new JButton("Confirm");
confirmBtn.addActionListener(this);
frameBottom.add(confirmBtn);
cancelBtn = new JButton("Cancel");
cancelBtn.addActionListener(this);
frameBottom.add(cancelBtn);
frmInventorysystem.setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
//creates new windows to sort equipment when confirmBtn is clicked
if(e.getSource() == confirmBtn)
{
if(equipList.getSelectedItem().equals("Weapon"))
{
//GUIWeaponCategory weapon = new GUIWeaponCategory();
category = equipList.getSelectedItem().toString();
}
}
//Exits when cancelBtn is clicked
if(e.getSource() == cancelBtn)
{
System.exit(0);
}
}
public String getCategory()
{
return category;
}
public void setCategory(String a)
{
category = a;
}
}
GUITest launches as expected.
However, the first println is missing.
How would I go about doing this?
What concepts or pieces of code am I missing?
EDIT1: Added a couple more details to make the program reproducible and complete.
EDIT2: Making the code more readable for easy understanding.
There are some changes to make on your program
Remove extends JFrame as stated in my comments above, see Extends JFrame vs. creating it inside the program
Place your program on the EDT, see point #3 on this answer and the main method for an example on how to do that.
You're confused about how the ActionListeners work, they wait until you perform certain action in your program (i.e. you press Confirm button) and then do something. "Something" in your program means: Print the selected item and check if it's a weapon then, do something else.
So, in this case, you don't need to return back to main to continue with your program, main only serves to initialize your application and nothing else. You need to think in the events and not in a sequential way. That's the tricky and most important part.
You need to change your programming paradigm from console applications and do-while that everything happens in a sequential manner rather than events that are triggered when the user does something with your application.
For example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class GUITest implements ActionListener {
private JFrame frmInventorysystem;
private JPanel frameBottom;
private JComboBox equipList;
private JButton confirmBtn, cancelBtn;
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new GUITest()); //Java 8+ if using an earlier version check the point #2 in this answer and modify the code accordingly.
}
/**
* Create the application.
*/
public GUITest() {
frmInventorysystem = new JFrame();
frmInventorysystem.setTitle("InventorySystem");
frmInventorysystem.setBounds(100, 100, 450, 300);
frmInventorysystem.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmInventorysystem.getContentPane().setLayout(new BorderLayout(0, 0));
/*
* JFrame inside another JFrame is not recommended. JPanels are used instead
* Creating a flow layout for the bottom frame
*/
frameBottom = new JPanel();
frameBottom.setLayout(new FlowLayout());
// creates comboBox to find out which of the three items player is looking to
// insert
String[] weaponCategories = { "Weapon", "Armor", "Mod" };
equipList = new JComboBox(weaponCategories);
frmInventorysystem.getContentPane().add(equipList, BorderLayout.NORTH);
// Converting BorderLayout.south into a flow layout
frmInventorysystem.getContentPane().add(frameBottom, BorderLayout.SOUTH);
confirmBtn = new JButton("Confirm");
confirmBtn.addActionListener(this);
frameBottom.add(confirmBtn);
cancelBtn = new JButton("Cancel");
cancelBtn.addActionListener(this);
frameBottom.add(cancelBtn);
frmInventorysystem.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
// creates new windows to sort equipment when confirmBtn is clicked
if (e.getSource() == confirmBtn) {
String category = equipList.getSelectedItem().toString(); //Get the selected category
doSomething(category); //Pass it as a parameter
}
// Exits when cancelBtn is clicked
if (e.getSource() == cancelBtn) {
frmInventorysystem.dispose();
}
}
// Do something with the category
private void doSomething(String selectedEquipment) {
System.out.println(selectedEquipment);
if (selectedEquipment.equals("Weapon")) {
System.out.println("It's a weapon!"); //You can open dialogs or do whatever you need here, not necessarily a print.
} else {
System.out.println("Not a weapon");
}
}
}
Notice that I removed inheritance, I'm not returning back to main and still printing the selected item and checking if it's a weapon or not.
I also exit the application in a safer way.
This is a sample output:
Weapon
It's a weapon!
Armor
Not a weapon
I don't have a lot of experience with KeyListeners but I used one in my application and it works fine except I need to wait for input before my program can continue. For this I made a while loop that loops until the String temp is not null (which would mean there would be input).
The problem is there is no way to type in the JTextField (called input). Below is code from my two methods that are supposed to work together so that the text in my JTextField (input) can be returned (as temp). I'm not sure why this doesn't work or how to fix it.
The keyPressed method for my KeyListener:
public void keyPressed(KeyEvent e)
{
//only sends text if the enter key is pressed
if (e.getKeyCode()==KeyEvent.VK_ENTER)
{
//if there really is text
if (!input.getText().equals(""))
{
//String temp is changed from null to input
temp=input.getText();
//text sent to another JTextField
output.append(temp+"\n");
//input no longer has text
input.setText("");
}
}
}
The method thats trying to get text, also in my KeyListener class
public String getTemp()
{
booleans isNull=temp==null;
//loops until temp is not null
while (isNull)
{
//unnecessary line of code, only used so the loop not empty
isNull=checkTemp();
}
return temp;
}
public boolean checkTemp()
{
return temp==null;
}
Your while loop is a common console program construct, but understand that you're not creating a console program here but rather an event-driven GUI, and in this situation, the while loop fights against the Swing GUI library, and you need to get rid of it. Instead of a while loop with continual polling you now want to respond to events, and if you're listening for user input into a JTextField do not use a KeyListener as this low-level listener can cause unwanted side effects. Instead add a DocumentListener to the JTextField's Document.
Edit: You're listening for the enter key, and so the solution is even easier: add an ActionListener to the JTextField!
e.g.,
input.addActionListener(e -> {
String text = input.getText().trim();
if (text.isEmpty()) {
return;
}
output.append(text + "\n");
input.setText("");
});
More complete example:
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import javax.swing.*;
public class ChatBox extends JPanel {
private static final int COLS = 40;
private JTextField input = new JTextField(COLS);
private JTextArea output = new JTextArea(20, COLS);
private JButton submitButton = new JButton("Submit");
public ChatBox() {
output.setFocusable(false); // user can't get into output
JScrollPane scrollPane = new JScrollPane(output);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
ActionListener inputListener = e -> {
String text = input.getText().trim();
if (text.isEmpty()) {
return;
}
output.append(text + "\n");
input.setText("");
input.requestFocusInWindow();
};
input.addActionListener(inputListener);
submitButton.addActionListener(inputListener);
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.LINE_AXIS));
bottomPanel.add(input);
bottomPanel.add(submitButton);
setLayout(new BorderLayout());
add(scrollPane, BorderLayout.CENTER);
add(bottomPanel, BorderLayout.PAGE_END);
}
private static void createAndShowGui() {
ChatBox mainPanel = new ChatBox();
JFrame frame = new JFrame("Chat Box");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
I have a problem with Java Textfield that is when I cover all text in the JTextField and input new text immediately(do not pass backspace) into the JTextField, then I use function getText() I get the previous string not current string. Please help for some solutions. Thanks in advance.
I just tested the problem you described by adding a keyListener to a JTextField and printing the getText() method's return value to the console.
What I found out is that it is always one character behind if you want to use the getText() method right in the keyTyped or keyPressed event (I didn't know this because I usually just use a button to confirm I'm done entering the text and bind a KeyEvent to the Return key to trigger the button if a user wants to confirm by hitting enter)
I think this is due to the textField updating its text value AFTER the event is shot.
I assume this is what you did since you didn't provide sample code, so I'll delete this answer if it's not.
The work around to this is to implement what you want to do in the keyReleased method instead.
public void keyReleased(Event e)
{
System.out.println(myTextField.getText());
}
Don't use a KeyListener. The character has NOT been added to the Document when the keyPressed() event is fired.
Add an ActionListener to a JButton. This way the user clicks on the button when text is finised being entered.
Also, in the future post a SSCCE with you question so we can better understand what you are trying to do.
for example :
import java.awt.GridLayout;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class TextLabelMirror {
private JPanel mainPanel = new JPanel();
private JTextField field = new JTextField(20);
private JTextField field1 = new JTextField(20);
public TextLabelMirror() {
field.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void changedUpdate(DocumentEvent e) {
updateLabel(e);
}
#Override
public void insertUpdate(DocumentEvent e) {
updateLabel(e);
}
#Override
public void removeUpdate(DocumentEvent e) {
updateLabel(e);
}
private void updateLabel(DocumentEvent e) {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
field1.setText(field.getText());
}
});
}
});
mainPanel.setLayout(new GridLayout(1, 0, 10, 0));
mainPanel.add(field);
mainPanel.add(field1);
}
public JComponent getComponent() {
return mainPanel;
}
private static void createAndShowUI() {
JFrame frame = new JFrame("TextLabelMirror");
frame.getContentPane().add(new TextLabelMirror().getComponent());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowUI();
}
});
}
}