showInputDialog displays too many times after selecting no - java

I want Play() to run again if String confirm input is anything other than "Y" or "y". When I press the war button, it shows the input dialog, and if I input "N" it will function as intended. However, if I press any button and input "N" again in the same program run, it will asks for confirmation a 2 times. If I do it again, it asks for confirmation 4 times, and it continues this pattern by powers of 2. What is causing that, and is there a better way to confirm the users choice?
I've tried setting String confirm equal to " " in the else{} just before it runs play() again, which didn't work and I didn't expect to work anyway. But other than that I have no idea.
public class Main {
public static void main(String[] args) {
GUI heroSelect = new GUI(450, 200, "Inscription", new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
JLabel heroLabel = new JLabel("Choose your class, hero.");
heroLabel.setFont(new Font("Serif", Font.PLAIN, 22));
c.gridx = 1;
c.gridy = 0;
c.weightx = .5;
c.weighty = .5;
heroSelect.add(heroLabel, c);
JButton war = new JButton("Warrior");
c.gridx = 0;
c.gridy = 2;
heroSelect.add(war, c);
JButton mage = new JButton("Mage");
c.gridx = 1;
c.gridy = 2;
heroSelect.add(mage, c);
JButton rog = new JButton("Rogue");
c.gridx = 2;
c.gridy = 2;
heroSelect.add(rog, c);
play(war, mage, rog);
}
public static void play(JButton war, JButton mage, JButton rog) {
war.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String confirm = JOptionPane.showInputDialog(null, "The warrior "
+ "is a strong, hard-hitting class. It relies on raw "
+ "damage and heals through offensive abilities.\n "
+ "However, the warior does not possess any direct "
+ "healing or spells. Are you sure you want to choose "
+ "this class? Y/N");
if(confirm.equalsIgnoreCase("Y")) {
//TBD
}
else {
play(war, mage, rog);
}
}
});
mage.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String confirm = JOptionPane.showInputDialog(null, "");//ADD DESCRIP
if(confirm.equalsIgnoreCase("Y")) {
}
else {
play(war, mage, rog);
}
}
});
rog.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
String confirm = JOptionPane.showInputDialog(null, "");//ADD DESCRIP
if(confirm.equalsIgnoreCase("Y")) {
}
else {
play(war, mage, rog);
}
}
});
}
}
showInputDialog should close when the user enters "N" or "n", and should re-run play() to allow the user to look at the description of other classes and eventually choose one. Instead, inputting "N" or anything other than "Y" or "y" for that matter results in multiple showInputDialog prompts back to back.

What you are doing by calling the play() method inside of itself is called recursion, every time you call it you are adding more EventListeners to the buttons.
I think that a do-while loop that repeatedly checks the input, in place of the if-else will work for you.
do {
String confirm = ...
....
if(confirm.equalsIgnoreCase("N")) {
break;
}
} while (!confirm.equalsIgnoreCase("Y"))
// Code to run game or whatever is next...

You call Play method in listeners that are created in Play method. and everytime you make new listener for each hero.
Also read about OOP (it is more important to use objects in java than using GUI for starters :))
As the question about better ways in general I really encourage You to get familiar with patterns.
Just gathering inputs are really simple thing and you have multiple choices like looping switch case for example.

Related

Basic GUI java program in Eclipse keeps crashing

