Coin flip simulation: Counting heads / tails - java

I am trying to simulate a coin flipper using Java and window builder. I have a button called "Flip" when that button is pressed the coin image changes depending on which number the random generator I created generates.
I now am trying to figure out a way to display the number of times the coin lands a heads or a tails in their respective JTextFields. I was thinking of using a counter, but I am struggling with how to update that into the text field, so far it only puts in that I have flipped each coin once.
I am very new to programming so any advice or guidance is much appreciated.
// this button flips the coin
btnFlip = new JButton("Flip");
btnFlip.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
int headCounter = 0;
int tails = 0;
// this implements the random flip of the coin when the checkbox Run Multiple
// flips is unchecked
if (chckbxNewCheckBox.isSelected() == false) {
Random r = new Random();
int flipper = r.nextInt(2);
if (flipper == 1) {
lblImages.setIcon(new ImageIcon(FinalPrep.class.getResource("/finalPrep/heads.png")));
textFieldHeads.setText(String.valueOf(headCounter));
} else {
lblImages.setIcon(new ImageIcon(FinalPrep.class.getResource("/finalPrep/tails.png")));
textFieldTails.setText(String.valueOf(tails));
}
}
}
});
btnFlip.setFont(new Font("Tahoma", Font.PLAIN, 15));
panel_1.add(btnFlip);

