Java Timer usage with JButtons - java

I have problem that I don't understand, how to correctly use the Java timer with JButton.
The idea of what I need -
When I click on JButton with text "0" then starts the timer counting from two seconds till zero.
When button is released program checks the situation:
if timer now is 0 then it shows in JTextField sign "+", else it shows "0".
Here is my code of program. Can someone please add the things that I need to make the program work like the idea I want?
public class DialPanel extends JPanel {
private MainFrame frame;
public DialPanel(MainFrame frame) {
this.frame = frame;
this.setLocation(0, 90);
this.setSize(300, 290);
this.setLayout(null);
this.setBackground(color);
this.initContent();
}
// -------------------------------------------------------------------------
private JButton btnNumZero;
private JTextField txfNumber;
private void initContent() {
txfNumber = new JTextField();
this.add(txfNumber);
txfNumber.setSize(190, 30);
txfNumber.setLocation(30, 0);
txfNumber.setFocusable(false);
txfNumber.addActionListener(controller);
btnNumZero = new JButton();
this.add(btnNumZero);
btnNumZero.setText("0");
btnNumZero.setFocusable(false);
btnNumZero.setSize(30, 30);
btnNumZero.setLocation(10, 10);
btnNumZero.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
//Start someTimer countdown from two seconds
}
});
btnNumZero.addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
//Stop someTimer
//if someTimer == 0 seconds then do this line:
txfNumber.setText("+");
//else do this line:
txfNumber.setText("0");
}
});
}
}
Excuse me if there is some unnecessary error with code. I deleted and changed a lot of things from the real one code so that this could be more understandable and clear for reading.

Instead of using a Timer, you may want to just make use of System.currentTimeMillis(). The Timer may not be a timer in the sense you are looking for, as a stopwatch type object.
You could do something like this
long startTime;
long endTime;
btnNumZero.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
startTime = System.currentTimeMillis();
}
});
btnNumZero.addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent e) {
endTime = System.currentTimeMillis();
long difference = endTime - startTime;
if (difference > 2000)
txfNumber.setText("+");
else
txfNumber.setText("0");
}
});

Related

Timer and JSlider with images

This is part of my code and it doesn't work because it keeps on saying it cannot find the symbol in my ActionListener. I don't know how to make it work.
So basically what I'm trying to do is make the images from 1-8.png move depending on where the slider lands and IDK how to:
private static JLabel value;
private static ImageIcon image;
private static Timer timer;
private static final int delay = 2000;
private static int newDelay;
private static int i = 1;
timer = new Timer(delay, new ActionListener() {
public void actionPerformed(ActionEvent e) {
// makes the image at i appear and then goes to 2 and so on until i i = 8 and will return a 1 after. Will keep on doing so
value.setIcon(new ImageIcon(i + ".png"));
i++;
if(i == 8) {
i = 1;
}
}
});
timer.start();
}
private static class SliderChange implements ChangeListener {
public void stateChanged(ChangeEvent event) {
JSlider source = (JSlider) event.getSource();
// while it is adjusting timer stops and gets the value of where the slider hits and the newDelay will be the new timer time. (So if they drag slider to 6, delay(which is 2000) will be divided by 6 to get new time
if (!source.getValueIsAdjusting()) {
timer.stop();
value.setIcon(new ImageIcon(i + ".png"));
newDelay = (delay/(int)source.getValue());
timer = new Timer(newDelay, new Actionlistener());
timer.start();
}
}
}
But this doesn't work. How can I fix it?
It points to this line saying there is an error:
timer = new Timer(newDelay, new Actionlistener());
I'm not sure it's really necessary to recreate the Timer each time. Instead, stop it, set it's delay property and restart it instead
private static class SliderChange implements ChangeListener {
public void stateChanged(ChangeEvent event) {
JSlider source = (JSlider) event.getSource();
// while it is adjusting timer stops and gets the value of where the slider hits and the newDelay will be the new timer time. (So if they drag slider to 6, delay(which is 2000) will be divided by 6 to get new time
if (!source.getValueIsAdjusting()) {
timer.stop();
value.setIcon(new ImageIcon(i + ".png"));
newDelay = (delay/(int)source.getValue());
timer.setDelay(newDelay);
timer.start();
}
}
}
The problem is timer = new Timer(newDelay, new Actionlistener()); is trying to create an instance of a interface without the implementing the requirements of the interface, which is confusing the compiler

