How to validate a textfield to enter only 4 digits after the decimal point in Swing?
Any validation in Swing can be performed using an InputVerifier.
1. First create your own input verifier:
public class MyInputVerifier extends InputVerifier {
#Override
public boolean verify(JComponent input) {
String text = ((JTextField) input).getText();
try {
BigDecimal value = new BigDecimal(text);
return (value.scale() <= Math.abs(4));
} catch (NumberFormatException e) {
return false;
}
}
}
2. Then assign an instance of that class to your text field. (In fact any JComponent can be verified)
myTextField.setInputVerifier(new MyInputVerifier());
Of course you can also use an anonymous inner class, but if the validator is to be used on other components, too, a normal class is better.
Also have a look at the SDK documentation: JComponent#setInputVerifier.
You could probably accomplish the same with DocumentListener. All you have to do is validate the input string against the desired string pattern. In this case, the pattern seems to be one or more digits, followed by a period, AND exactly 4 digits after the decimal point. The code below demonstrates using DocumentListener to accomplish this:
public class Dummy
{
private static JTextField field = new JTextField(10);
private static JLabel errorMsg = new JLabel("Invalid input");
private static String pattern = "\\d+\\.\\d{4}";
private static JFrame frame = new JFrame();
private static JPanel panel = new JPanel();
public static void main(String[] args)
{
errorMsg.setForeground(Color.RED);
panel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.insets = new Insets(5, 0, 0, 5);
c.gridx = 1;
c.gridy = 0;
c.anchor = GridBagConstraints.SOUTH;
panel.add(errorMsg, c);
c.gridx = 1;
c.gridy = 1;
c.anchor = GridBagConstraints.CENTER;
panel.add(field, c);
frame.getContentPane().add(panel);
field.getDocument().addDocumentListener(new DocumentListener()
{
#Override
public void removeUpdate(DocumentEvent e)
{
validateInput();
}
#Override
public void insertUpdate(DocumentEvent e)
{
validateInput();
}
#Override
public void changedUpdate(DocumentEvent e) {} // Not needed for plain-text fields
});
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static void validateInput()
{
String text = field.getText();
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(text);
if (m.matches())
{
errorMsg.setForeground(frame.getBackground());
}
else
{
errorMsg.setForeground(Color.RED);
}
}
}
As long as the text field does not contain a valid input, the error message is shown like the image below.
Once the input is validated, the error message will not be visible.
Of course, you can replace the validation action to whatever you need. For example, you may want to display some popup when a button is clicked if the input is not valid, etc.
I threw this together to show an alternative to answer given already. There might be cases when this solution might be more suitable. There might be cases when the given answer might be more suitable. But one thing is certain, alternatives are always a good thing.
Related
ı have problem about delete a empty string values like we can see in picture,
in the first time if here is empty he give a error but after that even we write some strings in that blank,its still giving the same error how can ı delete this label before the sending again How can ı fix that problem ı tried some codes but nothing worked well please help about that
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
public class ui {
public static void main(String[] args) {
uiVision();
}
public static void uiVision() {
ImageIcon eyes = new ImageIcon("a.png");
Globals.jf.setTitle("Deneme Uygulamasi");
Globals.jf.setLocation(100,200);
JLabel label1,label2,label3;
Globals.jf.getContentPane().setLayout(new FlowLayout());
JTextField isim = new JTextField(20);
JTextField soyisim = new JTextField(20);
JTextField pasaport = new JTextField(20);
JTextField mail = new JTextField(20);
JPasswordField passwordField = new JPasswordField(10);
JPasswordField passwordField2 = new JPasswordField(10);
JButton buton1 = new JButton("Send");
JButton buton2 = new JButton(eyes);
JButton buton3 = new JButton(eyes);
JButton buton4 = new JButton("!");
label1 = new JLabel("Name:");// -8
label2 = new JLabel("Surname:");// -9
label3 = new JLabel("Passaport-ID:");//+ 10
JLabel label4 = new JLabel("Mail:");// +10
JLabel label5 = new JLabel("Password:");//+10
JLabel label6 = new JLabel("Re-Password:");// +20
buton1.setBounds(170,400,150,30);
buton2.setBounds(320,190,50,30);
buton3.setBounds(320,230,50,30);
buton4.setBounds(370,230,50,30);
isim.setBounds(170,30,150,30);
soyisim.setBounds(170,70,150,30);
pasaport.setBounds(170,110,150,30);
mail.setBounds(170,150,150,30);
passwordField.setBounds(170,190,150,30);
passwordField2.setBounds(170,230,150,30);
label1.setBounds(125,30,150,30);
label2.setBounds(106,70,150,30);
label3.setBounds(90,110,150,30);
label4.setBounds(132,150,150,30);
label5.setBounds(105,190,150,30);
label6.setBounds(91,230,150,30);
Globals.jf.add(buton1);Globals.jf.add(buton2);Globals.jf.add(buton3);
Globals.jf.add(label1);Globals.jf.add(label2);Globals.jf.add(label3);Globals.jf.add(label4); Globals.jf.add(label5);Globals.jf.add(label6);
Globals.jf.add(isim);Globals.jf.add(soyisim);Globals.jf.add(pasaport);Globals.jf.add(mail);Globals.jf.add(passwordField);Globals.jf.add(passwordField2);
Globals.jf.setSize(1000,500);
buton2.addActionListener(l -> {
if ( passwordField.getEchoChar() != '\u0000' ) {
passwordField.setEchoChar('\u0000');
} else {
passwordField.setEchoChar((Character) UIManager.get("PasswordField.echoChar"));
}
});
buton3.addActionListener(l -> {
if ( passwordField2.getEchoChar() != '\u0000' ) {
passwordField2.setEchoChar('\u0000');
} else {
passwordField2.setEchoChar((Character) UIManager.get("PasswordField.echoChar"));
}
});
buton1.addActionListener(e -> {
checkEmpty(isim.getText(),label1.getText(),label1);
checkEmpty(soyisim.getText(),label2.getText(),label2);
checkEmpty(pasaport.getText(),label3.getText(),label3);
checkEmpty(mail.getText(),label4.getText(),label4);
ExitWhenLoopEnd();
Globals.globalInt = 0;
System.out.println(passwordField.getPassword());
System.out.println(passwordField2.getPassword());
Globals.clickCount++;
});
Globals.jf.setLayout(null);
Globals.jf.setVisible(true);
Globals.jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void checkEmpty(String value,String label,JLabel labelname) {
Integer syc = Integer.valueOf(0);
if(value != null && !value.trim().isEmpty()) {
if(Globals.globalInt != 4) {
Globals.globalInt++;
}
syc = 1;
}
else {
CreateEmptyMessageError(label,labelname,Globals.jf);
syc = -1;
}
System.out.println(syc);
}
public static void CreateEmptyMessageError(String labelError,JLabel label,JFrame jf) {
Globals.labelx = new JLabel(labelError.split(":")[0]+" is empty!");
Globals.labelx.setBounds(label.getBounds().x+250,label.getBounds().y,label.getWidth(),label.getHeight());
Globals.labelx.setForeground(Color.RED);
jf.add(Globals.labelx);
jf.revalidate();
jf.repaint();
}
public class Globals {
public static int globalInt = 0;
public static JLabel labelx = null;
public static JFrame jf = new JFrame();
public static int clickCount = 0;
public static int lastVal = 0;
public static int syc = 0;
}
public static void ExitWhenLoopEnd() {
if(Globals.globalInt == 4) {
System.exit(0);
}
}
}
Your problem is that you're creating a new JLabel and adding it to the GUI each time CreateEmptyMessageError(...) is called, and by doing this, you have no reference to this object, and no way to change its state.
The solution is to not do this, to instead create the error message label when you create the GUI itself, assign it to an instance field, and in that method above to not create a new JLabel object but rather to set the text of the existing object, one that shows a warning if the JTextField is empty, and one that sets the JLabel text to the empty String, "", if the JTextField has text.
Also,
As Progman has suggested in comments, avoid the use of static fields and methods unless the use suggests that these should be used, and this isn't the case here. Instead, use private instance fields and methods. This will make your code easier to mock/test/extend and re-use, this reduces potential for hard to identify bugs by reducing your code's cyclomatic complexity and coupling.
Avoid the use of null layouts and setBounds(...) and instead learn and use the layout managers.
Learn and use Java naming conventions. Variable names should all begin with a lower letter while class names with an upper case letter. Learning this and following this will allow us to better understand your code, and would allow you to better understand the code of others.
Give your fields names that describe what they represent, making your code self-commenting and easier to understand.
I have two JTextField which take numbers from users, like this:
nbMuscle = new JTextField();
nbMuscle.setText("2");
and this:
nbFuyard = new JTextField();
nbFuyard.setText("1");
my JTextArea() takes make an addition of both JTextField's values, like this:
nbPersonnages = new JTextArea();
int nombMusc = Integer.valueOf(nbMuscle.getText());
int nombFuy = Integer.valueOf(nbFuyard.getText());
int nbTotal = nombMusc + nombFuy;
nbPersonnages.setText(String.valueOf(nbTotal));
It works like a charm but I have one problem, if the user edit one of the JTextFields, the JTextArea value don't change. I have found on internet some notions like jTextArea.appened(String str) but it doesn't work.
Any idea of what I could do?
You have to add a DocumentListener to the underlying Document of the TextFields to listen to changes made while the program runs.
The easiest way to do this is proboably an anonymous class.
Here is the Code:
nbMuscle = new JTextField();
nbMuscle.setText("2");
nbFuyard = new JTextField();
nbFuyard.setText("1");
nbPersonnages = new JTextArea();
DocumentListener dl = new DocumentListener() {
#Override
public void removeUpdate(DocumentEvent e) {
textChanged();
}
#Override
public void insertUpdate(DocumentEvent e) {
textChanged();
}
#Override
public void changedUpdate(DocumentEvent e) {
// This method is not called when the text of the Document changed, but if attributes of the Document changed.
}
private void textChanged() {
int nombMusc = Integer.valueOf(nbMuscle.getText());
int nombFuy = Integer.valueOf(nbFuyard.getText());
int nbTotal = nombMusc + nombFuy;
nbPersonnages.setText(String.valueOf(nbTotal));
}
};
int nombMusc = Integer.valueOf(nbMuscle.getText());
int nombFuy = Integer.valueOf(nbFuyard.getText());
int nbTotal = nombMusc + nombFuy;
nbPersonnages.setText(String.valueOf(nbTotal));
nbMuscle.getDocument().addDocumentListener(dl);
nbFuyard.getDocument().addDocumentListener(dl);
Code with near-identical blocks like this makes me cringe. Plus it adds up to where you have a thousand lines of code where half that would suffice. Surely there is a way to make a loop to make it all happen and not have code that looks so unsophisticated and brainless.
Offhand it seems like to do so would be adding as much code as I seek to reduce: loop to make 5 buttons, array of labels for the buttons, array of backgrounds... maybe more. Even if that turned out to be acceptable, how would I make a loop to handle the listeners? I can't have an array of methods, can I? I guess such a loop it would have to include a switch. Yes? I'd probably do that if I didn't want to seek a better solution. So I'm asking...
What would code look like that would listen to the entire group of buttons and take action based on which one was pressed? To which component would I assign the single listener? And how?
(There's a chance that the answer to that question will make me cringe even more than the repetitive nature of the code, if I realize that I already know how to do so and needn't have even asked in the first place, but I'm asking anyway. I'm at one of those I've-had-it-for-today points where the brain just wants out.)
private void makeScoremasterBonuses(){
pnlBonuses = new JPanel(new GridLayout(1, 6));
pnlBonuses.setSize(6,1);
JButton t1 = (new JButton("3W"));
t1.setToolTipText("This is a triple-word cell.");
t1.setBackground(TRIPLE_WORD);
t1.setHorizontalAlignment(JButton.CENTER);
t1.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
Highlighter.shadeSymmetric(currentCell,TRIPLE_WORD);
}});
JButton t2 = (new JButton("3L"));
t2.setToolTipText("This is a triple-letter cell");
t2.setBackground(TRIPLE_LETTER);
t2.setHorizontalAlignment(JButton.CENTER);
t2.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
Highlighter.shadeSymmetric(currentCell,TRIPLE_LETTER);
}});
JButton t3 = (new JButton("2W"));
t3.setToolTipText("This is a double-word cell");
t3.setBackground(DOUBLE_WORD);
t3.setHorizontalAlignment(JButton.CENTER);
t3.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
Highlighter.shadeSymmetric(currentCell,DOUBLE_WORD);
}});
JButton t4 = (new JButton("2L"));
t4.setToolTipText("This is a double-letter cell");
t4.setBackground(DOUBLE_LETTER);
t4.setHorizontalAlignment(JButton.CENTER);
t4.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
Highlighter.shadeSymmetric(currentCell,DOUBLE_LETTER);
}});
JButton t5 = (new JButton(""));
t5.setToolTipText("No bonus");
t5.setBackground(WHITE);
t5.setHorizontalAlignment(JButton.CENTER);
t5.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
Highlighter.shadeSymmetric(currentCell,B_NORMAL);
}});
pnlBonuses.add(new JLabel("Legend: "));
pnlBonuses.add(t1);
pnlBonuses.add(t2);
pnlBonuses.add(t3);
pnlBonuses.add(t4);
pnlBonuses.add(t5);
}
I'm not asking anyone to write the code; I wouldn't even want that (but I couldn't ignore it!).
Here's what the code above does:
Generally any time you have repeated functionality like that, you want to extract that code out into a helper method like this:
private JButton makeJButton(String label, String toolTip, Color bgColor, final Color highlight) {
JButton button = new JButton(label);
button.setToolTipText(toolTip);
button.setBackground(bgColor);
button.setHorizontalAlignment(JButton.CENTER);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Highlighter.shadeSymmetric(currentCell, highlight);
}
});
return button;
}
Then your makeScoremasterBonuses() method becomes much simpler:
private void makeScoremasterBonuses() {
pnlBonuses = new JPanel(new GridLayout(1, 6));
pnlBonuses.setSize(6, 1);
pnlBonuses.add(new JLabel("Legend: "));
pnlBonuses.add(makeJButton("3W", "This is a triple-word cell.", TRIPLE_WORD, TRIPLE_WORD));
pnlBonuses.add(makeJButton("3L", "This is a triple-letter cell.", TRIPLE_LETTER, TRIPLE_LETTER));
pnlBonuses.add(makeJButton("2W", "This is a double-word cell.", DOUBLE_WORD, DOUBLE_WORD));
pnlBonuses.add(makeJButton("3L", "This is a double-letter cell.", DOUBLE_LETTER, DOUBLE_LETTER));
pnlBonuses.add(makeJButton("", "No bonus.", WHITE, B_NORMAL));
}
Identify the aspects that vary, collect them, and iterate over the collection.
Something like this (untested):
pnlBonuses = new JPanel(new GridLayout(1, 6));
pnlBonuses.setSize(6,1);
pnlBonuses.add(new JLabel("Legend: "));
// Create class "CellInfo" with constructor and getters for desired properties.
CellInfo cellInfos[] = {
new CellInfo("3W", "This is a triple-word cell.", TRIPLE_WORD),
new CellInfo("3L", "This is a triple-letter cell.", TRIPLE_LETTER),
// ...
};
// Add a button for each item described by the cellInfos.
for (CellInfo cellInfo : cellInfos) {
Button b = new JButton(cellInfo.getLabel());
b.setToolTipText(cellInfo.getToolTipText());
b.setBackground(cellInfo.getBackground());
b.setHorizontalAlignment(JButton.CENTER);
b.addActionListener(new ActionListener() {
#Override public void actionPerformed(ActionEvent e) {
Highlighter.shadeSymmetric(currentCell, cellInfo.getBackground());
}});
pnlBonuses.add(b);
}
Note that you might need to create some "final" variables for placeholders for use in the inner anonymous class but the idea should work.
An enum could be your friend here. It's almost an array of methods:
static enum Btn {
TripleWord("3W", "This is a triple word cell.", TRIPLE_WORD),
TripleLetter("3L", "This is a triple letter cell.", TRIPLE_LETTER),
DoubleWord("2W", "This is a double word cell.", DOUBLE_WORD),
DoubleLetter("2L", "This is a double letter cell.", DOUBLE_LETTER),
NoBonus("", "No bonus.", WHITE, B_NORMAL);
final String label;
final String tooltip;
final Color color;
final Color shade;
Btn(String label, String tooltip, Color color, Color shade) {
this.label = label;
this.tooltip = tooltip;
this.color = color;
this.shade = shade;
}
Btn(String label, String tooltip, Color color) {
this(label, tooltip, color, color);
}
public JButton asJButton() {
JButton btn = (new JButton(label));
btn.setToolTipText(tooltip);
btn.setBackground(color);
btn.setHorizontalAlignment(JButton.CENTER);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Highlighter.shadeSymmetric(currentCell, shade);
}
});
return btn;
}
}
private void makeScoremasterBonuses() {
int nBtns = Btn.values().length;
JPanel pnlBonuses = new JPanel(new GridLayout(1, nBtns + 1));
pnlBonuses.setSize(nBtns + 1, 1);
pnlBonuses.add(new JLabel("Legend: "));
for (Btn btn : Btn.values()) {
pnlBonuses.add(btn.asJButton());
}
}
(I know I could have edited my previous answer, but this one's so different...)
Thanks to #OldCurmudgeon, I have come up with what I think is pretty good.
Here's "proof" (I may just leave each label and tooltip as is):
public enum Colors {
TRIPLE_WORD (255, 220, 50),
TRIPLE_LETTER (255, 255, 150),
DOUBLE_WORD ( 0, 255, 0),
DOUBLE_LETTER (214, 245, 214),
NOT_A_BONUS (255, 255, 255);
private final int red, green, blue;
Colors(int r, int g, int b){
this.red = r;
this.green = g;
this.blue = b;
}
public java.awt.Color background(Colors c){
return new java.awt.Color(c.red, c.green, c.blue);
}
}
private void makeScoremasterBonuses(){
Colors c;
Colors all [] = Colors.values();
String labels[] = new String[all.length];
String abbrs [] = new String[all.length];
JButton but;
pnlBonuses = new JPanel();
pnlBonuses.add(new JLabel("Legend:"));
for (int i = 0; i < all.length; i++) {
labels[i] = all[i].name().replace("_", " ").toLowerCase();
abbrs [i] = abbreviate(all[i].name());
c = Colors.values()[i];
but = new JButton(abbrs[i]);
but.setToolTipText(labels[i]);
but.setBackground(c.background(c));
but.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
but.setActionCommand("" + i);
but.addActionListener(this);
pnlBonuses.add(but);
}
}
=== THIS IS A MAJOR EDIT OF WHAT I POSTED AN HOUR AGO ===
I wanted to see if I could implement my own naive method. Here it is:
public class Game implements ActionListener{
public Color [] backgrounds = {TRIPLE_WORD, TRIPLE_LETTER,
DOUBLE_WORD, DOUBLE_LETTER, B_NORMAL};
private void makeScoremasterBonuses(){
String[] labels = {"3W", "3L", "2W", "2L", " "};
JButton but;
pnlBonuses = new JPanel();
pnlBonuses.add(new JLabel("Legend:"));
for (int i = 0; i < labels.length; i++) {
char wt = labels[i].charAt(0);
char tp = labels[i].charAt(1);
but = new JButton(labels[i]);//("" + i);
but.setBackground(backgrounds[i]);
but.setHorizontalAlignment(SwingConstants.CENTER);
but.setActionCommand("" + i);
but.addActionListener(this);
but.setToolTipText("This is a "
+ (i == labels.length - 1 ? "non-bonus" :
(wt == '3' ? "triple" : "double")
+ " " + (tp == 'L' ? "letter" : "word"))
+ " cell.");
pnlBonuses.add(but);
}
}
public void actionPerformed(ActionEvent evt) {
int i = Integer.parseInt(evt.getActionCommand());
Highlighter.shadeSymmetric(currentCell,backgrounds[i]);
}
This has NOW (after edits) EVEN MORE SO been the best thread I've initiated, in terms of quality of responses and all that I've learned because of them. THANK YOU ALL.
BUT I STILL haven't managed to appropriately use setActionCommand. Whatever I did to TRY to use it wound up being so much longer code-wise that I gave up and went for the short and easy but inappropriate.
Any thoughts about how to use set... and getActionCommand the right way (i.e., as Actions) without adding a ton of code to do so?
I have a form that set a input verifier to it.
I want when a user type a correct value for a text field and want to go to other text field, a check icon should be display besides of text field.
But now in my code, when user type a correct value on first text field an go to other, Two icons displayed together!
public class UserDialog extends JDialog {
JButton cancelBtn, okBtn;
JTextField fNameTf, lNameTf;
JRadioButton maleRb, femaleRb;
ButtonGroup group;
JLabel fNameLbl, fNamePicLbl, lNameLbl, lNamePicLbl, genderLbl, tempBtn, temp3;
public UserDialog() {
add(createForm(), BorderLayout.CENTER);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLocation(400, 100);
pack();
setVisible(true);
}
public JPanel createForm() {
JPanel panel = new JPanel();
ImageIcon image = new ImageIcon("Check.png");
okBtn = new JButton("Ok");
cancelBtn = new JButton("Cancel");
tempBtn = new JLabel();
fNameLbl = new JLabel("First Name");
fNamePicLbl = new JLabel(image);
fNamePicLbl.setVisible(false);
lNameLbl = new JLabel("Last Name");
lNamePicLbl = new JLabel(image);
lNamePicLbl.setVisible(false);
genderLbl = new JLabel("Gender");
maleRb = new JRadioButton("Male");
femaleRb = new JRadioButton("Female");
temp3 = new JLabel();
group = new ButtonGroup();
group.add(maleRb);
group.add(femaleRb);
fNameTf = new JTextField(10);
fNameTf.setName("FnTF");
fNameTf.setInputVerifier(new MyVerifier(new JComponent[]{maleRb, femaleRb, okBtn}));
lNameTf = new JTextField(10);
lNameTf.setName("LnTF");
lNameTf.setInputVerifier(new MyVerifier(new JComponent[]{maleRb, femaleRb, okBtn}));
panel.add(fNameLbl);
panel.add(fNameTf);
panel.add(fNamePicLbl);
panel.add(lNameLbl);
panel.add(lNameTf);
panel.add(lNamePicLbl);
panel.add(genderLbl);
JPanel radioPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
radioPanel.add(maleRb);
radioPanel.add(femaleRb);
panel.add(radioPanel);
panel.add(temp3);
panel.add(okBtn);
panel.add(cancelBtn);
panel.add(tempBtn);
panel.setLayout(new SpringLayout());
SpringUtilities.makeCompactGrid(panel, 4, 3, 50, 10, 80, 60);
return panel;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new UserDialog();
}
});
}
public class MyVerifier extends InputVerifier {
private JComponent[] component;
public MyVerifier(JComponent[] components) {
component = components;
}
#Override
public boolean verify(JComponent input) {
String name = input.getName();
if (name.equals("FnTF")) {
String text = ((JTextField) input).getText().trim();
if (text.matches(".*\\d.*") || text.length() == 0) {
//disable dependent components
for (JComponent r : component) {
r.setEnabled(false);
}
return false;
}
} else if (name.equals("LnTF")) {
String text = ((JTextField) input).getText();
if (text.matches(".*\\d.*") || text.length() == 0) {
//disable dependent components
for (JComponent r : component) {
r.setEnabled(false);
}
return false;
}
}
//enable dependent components
for (JComponent r : component) {
r.setEnabled(true);
}
fNamePicLbl.setVisible(true);
lNamePicLbl.setVisible(true);
return true;
}
}
}
}
Updated
public class MyVerifier extends InputVerifier {
private JComponent[] component;
public MyVerifier(JComponent[] components) {
component = components;
}
#Override
public boolean verify(JComponent input) {
String name = input.getName();
if (name.equals("FnTF")) {
String text = ((JTextField) input).getText().trim();
if (text.matches(".*\\d.*") || text.length() == 0) {
return false;
}
} else if (name.equals("LnTF")) {
String text = ((JTextField) input).getText();
if (text.matches(".*\\d.*") || text.length() == 0) {
return false;
}
}
return true;
}
#Override
public boolean shouldYieldFocus(JComponent input) {
boolean isValidDate = verify(input);
if (isValidDate) {
for (JComponent r : component) {
r.setEnabled(true);
}
} else {
for (JComponent r : component) {
r.setEnabled(false);
}
}
return isValidDate;
}
But now in my code, when user type a correct value on first text field
an go to other, Two icons displayed together!
Because you did so: (Read the comments)
public boolean verify(JComponent input) {
String name = input.getName();
if (name.equals("FnTF")) {
// your code
}
} else if (name.equals("LnTF")) {
// your code
}
//enable dependent components
for (JComponent r : component) {
r.setEnabled(true);
}
/* And Now we are here */
fNamePicLbl.setVisible(true);
lNamePicLbl.setVisible(true);
// making visible two of them at once as soon as verify is called
// on any one of the components, verifier is registered
return true;
}
setVisible should be controlled by the if-else condition too. For your better understanding you need to do something like this:
if (text.matches(".*\\d.*") || text.length() == 0) {
// your code
}
else
{
fNamePicLbl.setVisible(true);
}
Second Issue:
fNameTf.setInputVerifier(new MyVerifier(new JComponent[]{maleRb, femaleRb, okBtn}));
lNameTf = new JTextField(10);
lNameTf.setName("LnTF");
lNameTf.setInputVerifier(new MyVerifier(new JComponent[]{maleRb, femaleRb, okBtn}));
The MyVerfier has the common code to verify both input field. But you are creating two instances of it with same instances of components. Create one and set it as the input verifier of the two field.
You might want to create two different InputVerifier class for the two Text Field. FnTFVerifier and LnTFVerifier. Then put your verification code that relates them e.g., enabling the radio buttons and showing the label with check.png. most of the if-else checking will go-away.
But I think, this should not really be the preferable way. As the two text field has the common functionality, one InputVerifier class and instance is sufficient. you would have to just encapsulate the input text field and related cehckLabel to one component, then register the InputVerifier instances to this component.
Third issue: you are misusing verify function:
The verify function is meant to be used for nothing but verify data: whether data is valid or not with user required condition. It should do nothing more. InputVerifier has another function boolean ShouldYieldFocus(Jcomponent): Before focus is transfered to another Swing component that requests it, the input verifier's shouldYieldFocus method is called, which decides whither the component under verification should lose focus or not. Focus is transferred only if this method returns true. You should however write the required state change of components inside this function.
public boolean shouldYieldFocus(JComponent input) {
boolean isDataValid = verify(input);
if(isDataValid); //do stuff
return isDataValid; // if verify is true(valid) return true;
}
i am trying to access global variable of a class from another class the glass is giving me null value instead of enter value during action performed`
package com.audit;
public class panel extends JPanel {
String shost;
String suser;
String spass;
int sport;
public int getsport() {
return this.sport;
}
public String getshost() {
return this.shost;
}
public String getsuser() {
return this.suser;
}
public String getspass() {
return this.spass;
}
public panel(){
Dimension size = getPreferredSize();
size.width = 680;
size.height = 600;
setPreferredSize(size);
setBorder(BorderFactory.createTitledBorder("Linux Audit"));
setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
JLabel labelhost = new JLabel("Host ");
JLabel labeluser = new JLabel("User name ");
JLabel labelpass = new JLabel("Password ");
JLabel labelport = new JLabel("Port ");
final JTextField host = new JTextField(15);
final JTextField user = new JTextField(15);
final JTextField pass=(JTextField)new JPasswordField(15);
final JTextField port = new JTextField(15);
final JButton start = new JButton("Start Audit");
//layout design
gc.anchor = GridBagConstraints.LINE_END;
gc.weightx = 0.5;
gc.weighty = 0.5;
gc.gridx=0;
gc.gridy=0;
add(labelhost,gc);
gc.gridx=0;
gc.gridy=1;
add(labeluser,gc);
gc.gridx=0;
gc.gridy=2;
add(labelpass,gc);
gc.gridx=0;
gc.gridy=3;
add(labelport,gc);
gc.anchor = GridBagConstraints.LINE_START;
gc.gridx=1;
gc.gridy=0;
add(host,gc);
gc.gridx=1;
gc.gridy=1;
add(user,gc);
gc.gridx=1;
gc.gridy=2;
add(pass,gc);
gc.gridx=1;
gc.gridy=3;
add(port,gc);
gc.anchor = GridBagConstraints.FIRST_LINE_START;
gc.weighty=10;
gc.gridx=1;
gc.gridy=4;
add(start,gc);
//startaudit action
start.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
String shost = host.getText();
String suser = user.getText();
String spass = pass.getText();
String sportb = port.getText();
int sport = Integer.parseInt(sportb);
sshConnection s = new sshConnection();
s.Connection();
/*System.out.println(shost);
System.out.println(suser);
System.out.println(spass);
System.out.println(sport);*/
}
});
}
}
in above i am trying to fetch the value of global variables
String shost;
String suser;
String spass;
int sport;
in another class
///another class
public class sshConnection {
public void Connection(){
String sshhost = new panel().getshost();
String sshuser = new panel().getsuser();
int sshport = new panel().getsport();
String sshpass = new panel().getspass();
System.out.println(sshhost);
System.out.println(sshuser);
System.out.println(sshport);
System.out.println(sshpass);
}
}
i am getting null values instead of inserted values at the time of execution.please solve the problem, i know its very basic but i m beginer.so plz help
thanks
In the panel class, shost, suser, etc., aren't set to anything until you click on the Start Audit button. But Connection constructs a 4 new panel objects. Those won't be the same panel objects that you clicked the button on. I think what you want to do is change your Connection method so that it takes a panel argument:
public void Connection(panel p){
String sshhost = p.getshost();
String sshuser = p.getsuser();
...
and change the s.Connection call inside your listener to
s.Connection (panel.this);
so that Connection knows what panel it's supposed to be working with.
Or, a better design might be to have Connection take the three strings and the integer as arguments, and not bother with getshost(), etc., at all.
You're creating multiple instances of panel in sshConnection#Connection whose fields are null.
The values from the existing instance of panel need to be used. I suggest simply pass them as parameters instead
public void performConnection(String sshHost, String sshUser, int sshPort, String sshPass){
...
}
Java Naming Conventions show that classes start with a uppercase letter, e.g. SshConnection while methods start with a lowecase letter, e.g. performConnection. Read Naming Conventions