You have to create something like 2 layers. One that contains the window itself along with the title (think of it like a receptor) then you have to create another "layer" that contains the buttons and the textfields. Something like this:
import javax.swing.*;
public class MyFrame extends JFrame {
private JPanel panel;
private JTextField textField;
private JButton button;
public MyFrame(){
panel = new JPanel(); //Step 1. Creation of a receptor
tfCount = new JTextField(10); //Step 2.
button = new JButton("Press Me"); //Creation of buttons & textfields.
panel.add(tfCount); //Step 3.
panel.add(button); //Add those graphics to the receptor
this.setContentPane(panel); //Step 4 Adjust the receptor to the object
this.setVisible(true);
this.setSize(400, 400);
this.setTitle("My 1st GUI!");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
(Sorry for the random example but you did not post any sample of code so I am trying to explain as best as I can)
Then you should put a "flag" depending of the number that was generated for example:
boolean flag = true; //Flag
int counter = 0; //The counter for the heads
int x; //The number you received from the generator
int counter_b; //The counter for the tails
if(x%2 == 0){ //If the number is even
flag = false; // You set down the flag
counter++; //And counter raises its value
}
else
counter_b++;
tfCount.setEditable(true); //This makes your textfield editable
tfCount.setText(String.valueOf(counter)); //And this prints the counter's value
Keep in mind that the counters for the tails and the heads are just examples for you to understand how to use "flags". I hope that I was able to help you because I am new too!! :)

Related

How to setText of 2d array of JTextFIelds using actionlistener?

My assignment is to create 2 JPanels, one for a 2d array, 6 rows of 5 empty JTextFields and another for JButtons that should somewhat resemble an on-screen keyboard. I created the JPanels with the empty JTextFields and JButtons, now I need a way so that when I press a JButton with a letter from the alphabet it will assign that letter to the first available JTextField on the first available row and move one column at a time until the whole row is filled with letters (trying to add letters to a full row should do nothing). I also need to create a backspace button which I have that will remove the last letter (pressing backspace on an empty row should do nothing).
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class Wordle extends JFrame implements ActionListener
{
private JPanel p1;
private JPanel p2;
private JTextField [][] g;
public Wordle()
{
setSize(500,300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p1 = new JPanel();
p1.setLayout(new GridLayout(6, 5));
g=new JTextField [5][6];
for(int r=0; r<g.length; r++)
{
for(int c=0; c<g[r].length; c++)
{
g[r][c]= new JTextField();
getContentPane().add(g[r][c]);
p1.add(g[r][c]);
}
}
p2 = new JPanel();
p2.setLayout(new GridLayout(4, 7));
JButton a= new JButton("A");
a.addActionListener(this);
p2.add(a);
JButton b= new JButton("B");
b.addActionListener(this);
p2.add(b);
JButton c= new JButton("C");
c.addActionListener(this);
p2.add(c);
JButton d= new JButton("D");
d.addActionListener(this);
p2.add(d);
JButton e= new JButton("E");
e.addActionListener(this);
p2.add(e);
JButton f= new JButton("F");
f.addActionListener(this);
p2.add(f);
JButton g= new JButton("G");
g.addActionListener(this);
p2.add(g);
JButton h= new JButton("H");
h.addActionListener(this);
p2.add(h);
JButton i= new JButton("I");
i.addActionListener(this);
p2.add(i);
JButton j= new JButton("J");
j.addActionListener(this);
p2.add(j);
JButton k= new JButton("K");
k.addActionListener(this);
p2.add(k);
JButton l= new JButton("L");
l.addActionListener(this);
p2.add(l);
JButton m= new JButton("M");
m.addActionListener(this);
p2.add(m);
JButton n= new JButton("N");
n.addActionListener(this);
p2.add(n);
JButton o= new JButton("O");
o.addActionListener(this);
p2.add(o);
JButton p= new JButton("P");
p.addActionListener(this);
p2.add(p);
JButton q= new JButton("Q");
q.addActionListener(this);
p2.add(q);
JButton r= new JButton("R");
r.addActionListener(this);
p2.add(r);
JButton s= new JButton("S");
s.addActionListener(this);
p2.add(s);
JButton t= new JButton("T");
t.addActionListener(this);
p2.add(t);
JButton u= new JButton("U");
u.addActionListener(this);
p2.add(u);
JButton v= new JButton("V");
v.addActionListener(this);
p2.add(v);
JButton w= new JButton("W");
w.addActionListener(this);
p2.add(w);
JButton x= new JButton("X");
x.addActionListener(this);
p2.add(x);
JButton y= new JButton("Y");
y.addActionListener(this);
p2.add(y);
JButton z= new JButton("Z");
z.addActionListener(this);
p2.add(z);
JButton BackSpace= new JButton("<-");
BackSpace.addActionListener(this);
p2.add(BackSpace);
JButton Enter= new JButton("[");
Enter.addActionListener(this);
p2.add(Enter);
this.getContentPane().add(p1,BorderLayout.NORTH);
this.getContentPane().add(p2,BorderLayout.SOUTH);
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) //need help with
{
if(e.getSource().equals("A"))
{
for(int r=0; r<g.length; r++)
{
for(int c=0; c<g[r].length; c++)
{
g[r][c].setText("A");
}
}
}
}
public static void main(String[] args)
{
new Wordle();
}
}
This is my code and my main issue is setting the text in the 2d array of JTextFields using actionlistener, I don't mind doing each if loop for each letter individually as long as it makes sense and works the way I intended it to, btw if you haven't already noticed this is the game "Wordle" I am trying to make, I'm still a newbie programmer and all of this is new to me so some kind of intuitive explanation would be much appreciated.
This line if(e.getSource().equals("A")) is your first issue. It simply will not work because e.getSource() returns an object that will never equal "A".
Instead, you need to first cast the source to the correct object type like so:
public void actionPerformed(ActionEvent e) //need help with
{
JButton clicked = (JButton)e.getSource();
Now we can now get the text from the button using use getText() like this (Although there is a smarter solution we can use down below):
public void actionPerformed(ActionEvent e) //need help with
{
JButton clicked = (JButton)e.getSource();
if(clicked.getText().equals("A")) {
...
The next issue you face is how you store the data, you need to track the current cell using a class variable, rather than just filling up the whole array:
private int row = 0;
private int column = 0;
Then all together the changes might look a bit like this:
//Class variables
private int row = 0;
private int column = 0;
public void actionPerformed(ActionEvent e) //need help with
{
//Cast the event source to a button
JButton clicked = (JButton)e.getSource();
//Handle backspace
if(clicked.getText().equals("<-"))
{
//Decrease the tracking number
column--;
//Make sure that only valid cells are back spaced
if(column < 0)
{
column = 0;
}
//Set the cell to be blank
g[row][column].setText("");
}
//Handle enter
else if(clicked.getText().equals("["))
{
//Add your behaviour here
....
//Finally move to the next row
row++;
}
//Handle the rest of the letter buttons here
else
{
//We don't need `for` loops, we can just directly add the letter from
//the clicked button to the correct place in the array like so
g[row][column].setText(clicked.getText);
//Increment the tracking numbers
column++;
//Move to the next row when the column value is over 5:
if(column > 4)
{
//Move to the next row
row++;
//Reset the column number to 0
column = 0;
}
}
}

Why will this hailstone number producer not work?

I am trying to make a JButton on a JPanel that, when clicked, produces the hailstone number (if the number is even divide by two; if the number is odd, multiply by 3 and then add one). However, when I click my JButton, the program freezes and no number is outputted. Why is this happening?
Here is my code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Panel03 extends JPanel {
private JLabel label;
private JButton button;
private JTextField box;
public Panel03()
{
box = new JTextField("0", 10);
box.setForeground(Color.black);
box.setHorizontalAlignment(SwingConstants.RIGHT);
add(box);
label = new JLabel();
label.setFont(new Font("Serif", Font.BOLD, 20));
label.setForeground(Color.blue);
add(label);
button = new JButton("Next");
button.addActionListener(new Listener());
add(button);
}
private class Listener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
String s = box.getText();
int a = Integer.parseInt(s);
int b = a;
do {
if(a%2 == 0){b/=2.0;}
else{a=((3*b)+1);}
label.setText(Integer.toString(b));
}
while(b!= 4||b!= 2||b!= 1);
}
}
}
Whenever a program freezes, a infinite loop is a prime suspect. In this case, adding this line to the loop
System.out.printf("* a=%d b=%d\n",a,b);
shows that a=0 and b=0 forever. Since a is zero, a%2=0, and b/=2 is still zero, so the variables never change. Starting with a=1 still gets stuck at a=4, b=0. In fact for any number I entered, b goes to zero and the loop gets stuck. I am not sure what you are trying to do here, but I suspect your loop exit logic should be and instead of or, and needs to catch the b=0 possibility:
while (b!=4 && b!=2 && b!=1 && b!=0);

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.

JLabel changing on it's own

I've been working on what should be a relatively simple game, Mormon Sim. The goal is to hold a successful conversation while going door to door. It's pretty simple, on the click of a button, it changes a JLabel's text according to the button and method called. For example, using the Knock button will activate the method knockResponse, which will calculate if someone will come to the door or not. Based on the result of the calculation, someone will answer the door or you will be turned away. The problem is, after a few clicks, usually once the player gets past the knock check, the JLabel begins to revert itself back to other text, and back and forth between a few different things, sometimes completely disregarding the swing timers on them. I really have no idea what is going on here, and I can't really find a reason that this would happen. A whole week of thorough googling has yielded no similar problems or solutions. TL;DR Java has become self aware
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.Timer;
//To do: ASCII art in JLabels
public class mainMenu implements ActionListener{
static JButton start = new JButton("Start!"), knock = new JButton("Knock"), talk = new JButton("Talk"), stats = new JButton("Stats");
static int level = 1, stamina = 100, knocking = 1, speech = 1, points = 0;
static JFrame frame = new JFrame("Mormon Sim");
static mainMenu game = new mainMenu();
static JLabel text = new JLabel(), knockSkill, speechSkill, staminaBar;
static JPanel DoorMenu = new JPanel();
JTextField name = new JTextField("Enter your name here", 25);
static String playerName;
public JPanel createStartMenu(){//JPanel for the start menu. Replaced on start click
JPanel startMenu = new JPanel();
JLabel instructions = new JLabel("<html>Welcome to Mormon Adventure, the first text-based mormon sim. Your goal is to <br>hold as many successful door to door<br>conversations as possible. Every successful conversation earns you a<br>skill point and a level. Level 15 is a win!<br>A conversation requires stamina as it goes on, find Orange Crush to replenish your stamina<html>");
startMenu.setLayout(null);
startMenu.setLocation(0, 0);
startMenu.setSize(500, 500);
start.setLocation(200, 300);
start.setSize(100, 50);
start.addActionListener(this);
startMenu.add(start);
instructions.setLocation(100, 100);
instructions.setSize(300, 200);
startMenu.add(instructions);
name.setSize(150, 25);
name.setLocation(100, 50);
name.addActionListener(this);
startMenu.add(name);
startMenu.setOpaque(true);
return startMenu;
}
public JPanel createDoorMenu(){//used for knocking, speaking, and going to the stat page. The problem is here
talk.setEnabled(false);
String knockText = "<html>You walk up the driveway of the next house on your<br>list. As you approach the door, you adjust your<br>tie, and smooth your hair. Your mouth is dry, and<br>you could really go for a bottle of orange crush.<br>You decide you should get one after this house.<br>Time to knock, someone is clearly home.<html>";
DoorMenu.setLayout(null);
DoorMenu.setLocation(0, 0);
DoorMenu.setSize(500, 500);
text = new JLabel(knockText);
text.setLocation(100, 150);
text.setSize(300, 200);
DoorMenu.add(text);
knock.setLocation(100, 400);
knock.setSize(100, 50);
knock.addActionListener(this);
DoorMenu.add(knock);
talk.setLocation(200, 400);
talk.setSize(100, 50);
talk.addActionListener(this);
DoorMenu.add(talk);
stats.setLocation(300, 400);
stats.setSize(100, 50);
stats.addActionListener(this);
DoorMenu.add(stats);
knockSkill = new JLabel("Knocking: " +knocking+ " Speech: " +speech+ " Level: " +level+ " Skill Points: " +points);
knockSkill.setLocation(100, 25);
knockSkill.setSize(500, 50);
DoorMenu.add(knockSkill);
DoorMenu.setOpaque(true);
return DoorMenu;
}
public JPanel createStatMenu(){//still doesn't do anything
JPanel statMenu = new JPanel();
return statMenu;
}
public static void knockResponse(){//generates a response from a knock based on knock level (1 <= x <= 10). Random number (1 <= y <= 10) is generated, level determines how many are successful
//max knock level will shatter the door. 50/50 chance of conversation or police. max speech + police will talk them into letting you go
knock.setEnabled(false);
Random rand = new Random();
int n = rand.nextInt(10) + 1;
if(n > knocking){//knock check loss
text.setText("<html>All you hear is someone yelling to go away...<br>Oh well. You chipper up and go to<br>the next house on your list. That orange Crush<br>will have to wait!<html>");
ActionListener taskPerformer = new ActionListener(){//delay the label reset
public void actionPerformed(ActionEvent evt){
text.setText("<html>You walk up the driveway of the next house on your<br>list. As you approach the door, you adjust your<br>tie, and smooth your hair. Your mouth is dry, and<br>you could really go for a bottle of orange crush.<br>You decide you should get one after this house.<br>Time to knock, someone is clearly home.<html>");
knock.setEnabled(true);
}
};
new Timer(1000, taskPerformer).start();
}
if(n <= knocking && knocking != 10){//successful knock check
knock.setEnabled(false);
stats.setEnabled(false);
text.setText("<html>Someone's coming to the door!<br>You straighten your hair and adjust your tie.<html>");
ActionListener taskPerformer = new ActionListener(){//delay the label reset
public void actionPerformed(ActionEvent evt){
text.setText("<html>The door opens, and you introduce yourself;<br>\"Hi! my name is " +playerName+ ". Have you accepted my homeboy JC as your lord and savior?\"<html>");//I couldn't really think of anything to make him say other than that
talk.setEnabled(true);
}
};
new Timer(1000, taskPerformer).start();
}
if(knocking == 10){//door breaks
text.setText("<html>You managed to shatter the door thanks to<br>your orange crush powered knocking skeelz.<html>");
n = rand.nextInt(1) + 1;
if(n == 0){//response check. Both are empty for now
text.setText("0");
}else if(n == 1){
text.setText("1");
}
}
}
public static void successCalc(){//calculate the success in talking to someone by
talk.setEnabled(false);
Random rand = new Random();
int n = rand.nextInt(10) + 1;
if(n <= speech && speech != 10){
level++;
points++;
text.setText("<html>After some time, your conversation is over.<br>That went well. Better than you thought.<br>As you leave, you feel a rumbling in your gut.<br>It soon becomes painful. You fall to<br>the ground, and a gleaming light comes from<br>your stomach, as a skill point bursts out.<br>You hear a faint \"dunananaaa...\"<html>");
talk.setEnabled(false);
knockSkill.setText("Knocking: " +knocking+ " Speech: " +speech+ " Level: " +level+ " Skill Points: " +points);
}else if(n > speech){
talk.setEnabled(false);
text.setText("<html>After a moment of you speaking, all they do<br>is start blaring death metal.<br>You decide it's time to leave!<html>");
}else if(speech == 10){
text.setText("<html>Your golden, heavenly voice convinces them<br>to convert immediately.<br>You run down to the nearest convenience store<br>and grab yourself an orange Crush. Bottled, of course.<html>");
}
}
public void actionPerformed(ActionEvent e){
if(e.getSource() == start){
frame.getContentPane().removeAll();
frame.setContentPane(createDoorMenu());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setResizable(false);
frame.setVisible(true);
}else if(e.getSource() == knock){
knock.setEnabled(false);
knockResponse();
}else if(e.getSource() == talk){
talk.setEnabled(false);
successCalc();
}
playerName = name.getText();
}
public static void createAndShowGUI(){
JFrame.setDefaultLookAndFeelDecorated(false);
frame.setContentPane(game.createStartMenu());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
frame.setResizable(false);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run(){
createAndShowGUI();
}
});
}
}
Thanks for any help, I'm terrible at asking questions.
A Timer starts out repeating, by default. So, your timers are all firing every second, forever.
You ought to call setRepeats(false):
void doLater(ActionListener action, int delay) {
Timer timer = new Timer(delay, action);
timer.setRepeats(false);
timer.start();
}

Adding multiple instances of a JButton to JFrame in grid

The code below is supposed to create and object instance for a specific type (say color) JButton I want to represent in a grid. When I iterate through the for-loop to add the buttons to the jframe it adds nothing. But if I add a single instance variable it will add that. Anybody have an idea?
public class Grid {
protected JButton [][] board;
private JButton player;
private JButton openCell;
private JButton wall;
private JButton closedCell;
public Grid(String [] args) { // args unused
// Instantiation
board = new JButton [6][6];
layout = new String [6][6];
blueCell = new JButton("BLUE CELL");
redCell = new JButton("RED CELL");
greenCell = new JButton("GREEN CELL");
whiteCell = new JButton("WHITE CELL");
// Configuration (add actions later)
// Decoration
blueCell.setBackground(Color.blue);
redCell.setBackground(Color.red);
greenCell.setBackground(Color.green);
whiteCell.setBackground(Color.white);
for (int rows = 0; rows < 6; rows++) {
for (int cols = 0; cols < 6; cols++) {
if ((layout[rows][cols]).equals('*')) {
board[rows][cols] = blueCell;
}
else if ((layout[rows][cols]).equals('.')) {
board[rows][cols] = redCell;
}
else if ((layout[rows][cols]).equals('x')) {
board[rows][cols] = greenCell;
}
else {
board[rows][cols] = whiteCell;
}
}
}
JFrame game = new JFrame();
game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.setLayout(new GridLayout (6, 6));
game.setSize(500, 500);
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board.length; j++) {
if ((board[i][j]).equals(blueCell)) {
grid.add(blueCell);
}
else if ((board[i][j]).equals(redCell)) {
grid.add(redCell);
}
else if ((board[i][j]).equals(greenCell)) {
grid.add(greenCell);
}
else {
grid.add(whiteCell);
}
}
}
grid.setVisible(true);
} // end of constructor
} // end of Grid class
You can add a component to your GUI only once. If you add it to another component, it will be removed from the previous component. You're trying to add the same JButtons several times, and that won't work. Instead you're going to have to create more JButtons. Consider having your buttons share Actions which is allowed.
If you need more help, consider posting compilable code (your current code is not), a small runnable, compilable program that demonstrates your problem, in other words, an sscce.
Edit
You comment:
But don't these count as instances of a JButton not the same JButton? (I don't understand what your answer meant...)
Think of it mathematically... how many JButtons do you create in your code above? Well, this is easy to figure, exactly 4:
blueCell = new JButton("BLUE CELL");
redCell = new JButton("RED CELL");
greenCell = new JButton("GREEN CELL");
whiteCell = new JButton("WHITE CELL");
So, now ask yourself, how many JButtons are you trying to display in your GUI with these four JButtons? If it's four, then you're possibly OK (as long as you use each button), but if it's more, then you're in trouble. From your 6x6 grid, board = new JButton [6][6];, it looks like you're trying to display 36 JButtons, and if this is true, you've got problems.
But again, if still stuck, please consider creating and posting an sscce.

Categories