i have a problem i can't solve.
I want this:
When i open the gui, i will show a random number and a button that says "change number".
Then, when the button is clicked, i want that the previous random number change into another random number and so on.
This is my code:
public class RandomDisplayPanel extends JPanel {
public RandomDisplayPanel() {
JPanel panel = new JPanel();
add(panel);
JPanel inside = new JPanel();
panel.setBackground(Color.yellow);
JButton sendButton = new JButton("Send");
Random generator = new Random();
int num;
num = generator.nextInt(100) +1;
JLabel numero = new JLabel("" + num);
inside.add(numero);
inside.add(sendButton);
panel.add(inside);
sendButton.addActionListener(new RandomDisplayPanel.RandomListener());
}
private class RandomListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
Random generator = new Random();
int num;
num = generator.nextInt(100) +1;
}
}
}
How can i do that? thank you in advance :)
You can pass the (JLabel) number to the listener as follow:
sendButton.addActionListener(new RandomDisplayPanel.RandomListener(number));
private class RandomListener implements ActionListener {
private JLabel target;
public RandomListener(JLabel target) {
this.target = target;
}
#Override
public void actionPerformed(ActionEvent e) {
Random generator = new Random();
int num;
num = generator.nextInt(100) +1;
this.target.setText(String.valueOf(num));
}
}
Hope this helps!
You need to effectively call numero.setText(num) inside of your ActionPreformed method. I would recommend maybe adding a checking statement similar to this..
if(e.getSource() == sendButton) {
numero.setText(num);
}
There is another problem I see, being that you might not be able to know the values of numero or sendButton. Offhand you could make them public variables in your main class, or you could pass them as parameters.
Add numero.setText(num + ""); inside your listener.
EDIT : Declare the JLabel numero as a class variable and it will work.
To get a random number you can use Math.random(); and multiply it with 10 and add 1 for example. (Then it is between 1 and 10)
To set the button text then use
Button myButton=(Button)this.findViewById(R.id.yourButtonsID);
myButton.setText(yourRandomNumber);
Related
I'd like to change value of my variable "name" when I select right button and click "ok" on my JRadio Frame.
For example when i select r1 and hit "ok" I'd like to have name=="Fast" in the entire package.
package Snake;
public class Radio extends JFrame {
private int delay = 100;
private String name;
JTextField t1;
JButton b;
JRadioButton r1, r2;
JLabel l;
public void selectSpeed() {
b = new JButton("Ok");
r1 = new JRadioButton("Fast");
r2 = new JRadioButton("Slow");
l = new JLabel("Speed: ");
ButtonGroup bg = new ButtonGroup();
bg.add(r1);
bg.add(r2);
add(b);
add(r1);
add(r2);
add(l);
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (r1.isSelected()) {
name = "Fast";
} else {
name = "Slow";
}
l.setText("Speed: " + name); // name=="Fast" when r1 is selected
} // name=="Slow" when r2 is selected
});
if (name == "Fast") { // and now name is empty...
delay = 50;
}
if (name == "Slow") {
delay = 500;
}
setLayout(new FlowLayout());
setSize(400, 400);
setVisible(true);
}
public int setSpeed() {
selectSpeed();
return delay;
}
}
If you want to change the delay on button click, You need to write the logic in the ActionListener itself because the code you have written to change the delay will run only once and that too at the start of the execution of your program and at that time, name will be empty.
Then when ever you click the button, It will only execute the ActionListener So delay will not be changed at any time. And other mistake you are making is that you are comparing Strings in wrong way. For more information take a look at it How do I compare Strings in Java?
To change delay dynamically on button click, you need to change it in the ActionListener.
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (r1.isSelected()) {
name = "Fast";
delay = 50;
} else {
name = "Slow";
delay = 500;
}
l.setText("Speed: " + name); // name=="Fast" when r1 is selected
} // name=="Slow" when r2 is selected
});
You need to do it in your JRadioButton listener. For example, like here, at first you change the variable "name" and later in the current listener you check conditions, but you need remember that to compare the strings you need to use "equals":
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if (r1.isSelected()) {
name = "Fast";
} else {
name = "Slow";
}
l.setText("Speed: " + name); // name=="Fast" when r1 is selected
if (name.equals("Fast")) { // and now name is empty...
delay = 50;
}
if (name.equals("Slow")) {
delay = 500;
}
} // name=="Slow" when r2 is selected
});
Well I see my mistake now, Thank you.
But it still does not work the way I like. I'd like to change the "delay" value every time I select right button on JRadio and hit "ok" and with this changed value I'd like to go to the other class.
There is the code of a class where I need value of "delay":
package Snake;
public class Gameplay extends Paint implements KeyListener, ActionListener {
private Timer timer;
private int q = 0;
Radio radio = new Radio();
public Gameplay() {
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
timer = new Timer(radio.selectSpeed(), this); //here i need flexible "delay" value
timer.start();
}
I'm stuck on an assignment where I will need to have a text field update each time a user clicks on a button. In total there are 5 buttons, each with their own text field that should be updated when they are clicked on. The issue that I am having is that the counter does not seem to update the text field when clicked multiple times. So the first time I click the button, the text field will say "1", but it stays like that after multiple clicks.
private class ButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
int snickers = 0;
int butterfinger = 0;
int lays = 0;
int coke = 0;
int dietCoke = 0;
int totalItems = 0;
double totalPrice = (totalItems * PRICE);
if (e.getSource() == snickersButton)
{
totalItems++;
snickers++;
quantityTextS.setText(String.valueOf(snickers)); //Display snickers value in text field
itemsSelectedText.setText(String.valueOf(totalItems)); //Display total items value in text field
if(snickers > MAX)
{
JOptionPane.showMessageDialog(null, "The maximum number of each item that can be selected is 3.",
"Invalid Order Quantity", JOptionPane.ERROR_MESSAGE);
quantityTextS.setText("3"); //Set text to 3
}
}
All your "counters" are local variables, so they will be re-initalised each time actionPerformed is called
You should make the counters instance fields instead...
private class ButtonListener implements ActionListener
{
private int snickers = 0;
private int butterfinger = 0;
private int lays = 0;
private int coke = 0;
private int dietCoke = 0;
private int totalItems = 0;
public void actionPerformed(ActionEvent e)
{
double totalPrice = (totalItems * PRICE);
if (e.getSource() == snickersButton)
{
This assumes, though, you are using the same instance of ButtonListener for ALL your buttons
Take a look at Understanding Class Members for more details
Add action listener to your button
buttonName.addActionListener(this);
also, write the variable that holds the value to be displayed as Global variable. Don't declare in inside the function
try this code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class DrawOval implements ActionListener
{
JButton genderBtn = new JButton("gender");
JFrame frm = new JFrame();
JTextField displayTF = new JTextField(15);
int i = 0;
public DrawOval(){
displayTF.setText(""+i);
frm.setTitle("Grocery");
frm.setVisible(true);
frm.setSize(200,100);
frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frm.setResizable(true);
frm.setLayout(new FlowLayout());
frm.add(displayTF);
frm.add(genderBtn);
genderBtn.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent ae) {
if(ae.getSource() == genderBtn){
i++;
displayTF.setText(""+i);
}
}
public static void main(String args[]){
new DrawOval();
}
}
This is because you declare snickers and totalItems as local fields of actionPerformed method so they will be created and initilized to 0 every time you click. Consider one of the following approach:
Make these fields static fields of the class
Get the snickers and totalItems from the current buttons, parse them to int values and compute based on those values
I have a Java program that contains multiple classes, all of which extend JPanel (except for the class containing the main method). I am trying to pass int variables from one class to another and, using some previously asked questions, came up with this:
Class RollPanel
public int getbrainCount()
{
return brainCount;
}
Class BrainsPanel (where I am trying to send the variable)
void setbrainCount()
{
RollPanel rollpanel = new RollPanel();
brainCount = rollpanel.getbrainCount();
}
This doesn't give any errors, but when I add brainCount to a label to see its value, it is always 0.
brainCount is declared at the class level of RollPanel, then given a value with this code which is in a button listener:
value1 = generator.nextInt(3) + 1;
value2 = generator.nextInt(3) + 1;
value3 = generator.nextInt(3) + 1;
//rollTotal++;
//Counts how many brains were rolled.
if (value1 == 1)
brainCount++;
if (value2 == 1)
brainCount++;
if (value3 == 1)
brainCount++;
I understand that just declaring a variable will automatically mean its value will be zero at first(which I assume is why it is displayed as zero), but how can I pass its updated value after the above code to brainsPanel so I can add its value to a label in brainsPanel? Would getBrainCount() come after the button listener? I feel like I'm overlooking something simple here...
EDIT:
I think the problem isn't with the setter as it is the getter. Since in RollPanel(where the getter is) I declare brainCount as an int its initial value is 0, so when the getter gets the value it always remains at 0 even though brainCount should be altered in the button listener. Here is RollPanel in its entirety. How can I make the getter get the updated value of brainCount instead of its initial 0?
package zombiedice;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class RollPanel extends JPanel
{
JLabel die1Label, die2Label, die3Label, testLabel;
JButton rollButton, sortButton;
JPanel dicePanel, buttonPanel;
ImageIcon die1, die2, die3;
int rollTotal, value1, value2, value3;
int brainCount, blastCount;
Random generator = new Random();
public RollPanel()
{
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
setBackground(Color.black);
dicePanel = new JPanel();
dicePanel.setBackground(Color.black);
//Creates blank ImageIcons to be used later to display dice.
die1 = new ImageIcon();
die2 = new ImageIcon();
die3 = new ImageIcon();
//A panel just to hold the buttons.
buttonPanel = new JPanel();
//Creates and links roll button to RollListener.
rollButton = new JButton("Roll");
rollButton.addActionListener(new RollListener());
buttonPanel.add(rollButton);
//After a roll, this button will need to be clicked so brain and blast
//die can be sorted into their proper catergories.
sortButton = new JButton("Sort");
sortButton.addActionListener(new SortListener());
//Creates labels out of the dice images.
die1Label = new JLabel(die1);
die2Label = new JLabel(die2);
die3Label = new JLabel(die3);
//Adds image labels to the panel that holds the dice.
dicePanel.add(die1Label);
dicePanel.add(die2Label);
dicePanel.add(die3Label);
add(dicePanel);
add(buttonPanel);
} //Closes constructor
//Roll button listener.
private class RollListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
rollButton.setEnabled(false);
repaint();
buttonPanel.add(sortButton);
repaint();
sortButton.setEnabled(true);
repaint();
value1 = generator.nextInt(3) + 1;
value2 = generator.nextInt(3) + 1;
value3 = generator.nextInt(3) + 1;
//rollTotal++;
//Counts how many brains were rolled.
if (value1 == 1)
brainCount++;
if (value2 == 1)
brainCount++;
if (value3 == 1)
brainCount++;
//Updates the dice
die1Label.setIcon(new ImageIcon(value1 + ".png"));
die2Label.setIcon(new ImageIcon(value2 + ".png"));
die3Label.setIcon(new ImageIcon(value3 + ".png"));
} //Closes actionPerformed
} //Closes the listener for the roll button
//Sort button listener.
private class SortListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
sortButton.setEnabled(false);
repaint();
rollButton.setEnabled(true);
repaint();
} //Closes actionPerformed.
}//Closes sort button listener.
public int getBrainCount()
{
return brainCount;
}
} //Closes class
BrainsPanel
package zombiedice;
import javax.swing.*;
import java.awt.*;
public class BrainsPanel extends JPanel
{
ImageIcon icon1 = new ImageIcon();
ImageIcon icon2 = new ImageIcon();
JLabel brainTotal, label1, label2;
JPanel brainPanel;
int brainCount;
void setbrainCount(int count)
{
// RollPanel rollpanel = new RollPanel();
brainCount = count;
//brainCount = count;
}
public BrainsPanel()
{
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
setBackground(Color.black);
icon1 = new ImageIcon("1.png");
icon2 = new ImageIcon("1.png");
label1 = new JLabel(icon1);
label2 = new JLabel(icon2);
brainTotal = new JLabel ("Brains eaten: " + brainCount);
add(label1);
add(label2);
add(brainTotal);
} //Closes constructor
} //Closes class
In this peace of code:
void setbrainCount() {
RollPanel rollpanel = new RollPanel();
brainCount = rollpanel.getbrainCount();
}
You always create a new RollPanel object before getting brainCount. Of course it is 0 if it is declared as field in RollPanel. The variable was newly initialized with the object creation just the line before.
You should make sure you always use the same RollPanel object, e.g. keep it as field in BrainsPanel. It's hard to say for sure with the given code.
I believe you should try the following:
void setbrainCount(RollPanel rollPanel)
{
brainCount = rollpanel.getbrainCount();
}
This way you won't try to use the newly initialized value which is always 0.
Althozuh technically, it would make more sense to just send the count over and set that
void setbrainCount(int brainCount)
{
this.brainCount = brainCount;
}
I just need to get it to alternate between "X" and "O" for the turns but it's only giving me X's.
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class tictactoe {
public static final int FRAME_WIDTH = 700;
public static final int FRAME_HEIGHT = 200;
public static void main(String[] args)
{
int slots = 9;
final JButton[] gameButton = new JButton[9];
JPanel ticTacToeBoard = new JPanel();
ticTacToeBoard.setLayout(new GridLayout(3, 3));
JButton clearButtons = new JButton("New Game");
for (int i = 0; i < slots; i++)
{
gameButton[i] = new JButton();
ticTacToeBoard.add(gameButton[i]);
final int countTurns = i;
gameButton[i].addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Object clicked = e.getSource();
int turns = 1;
for (int p = 0; p < 9; p++)
{
if(clicked == gameButton[countTurns] && turns < 10)
{
if (!(turns % 2 == 0))
{
((JButton)e.getSource()).setText("X");
turns++;
}
else
{
((JButton)e.getSource()).setText("O");
turns++;
}
}
}
}
});
final int integerHack = i;
clearButtons.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
gameButton[integerHack].setText("");
}
});
}
JButton exit = new JButton("Exit");
exit.setActionCommand("EXIT");
exit.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
String cmd = e.getActionCommand();
if (cmd == "EXIT")
{
System.exit(FRAME_WIDTH);
}
}
});
JPanel rightPanel = new JPanel();
JLabel wonLabel = new JLabel();
rightPanel.setLayout(new GridLayout(1, 3));
rightPanel.add(wonLabel);
rightPanel.add(clearButtons);
rightPanel.add(exit);
JFrame mainFrame = new JFrame();
mainFrame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
mainFrame.setVisible(true);
mainFrame.setLayout(new GridLayout(1,2));
mainFrame.add(ticTacToeBoard);
mainFrame.add(rightPanel);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Look at your actionPerformed method. Every time a click happens, you set turns to 1. As a result, !(turns % 2 == 0) will always evaluate true, and you'll always draw an X.
Just by quickly looking at your code, I would guess it is because your turn variable is local in all the ActionListener objects. Therefore, the turn variable is always 1 and you always run into the first if case. So the turn variable is always recreated on the stack as soon as you get a callback in the actionPerformed method. For a quick fix and test, try to put the turn variable in the tictactoe class and see if that helps.
The trouble is with the turns variable in your actionPerformed. If you want to keep a track of it you should move that out from your method.
Firstly, as the other people have also said, you want "turns" to be initialized outside all your loops.
Secondly, I would like to point out a typo:
if(clicked == gameButton[countTurns] && turns < 10)
should be
if(clicked == gameButton[p] && turns < 10)
...unless you really want to change each button's text from X to O nine times each time a button is clicked.
But even fixing that typo is pointless. Why loop through to find a specific button when it doesn't matter which specific button it is? All the buttons have the same action handler, anyway, just nine separate copies of it, because you are creating nine identical copies each time around.
Instead, because all the buttons do the same thing, you should have one action handler for all the buttons. If you're not sure how that's done, you create it outside your button making loop and assign it to a variable, and then you put in that variable when you assign each button's action handler, e.g.
gameButton[i].addActionListener(myActionListener);
Okay so I am making a 2d array of JToggleButtons. I got the action listener up and going, but I have no way to tell which button is which.
If I click one, all it returns is something like
javax.swing.JToggleButton[,59,58,19x14,alignmentX=0.0,alignmentY=0.5,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource#53343ed0,flags=296,maximumSize=,minimumSize=,preferredSize=,defaultIcon=,disabledIcon=,disabledSelectedIcon=,margin=javax.swing.plaf.InsetsUIResource[top=2,left=14,bottom=2,right=14],paintBorder=true,paintFocus=true,pressedIcon=,rolloverEnabled=false,rolloverIcon=,rolloverSelectedIcon=,selectedIcon=,text=]
Is there anyway to stick some sort of item or number in the button object to associate each button?
And then when the button is clicked I can retrieve that item or number that was given to it?
Here is my button generator code. (How could I make "int l" associate (and count) to each button made, when it is called, it will return that number, or something along those lines.
JToggleButton buttons[][] = new JToggleButton[row][col];
int l = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
buttons[i][j] = new JToggleButton("");
buttons[i][j].setSize(15,15);
buttons[i][j].addActionListener(new e());
panel.add(buttons[i][j]);
l++;
}
}
ActionListner
public class e implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
System.out.println(source);
}
}
variable "source" is what I use to get my data, so how can int l, be returned through "source" (as its unique value for the unique button clicked) as a button is clicked?
Thanks,
-Austin
very simple way is add ClientProperty to the JComponent, add to your definition into loop e.g.
buttons[i][j].putClientProperty("column", i);
buttons[i][j].putClientProperty("row", j);
buttons[i][j].addActionListener(new MyActionListener());
rename e to the MyActionListener and change its contents
public class MyActionListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JToggleButton btn = (JToggleButton) e.getSource();
System.out.println("clicked column " + btn.getClientProperty("column")
+ ", row " + btn.getClientProperty("row"));
}
EDIT:
for MinerCraft clone isn't required to implements ony of Listeners, there is only about Icon, find out that in this code (don't implement any of Listeners anf remove used ItemListener)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ButtonsIcon extends JFrame {
private static final long serialVersionUID = 1L;
private Icon errorIcon = UIManager.getIcon("OptionPane.errorIcon");
private Icon infoIcon = UIManager.getIcon("OptionPane.informationIcon");
private Icon warnIcon = UIManager.getIcon("OptionPane.warningIcon");
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ButtonsIcon t = new ButtonsIcon();
}
});
}
public ButtonsIcon() {
setLayout(new GridLayout(2, 2, 4, 4));
JButton button = new JButton();
button.setBorderPainted(false);
button.setBorder(null);
button.setFocusable(false);
button.setMargin(new Insets(0, 0, 0, 0));
button.setContentAreaFilled(false);
button.setIcon((errorIcon));
button.setRolloverIcon((infoIcon));
button.setPressedIcon(warnIcon);
button.setDisabledIcon(warnIcon);
add(button);
JButton button1 = new JButton();
button1.setBorderPainted(false);
button1.setBorder(null);
button1.setFocusable(false);
button1.setMargin(new Insets(0, 0, 0, 0));
button1.setContentAreaFilled(false);
button1.setIcon((errorIcon));
button1.setRolloverIcon((infoIcon));
button1.setPressedIcon(warnIcon);
button1.setDisabledIcon(warnIcon);
add(button1);
button1.setEnabled(false);
final JToggleButton toggleButton = new JToggleButton();
toggleButton.setIcon((errorIcon));
toggleButton.setRolloverIcon((infoIcon));
toggleButton.setPressedIcon(warnIcon);
toggleButton.setDisabledIcon(warnIcon);
toggleButton.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if (toggleButton.isSelected()) {
} else {
}
}
});
add(toggleButton);
final JToggleButton toggleButton1 = new JToggleButton();
toggleButton1.setIcon((errorIcon));
toggleButton1.setRolloverIcon((infoIcon));
toggleButton1.setPressedIcon(warnIcon);
toggleButton1.setDisabledIcon(warnIcon);
toggleButton1.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
if (toggleButton1.isSelected()) {
} else {
}
}
});
add(toggleButton1);
toggleButton1.setEnabled(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
}
Just add the row and column data to each listener. You could add an explicit constructor, but I suggest adding a little method (which may have more added to it later).
buttons[i][j].addActionListener(e(i, j));
...
private ActionListener e(final int i, final int j) {
return new ActionListener() {
// i and j available here
...
(In JDK8 you should be able to use a lambda to reduce the syntax clutter.)
And then renaming it with a better name.
I made a minesweeper game and ran into a similar problem. One of the only ways you can do it, is to get the absolute location of the clicked button, then divide that by the x and y between buttons, so for me it was
if ((e.getComponent().getX() != (randx) * 25 && e.getComponent().getY() != (randy) * 25) &&bomb[randx][randy] == false) {
This code was to check if the area had bombs. So I had 25 x and y difference between location of bombs. That will just give you a general idea on how to do this.
I believe: (x - x spacing on left side) / buffer - 1 would work.
Instead of 'e.getSource()' you can always call 'e.getActionCommand()'. For each button you can specify this by:
JButton button = new JButton("Specify your parameters here"); /*you get these from getActionCommand*/
button.setText("title here"); /*as far as I remember*/