please see my attached code below and then my question at the end.
class events extends JFrame{
private JLabel label;
private JButton button;
public events() {
setLayout(new FlowLayout());
button = new JButton("Click for text");
add(button);
label = new JLabel("");
add(label);
event e = new event();
button.addActionListener(e);
}
public class event implements ActionListener {
public void actionPerformed(ActionEvent e) {
int x = 0;
if (x == 0) {
label.setText("the new label");
System.out
.println("setting x to 0 and label to display a label");
x = 1;
System.out.println(x);
} else {
label.setText("newerer label");
System.out.println("i reached the else segment");
x = 0;
System.out.println(x);
}
}
}
public static void main(String args[]) {
events gui = new events();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.setTitle("Events Test");
gui.setSize(300, 100);
gui.setVisible(true);
}
}
Background: I am learning java and attempting to understand a concept. With this program I was attempting to create a small gui with a button that when clicked would assign a JLabel the String value of "the new label." I wanted to use that same button however to change the label to "newerer label" if clicked a second time and back again if clicked a third. I attempted to do this using an If/ Else statement with a variable x to hold essentially a state of 1 or 0. At the end of each portion of the If/Else i change the state of x to either 1 or 0 appropriately. When attempting to run the program in eclipse however, I have run into some kind of error. I assigned a system.out.println to each portion of the If/Else in an attempt to see how the program switches between the two states but it appears that my else statement is never reached.
Questions:
Is an If/Else statement appropriate to perform such a simple 2 state switch?
Is there a more appropriate way to do this? (i know about switch statements but opted for this as it was only a two state project).
What did I do wrong and why is my Else path never achieved when the state should be 1?
Thank you for your responses,
Pano
Your variable "x" must be declared as a class member.
public class event implements ActionListener{
private int x = 0;
public void actionPerformed(ActionEvent e){
if(x == 0){
label.setText("the new label");
System.out.println("setting x to 0 and label to display a label");
x = 1;
System.out.println(x);
}
else {
label.setText("newerer label");
System.out.println("i reached the else segment");
x = 0;
System.out.println(x);
}
}
}
You are initializing x every time the action listener gets called, so x is always 0. Move x somewhere else, possibly declare it as a class member.
Yes, I personally would use an if/else statement here, although if you are likely to add more states a switch statement may be appropriate, but I think given you have more than 1 line of code in the if/else blocks I would keep it as if/else as it has better readability in my experience.
I guess my answer to 1 covers this!
The reason your else block isn't being reached is that your x variable is only in scope (only exists) inside that method. As soon as you leave the method the value is no longer in scope so as far as your code in concerned it no longer exists. The code P Lalonde posted shows the correct way: having the variable as a member variable (object scope). Read more about member variable scope here: http://docs.oracle.com/javase/tutorial/java/javaOO/variables.html
If you are just looking for a switch of state you could actually do something like:
if( label.getText().equals("the new label") ) {
label.setText("newerer label");
} else {
label.setText("the new label");
}
Related
When I try to run this, I keep getting an empty frame that cannot be closed, and I have to terminate the program from eclipse. I am fairly certain that the problem is a result of the while loop (about 2/3 of the way down the code block), but I haven't been able to figure out a way to fix this
public Draw()
{
super( "Uno");
JMenuBar bar = new JMenuBar(); // create menu bar
JMenu gameMenu = new JMenu( "Play Game" );
JMenu quitMenu = new JMenu( "Quit" ); //Quit Program
bar.add( gameMenu ); // add Add menu to menu bar
bar.add( quitMenu ); // add quit button to menu bar
setJMenuBar( bar ); // set menu bar for this application
window = new JDesktopPane();
add(window);
gameMenu.addMouseListener(
new MouseListener()
{
public void mouseClicked(MouseEvent e)
{
Dimension size = window.getSize();
double height = size.getHeight();
double width = size.getWidth();
JInternalFrame frame = new JInternalFrame("Uno", true, true, true, true );
JFrame input = new JFrame();
input.setTitle(" ");
input.setSize(350, 155);
input.setLayout(new FlowLayout());
input.setLocationRelativeTo(null);
input.setVisible(true);
JLabel label1 = new JLabel("How many total players? (2-10)");
final JTextField text1 = new JTextField(3);
JLabel label2 = new JLabel("How many computer players? *");
final JTextField text2 = new JTextField(3);
JLabel label3 = new JLabel("* Computer players must be <= total number of players");
JButton confirm = new JButton("OK");
label1.setVisible(true);
label2.setVisible(true);
label3.setVisible(true);
text1.setVisible(true);
text2.setVisible(true);
confirm.setVisible(true);
input.add(label1);
input.add(text1);
input.add(label2);
input.add(text2);
input.add(label3);
input.add(confirm);
while(valid == false)
{
confirm.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
String players = text1.getText();
String computers = text2.getText();
int temp1 = Integer.parseInt(players);
System.out.println("Number of players = " + temp1);
int temp2 = Integer.parseInt(computers);
System.out.println("Number of computers = " + temp2);
if (temp1 >= 2 && temp1 <= 10)
if (temp2 <= temp1 && temp2 >= 0)
valid = true;
} //close actionPerformed
}); //close ActionListener
} //close while loop
} //close mouseClicked
} //close mouseListener
} //close Draw
Initially, I was having an issue where it kept infinitely drawing the frame on top of itself because the while loop kept returning false. That issue was solved by removing the components from the while loop, and placing them before it as they are above. Now when I run it, all I get is this: picture
The goal of this program is to make an Uno game, but the first step is to determine the number of players. This is the only way I know how to do this, and this is only the second program I have done with graphics, so I am by no means an expert at Java. I will appreciate any help I can get because I have been stuck for a few days now.
The problem is that you are not giving the event handlers any chance to do their job. Your while loop continually creates event handlers. However, the actionPeformed() method can never be called because the while loop has control of the CPU and the button will not respond to any clicks.
I suggest that you learn a bit more about event handling. You will need to redesign your code in order to get the behavior you wish. Most likely you need to remove the while loop entirely and just create an event handler which will execute code when the button is clicked.
For future reference:
In general, checking equality with a boolean value is unnecessary. The result of == is a bool, but the variable you are checking is already a bool. So use it directly: instead of while (valid == false), you can do while (!valid). If you read the ! as "not", this actually makes a lot of sense.
In this case, the point is moot, since you need to remove the while loop entirely. However, this might be useful information for you some time in the future.
I know this sounds very basic, but I never really learned how to do this.
I know about for loops where you can just use for example:
for(int i=0; i<=10; i++)
System.out.println(i);
But that just prints out numbers from 0 to 10 with a gap of 1...which isn't what I'm looking for.
I'm looking for some code where the program starts at a value and adds 1 (or another number) whenever the a button is clicked.
I already have the code for the button and everything, but I have an empty ActionListener as I don't know what to place inside it.
In the ActionListener actionPerformed method write the following code:
public void actionPerformed(ActionEvent event)
{
if(event.getSource() == button_name)
{
count_variable += 1;
}
}
Just add something like this.
int counter = 0;
JButton button = new JButton(" Click me ");
//Add action listener to button
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
//Execute when button is pressed
counter++;
}
});
This will make counter++ execute whenever the button is pressed. If you want another number, say 10, then just replace counter++ with counter+=10
**disclaimer**
Make sure that counter is accessible inside of ActionPerformed. You can do this by making it a field variable of an encapsulating class, making it a mutable object, and many other ways.
I am writing a Blackjack program using JFrame and trying to keep it as simple as possible. My JButton, jbHit works with a single click, however it overwrites the playersHand and playerSide slot with every click. I would like it to work with multiple clicks (3 clicks - since that is the max number of cards you can get after the first two are dealt) options It should count them so to speak so that the array index can record the card image. Here is my ActionListener code that I have so far. I am afraid I am stuck. Should I use some sort of for loop with an int i++?
//Hit Button ActionListener
jbHit.addActionListener( new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if ( playerValue < 21 ) {
//Draw a card
Card c = deck.drawCard();
playersHand.add(c);
playerSide[2].setIcon( new ImageIcon( c.getFilename() ) );
}
//If playerValue > 21, bust
else if ( playerValue > 21 ) {
//Toggle Buttons
jbDeal.setEnabled(true);
jbHit.setEnabled(false);
jbStand.setEnabled(false);
jbDoubleDown.setEnabled(false);
message = "You bust.";
}
}
});
You could create an array of "action commands" and every time you click the button, the action command changes to the next. If you reach the end, set the index back to zero. Perhaps something like this:
public static void main(String[] args)
{
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JButton button = new JButton("Action");
String[] commands = {"command1", "command2", "command3"};
button.setActionCommand(commands[0]);
button.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
JButton btn = (JButton)e.getSource();
String cmd = btn.getActionCommand();
System.out.println("Command: " + cmd);
if(cmd.equals("command1"))
{
btn.setActionCommand(commands[1]);
System.out.println("Command 1 was pressed");
}
else if(cmd.equals("command2"))
{
btn.setActionCommand(commands[2]);
System.out.println("Command 2 was pressed");
}
else if(cmd.equals("command3"))
{
btn.setActionCommand(commands[0]);
System.out.println("Command 3 was pressed");
}
else
System.out.println("Something went wrong!");
}
});
panel.add(button);
frame.add(panel);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
If you are using Java 7 or later, you can replace the if/else with a Switch statement.
I believe you're looking for a logical flag based on an integer, for example:
if(cardsDealt < 3) {
// DoThings();
} else {
return;
}
Which would require you to do
cardsDealt++;
at the bottom of your button click handle.
If this is not what you're asking, please re-explain the question.
It sounds like you might be a little confused about how jbHit will be called. Realize that it will be called one complete time every time the mouse is clicked. It's not like it inherently knows that it is on the second or third click. Add a class member like int clickCount; that you increment at the appropriate point inside of jbHit. Then you can alter your method's response depending on the value of clickCount.
my problem ist that my while loop just runs one time when I run it. Here is my code. I would be very thankful if someone would check it and maybe look for other faults (i'm new at programming java!)
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Program {
boolean exit;
JFrame frame;
JPanel panel;
JTextField title;
JButton start;
JButton stop;
long x;
public Program() {
frame = new JFrame("Überlast your PC");
panel = new JPanel();
title = new JTextField("Überlast your PC v1.0");
start = new JButton("Start");
stop = new JButton("Stop");
x = 1;
exit = false;
stop.addActionListener(new ActionListener () {
public void actionPerformed(ActionEvent e) {
exit = true;
}});
start.addActionListener(new ActionListener () {
public void actionPerformed(ActionEvent e) {
panel.remove(start);
panel.add(stop);
frame.repaint();
frame.revalidate();
start.setForeground(Color.red);
while(x <= 9223372036854775807L) {
System.out.println(x * x);
x++;
if (exit = true) {
break;
}
}
}});
frame.add(panel);
panel.add(title);
panel.add(start);
frame.setVisible(true);
frame.setSize(150,100);
title.setEditable(false);
start.setForeground(Color.green);
stop.setForeground(Color.red);
}
}
if(exit = true) {
break;
}
should be
if(exit == true) {
break;
}
Or even simpler, just use
if(exit){
break;
}
exit=true assigns true to exit, thus the if condition is true thus it breaks outta of the loop.
As #jlordo pointed, even after fixing the error its an infinite loop.
if(exit = true)
This is the first problem. The above if condition will always be true. You need to do comparison instead of assignment. In fact you should not do comparison for boolean variable. Just use: -
if (exit)
Secondly, you are not changing your exit anywhere in your while loop, so, it doesn't make sense for using it as a exit condition.
And you don't need to hard code the value of Long.MAX_VALUE. You already have that constant defined. Now, even if you get through that problem of if, you will face the problem of infinite loop. See below how: -
// Your below while loop is `infinite`
// every long value will satisfy this condition
while(x <= Long.MAX_VALUE) { // Don't hard code max long value
System.out.println(x * x);
x++;
// You are not changing `exit` anywhere, so this check is absurd.
if (exit) {
break;
}
}
What probably you want: -
Probably you want to run your loop infinitely, until your exit value if false. In that case, just use while (true). And change the value of exit somewhere in your loop.
In fact, if you are using exit as exit criteria, I would change your while loop to: -
while (exit) {
System.out.println(x * x);
if (someCondition) {
exit = false;
}
}
you are using
if(exit = true) {
instead of
if(exit == true) {
or even better
if (exit) {
But when you fix it, you will have an infinite loop, because all long values are smaller than 9223372036854775807, which is the the highest value long can have.
It is because of this line:
if(exit = true)
You are assigning true to exit here. Use == for comparing values:
if(exit == true)
And in the case of boolean values, you don't need to compare it to true at all. Write it like this:
if(exit)
if (exit = true) will set the value exit to true. You need to compare using ==
Here's the ActionListener portion of my code. Focus on the reset button.
public void actionPerformed( ActionEvent e) {
int i;
for (i = 0; i < 26; i++) {
if (e.getSource() == a[i]) {
consultWord(i);
}
}
if (e.getSource() == reset) {
Hangman gui = new Hangman();
System.out.print("test");
gui.go();
}
}
Obviously there is much more above it (as this is at the VERY end). Button array 1 (top if statement) works perfectly. Button 2 (bottom if statement) doesn't work at all. The test output text does not appear. Here is where I declared the variables. (They are available to all code).
JButton reset = new JButton("Reset");
private Button a[];
And if it means anything to you, here's the code for setting up the a[] buttons.
int i;
StringBuffer buffer;
a = new Button[26];
topPanel.setLayout( new GridLayout( 4,0, 10, 10) );
for (i = 0; i <26; i++) {
buffer = new StringBuffer();
buffer.append((char)(i+'a'));
a[i] = new Button(buffer.toString());
a[i].setSize(100,100);
a[i].addActionListener( this );
topPanel.add(a[i]);
}
Any ideas why my bottom button isn't doing squat? I'll paste my whole code if need be.
Maybe you simply forgot to add the ActionListener to your reset button? This is missing from your code above…
As a side note some suggestions to make your code cleaner:
The StringBuffer is not needed: Simply use String.valueOf((char)(i+'a'))
I would not use the same ActionListener for all buttons you have, as this clutters your actionPerformed method. Anonymous inner classes can be useful here.