Increment an integer in a JTextField by one

I am trying to increment the value of a JTextfield (tenSecs) by one for every instance that my other JTextfield (oneSecs) reaches 0. I am having difficulty trying to increase the value of my tenSecs JTextfield as it is always 0. When manually changing the number, as soon as oneSecs reaches 0, tenSecs reverts to 0.
javax.swing.Timer tm = new javax.swing.Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
AddOneActionPerformed(evt);
}
});
private void StartStopTimerActionPerformed(java.awt.event.ActionEvent evt) {
if (!tm.isRunning()) {
tm.start();
} else {
tm.stop();
}
ScheduledExecutorService e= Executors.newSingleThreadScheduledExecutor(); //Start new scheduled executor service to invoke a timer that start wehn button is pressed
e.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
//Follow this Override to do task
SwingUtilities.invokeLater(new Runnable() {
//Override will let the task run
#Override
public void run() {
oneSecsDisplay.setIcon(new ImageIcon("images\\" + TextGrabber() + ".png"));
oneSecs.setText( DigitValue.getText());
int i = 0;
if (Integer.parseInt(oneSecs.getText()) == i) {
tenSecs.setText(Integer.toString(i++));
}
}
});
}
}, 0, 100, TimeUnit.MILLISECONDS); //Update will be for every 100 milliseconds concurrent to system time
}
// Variables declaration - do not modify
private javax.swing.JTextField oneSecs;
private javax.swing.JTextField tenSecs;
// End of variables declaration
I am sure that the error is occurring around the line int i = 0;. I am also sure that my way of increasing the value is not the best way to do this, if someone could kindly point me in the correct direction
If I'm understanding you correctly, try tenSecs.setText(String.valueOf(Integer.parseInt(tenSecs.getText()) + 1));

Swing timer synchronization

I'm confused about how the Swing timer work. In the code below, I want to display from 0~9 every 400ms in the first text field when press START (once). After that the second text field will display "Finished".
public class Main extends JPanel{
private static final long serialVersionUID = 1L;
private JButton bStart;
private JTextField tTest;
private JTextField tNumber;
Main(){
bStart = new JButton("Start");
bStart.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
displayNumbers();
}
});
tTest = new JTextField(null, 30);
tNumber = new JTextField(" ", 30);
tNumber.setEditable(false);
this.setSize(300, 100);
this.add(bStart);
this.add(tNumber);
this.add(tTest);
}
public void displayNumbers(){
new Timer(400, new ActionListener() {
int i = 0;
public void actionPerformed(ActionEvent evt) {
if(i<10){
tNumber.setText(Integer.toString(i));
i++;
}
else
((Timer)evt.getSource()).stop();
}
}).start();
tTest.setText("Finished");
}
public static void createAndShowGUI(){
JFrame frame = new JFrame("test");
frame.add(new Main());
frame.setSize(400, 150);
frame.setVisible(true);
}
public static void main(String args[]){
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
createAndShowGUI();
}
});
}
}
However, it first displays "Finished" before finishing displaying 0 ~ 9. I think the Swing timer works also in EDT, so "tTest.setText("Finished");" will be executed after timer thread. Why does not it work? How do I wait finishing displaying 0 ~ 9 then print "Finished"? Thanks!
Thanks for your answers. In fact what I want to ask is in general:
new Timer(delay, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
doSomething();
}
}).start();
doOthers();
How to let doOthers() execute after all the doSomething()? (In some cases, we cannot put doOthers() inside actionPerformed function, as some answers mentioned).
The timer works concurrently. So the timer is started, then the text is set to finished, and then the timer fires and the first number appears.
To make the timer display finished after it is finished, put the tTest.setText("Finished"); in the else clause of if(i<10).

