I am new to Swing and I have a situation. I am designing an application that renders the GUI components dynamically based on an xml file input(meta-data) . Now most of my JTextFields have InputVerifier set to them, for validation purpose. The input verifier pops up JOptionPane whenever there is an invalid input.
Now, if a user enter an invalid data and moves ahead and clicks a button on the Panel, then a dialog pops up and the user have to respond to it. but after that also the button does not paint to release state. It still looked like it is pressed but actually it is not. As the whole code is pretty messy, I am putting the problem scenario in the code below:-
What should I do so that the JButton looks unpressed? I would appreciate if the logic is also explained.
Thanks in advance.
package test;
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.InputVerifier;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
public class VerifierTest extends JFrame {
private static final long serialVersionUID = 1L;
public VerifierTest() {
JTextField tf;
tf = new JTextField("TextField1");
getContentPane().add(tf, BorderLayout.NORTH);
tf.setInputVerifier(new PassVerifier());
final JButton b = new JButton("Button");
b.setVerifyInputWhenFocusTarget(true);
getContentPane().add(b, BorderLayout.EAST);
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (b.hasFocus())
System.out.println("Button clicked");
}
});
addWindowListener(new MyWAdapter());
}
public static void main(String[] args) {
Frame frame = new VerifierTest();
frame.setSize(400, 200);
frame.setVisible(true);
//frame.pack();
}
class MyWAdapter extends WindowAdapter {
public void windowClosing(WindowEvent event) {
System.exit(0);
}
}
class PassVerifier extends InputVerifier {
public boolean verify(JComponent input) {
JTextField tf = (JTextField) input;
String pass = tf.getText();
if (pass.equals("Manish"))
return true;
else {
String message = "illegal value: " + tf.getText();
JOptionPane.showMessageDialog(tf.getParent(), message,
"Illegal Value", JOptionPane.ERROR_MESSAGE);
return false;
}
}
}
}
The method verify
is actually not a good place to open a JOptionPane.
There are several approaches you could consider to solve your problem:
Here is a small snippet of the latter option:
import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.InputVerifier;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
public class VerifierTest extends JFrame {
private static final long serialVersionUID = 1L;
public VerifierTest() {
final JTextField tf = new JTextField("TextField1");
getContentPane().add(tf, BorderLayout.NORTH);
tf.setInputVerifier(new PassVerifier());
final JButton b = new JButton("Button");
b.setVerifyInputWhenFocusTarget(true);
getContentPane().add(b, BorderLayout.EAST);
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!tf.getInputVerifier().verify(tf)) {
JOptionPane.showMessageDialog(tf.getParent(), "illegal value: " + tf.getText(), "Illegal Value",
JOptionPane.ERROR_MESSAGE);
}
if (b.hasFocus()) {
System.out.println("Button clicked");
}
}
});
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static void main(String[] args) {
Frame frame = new VerifierTest();
frame.setSize(400, 200);
frame.setVisible(true);
}
class PassVerifier extends InputVerifier {
@Override
public boolean verify(JComponent input) {
final JTextField tf = (JTextField) input;
String pass = tf.getText();
return pass.equals("Manish");
}
}
}
Also consider setting the default close operation of the JFrame instead of adding a window listener (but it is a good approach to use a WindowListener if you want to pop up a dialog asking the user if he is sure he wants to exit your application).
I added a call to SwingUtilities
to ensure that the GUI is on the event thread, and I removed your reference to Frame.
The GUI works for me on Windows XP.
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.InputVerifier;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class VerifierTest implements Runnable {
private static final long serialVersionUID = 1L;
public VerifierTest() {
}
@Override
public void run() {
JFrame frame = new JFrame();
frame.setSize(400, 200);
JTextField tf;
tf = new JTextField("TextField1");
tf.setInputVerifier(new PassVerifier());
frame.getContentPane().add(tf, BorderLayout.NORTH);
final JButton b = new JButton("Button");
b.setVerifyInputWhenFocusTarget(true);
frame.getContentPane().add(b, BorderLayout.EAST);
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (b.hasFocus())
System.out.println("Button clicked");
}
});
frame.addWindowListener(new MyWAdapter());
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new VerifierTest());
}
class MyWAdapter extends WindowAdapter {
@Override
public void windowClosing(WindowEvent event) {
System.exit(0);
}
}
class PassVerifier extends InputVerifier {
@Override
public boolean verify(JComponent input) {
JTextField tf = (JTextField) input;
String pass = tf.getText();
if (pass.equals("Manish"))
return true;
else {
String message = "illegal value: " + tf.getText();
JOptionPane.showMessageDialog(tf.getParent(), message,
"Illegal Value", JOptionPane.ERROR_MESSAGE);
return false;
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With