I am trying to make a game and in said game, there are 21 sticks and each person takes turns taking 1-4 sticks until there are no sticks left, if you cant take anymore sticks you lose. I have successfully made this program in eclipse but now I want to add GUI to it so I have to change the code. This code isn't complete but it crashes whenever I press the Go button which is my actionListener. I would type in a number to the text field, press go and it will just crash. How can I fix this?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Sticks extends JFrame {
JButton Go;
JTextField tf1, tf2;
static JTextField sttf;
JLabel startTake;
static JLabel errorTake;
JLabel uTake;
JLabel compTake;
public Sticks() {
setLayout(new GridLayout(5, 2, 5, 5));
startTake = new JLabel("How many sticks do you want to take? (1-4)");
add(startTake);
sttf = new JTextField();
add(sttf);
errorTake = new JLabel("Hello");
add(errorTake);
Go = new JButton("Go");
add(Go);
uTake = new JLabel("");
add(uTake);
compTake = new JLabel("");
add(compTake);
// tf1 = new JTextField();
// add(tf1);
// TakeP = new JLabel("One stick taken");
// add(TakeP);
event e = new event();
Go.addActionListener(e);
}
public static class event implements ActionListener {
public void actionPerformed(ActionEvent e) {
int numSticks = 21;
int numToTake = 0;
int randomNum = 0;
while (numSticks > 0) {
try {
int num = (int) (Double.parseDouble(sttf.getText()));
int NumSticks = numSticks - num;
errorTake.setText("There are: " + numSticks + " left");
Robot Rob = new Robot();
numToTake = (int)Math.random() * 4 + 1;
errorTake.setText("There are: " + numSticks + " left");
}
catch (Exception ex) {
ex.printStackTrace();;errorTake.setText("There is a problem");
}
}
}
}
public static void main(String[] args) {
Sticks gui = new Sticks();
gui.setDefaultCloseOperation(EXIT_ON_CLOSE);
gui.setVisible(true);
gui.setSize(600, 200);
gui.setTitle("Nice Game");
}
}
Everytime you click the "Go" button, your actionPerformed fires, and it doesn't wait for user input at all. This is your problem line.
public static class event implements ActionListener {
public void actionPerformed(ActionEvent e) {
//...
int num = (int) (Double.parseDouble(sttf.getText()));
//...
}
}
sttf.getText() always returns "" because sttf is empty, the program doesn't wait for user input unlike Scanner(System.in).
Makes sense that you don't get any Exceptions because it just runs and finishes the game without giving the user enough time to input anything. Are you sure the console doesn't print "Numbers only!", though? Because I've never tried to parse an empty String before.
Okay I've been reading this all wrong, sorry.
Your actionListener generates a new game everytime you click it, because you set your numSticks to 21 at each click. Looking forward, I don't think that's a good idea unless you want to take the same amount of sticks the whole way until the game ends. Same thing stands. If you input a value in sttf, the program won't wait for you to change it because it'd keep using that value until your while loop ends.

JTextField won't disappear completely

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.

NumberFormatException and other problems while making a calculator in java

