Java Swing JTextField text one tick behind - java

I use this Java code for demonstration (Just created using eclipse)
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.JTextField;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
public class executor extends JFrame {
private JPanel contentPane;
private JTextField textField;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
executor frame = new executor();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public executor() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(contentPane);
final JLabel lblNewLabel = new JLabel("New label");
contentPane.add(lblNewLabel, BorderLayout.NORTH);
textField = new JTextField();
textField.addKeyListener(new KeyAdapter() {
#Override
public void keyTyped(KeyEvent e) {
lblNewLabel.setText(textField.getText());
}
});
contentPane.add(textField, BorderLayout.CENTER);
textField.setColumns(10);
}
}
and if you type anything into the textfield the label shows everything exactly except prior to the last
Buttonpress. Is there any way to fix that? thank you!

The text field contents change only after the key listener is notified. Instead of trying to track key presses, it is better to listen to the changes in the contents of the text field. This ensures that you also catch changes made by other means, such as cut and paste. The interface for doing that is DocumentListener:
textField.getDocument().addDocumentListener(new DocumentListener() {
#Override
public void removeUpdate(DocumentEvent e) {
lblNewLabel.setText(textField.getText());
}
#Override
public void insertUpdate(DocumentEvent e) {
lblNewLabel.setText(textField.getText());
}
#Override
public void changedUpdate(DocumentEvent e) {
}
});

Related

How to close jframe panel or window

I have 2 frames/windows, I have Exit button on window 2, an from window 1 I launch window 2 and then exit it i.e setVisible(false);
When I execute window 2 I can easily click button exit and hide the current window, however when I launch window 2 from window 1, and then click exit button I get NullPointerException Error. then I instantiated it in the beginning with static and this error was gone, however the window 2 is not being closed/hidden its still there with no effect of button.
Window 1 code:
package com.my.jlms;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class LibrarianMenu extends JFrame {
private JPanel contentPane;
private static LibrarianMenu frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame = new LibrarianMenu();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public LibrarianMenu() {
setTitle("Librarian");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 385, 230);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JButton btnPasswd = new JButton("Change Pass");
btnPasswd.setBounds(202, 76, 146, 39);
contentPane.add(btnPasswd);
btnPasswd.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
ChangePwd framee = new ChangePwd();
framee.setVisible(true);
}
});
}
}
Window 2 Code:
package com.my.jlms;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
public class ChangePwd extends JFrame {
private JPanel contentPane;
private static ChangePwd frame = new ChangePwd();;
private JButton btnExit;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame = new ChangePwd();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public ChangePwd() {
setResizable(false);
setTitle("Password!");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setBounds(100, 100, 266, 154);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
btnExit = new JButton("Exit");
btnExit.setBounds(20, 80, 89, 30);
contentPane.add(btnExit);
btnExit.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent ae) {
frame.setVisible(false);
}
});
}
}
Is there a solution I can set window 2 to hide ?
The problem here is that you are creating your frame, as your class, and not on the object frame, but you hide the frame which represents the object frame.
Change this line (in your actionListener's actionPerformed() method):
frame.setVisible(false);
to:
setVisible(false);
You can use dispose function for the purpose.see how dispose works.
If you want to close a JFrame, you could use the dispose() method.
Example:
public void actionPerformer(ActionEvent e)
{
if(e.getSource().equals(closeFrameButton)
{
dispose(); //This will close the current JFrame
}
}
NOTE: this is different to System.exit(0);. Using this will close the Java virtual machine. if you just want to close the frame, use dispose()

How to slowly(like a effect) move a label(image) to click position of mouse in JAVA with swing

I want to make a GUI program that, when I press mouse button, moves label to the position of pressed X and Y locations. I did that, it was easy, but I want to make it now like a slow moving effect. I tried to do it with thread.sleep() but it didn't work. Can you help me with ideas or code? This is my code:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class jGame extends JFrame {
private JPanel contentPane;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
jGame frame = new jGame();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public jGame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 568, 459);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new BorderLayout(0, 0));
JPanel panel = new JPanel();
contentPane.add(panel, BorderLayout.CENTER);
JLabel robot = new JLabel("");
robot.setIcon(new ImageIcon("/home/ubuntu/Desktop/robot.png"));
panel.add(robot);
panel.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
robot.setLocation(e.getX() - 25, e.getY() - 40);
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
});
}
}
And here is the image I use:
Writing is half the fun...
Store the startPoint & nextStep as Points
Initialize a javax.swing.Timer
When user clicks, save the Root startPoint, set nextStep to mouse location and call timer.start().
Timer.actionPerformed() needs to calculate the nextStep Point as it moves back to startPoint.
if startPoint equals nextStep call timer.stop()

swing.timer working but has some bug

