I have a JTextField that is cleared if it has invalid content. I would like the background to flash red one or two times to indicate to the user that this has happened. I have tried:
field.setBackground(Color.RED);
field.setBackground(Color.WHITE);
But it is red for such a brief time that it cannot possibly be seen. Any tips?
The correct solution, almost arrive at by just eric, is to use a Swing Timer, since all the code in the Timer's ActionListener will be called on the Swing event thread, and this can prevent intermittent and frustrating errors from occurring. For example:
public void flashMyField(final JTextField field, Color flashColor,
final int timerDelay, int totalTime) {
final int totalCount = totalTime / timerDelay;
javax.swing.Timer timer = new javax.swing.Timer(timerDelay, new ActionListener(){
int count = 0;
public void actionPerformed(ActionEvent evt) {
if (count % 2 == 0) {
field.setBackground(flashColor);
} else {
field.setBackground(null);
if (count >= totalCount) {
((Timer)evt.getSource()).stop();
}
}
count++;
}
});
timer.start();
}
And it would be called via flashMyField(someTextField, Color.RED, 500, 2000);
Caveat: code has been neither compiled nor tested.
You need to extend public class Timer
Do it like so:
private class FlashTask extends TimerTask{
public void run(){
// set colors here
}
}
You can set Timer to execute in whatever intervals you prefer to create the flashing effect
From documentation:
public void scheduleAtFixedRate(TimerTask task, long delay, long period)
Schedules the specified task for repeated fixed-rate execution, beginning after the specified delay.
Related
I'm trying to make a class called timer. The timer class is supposed to be called upon when my character enters the enemy's area. And the timer class is supposed to remove the characters health by 10-health points every 5 seconds. Ive tried multiple different timers but i cant seem to get any of them right. When i tried it removed health but it didn't do it only once, it kept repeating it until the health bar was out of the screen. here is my code:
class Timer {
g = new gubbe();
gubbe g;
Timer timer = new Timer(3000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
g.RemoveHealth();
}
});
timer.setRepeats(false);
timer.start();
}
That is what I've come up with so far.
If any more code is needed just ask.
Here's a class which you can use to time your events:
class Delay {
protected int limit;
public Delay() {limit = millis();}
public Delay (int l) {
limit = millis() + l;
}
public boolean expired () {
if (millis() > limit) { return true; }
return false;
}
}
To check on something every 5 seconds, you would have to initialize it like this:
Delay _delay;
void setup() {
_delay = new Delay(5000);
}
void draw() {
if (_delay.expired()) {
//do something
_delay = new Delay(5000);
}
}
The 5000 is in milliseconds, so it means 5 seconds. If you want to check for a 1 second delay, it would be 1000 instead. We re-initialize it when the delay is finished so it triggers again in 5 more seconds.
Have fun!
I want to create a program that when a button is clicked, a panel may or may not change it's color. I have an array of panels that will turn red if a wrong combination is chosen. But I just want to make it red for about 1-2 seconds. After that I will change again the panel background to null. I want every panel to have it's own timer when it goes red. So far here is my code:
javax.swing.Timer timer = new javax.swing.Timer (250, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
pnlArray [count - 2][count2].setBackground (Color.RED);
};
});
pnlArray [count - 2][count2].setBackground (null);
This code generates an error: local variables referenced from an inner class must be final or effectively final. Obviously, pnlArray[][] is not a final panel. Thread.sleep() method however, freezes the whole program. How can I achieve this?
I found a solution to my question using java.util.Timer package. Since the Timer() class needs final to run the run() method, I assigned the JPanel to a final variable. Then I canceled the timer once the first delay is over.
final JPanel pnlChange = pnlArray [count - 2][count2];
pnlChange.setBackground (Color.RED);
java.util.Timer timer = new java.util.Timer ();
TimerTask task = new TimerTask () {
int seconds = 4;
int divisor = 0;
#Override
public void run() {
divisor++;
if (divisor % seconds == 0) {
timer.cancel ();
pnlChange.setBackground (null);
}
}
};
timer.schedule(task, 0, 1000);
I made a blackjack game, and I want the AI player to pause between taking cards. I tried simply using Thread.sleep(x), but that makes it freeze until the AI player is done taking all of his cards. I know that Swing is not thread safe, so I looked at Timers, but I could not understand how I could use one for this. Here is my current code:
while (JB.total < 21) {
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
System.out.println("Oh noes!");
}
switch (getJBTable(JB.total, JB.aces > 0)) {
case 0:
JB.hit();
break;
case 1:
break done;
case 2:
JB.hit();
JB.bet *= 2;
break done;
}
}
BTW, the hit(); method updates the GUI.
so I looked at Timers, but I could not understand how I could use one for this
The Timer is the solution, since as you say you are updating the GUI which should be done on the EDT.
I'm not sure what your concern is. You deal a card and start the Timer. When the Timer fires you decide to take another card or hold. When you hold your stop the Timer.
Well, the following code shows a JFrame with a JTextArea and a JButton. When the buttons is clicked, the Timer send the event repeatedly (with a second delay between them) to the actionListener related to the button which appends a line with the current time.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.Timer;
public class TimerTest extends JFrame implements ActionListener{
private static final long serialVersionUID = 7416567620110237028L;
JTextArea area;
Timer timer;
int count; // Counts the number of sendings done by the timer
boolean running; // Indicates if the timer is started (true) or stopped (false)
public TimerTest() {
super("Test");
setBounds(30,30,500,500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(null);
area = new JTextArea();
area.setBounds(0, 0, 500, 400);
add(area);
JButton button = new JButton("Click Me!");
button.addActionListener(this);
button.setBounds(200, 400, 100, 40);
add(button);
// Initialization of the timer. 1 second delay and this class as ActionListener
timer = new Timer(1000, this);
timer.setRepeats(true); // Send events until someone stops it
count = 0; // in the beginning, 0 events sended by timer
running = false;
System.out.println(timer.isRepeats());
setVisible(true); // Shows the frame
}
public void actionPerformed(ActionEvent e) {
if (! running) {
timer.start();
running = true;
}
// Writing the current time and increasing the cont times
area.append(Calendar.getInstance().getTime().toString()+"\n");
count++;
if (count == 10) {
timer.stop();
count = 0;
running = false;
}
}
public static void main(String[] args) {
// Executing the frame with its Timer
new TimerTest();
}
}
Well, this code is a sample of how to use javax.swig.Timer objects. In relation with the particular case of the question. The if statement to stop the timer must change, and, obviously, the actions of the actionPerformed. The following fragment is a skeleton of the solution actionPerformed:
public void actionPerformed(ActionEvent e) {
if (e.getComponent() == myDealerComponent()) {
// I do this if statement because the actionPerformed can treat more components
if (! running) {
timer.start();
runnig = true;
}
// Hit a card if it must be hitted
switch (getJBTable(JB.total, JB.aces > 0)) {
case 0:
JB.hit();
break;
case 1:
break done;
case 2:
JB.hit();
JB.bet *= 2;
break done;
}
if (JB.total >= 21) { // In this case we don't need count the number of times, only check the JB.total 21 reached
timer.stop()
running = false;
}
}
}
IMHO this resolves the problem, now #user920769 must think where put the actionListener and the starting/stopping conditions...
#kleopatra: Thanks for show me the existence of this timer class, I don't know nothing about it and it's amazing, make possible a lot of tasked things into a swing application :)
Well, a quick explanation about Timers.
First of all, you need a java.util.Timer variable in your class and another class in your project which extends from java.util.TimerTask (let's call it Tasker).
The initialization of the Timer variable is so easy:
Timer timer = new Timer();
Now the Tasker class:
public class Tasker extends TimerTask {
#Override
public void run() {
actionToDo(); // For example take cards
}
// More functions if they are needed
}
Finally, the installation of the timer with its related Tasker:
long delay = 0L;
long period = pauseTime;
timer.schedule(new Tasker(),delay,period);
The schedule function indicates the following:
Fisrt param: Action to do each period milliseconds (Executes the run function of a TimerTask class or its extension)
Second param: When the timer must start. In this case, it starts when the schedule function is called. The following example indicates a starting 1 second after call the schedule function: timer.schedule(new Tasker(),1000,period);
Third param: milliseconds between one call of Tasker.run() function and the following call.
I hope you understand this microtutorial :). If you have any problem, ask for more detailed information!
Kind regards!
I think that in this tutorial is clear how to use Timers in order to achieve what you want, without having to deal with Threads.
I'm trying to turn on the timer using mouseEntered event with MouseListener it doesn't seem to work. Am i doing somthing wrong? I'm new to Java. Thanks in advance!
int counter = 0;
Timer timer = new Timer(1000,this);
public void mouseEntered(e MouseEvent)
{
if(e.getComponent == mouseEnteredArea)
{
timer.start()
counter++;
if(counter == 10)
{
timer.stop();
}
}
}
What's happening is when the mouse enters the area, your code starts the timer, adds one to counter (so counter == 1), checks if counter is equal to 10. Since it isn't, the code then skips the if statement and exits the method.
It's difficult to tell your actual intentions from that question, so if that wasn't enough to help, please explain what you're trying to do.
I think you may not understand how the timer works. Basically the timer has an ActionListener. Every 1000 milliseconds (in your case), the actionPerformed will be called. So I believe the code you have above should be in the ActionListener, and just call timer.start() in the mouse method. Something like.
Timer timer = new Timer(1000, new ActionListener(){
private int counter = 0;
#Override
public void actionPerformed(ActionEvent e) {
if (counter == 10) {
((Timer)e.getSource()).stop();
counter = 0;
} else {
System.out.println("Count: " + (++counter));
}
}
});
....
#Override
public void mouseEntered(MouseEvent e) {
timer.start();
}
Resources
How to Use Swing Timers
How to Write a Mouse Listener
I want to create a countdown clock in GWT but I cannot find the right function that waits for one second. I tried with Thread.Sleep() but I think it is for another purpose.
Can you help me? This is my code.
int count=45;
RootPanel.get("countdownLabelContainer").add(countdown);
for(int i=count; i>=0; i--)
{
countdown.setText(Integer.toString(i));
// Place here the wait-for-one-second function
}
Give Timer a try (See Here).
Changing the example code real quick to something close to what you want, you'll want to buff this up for your purposes though:
public class TimerExample implements EntryPoint, ClickListener {
int count = 45;
public void onModuleLoad() {
Button b = new Button("Click to start Clock Updating");
b.addClickListener(this);
RootPanel.get().add(b);
}
public void onClick(Widget sender) {
// Create a new timer that updates the countdown every second.
Timer t = new Timer() {
public void run() {
countdown.setText(Integer.toString(count));
count--;
}
};
// Schedule the timer to run once every second, 1000 ms.
t.schedule(1000);
}
}
This sounds like something in the general area of what your looking for. Note that you can use timer.cancel() to stop the timer. You'll want to tie this in with your count (when 45 hits 0).
The following snippet showing the use of the timer works too. It shows how to schedule the timer properly and how to cancel it.
// Create a new timer that updates the countdown every second.
Timer t = new Timer() {
int count = 60; //60 seconds
public void run() {
countdown.setText("Time remaining: " + Integer.toString(count) + "s.");
count--;
if(count==0) {
countdown.setText("Time is up!");
this.cancel(); //cancel the timer -- important!
}
}
};
// Schedule the timer to run once every second, 1000 ms.
t.scheduleRepeating(1000); //scheduleRepeating(), not just schedule().