i am developing a project to a class and i came up with a stand-still.
So, what i want to do is to refresh the label when the user presses enter in the textfield to verify the ID.
Here is my code to catch when "enter" key is pressed, it's an event of the textfield "txtNbi":
if (evt.getKeyCode() == 10) {
this.BI = txtNbi.getText();
String BIs[];
BIs = DadosAplicacao.getInstance().getBIs();
for (int i = 0; i < BIs.length; i++) {
System.out.println("BI: " + this.BI + "\nBIlista: " + BIs[i]);
if (this.BI.equals(BIs[i])) {
encontrou.setIcon(new javax.swing.ImageIcon(getClass().getResource("/pt/estg/dint/imagens/Ok.png")));
this.repaint();
} else {
encontrou.setIcon(new javax.swing.ImageIcon(getClass().getResource("/pt/estg/dint/imagens/Cross.png")));
this.repaint();
}
}
}
txtNbi = name of my textfield;
BIs = array of strings that get pre-inserted IDs from the 'DadosAplicacao' class;
encontrou = name of my label that receives the image as an icon
So here is my problem:
I have the following data:
- BIs[0] = 12345678
- BIs[1] = 87654321
- BIs[2] = 54321678
When i type in the first 2 the label doesn't change to the "Ok.png" icon, but when i type the last one the label changes his icon to "Ok.png"!
Can anyone help me fix this?
You need to use the DocumentListener class:
txtNbi.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent documentEvent) {
//add the code handling the different conditions here
}
});
you need a break after you found the typed ID
if(this.BI.equals(BIs[i]))
{
encontrou.setIcon(newjavax.swing.ImageIcon(getClass().getResource("/pt/estg/dint/imagens/Ok.png")));
this.repaint();
break;
}
Related
I created a dialog box and have the user enter 5 colors in it from memory. That all completely works, there's just a slight aesthetic problem. Upon entering all 5 colors correctly, or getting one incorrect, it's suppose to wipe the contents within the dialog box and print a message "Sorry! Incorrect color" or "Congratulations". It prints the message, but the JTextField can still be seen somewhat behind the message (A left over portion/clipping).
I've tried using the hide() and remove() methods but they didn't seem to work (Or I'm using them incorrectly), I tried re-making a dialog box upon either but I couldn't seem to solve the issue still. What am I doing wrong/how can I make the JTextField disappear upon completion? Thank you in advance for any help!
Here's the portion where if the user enters a color incorrectly or gets them all correct (txtName is the JTextField):
if(count == 6)//User either finished or entered a color incorrectly
{
//Entered color incorrectly
if(incorrect == true)
{
txtName.setEnabled(false); //Doesn't work
homeScreen.remove(txtName); //Doesn't work
labelName.setText("Incorrect! Sorry - Wrong color.");
//txtName.removeActionListener(new MyButtonListener());
}
else//Correctly finished the game.
{
labelName.setText("Congratulations - your memory skills are perfect!");
//txtName.removeActionListener(new MyButtonListener());
homeScreen.remove(txtName);//Doesn't work
}
}
Here's my entire program (I can't get it format properly in the post):
package memorygame;
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.FlowLayout;
public class MemoryGame
{
private JFrame homeScreen;
private JLabel labelName;
private JTextField txtName;
private JLabel correct;
Vector<String> name = new Vector();
private int count = 1;
private MyButtonListener listen1 = new MyButtonListener();
//Constructor - Method to be called when MemoryGame object called
public void MemoryGame ()
{
homeScreen = new JFrame();
homeScreen.setSize(400,200);
homeScreen.setTitle("Memory Game");
homeScreen.setDefaultCloseOperation(homeScreen.EXIT_ON_CLOSE);
homeScreen.setLayout(new FlowLayout());
labelName = new JLabel();
txtName = new JTextField(10);
createContents();
homeScreen.setVisible(true);
}//End Constructor
//Create components and add them to the window/dialog box
private void createContents()
{
labelName.setText("Enter the color " + count + ":");
System.out.println("The current count is: " + count);
homeScreen.add(labelName);
homeScreen.add(txtName);
txtName.addActionListener(new MyButtonListener());//Allows you to press enter to invoke action
}
//Upon user hitting enter
private class MyButtonListener implements ActionListener
{
public void actionPerformed (ActionEvent e)//When event occurs
{
Scanner in = new Scanner (System.in);//For program input
String answer = "";
//Make memColor an array for randomized colors
/*
Random r = new Random();
String[] memColors = new String[5];
String[] colors = {"red", "green", "blue", "yellow", "brown", "purple"};
for(int i =0; i < memColors.length; i++)
{
memColors[i] = colors[r.nextInt(6)];
}
*/
String memColor1 = "red";
String memColor2 = "black";
String memColor3 = "yellow";
String memColor4 = "green";
String memColor5 = "blue";
boolean incorrect = false;
//If answered incorrectly set count to 5(it'll be 6)
//And have a boolean for if count== 6 for congrats and failure
if(e.getSource() == txtName)
{
answer = txtName.getText();
System.out.println(answer);
}
else
{}
//Check if user entered Correct color, 1= Red, 2= Black, etc.
if(count == 1)
{
if(answer.equalsIgnoreCase(memColor1))
{
txtName.setText("");
}
else
{//Needs to be a custom message box
count = 5;
incorrect = true;
}
}
else if(count == 2)
{
if(answer.equalsIgnoreCase(memColor2))
{
txtName.setText("");
}
else
{
count = 5;
incorrect = true;
}
}
else if(count == 3)
{
if(answer.equalsIgnoreCase(memColor3))
{
txtName.setText("");
}
else
{
count = 5;
incorrect = true;
}
}
else if(count == 4)
{
if(answer.equalsIgnoreCase(memColor4))
{
txtName.setText("");
}
else
{
count = 5;
incorrect = true;
}
}
else if(count == 5)
{
if(answer.equalsIgnoreCase(memColor5))
{
txtName.setText("");
}
else
{
count = 5;
incorrect = true;
}
}
else
{
JOptionPane.showMessageDialog(null, "Something went wrong!");
}
count += 1;
//User has completed the game or entered a color incorrectly
if(count == 6)
{
if(incorrect == true) //Incorrect color
{
txtName.setEnabled(false);
homeScreen.remove(txtName);
labelName.setText("Incorrect! Sorry - Wrong color.");
//txtName.removeActionListener(new MyButtonListener());
}
else //Completed the game correctly
{
labelName.setText("Congratulations - your memory skills are perfect!");
//txtName.removeActionListener(new MyButtonListener());
homeScreen.remove(txtName);
}
}
else
{
labelName.setText("Enter the color " + count + ":");
}
}//End Listener
}//End Button class
public static void main(String[] args) {
//Show message box
//Randomize colors
JOptionPane.showMessageDialog(null, "How good is your memory?\nTry to memorize this color sequence:\n\n red black yellow green blue");
MemoryGame mem = new MemoryGame();
mem.MemoryGame();
}//End Main
}// End Class
Use txtName.setVisible(false); instead of homeScreen.remove(txtName);
Basically, if you want to call remove, you will need to revalidate and repaint container...
You'll also want to ensure that your UI is create within the context of the Event Dispatching Thread, see Initial Threads for more details
Change the code
homeScreen.remove(txtName);
to
homeScreen.remove(txtName);
homeScreen.revalidate();
homeScreen.repaint();
The reason why remove() does not imply revalidate() + repaint() is that remove() is not atomic. The caller might want to perform multiple updates, a sequence of several add() and remove() calls. revalidate() basically "completes" your "UI update transaction", repaint() "pushes it to the screen".
As a side note, your code will be easier to understand and maintain, if you perform a small tiny improvements on variable names. What's homeScreen? And why is it called labelName - what name? And what's txtName - the name of what text? count of what, icecreams?
I suggest the following improvements:
incorrect -> isIncorrect (also change if (incorrect == true) to if (isIncorrect)
homeScreen -> mainFrame or just frame (as you only have one frame)
labelName -> infoLabel or just label (as you only have one label - and remove JLabel correct, it's unused)
txtName -> answerTextField
count -> answerCount
Remove variable listen1, it's not used.
Plus, if you look at the code that does if (count == 1) and the following four if clauses, they are all identical except for the number. A perfect situation for an array. You can convert the variables memColor* to an array String[] memColor. Or maybe that's what the Vector was for. You might instead want to use ArrayList, nobody uses Vector these days in such situations.
I have a button. If I click this button, a popup appears. The popup asking me to write a word. if I write a word 6 letter, 6 jlabels appear, but if I enter another word shorter, the JLabels do not disappear
I want my JLabels may decrease according to a shorter word, but i don't know :(
thx for your great help !
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
//BUTTON 1 WORD
Controller c = new Controller();
try {
final JFrame popup = new JFrame();
//display popup
word = JOptionPane.showInputDialog(popup, "Enter one word", null);
//control the length of the word
c.controleW(word);
//display jlabel lenght of word
keyNumber.setText(String.valueOf(word.length()));
//JLabels displays depending on the word length
int pixels = 50;
for (int i = 0; i < word.length(); i++) {
label = new JLabel("_");
label.setBounds(pixels, 200, 30, 30);
add(label);
label.repaint();
pixels += 20;
}
} catch (Exception e) {
System.out.println(e);
}
}
And my class to control the length of the word
public String controleW(String word) {
boolean flag = false;
final JFrame popup = new JFrame();
while (flag == false) {
if (word.length() <= 3) {
word = JOptionPane.showInputDialog(popup, "Enter one word", null);
} else {
flag = true;
}
};
return null;
}
You are always adding labels in your method, never removing any, thus running the code twice will indeed add labels twice. To fix it, you can simply add a removeAll(); in jButton1ActionPerformed before you add any labels. This makes sure that any previously added components will be removed.
I am writing an tip calculator app in java applet with GUI, my question is how I make sure the error message will pop up if users enter letter instead of number
it is my first time asking question, please be easy on me! Thanks!!!
import objectdraw.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
// Typing in the text field and hitting return adds text to text area.
// Clicking on button erases the text area.
public class TextApplet extends Controller implements ActionListener
{
private static final int ROWS = 1; // rows in TextArea
private static final int COLS = 10; // cols in text field & area
private String amount;
private float number;
private JTextField inField, output; // Input field
private JButton clear, calc;
// button to clear output
public void begin()
{
Container contentPane = getContentPane();
JPanel topPanel = new JPanel(); // prepare text field & label
JLabel inLabel = new JLabel("Bill Cost: ");
inField = new JTextField(COLS);
inField.addActionListener(this);
JLabel topTitle = new JLabel("Tip Calculator", JLabel.CENTER);
JPanel combinePanel = new JPanel();
combinePanel.add ( inLabel );
combinePanel.add ( inField );
JPanel combinePanel1 = new JPanel();
combinePanel1.add ( topTitle );
topPanel.add ( combinePanel1 );
topPanel.add ( combinePanel );
topPanel.setLayout ( new GridLayout ( 3,1) );
contentPane.add(topPanel,BorderLayout.NORTH);
JPanel centerPanel = new JPanel(); // prepare text area & label
JLabel outLabel = new JLabel("Bill + Tip:");
output = new JTextField(COLS);
output.setEditable(false); // Prevent user from wrting in output
centerPanel.add(outLabel);
centerPanel.add(output);
contentPane.add(centerPanel,BorderLayout.CENTER);
JPanel bottomPanel = new JPanel();
// create button
clear = new JButton(" Clear ");
calc = new JButton("Calculate");
calc.addActionListener(this);
clear.addActionListener(this);
bottomPanel.add(calc);
bottomPanel.add(clear);
contentPane.add(bottomPanel,BorderLayout.SOUTH);
validate();
}
// add text to area if user hits return, else erase text area
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() == calc )
{
amount = inField.getText();
number = ( Float.parseFloat( amount ) );
number = (15*number/100);
output.setText ( Float.toString ( number ) + '$' );
}
else if (evt.getSource() == clear )
{
output.setText("$");
inField.setText("");
}
}
}
There are any number of ways you might achieve this, you could use
An InputVerifier
A JFormattedTextField
A JSpinner
Or a DocumentFilter and examples
Take a look at javax.swing.InputVerifier. That can be easily attached to a JTextField
JTextField inputField = new JTextField();
inputField.setInputVerifier(new NumericInputVerifier());
private class NumericInputVerifier extends InputVerifier
{
#Override
public boolean verify(JComponent input)
{
if (((JTextField) input).getText().matches("[0-9]+"))
{
return true;
}
else
{
JOptionPane.showMessageDialog(input, "Only numbers are allowed", "Warning", JOptionPane.WARNING_MESSAGE);
return false;
}
}
}
A complete example can be found here.
Edit Added an example of how to use InputVerifier to limit to numeric input. You'll want to double check the regex, but the basic idea is there...
Use a JFormattedTextField or a DocumentFilter. Then the user won't even be able to enter a non-numeric digit. See:
How to Use Formatted Text Fields
Implementing a Document Filter
For the document filter you will need to check each chraacter as it is entered to make sure it is a digit.
It is always better to do simple edits like that as the user types, rather than wait until you click on a button to do processing.
Hello Friend I will give a suggestion
please add validation when call actionPerformed method
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() == calc )
{
if(validate()){
amount = inField.getText();
number = ( Float.parseFloat( amount ) );
number = (15*number/100);
output.setText ( Float.toString ( number ) + '$' );
}
else{
// show message for inter valid number or any other
}
}
else if (evt.getSource() == clear )
{
output.setText("$");
inField.setText("");
}
}
boolean validate(){
try{
amount = inField.getText();
number = ( Float.parseFloat( amount ) );
return true;
}
catch(Exception e){
return false;
}
}
If you try to call Float.parseFloat on a String that cannot be converted to a float, it will throw a NumberFormatException. You need to catch this exception.
try {
number = ( Float.parseFloat( amount ) );
number = (15*number/100);
output.setText ( Float.toString ( number ) + '$' );
} catch(NumberFormatException e) {
//code to show error message here
}
Well considering, you'd have to turn the string into an integer to do the math, you could do this:
try {
int number = Ineger.parseInt(inField.getText());
} catch (NumberFormatException e) {
//SHOW WARNING
}
if (Label1.getText().matches("[0-9]+"))
// does Label1 containts numbers.
{
// do math
}
else
{
// warning
Lavbel1.setText("");
}
I'm new to Java and I am having some trouble with my assignment.
I have a Panel containing 100 JLabels:
for(int i=0;i<100;i++)
{
num[i] = new JLabel(""+i, JLabel.CENTER);
mainPanel.add(num[i]);
}
And a button to set image icon for the label when clicked
public void actionPerformed(ActionEvent ae)
{
int a = ran.nextInt(6) +1;//random number
int b +=a;
if(b>=100)
{
b=99;
num[b].setIcon(icon);
}
else
{
num[b].setIcon(icon);
}
}
How can i remove the icon from the last position and update it to a new position?
You can try to remember the index of the array of the label, for which you tried to set the icon.
For example-
int b = 0; // make b an instance variable
public void actionPerformed(ActionEvent ae)
{
int a = ran.nextInt(6) +1;//random number
num[b].setIcon(null); //remove the icon from from previously set label
b=a; //since b already has some value, b+=a might create unexpected result, hence just assigned a
if(b>=100)
{
b=99;
num[b].setIcon(icon);
}
else
{
num[b].setIcon(icon);
}
}
I am passing some coordinates from one class to another using the following code
**edited to show more detail
At start of class1:
public class BattleGui implements ActionListener {
private int xCoordinate;
private int yCoordinate;
public void coordinateHandler(int xCoord, int yCoord) {
xCoordinate=xCoord;
yCoordinate=yCoord;
System.out.println("Coordinates Received "+xCoord + " " +yCoord);
System.out.println("Test "+xCoordinate + " " +yCoordinate);
}
public void actionPerformed(ActionEvent e) {
String classname = getClassName(e.getSource());
JComponent component = (JComponent)(e.getSource());
cellState cs = new cellState();
if (classname.equals("JMenuItem")) {
JMenuItem menusource = (JMenuItem)(e.getSource());
String menutext = menusource.getText();
// Determine which menu option was chosen
if (menutext.equals("Load Game")) {
/* BATTLEGUI Add your code here to handle Load Game **********/
System.out.println(cs.turnFeedback());
LoadGame();
}
else if (menutext.equals("Save Game")) {
/* BATTLEGUI Add your code here to handle Save Game **********/
SaveGame();
}
else if (menutext.equals("New Game")) {
/* BATTLEGUI Add your code here to handle Save Game **********/
NewGame();
}
}
// Handle the event from the user clicking on a command button
else if (classname.equals("JButton")) {
JButton button = (JButton)(e.getSource());
int bnum = Integer.parseInt(button.getActionCommand());
int row = bnum / GRID_SIZE;
int col = bnum % GRID_SIZE;
//col=yCoord;
//row=xCoord;
//System.out.println(e.getSource());
//System.out.println(bnum / GRID_SIZE);
fireShot(row, col);
if (row==xCoordinate){
if (col==yCoordinate){
button.setBackground(cellColour[cs.turnFeedback()]);
}
else {
//Remember to change the 1 to whatever is reported back from cell class cell state
//button.setBackground(cellColour[cs.turnFeedback()]);
button.setBackground(Color.BLUE);
}
}
else {
button.setBackground(Color.BLUE);
}
}
}
From class2:
public void shipDeploy() {
int gridLength;
int lengthDraw;
int winningNumbers = 0;
int xCoord;
int yCoord;
xCoord=99;
yCoord=100;
System.out.println(xCoord + "\n" + yCoord);
BattleGui bGui = new BattleGui();
//Passing the coordinates back to the battlegui coordinate handler class
bGui.coordinateHandler(xCoord, yCoord);
}
This passes these two values to a coordinate handler method within the first class.
within this class I have an xCoordinate variable used throughout a variety of methods, the problem is that I dont seem to be able to set this, 0 is always being returned outside of this method for xCoordinate and yCoordinate and I dont understand why, as they seem to be ok in the line System.out.println("Test "+xCoordinate + " " +yCoordinate); above.
just figured it out on my own, quite simple really, actionlistener was basically re-instantiating the variable on every "event" explaining the zero values, as soon as i took this process outside of the listener it worked and set the values as intended. thanks for the input guys and hope this helps someone along the way!