Is there a way to animate an entire Jframe in Java so that it moves?

I would like to create a program where the Jframe is able to move freely on it's own. Kind of like a translation / transition.
For example,
Click on program to begin.
Jframe spawns at location (0,0).
Automatically move (animate) 100 pixels to the right so that the new coordinates are (100,0).
I know there's the setLocation(x,y) method that sets the initial position once the program runs but is there a way to move the entire Jframe after the program starts?
The basic concept would look something like this...
public class MoveMe01 {
public static void main(String[] args) {
new MoveMe01();
}
public MoveMe01() {
EventQueue.invokeLater(
new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
final JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JLabel("Use the Force Luke"));
frame.pack();
frame.setLocation(0, 0);
frame.setVisible(true);
Timer timer = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Point location = frame.getLocation();
Point to = new Point(location);
if (to.x < 100) {
to.x += 4;
if (to.x > 100) {
to.x = 100;
}
}
if (to.y < 100) {
to.y += 4;
if (to.y > 100) {
to.y = 100;
}
}
frame.setLocation(to);
if (to.equals(location)) {
((Timer)e.getSource()).stop();
}
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
});
}
}
This is a pretty straight, linear animation. You'd be better of investigating one of the many animation engines available for Swing, this will provide you with the ability to change the speed of the animation based on the current frame (doing things like slow-in and slow-out for example)
I would take a look at
Timing Framework
Trident
Universla Tween Engine
Updated with a "variable time" solution
This is basically an example of how you might do a variable time animation. That is, rather then having a fixed movement, you can adjust the time and allow the animation to calculate the movement requirements based on the run time of the animation...
public class MoveMe01 {
public static void main(String[] args) {
new MoveMe01();
}
// How long the animation should run for in milliseconds
private int runTime = 500;
// The start time of the animation...
private long startTime = -1;
public MoveMe01() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
final JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JLabel("Use the Force Luke"));
frame.pack();
frame.setLocation(0, 0);
frame.setVisible(true);
Timer timer = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (startTime < 0) {
// Start time of the animation...
startTime = System.currentTimeMillis();
}
// The current time
long now = System.currentTimeMillis();
// The difference in time
long dif = now - startTime;
// If we've moved beyond the run time, stop the animation
if (dif > runTime) {
dif = runTime;
((Timer)e.getSource()).stop();
}
// The percentage of time we've been playing...
double progress = (double)dif / (double)runTime;
Point location = frame.getLocation();
Point to = new Point(location);
// Calculate the position as perctange over time...
to.x = (int)Math.round(100 * progress);
to.y = (int)Math.round(100 * progress);
// nb - if the start position wasn't 0x0, then you would need to
// add these to the x/y position above...
System.out.println(to);
frame.setLocation(to);
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
});
}
}

How to stop the timer function after the object has been shot?

I am making a simple target shooting game.I have a countdownTimer inside the label and an object that blinks in a random position inside the panel. Every time I click on the object,. the object's timer stops which makes that object stop too, but the countdown timer doesn't and that is my problem. I want the countdown timer should stop also.
Could someone help me about this matter?
Here's the code :
private void starting()
{
new Timer(TIMER_PERIOD, new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
if (count++ < MAX_COUNT)
{
String text = "Time remaining: (" + (MAX_COUNT - count) + ") seconds left";
setCountDownLabelText(text);
Date date = new Date();
setCountDownPanelText(date);
}
else
{
((Timer) e.getSource()).stop();
randomTimer.stop();
JOptionPane.showMessageDialog(null, "Game Over");
System.exit(0);
}
}
}).start();
}
It strikes me that you don't understand the code at all, that you are unaware of the anonymous class created that is extending Timer, which (if you'd seen the documentation) has a function stop() which does what you ask.
You need to store a reference to the Timer.
private javax.swing.Timer timer;
private void starting() {
timer = new Timer(TIMER_PERIOD, new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
// do stuff
// stop the timer
timer.stop();
// do other stuff
}
}
}

Categories

Resources