So I'm making a Java Calculator and walking into some errors upon clicking the function buttons (it compiles perfectly fine though).
The error on the 1st line in my CMD was a NumberFormat Exception. After some searching I figured out that somewhere in my code I was trying to get a double out of an empty string (basically what I'm trying to do is parse a double from the label text). I'm guessing it's this part:
// if statement that puts the labels text into the first or second number
if(firstNumber)
{
number1 = Double.parseDouble(label.getText().trim());
} else {
number2 = Double.parseDouble(label.getText().trim());
}
Basically the problems are when i push the / * + or - button i get a NumberFormatExeption: For input string "/" etc.
I can't quite figure out how i have to fix this error (I'm still (somewhat) a beginner in Java).
Further down the line of errors (there were quite alot) were a whole lot of errors I didn't understand such as EventDispatchThread, EventQueue and many others. I couldn't find an explanation on my level of experience either so I'm asking for help here.
The numeric buttons all work fine.
At run: [http://gyazo.com/71cb4dde449ccf7ece44017388a71a0f]
Putting in numbers: [http://gyazo.com/5c7ab6c54ac6da180845c66866d66f8f]
All other buttons give errors in my CMD.
Here's my code (the spacing might be messed up in some parts):
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
// import for Nimbus look
import javax.swing.UIManager.*;
public class Calculator extends JFrame implements ActionListener
{
private JPanel bottom = new JPanel(); private JPanel top = new JPanel();
private JLabel label = new JLabel(" ");
private JButton[] buttons = new JButton[16];
// booleans for calculator functions
boolean add = false, substract = false, devide = false, multiply = false, firstNumber = true;
// numbers that will be calculated
double number1, number2;
public Calculator()
{
setLayout(new BoxLayout(getContentPane(), BoxLayout.PAGE_AXIS));
// bottom panel
bottom.setPreferredSize(new Dimension(100,100));
bottom.setLayout(new BorderLayout());
//add bottom panel to frame
add(bottom);
// top panel
top.setPreferredSize(new Dimension(300,400));
top.setLayout(new GridLayout(4,4,3,3));
top.setBackground(Color.BLACK);
//dont add top panel to frame: you want top to be on bottom
// add top panel to bottom panel
bottom.add(top);
// label
label.setFont(new Font("Courier", Font.PLAIN, 20));
label.setBackground(Color.BLACK);
label.setForeground(Color.WHITE);
label.setHorizontalAlignment(SwingConstants.RIGHT); // text is right-aligned
label.setOpaque(true);
// add the label to the bottom panel
bottom.add(label, BorderLayout.NORTH);
// creating buttons
for(int i = 0; i < buttons.length; i++)
{
buttons[i] = new JButton("789/456*123+c0=-".substring(i, i+1));
buttons[i].addActionListener(this);
// add them to the top panel
top.add(buttons[i]);
}
// Nimbus look
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
// If Nimbus is not available, you can set the GUI to another look and feel.
//set to default somehow o.o
}
// frame setters
setTitle("Calculator");
setSize(400,400);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void Clear()
{
label.setText(" ");
}
#Override
public void actionPerformed(ActionEvent e)
{
//if's for all function buttons
if(e.getSource() == buttons[3])
{
// devide
devide = true;
substract = false;
add = false;
multiply = false;
firstNumber = false;
Clear();
label.setText("/");
}
if(e.getSource() == buttons[7])
{
// multiply
multiply = true;
substract = false;
devide = false;
add = false;
firstNumber = false;
Clear();
label.setText("*");
}
if(e.getSource() == buttons[11])
{
// add
add = true;
substract = false;
devide = false;
multiply = false;
firstNumber = false;
Clear();
label.setText("+");
}
if(e.getSource() == buttons[12])
{
// clear
label.setText("0");
number1 = 0.00;
number2 = 0.00;
add = false;
substract = false;
devide = false;
multiply = false;
firstNumber = true;
Clear();
}
if(e.getSource() == buttons[15])
{
// substract
substract = true;
add = false;
devide = false;
multiply = false;
firstNumber = false;
Clear();
label.setText("-");
}
// for loops that add the numbers on the buttons to the label
for(int i = 0; i < 3; i++)
{
if(e.getSource() == buttons[i])
{
if(label.getText() == "0")
{
label.setText("");
label.setText(label.getText() + buttons[i].getText());
} else {
label.setText(label.getText() + buttons[i].getText());
}
}
}
for(int i = 4; i < 7; i++)
{
if(e.getSource() == buttons[i])
{
if(label.getText() == "0")
{
label.setText("");
label.setText(label.getText() + buttons[i].getText());
} else {
label.setText(label.getText() + buttons[i].getText());
}
}
}
for(int i = 8; i < 11; i++)
{
if(e.getSource() == buttons[i])
{
if(label.getText() == "0")
{
label.setText("");
label.setText(label.getText() + buttons[i].getText());
} else {
label.setText(label.getText() + buttons[i].getText());
}
}
}
for(int i = 13; i < 14; i++)
{
if(e.getSource() == buttons[i])
{
if(label.getText() == "0")
{
label.setText("");
label.setText(label.getText() + buttons[i].getText());
} else {
label.setText(label.getText() + buttons[i].getText());
}
}
}
// if statement that puts the labels text into the first or second number
if(firstNumber)
{
number1 = Double.parseDouble(label.getText().trim());
} else {
number2 = Double.parseDouble(label.getText().trim());
}
// calculation
if(e.getSource() == buttons[14])
{
// calculate
if(devide){number1 = ((double)(number1) / (double)(number2)); }
if(multiply){number1 = ((double)(number1) * (double)(number2)); }
if(add){number1 = ((double)(number1) + (double)(number2)); }
if(substract){number1 = ((double)(number1) - (double)(number2)); }
label.setText(Double.toString(number1));
}
}
public static void main(String[] args)
{
new Calculator();
}
}
Lastly, the calculations made by the calculator are incorrect. I also can't wrap my head around what's causing that. Please bear in mind that I'm a beginner at Java and this is my first question on stackoverflow. Thanks in advance for helping me, whoever will :)
UPDATE: i fixed the errors by putting my code as follows:
if(e.getSource() == buttons[15])
{
// substract
substract = true;
add = false;
devide = false;
multiply = false;
firstNumber = false;
isNumberKey = false;
if(isNumberKey)
{
if(firstNumber)
{
label.setText(label.getText().replace("/",""));
label.setText(label.getText().replace("*",""));
label.setText(label.getText().replace("+",""));
label.setText(label.getText().replace("-",""));
number1 = Double.parseDouble(label.getText().trim());
} else {
label.setText(label.getText().replace("/",""));
label.setText(label.getText().replace("*",""));
label.setText(label.getText().replace("+",""));
label.setText(label.getText().replace("-",""));
number2 = Double.parseDouble(label.getText().trim());
}
}
Clear();
label.setText("-");
}
All i need to do now is fix the calculations...
Thanks for the help everyone!
Cannot delve totaly into your logic there, but here's some hints:
First, you don't have to guess where the error is. In case of uncaught exception like here, thread that produced it will print it's stack trace to console. It looks like this:
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: For input string: "/"
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1222)
at java.lang.Double.parseDouble(Double.java:510)
at mypackage.Calculator.actionPerformed(Calculator.java:229)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:6297)
From here you see that exception happened in thread named AWT-EventQueue-0, which is swing's standard event dispatching thread (all GUI applications handles events in single thread). Another thing you search in stack trace is to find what line in your code thrown it. Here it's the line:
at mypackage.Calculator.actionPerformed(Calculator.java:229)
In source, it is line:
number2 = Double.parseDouble(label.getText().trim());
, so you guessed right. What you can do is add another boolean there which will be set only if number button is hit, and then change that part of code to something like:
if( isNumber){
if(firstNumber)
{
number1 = Double.parseDouble(label.getText().trim());
} else {
number2 = Double.parseDouble(label.getText().trim());
}
}
Apart from that, instead of using multiple boolean flags for operation, use Java enum type
enum Operation {devide, substract, add, multiply};
your code will be more readable and "java" styled.
Good starting point, just go ahead!
Disclaimer: I'm on my phone so it's hard to parse your code; with that being said, I believe your number format exception deals with what is stored in the label text.
From the looks of it if you hit an operator button (like multiply), the labelText will be "*", then if you hit number button (like 5), the labelText will be "*5". Finally, if you hit the enter button now to go calculate the answer, Double.parseDouble(label.getText().trim()), will be ran which will throw the NumberFormatException. Using the operation flags, it looks like you don't even need to store the operator (unless you're trying to display the operator to the user); in that case you need to strip the operator from the string before trying the parse the double.
label.setText(label.getText().replace("/",""));
label.setText(label.getText().replace("*",""));
label.setText(label.getText().replace("+",""));
label.setText(label.getText().replace("-",""));
As for the other exceptions, in eclipse you can set a breakpoint to halt the program when a specific exception occurs. This will help you debug your code further.
more info on that here

