My first post, so forgive any incorrect etiquette. I'm currently doing my year end project for school and I need a bit of help. I am making a GUI java app in Netbeans. I have two classes. One is a class that controls a timer, the other is a class that is a scoreboard screen. I need to update the scoreboard timerLabel with the time that is being counted down in the timerClass. Its quite messy as there is another timer label in the Timer class which does update. My problem is that I cannot get timerLabel in MatchScreen() to update. Here is my code :
Timer Class
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class TimerClass extends JFrame {
Timer timer;
JLabel promptLabel, timerLabel;
int counter;
JTextField tf;
JButton button;
MatchScreen call = null;
public TimerClass() {
call = new MatchScreen();
setLayout(new GridLayout(4, 4, 7, 7));
promptLabel = new JLabel(""
+ "Enter number of seconds for the timer",
SwingConstants.CENTER);
add(promptLabel);
tf = new JTextField(5);
add(tf);
button = new JButton("Start");
add(button);
timerLabel = new JLabel("waiting...",
SwingConstants.CENTER);
add(timerLabel);
event e = new event();
button.addActionListener(e);
System.out.println("Button pressed");
}
public class event implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("Action performed");
int count = (int) (Double.parseDouble(tf.getText()));
timerLabel.setText("Time left: " + count);
call.setTimerLabel(count);
System.out.println("Passed count to tc");
TimeClass tc = new TimeClass(count);
timer = new Timer(1000, tc);
System.out.println("Timer.start");
timer.start();
//throw new UnsupportedOperationException("Not supported yet.");
}
/*public void actionPerformed(ActionEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}*/
}
public class TimeClass implements ActionListener {
int counter;
public TimeClass(int counter) {
this.counter = counter;
}
public void actionPerformed(ActionEvent e) {
counter--;
if (counter >= 1) {
call.setTimerLabel(counter);
} else {
timerLabel.setText("END");
timer.stop();
Toolkit.getDefaultToolkit().beep();
}
}
}
public static void main(String args[]) {
TimerClass gui = new TimerClass();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.setSize(250, 150);
gui.setTitle("Time Setup");
gui.setVisible(true);
}
}
And now the ScoreBoard Screen
public class MatchScreen extends javax.swing.JFrame {
int redScore = 0, blueScore = 0, blueCat1 = 0,
blueCat2 = 0, redCat1 = 0, redCat2 = 0, winner = 0;
public MatchScreen() {
initComponents();
}
//Determine Winner of the match
public int getWinner() {
if (redScore > blueScore) {
winner = 1;
} else {
winner = 2;
}
return winner;
}
public void setTimerLabel(int a) {
int time = a;
while (time >= 1) {
timerLabel.setText("" + time);
}
if (time < 1) {
timerLabel.setText("End");
}
}
private void jButton13ActionPerformed(java.awt.event.ActionEvent evt) {
//Creates an object of the timerClass
TimerClass gui = new TimerClass();
gui.setSize(300, 175);
gui.setTitle("Time Setup");
gui.setVisible(true);
}
}
Some code that I felt is irrelevant was left out from the MatchScreen().
Many thanks
Managed to solve the general problem. I put all the code into one class. Not ideal, but it works :/ Anyway, deadlines are looming.
Sincere thanks.
You have a while loop in the setTimerLabel method, which I don't think you intended to put there. Also, you take the parameter a and assign it to time and then never use a again, why not just rename your parameter to time and bypass that additional variable?
EDIT
Sorry, I forgot to explain what I'm seeing :P If you say call.setTimerLabel(10) then you hit that while loop (while(time >= 1) which is essentially running while(10 >= 1) which is an infinite loop. Your program is never leaving the method setTimerLabel the first time you call it with a value >= 1.
Related
This question already has answers here:
What is a debugger and how can it help me diagnose problems?
(2 answers)
Closed 4 years ago.
I am working on this program that calculates the Beats per Minute (BPM) when you click the button. When you click two times, it is supposed to display the current BPM, and display the new one with every click after that. What the problem is, though, is that the display isn't changing. What do I need to do?
Here is my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class BPM extends JPanel implements ActionListener {
JLabel label;
public String display;
public int bpm;
public int buttonPressed;
public int time1;
public int time2;
public int time3;
public int counter[];
public void addComponents(Container pane) {
JPanel buttons = new JPanel();
JButton bpmButton = new JButton("Click");
bpmButton.setSize(new Dimension(100, 50));
bpmButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
buttonPressed++;
counter = new int[2];
if (buttonPressed == 1) {
counter[0] = (int)(System.currentTimeMillis());
} else if (buttonPressed == 2) {
counter[1] = (int)(System.currentTimeMillis());
calculateTimeBetweenClicks();
setTime();
} else {
counter[0] = counter[1];
counter[1] = (int)(System.currentTimeMillis());
calculateTimeBetweenClicks();
setTime();
}
}
});
display = "0";
label = new JLabel(display, SwingConstants.CENTER);
label.setFont(label.getFont().deriveFont(100.0f)); // original 45
pane.add(label, BorderLayout.PAGE_START);
pane.add(bpmButton, BorderLayout.CENTER);
}
// Calculates the difference between the two saved clicks
public void calculateTimeBetweenClicks() {
if (buttonPressed == 1) {
time1 = counter[0];
} else {
time1 = counter[0];
time2 = counter[1];
}
time3 = time2 - time1;
}
// Calculates the BPM and changes the display accordingly
public void setTime() {
bpm = 60000 / time3;
display = "" + bpm + "";
label.setText(display);
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
public static void createAndShowGUI() {
// Creates the window
JFrame frame = new JFrame("BPM Calculator");
frame.setPreferredSize(new Dimension(300, 200)); // original (250, 130)
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Adds the components to the content pane
BPM window = new BPM();
window.addComponents(frame.getContentPane());
//Displays the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
// Turns off bold text
UIManager.put("swing.boldMetal", Boolean.FALSE);
// Allows the components to be used and interacted with
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
The problem is in your addComponents method, you are creating a new array on each and every button click (so you end up with a new and empty array). This is throwing off your calculation. Simply move the instantiation of your array to somewhere outside of the ActionListener like this...
public void addComponents(Container pane) {
JPanel buttons = new JPanel();
counter = new int[2]; //Move this line to here...
JButton bpmButton = new JButton("Click");
bpmButton.setSize(new Dimension(100, 50));
bpmButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
buttonPressed++;
if (buttonPressed == 1) {
counter[0] = (int)(System.currentTimeMillis());
} else if (buttonPressed == 2) {
counter[1] = (int)(System.currentTimeMillis());
calculateTimeBetweenClicks();
setTime();
} //Removed the else - see edit below :-)
}
});
Additional
Your code as-is seems to get a litle confused after the 2nd click (the first BPM calculation) as it seems to take that 2nd click as the first click of the next set of 2 clicks if you get what I mean. I'm not sure if this is intended behaviour, but if not, I would reset everything in the calculateTimeBetweenClicks method after you've calculated the correct bpm ready for a new set of 2 clicks...
// Calculates the difference between the two saved clicks
public void calculateTimeBetweenClicks() {
if (buttonPressed == 1) {
time1 = counter[0];
} else {
time1 = counter[0];
time2 = counter[1];
//Reset here ready for next 2 clicks...
counter[0]=0;
counter[1]=0;
buttonPressed = 0;
}
time3 = time2 - time1;
}
program suppose to run "Guess the number" game
after guessing the number correctly , there's an option to start over
Pressing the "playAgainBtn" make the program stuck.
Another issue is after guessing the "guessText" cant be .selectAll
any insight will be welcomed
Tnx.
public class GuessTheNumberGame extends JFrame
{
private int randomNumber;
private boolean correctGuess;
private JLabel startMsg;
private JLabel enterGuessJLabel;
private JButton playAgainBtn;
private JLabel msgToPlayer;
private JTextField guessText;
private int previousGuess; // previous guessed number hot/cold
private int numOfGuess;
private Container container;
public GuessTheNumberGame()
{
container = getContentPane();
startMsg = new JLabel();
enterGuessJLabel = new JLabel();
guessText = new JTextField(10);
guessText.addActionListener(
new ActionListener()
{
#Override
public void actionPerformed(ActionEvent event)
{
int playerGuess = Integer.parseInt(event.getActionCommand());
if ( playerGuess == randomNumber )
{
msgToPlayer.setText("Great ! u guessed in " + numOfGuess + "Guesses");
correctGuess = true;
}
else
{
wrongGuess(playerGuess);
}
}
}
);
msgToPlayer = new JLabel("");
playAgainBtn = new JButton("Play Again");
ButtonHandler buttonHandler = new ButtonHandler();
playAgainBtn.addActionListener(buttonHandler);
setLayout(new FlowLayout());
add(startMsg);
add(enterGuessJLabel);
add(guessText);
add(msgToPlayer);
add(playAgainBtn);
}
protected class ButtonHandler implements ActionListener
{
#Override
public void actionPerformed(ActionEvent event)
{
startGame();
}
}
public void startGame()
{
previousGuess = 1000;
numOfGuess = 1;
correctGuess = false;
Random rand = new Random();
randomNumber = rand.nextInt(1000) + 1;
startMsg.setText( "I have a number between 1 and 1000. can you Guess my Number?" );
playAgainBtn.setVisible( false );
while ( !correctGuess)
{
enterGuessJLabel.setText( "Please enter your " + numOfGuess + " guess: " );
}
playAgainBtn.setVisible(true);
}
private void wrongGuess(int playerGuess)
{
numOfGuess++;
if ( Math.abs(playerGuess - randomNumber) > previousGuess )
container.setBackground( Color.GREEN);
else
container.setBackground( Color.RED);
previousGuess = Math.abs(playerGuess - randomNumber);
if (playerGuess > randomNumber)
msgToPlayer.setText("Too High");
else
msgToPlayer.setText( "Too Low" );
}
}
When you start the application, startGame() runs on the main thread, which is OK. When you press playAgainBtn, it calls startGame() on the AWT Dispatch Thread, thus tying up this thread, prohibiting the AWT from processing events. Try this to free up the AWT Dispatch Thread:
protected class ButtonHandler implements ActionListener
{
#Override
public void actionPerformed(ActionEvent event)
{
new Thread() {
#Override
public final void run() {
startGame();
}
}.start();
}
}
The problem is that your startGame method, called when the button is clicked, has an infinite loop in it.
while ( !correctGuess)
{
enterGuessJLabel.setText( "Please enter your " + numOfGuess + " guess: " );
}
The correctGuess variable will never be changed so your program will just execute the setText command endlessly.
The way Swing (and all GUI frameworks) work is that you must always respond to an event such as a button click and then return control.
I'm self learning java beginner
i'm trying to create simple calculator using java swing and i want to create array of JButtons to create all the buttons in the project , i had some issues so i declare all variables outside the constructor
public class SimpleCalculator extends JFrame implements ActionListener {
JButton btnArray[] = new JButton[16];
JLabel nameLabel = new JLabel("Ghanayem's Calculator",
SwingConstants.CENTER);
JTextField txt = new JTextField();
JPanel numPanel = new JPanel(new GridLayout(4, 3, 15, 5));
JPanel opPanel = new JPanel(new GridLayout(4, 1, 0, 5));
JPanel panel = new JPanel(new GridLayout(2, 1, 0, 5));
int counter;
char operation;
double operand1;
double operand2;
like that ,and i think to add actions to buttons inside for-loop no compiler errors every thing is ok
for (counter = 0; counter < 10; counter++) {
btnArray[counter] = new JButton("" + counter);
btnArray[counter].addActionListener(this);
}
and here is action performed implementation
#Override
public void actionPerformed(ActionEvent e) {
txt.setText(txt.getText() + counter);
}
just like that ,when i try to run the program and press any number button the number added to text field is "16" for all buttons, and this is main method
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
SimpleCalculator frame = new SimpleCalculator();
frame.setVisible(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setResizable(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
i am getting crazy i don't know what is wrong , please i need your help this my first swing application i am so disperate
thank you
Try something like this (I can't test right now so it may contain some lesser errors):
#Override
public void actionPerformed(ActionEvent e) {
String value = ((JButton)e.getSource()).getText();
Integer intValue = Integer.parseInt(value);
Integer intValue2 = Integer.parseInt(txt.getText());
txt.setText( "" + (intValue + intValue2));
}
#Override
public void actionPerformed(ActionEvent e) {
JButton b = (JButton) e.getSource();
txt.replaceSelection(b.getActionCommand());
}
this is a solution for my question i found here
java-action-listener
#Override
public void actionPerformed(ActionEvent e) {
String value = (JButton) e.getSource().getText();
txt.setText(txt.getText() + value);
}
and this is another solution #Paco Abato helps me to find
I have been having some problems with using the Timer function of Java swing. I am fairly new to programming with Java, so any help is greatly appreciated. I have looked over many other Timer questions on this site but none of them have answered my question. I have made a GUI that allows you to play rock paper scissors, where you can choose from clicking three buttons. I want my program to sleep for around 1 second after you click the button, and again after it displays a message. After I realized Thread.sleep() wouldn't work for my GUI, I tried to implement a timer.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.Border;
import java.io.*;
public class rps {
//ROCK PAPER SCISSORS
static JLabel middle = new JLabel();
static JLabel them = new JLabel();
static JLabel yourWins = new JLabel();
static JLabel theirWins = new JLabel();
static JPanel yourPanel = new JPanel();
static JPanel middlePanel = new JPanel();
static JLabel blank1 = new JLabel();
static JLabel blank2 = new JLabel();
static JButton rock = new JButton("Rock");
static JButton paper = new JButton("Paper");
static JButton scissors = new JButton("Scissors");
static int yw = 0;
static int tw = 0;
static ButtonHandler listener = new ButtonHandler();
public static void main(String[] args) {
//Create the frame
JFrame frame = new JFrame("Rock Paper Scissors");
frame.setSize(500, 500); //Setting the size of the frame
middle.setFont(new Font("Serif", Font.PLAIN, 30));
middle.setHorizontalAlignment(SwingConstants.CENTER);
them.setFont(new Font("Serif", Font.PLAIN, 15));
them.setHorizontalAlignment(SwingConstants.CENTER);
yourWins.setHorizontalAlignment(SwingConstants.CENTER);
theirWins.setHorizontalAlignment(SwingConstants.CENTER);
//Creating panels
JPanel bigPanel = new JPanel();
Border border = BorderFactory.createLineBorder(Color.BLACK, 1);
Border wlb = BorderFactory.createLineBorder(Color.RED, 1);
them.setBorder(border);
yourPanel.setBorder(border);
bigPanel.setBorder(border);
yourWins.setBorder(wlb);
theirWins.setBorder(wlb);
middlePanel.setBorder(border);
//Creating grid layouts
GridLayout yourGrid = new GridLayout(1,3,10,10);
GridLayout theirGrid = new GridLayout(1,1); //One row, one column
GridLayout middleGrid = new GridLayout(5,1);
GridLayout bigGrid = new GridLayout(3,1);//Two rows, one column
//Setting the layouts of each panel to the grid layouts created above
yourPanel.setLayout(yourGrid); //Adding layout to buttons panel
them.setLayout(theirGrid); //Adding layout to label panel
middlePanel.setLayout(middleGrid);
bigPanel.setLayout(bigGrid);
//Adding r/p/s to your grid.
yourPanel.add(rock);
yourPanel.add(paper);
yourPanel.add(scissors);
//Adding w/l rations to middlegrid.
middlePanel.add(theirWins);
middlePanel.add(blank1);
middlePanel.add(middle);
middlePanel.add(blank2);
middlePanel.add(yourWins);
//Attaching the listener to all the buttons
rock.addActionListener(listener);
paper.addActionListener(listener);
scissors.addActionListener(listener);
bigPanel.add(them);
bigPanel.add(middlePanel);
bigPanel.add(yourPanel);
//Shows the score at 0-0.
yourWins.setText("Your wins: " + yw);
theirWins.setText("Their wins: " + tw);
frame.getContentPane().add(bigPanel); //panel to frame
frame.setVisible(true); // Shows frame on screen
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
//Class represents what do when a button is pressed
private static class ButtonHandler implements ActionListener {
public void actionPerformed (ActionEvent e) {
Timer timer = new Timer(1000, this);
String tc = random();
them.setText("They chose: " + tc + "!");
if (e.getSource() == rock) {
whoWins("rock", tc);
} else if (e.getSource() == paper) {
whoWins("paper", tc);
} else if (e.getSource() == scissors) {
whoWins("scissors", tc);
}
yourWins.setText("Your wins: " + yw);
theirWins.setText("Their wins: " + tw);
timer.setRepeats(false);
timer.start();
}
}
public static String random() {
int random = (int) (Math.random() * 3);
if (random == 0) {
return "Rock";
} else if (random == 1) {
return "Paper";
} else if (random == 2) {
return "Scissors";
}
return "";
}
public static void whoWins(String yc, String tc) {
if (yc.equals("rock")) {
if (tc.equals("Rock")) {
middle.setText("It's a tie!");
} else if (tc.equals("Paper")) {
middle.setText("You lose!");
tw++;
} else if (tc.equals("Scissors")) {
middle.setText("You win!");
yw++;
}
} else if (yc.equals("paper")) {
if (tc.equals("Rock")) {
middle.setText("You win!");
yw++;
} else if (tc.equals("Paper")) {
middle.setText("It's a tie!");
} else if (tc.equals("Scissors")) {
middle.setText("You lose!");
tw++;
}
} else if (yc.equals("scissors")) {
if (tc.equals("Rock")) {
middle.setText("You lose!");
tw++;
} else if (tc.equals("Paper")) {
middle.setText("You win!");
yw++;
} else if (tc.equals("Scissors")) {
middle.setText("It's a tie!");
}
}
}
}
What is actually happening is there is no delay from when I press the button to a message displaying, because clearly I am not using the timer correctly. I would like the timer to just run once, and after it runs the code will execute. However, when I click a button the timer will run on repeat although setRepeats is false. Therefore, the message I want to display, instead of being delayed, is displayed instantaneously but then goes on a loop and keeps displaying a message (the message is random) until I shut off the program. If I click the button again, it will double the tempo of the timer it seems, and the messages display twice as fast and so on and so forth.
them.setText("They chose: " + tc + "!");
This is the message that is displayed on repeat, with the variable tc changing every time. The timer seems to just be displaying this message every timer interval (1s).
Any help would be greatly appreciated.
EDIT:
So I added this section :
private static class ButtonHandler implements ActionListener {
public void actionPerformed (ActionEvent e) {
// I'd be disabling the buttons here to prevent
// the user from trying to trigger another
// update...
// This is an instance field which is used by your
// listener
Timer timer = new Timer(1000, listenert);
timer.setRepeats(false);
timer.start();
}
}
private static class timer implements ActionListener {
public void actionPerformed (ActionEvent e) {
String tc = random(); //A method that chooses a random word.
them.setText("They chose: " + tc + "!");
if (e.getSource() == rock) {
whoWins("rock", tc); //whoWins is a method that will display a message.
} else if (e.getSource() == paper) {
whoWins("paper", tc);
} else if (e.getSource() == scissors) {
whoWins("scissors", tc);
}
yourWins.setText("Your wins: " + yw);
theirWins.setText("Their wins: " + tw);
// Start another Timer here that waits 1 second
// and re-enables the other buttons...
}
}
so what I believe happens now is when I click a button, the buttonhandler listener starts the timer which is attached to the timer listener (named listenert) which will run the code in the actionPerformed of the timer class. however the sleep function still is not working
EDIT 2.5:
private static class ButtonHandler implements ActionListener {
public void actionPerformed (ActionEvent e) {
final JButton button = (JButton)e.getSource();
Timer timer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
String tc = random();
them.setText("They chose: " + tc + "!");
if (button == rock) {
whoWins("rock", tc);
} else if (button == paper) {
whoWins("paper", tc);
} else if (button == scissors) {
whoWins("scissors", tc);
}
yourWins.setText("Your wins: " + yw);
theirWins.setText("Their wins: " + tw);
}
});
timer.setRepeats(false);
timer.start();
}
}
that is what I have so far, I just need to add antoher sleep after
them.setText("They chose: " + tc + "!");
where would I put a timer.restart() if any? the timer.start() is at the end of the method which I don't quite understand.
So, the ActionListener you supply to the Timer is notified when the timer "ticks", so you ButtonHandler actionPerformed should look more like...
public void actionPerformed (ActionEvent e) {
// I'd be disabling the buttons here to prevent
// the user from trying to trigger another
// update...
// This is an instance field which is used by your
// listener
choice = e.getSource();
Timer timer = new Timer(1000, listener);
timer.setRepeats(false);
timer.start();
}
And your listener should look more like
public void actionPerformed (ActionEvent e) {
String tc = random(); //A method that chooses a random word.
them.setText("They chose: " + tc + "!");
if (choice == rock) {
whoWins("rock", tc); //whoWins is a method that will display a message.
} else if (choice == paper) {
whoWins("paper", tc);
} else if (choice == scissors) {
whoWins("scissors", tc);
}
yourWins.setText("Your wins: " + yw);
theirWins.setText("Their wins: " + tw);
// Start another Timer here that waits 1 second
// and re-enables the other buttons...
}
For example...
You may consider taking a look at How to use Swing Timers for more details
Updated
Start with a simple example...
public class TestPane extends JPanel {
private JLabel label;
private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
public TestPane() {
setLayout(new GridBagLayout());
label = new JLabel();
add(label);
tick();
Timer timer = new Timer(500, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
tick();
}
});
timer.start();
}
protected void tick() {
label.setText(sdf.format(new Date()));
}
}
This just calls the tick method every half second to update the time on the JLabel...
firstly import the following ;
import java.awt.event.ActionEvent ;
import java.awt.event.ActionListener ;
import javax.swing.Timer ;
then initialize the timer at the end of the form like this ;
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new mainprogramme().setVisible(true);
}
});
}
private Timer timer ;
then after initializing the timer add a public class like following;
public class progress implements ActionListener {
public void actionPerformed(ActionEvent evt){
int n = 0 ;
if (n<100){
n++ ;
System.out.println(n) ;
}else{
timer.stop() ;
}
}
}
after you do this go to the j Frame>right click and select>Events>window>window Opened and type the following ;
private void formWindowOpened(java.awt.event.WindowEvent evt) {
timer = new Timer(100,new progress()) ;
and after you do all this take a button name it as anything and type the following in its void like following ;
timer.start();
AND THAT'S IT CODE IT AND THEN REPLY ME...
I was reading different threads on the subject which suggested the Swing Timer class or SwingUtilities.InvokeLater
...but I am having a lot of trouble wrapping my head around them.
I used atomicInteger to create my countdown timer and it works fine in the console. However, When I try to incorporate it in Swing, it only updates the starting and ending value (e.g. set a 5 sec countdown will display in the frame: "5" -> after 5 seconds -> "0".
Is there any simple way for me to keep and "refresh" my atomicInteger countdown label, or the only way is using the Swing Timer class?
Thank you for your patience!
ps. not homework, just trying to make myself a custom timer to study. (ie. procrastinating)
I hope this class is enough, please let me know if you need the frame/panel code as well.
private class ClickListener implements ActionListener{
public void actionPerformed(ActionEvent e){
int t_study = 5;
atomicDown.set(t_study);
if (e.getSource() == b_study){
while(atomicDown.get() > 0){
t_study = atomicDown.decrementAndGet();
l_studyTime.setText(Integer.toString(t_study));
try {
Thread.sleep(1000);
}
catch (InterruptedException e1) {
System.out.println("ERROR: Thread.sleep()");
e1.printStackTrace();
}
}
}
else if(e.getSource() == b_exit){
System.exit(0);
}
else
System.out.println("ERROR: button troll");
}
}
After turning the code snippet into an SSCCE, this is what I get (which seems to work - as best as I understand the original code).
I have not changed the variable names. Please learn common Java naming conventions1 for class, method & attribute names & use it consistently.
Specifically names like b_study should be more along the lines of studyButton or similar. Some will note that 'button' should not be part of the name, but when you have a GUI with both a 'Study' button & label, I don't see any other logical way to separate them.
import java.awt.event.*;
import javax.swing.*;
import java.util.concurrent.atomic.AtomicInteger;
class TimerTicker {
public static final int STUDY_TIME = 15;
AtomicInteger atomicDown = new AtomicInteger(STUDY_TIME);
JButton b_study;
JButton b_exit;
JLabel l_studyTime;
TimerTicker() {
JPanel gui = new JPanel();
b_study = new JButton("Study");
ClickListener listener = new ClickListener();
b_study.addActionListener(listener);
gui.add(b_study);
b_exit = new JButton("Exit");
b_exit.addActionListener(listener);
gui.add(b_exit);
l_studyTime = new JLabel("" + atomicDown.get());
gui.add(l_studyTime);
JOptionPane.showMessageDialog(null, gui);
}
private class ClickListener implements ActionListener {
Timer timer;
public void actionPerformed(ActionEvent e){
if (e.getSource() == b_study) {
ActionListener countDown = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (!(atomicDown.get() > 0)) {
timer.stop();
// reset the count.
atomicDown.set(STUDY_TIME);
} else {
l_studyTime.setText(
Integer.toString(
atomicDown.decrementAndGet()));
}
}
};
timer = new Timer(1000,countDown);
timer.start();
} else if(e.getSource() == b_exit) {
System.exit(0);
} else {
System.out.println("ERROR: button troll");
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new TimerTicker();
}
});
}
}