I have a working app, but very fast timer gets confused.
The idea is to to load data from database to two JTables every 100s and constantly switch between them every 10 seconds. Have everything working but after a few. I am posting the simple example of the problem, please help me find the bug, this is my first time with swing.timers and i guess it is something trivial:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.JTable;
import javax.swing.JScrollPane;
public class Test extends JFrame {
private JPanel contentPane;
private JTable pTable ;
private JTable cTable;
private Timer timer;
private Timer worker;
public int flag=0;
public int flip=0;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try{
initialize();
}catch(Exception e){
JOptionPane.showMessageDialog(null, e);
}
}
});
}
public static void initialize(){
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
Test frame = new Test();
frame.setVisible(true);
} catch (Exception e1) {
JOptionPane.showMessageDialog(null, e1);
}
}
public Test() {
try{
setTitle("Warehouse stats");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new BorderLayout(0, 0));
JScrollPane scrollPane = new JScrollPane();
contentPane.add(scrollPane, BorderLayout.CENTER);
ActionListener work = new ActionListener(){
#Override
public void actionPerformed(ActionEvent event)
{
flip=0;
// this is where i would load the tables from DB
pTable = new JTable(10,10);
cTable = new JTable(5,5);
ActionListener action = new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
if(flip==0){
scrollPane.setViewportView(pTable);
flip=1;
}else if (flip==1){
scrollPane.setViewportView(cTable);
flip=0;
}
}
};
timer = new Timer(10*1000,action);
timer.setInitialDelay(0);
if(!timer.isRunning()){
timer.start();
}
}
};
worker = new Timer(100*1000,work);
worker.setInitialDelay(0);
worker.start();
}catch (Exception e2){
JOptionPane.showMessageDialog(null, e2);
}
}
}

Opening a different frame with a button in Java

I am trying to open the menu frame using a button on the main frame. I added an event to the button and I tried calling the other class but it keeps giving me an error of ":: expected after this token"
This is my main frame
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Main extends JFrame {
public static JPanel mainPane;
public final JButton menuButton = new JButton("New button");
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main frame = new Main();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Main() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
mainPane = new JPanel();
mainPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(mainPane);
mainPane.setLayout(null);
menuButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Menu.main(String[] args);
}
});
menuButton.setBounds(76, 89, 104, 32);
mainPane.add(menuButton);
}
}
And this is my menu frame
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
public class Menu extends JFrame {
public static JPanel menuPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Menu frame = new Menu();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public Menu() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
menuPane = new JPanel();
menuPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(menuPane);
menuPane.setLayout(null);
JLabel menuTitle = new JLabel("Menu");
menuTitle.setBounds(194, 11, 46, 14);
menuPane.add(menuTitle);
}
}
change your action event to this.no need to call main method .create a new instance of Menu class instead.
menuButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Menu menu = new Menu();
menu.setVisible(true);
}
});
if you relly want to call main method then use
menuButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Menu.main(new String[0]);
}
});
the error is here
Menu.main(String[] args);//error
this is not a correct way of passing arguments to a methods.this is declaration of parameter list.
you can correct error by changing it to ,
String args[] = null;
Menu.main(args); //correct

Changing the content of jTextField while typing

I'm trying to reset my JTextField in case that Space is typed. It throws me:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Attempt to mutate in notification
my code is:
import java.awt.Color;
import java.awt.EventQueue;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
public class MainFrame extends JFrame {
private JPanel contentPane;
private JTextField textField;
/** * Launch the application. */
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainFrame frame = new MainFrame();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/** * Create the frame. */
public MainFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JDesktopPane desktopPane = new JDesktopPane();
desktopPane.setBackground(Color.LIGHT_GRAY);
desktopPane.setBounds(6, 6, 438, 266);
contentPane.add(desktopPane);
textField = new JTextField();
textField.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
}
public void removeUpdate(DocumentEvent e) {
}
public void insertUpdate(DocumentEvent e) {
if (textField.getText().contains(" ")) {
System.out
.println("Space was entered! clearing the text field");
textField.setText("");
}
}
});
textField.setBounds(133, 112, 134, 28);
desktopPane.add(textField);
textField.setColumns(10);
}
}
A DocumentListener is only suitable for notifications to the underlying Document of a JTextComponent. You need a DocumentFilter here
Example
Document listeners should not modify the contents of the document; The change is already complete by the time the listener is notified of the change. Instead, write a custom document that overrides the insertString or remove methods, or both. See Listening for Changes on a Document for details.
(From http://docs.oracle.com/javase/tutorial/uiswing/events/documentlistener.html)
Instead of writing a custom document, I believe it's easier to implement a KeyListener as followed:
JTextField textField = new JTextField();
textField.addKeyListener( new KeyListener() {
#Override
public void keyTyped(KeyEvent arg0) {
if(arg0.getKeyChar() == ' '){
System.out.println("Space was entered! clearing the text field");
textField.setText("");
arg0.consume();
}
}
#Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyPressed(KeyEvent arg0) {
// TODO Auto-generated method stub
}
Where the arg0.consume() prevents the space from appearing after clearing the textfield

Categories

Resources