Making a notepad in java with a on screen keyboard, cant link it to the text area properly

First of all, thank you for taking your time to read this.
this is what am trying to make:
A Text editor with multiple options.
a button for a virtual keyboard. I've managed to create the buttons, also successfully added all the buttons, however I am having difficulties linking each button to my text area and making each button press work.
Not looking for anything complex also all other aspects of the app works, as you will see from the screenshot provided.
this is the bits of code in relation to my keyboard.
class KbListener implements ActionListener //kb function.
{
public void actionPerformed(ActionEvent e) //checking events.
{
keyboard = new JFrame("VK");
keyboard.setSize(400,300);//setting initial size of app.
keyboard.setVisible(true);//making sure its active.
keyboard.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);//closes when the x is pressed.
JButton[] letter = new JButton[27];
keyboard.setLayout(new GridLayout(3,9));
for (int i = 0;i<27;i++)
{
letter[i] = new JButton(""+(char)('A'+ i));
keyboard.add(letter[i]);
//up until this point all is fine.
letter[i].addActionListener = (new ActionListener());
if(e.getSource() ==letter[A])
textArea.append("A");
}
}
}
You need to create a String that is used in the button and used in its listener both, something like,
for (int i = 0; i < 27; i++) {
final String buttonText = String.valueOf((char) ('A' + i));
letter[i] = new JButton(buttonText);
keyboard.add(letter[i]);
letter[i].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
textArea.append(buttonText);
}
});
}
Note that buttonText must be final so that it is accessible within the anonymous inner ActionListener class.
Also, consider avoiding magic numbers. For instance, you could do
for (int i = 0; i <= (int)('Z' - 'A'); i++) {
or
int i = 0;
for (char myChar = 'A'; myChar <= 'Z'; myChar++) {
final String btnText = String.valueOf(myChar);
letter[i] = new JButton(btnText);
keyboard.add(letter[i]);
letter[i].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
textArea.append(btnText);
}
});
i++;
}
Edit
Another and perhaps better way to do this is to use Actions rather than ActionListeners. For instance,...
//....
int i = 0;
for (char myChar = 'A'; myChar <= 'Z'; myChar++) {
final String btnText = String.valueOf(myChar);
MyKeyBoardAction action = new MyKeyBoardAction(btnText);
letter[i] = new JButton(action);
i++;
}
}
private class MyKeyBoardAction extends AbstractAction {
public MyKeyBoardAction(String name) {
super(name);
}
#Override
public void actionPerformed(ActionEvent e) {
textArea.append(getValue(NAME).toString());
}
}
You also ask about the space character,
do u know how to add a space to the code as well?
That would not work with your for loop but can be added on its own.
Also,
but why avoid the numbers?
Because it's easy to make hard to fix bugs if you use "magic" numbers that don't intrinsically make sense. Also, by using constants, variables rather than hard-coded numbers, your variables make your code self-commenting.
Why don't create direct the action listener?
letter[i].addActionListener = (new ActionListener() {
public void onClick(View view) {
textArea.append(""+(char)('A'+ i));
}
);

java dynamic display JLabel

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.

Categories