Is there a way to easily convert thread.sleep to javax.swing.timer?
The reason why I would need to do this, is to stop the user-interface from freezing when you press a button, so that you can implement a pause button.
Code Example:
btnStartTiming.addMouseListener(new MouseAdapter() {
#Override
public void mouseReleased(MouseEvent arg0) {
try{
inputA = Double.parseDouble(txtEnterHowLong.getText()); //Changes double to string and receives input from user
}catch(NumberFormatException ex){
}
while (counter <= inputA){
txtCounter.setText(counter + "");
try {
Thread.sleep(1000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
System.out.println(counter);
counter++;
}
}
});
Some tips:
Take a look to How to use Swing
Timers
trail and come back with concrete problems. Describe what are you trying to accomplish and your work so far, show your attempts to solve the problem and make an answerable question.
Don't use MouseListener
to listen when a button is pressed. Use ActionListener
instead. Take a look to How to Use Buttons, Check Boxes, and Radio
Buttons trail.
Put the java.swing.Timer in your constructor. You can use the button to .start() the timer.
Also instead of the while, you can add an if statement in the timer code check when to .stop()
Something like this
int delay = 1000;
Timer timer = new Timer(delay, null);
public Constructor(){
timer = new Timer(delay, new ActionListener(){
public void actionPerformed(ActionEvent e) {
if (counter >= inputA) {
timer.stop();
} else {
// do something
}
}
});
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
timer.start();
}
});
}
Related
I have some labels that become visible when the letter a is pressed.
private void formKeyPressed(java.awt.event.KeyEvent evt) {
// TODO add your handling code here:
if(evt.getKeyCode()==KeyEvent.VK_A){
jLabel7.setVisible(true);
jLabel8.setVisible(true);
jLabel9.setVisible(true);
myBlink();
}
I have Label8 on a timer myBlink()
public void myBlink()
{
new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("begin");
jLabel8.setVisible(false);
jLabel8.setVisible(true);
System.out.println("Timer");
}
}).start();
}
I have placed printlns to see if timer begins and ends and when I press key "a" my output shows begin Timer multiple times but my label does not appear and disappear. What tweak does this code need? What am I missing? Thanks for the extra set of eyes.
This is probably because you call successively setVisible(false) and setVisible(true) which is done too fast to be seen, you should use a variable and modify its value any time the action of the Timer is called as next:
public void myBlink()
{
new Timer(1000, new ActionListener() {
boolean visible = true;
public void actionPerformed(ActionEvent e) {
jLabel8.setVisible(visible = !visible);
}
}).start();
}
I am trying to implement a Thread.sleep(6000) line but it seems to freeze in the applet. When I tried to use Timers, I wasn't sure how to use because I am not very good with event listeners. I am basically trying to call a method fetchUrl() every 6 seconds, after the user clicks the enter button. How can I implement this?
public void init() {
c = getContentPane();
c.setLayout(flow);
c.setBackground(forum);
question.setForeground(Color.white);
question.setFont(tnr);
question2.setForeground(Color.white);
question2.setFont(tnr);
result.setForeground(Color.white);
result.setFont(tnr);
resp.setBorder(BorderFactory.createBevelBorder(0));
timeLength.setBorder(BorderFactory.createBevelBorder(0));
c.add(question);
c.add(resp);
c.add(question2);
c.add(timeLength);
c.add(enter);
c.add(result);
resp.requestFocus();
enter.addActionListener(this);
t = new Timer(DELAY, this);
t.setInitialDelay(DELAY);
}
public void actionPerformed(ActionEvent e) {
final String n1;
int timeMin, timeSec, count = 0, maxCount;
timeMin = Integer.parseInt(timeLength.getText());
timeSec = timeMin * 60;
maxCount = (int)(timeSec/6);
if (e.getSource() == enter) { //user clicks enter
n1 = resp.getText();
while (count < maxCount) {
fetchUrl(n1); //this method called every 6 seconds
t.start();
count++;
}
}
}
First I would start by separating the ActionListener for the Timer and for the JButton.
Second nothing is happening logically with the Timer because you're swallowing it with the button source check.
Third you should understand how the timer works. Basically for every "tick" (in your case six seconds) the actionPerformed of the timer ActionListener is called. So if you want the fetch() method called, then that's what you should be visible/accessible to the in the Timer's actionPerformed.
The button's ActionListener should only handle the starting of the timer I believe. So just separate the listeners. Give each one an anonymous ActionListener and no need to make the class implement ActionListener.
For example
timer = new Timer(DELAY, new ActionListener(){
public void actionPerformed(ActionEvent e) {
// do some stuff every six seconds
fetchURL();
}
});
enter = new JButton(...);
enter.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
timer.start();
}
});
If you want some automatic stopping feature for the timer, you could do something like
timer = new Timer(DELAY, new ActionListener(){
public void actionPerformed(ActionEvent e) {
if (someStoppingCondition()) {
timer.stop();
} else {
// do some stuff every six seconds
fetchURL();
}
// do some stuff every six second
}
});
You need to call a method after user clicks on button every 6 seconds, but you have not said how many times you want to call it.
For infinite number of times, try something like the following,
while(true){
new Thread(){
#Override
public void run(){
try{
Thread.sleep(6000);
fetchUrl(n1);
}catch(InterruptedException e){}
}
}.start();
}
If you will use Thread.sleep() in your applet, then your applet will be hanged for 6 seconds and so create a new thread for it.
How can i change the background of a button to green when i press it , wait for one second and then return to default color background ?
thanks
for answering your question it would be useful to know, which kind of UI library you use? Swing, AWT, whatever?
Try this:
final JButton button = new JButton("MyButton");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
button.setBackground(Color.green);
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException err) {
}
button.setBackground(Color.blue);
}
});
Sleep 1 second
I have a jList called todoList
When the user click on an item in the list, it stays selected. But I would like the currently selected item in the list to deselect "by itself" after 400 milliseconds when the mouse exits the jList.
This must only run if there is something already selected in the list.
I am using Netbeans IDE and this is what is have tried so far:
private void todoListMouseExited(java.awt.event.MouseEvent evt) {
if (!todoList.isSelectionEmpty()) {
Thread thread = new Thread();
try {
thread.wait(400L);
todoList.clearSelection();
} catch (InterruptedException ex) {
System.out.println(ex);
}
}
}
and
private void todoListMouseExited(java.awt.event.MouseEvent evt) {
if (!todoList.isSelectionEmpty()) {
Thread thread= Thread.currentThread();
try {
thread.wait(400L);
todoList.clearSelection();
} catch (InterruptedException ex) {
System.out.println(ex);
}
}
}
These both just make everything stop working.
My though process was that i need to create a new Thread that will wait for 400 milliseconds and then run the clearSelection() method of the jList. This would happen every time the mouse exits the list and run only if there is something in the list that is already selected.
I hope I am explaining my problem thoroughly enough.
The problem is that you are blocking the AWT-Event-Thread.
The solution is to use a swing timer:
private void todoListMouseExited(java.awt.event.MouseEvent evt)
{
if (!todoList.isSelectionEmpty()) {
new Timer(400, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
todoList.clearSelection();
}
}).start();
}
}
The problem is that Object#wait is waiting(rather than sleeping) to be notified but this is not happening. Instead the timeout causing an InterruptedException bypassing the call to clearSelection.
Don't use raw Threads in Swing applications. Instead use a Swing Timer which was designed to interact with Swing components.
if (!todoList.isSelectionEmpty()) {
Timer timer = new Timer(400, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
todoList.clearSelection();
}
});
timer.setRepeats(false);
timer.start();
}
I have a save button in a JFrame ;on clicking save the 'save' text sets to 'saving....'; I need to set that text as 'saved' after a delay of 10 seconds.How is it possible in java?
Please help...
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
This is what i did...but this wont shows as 'saving' during that delayed time.
If you want to provide the user with visual feedback that something is going on (and maybe give some hint about the progress) then go for JProgressBar and SwingWorker (more details).
If on the other hand you want to have a situation, when user clicks the button and the task is supposed to run in the background (while the user does other things), then I would use the following approach:
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
button.setEnabled(false); // change text if you want
new SwingWorker<Void, Void>() {
#Override
protected Void doInBackground() throws Exception {
// Do the calculations
// Wait if you want
Thread.sleep(1000);
// Dont touch the UI
return null;
}
#Override
protected void done() {
try {
get();
} catch (Exception ignore) {
} finally {
button.setEnabled(true); // restore the text if needed
}
}
}.execute();
}
});
Finally, the initial solution that was using the Swing specific timer:
final JButton button = new JButton("Save");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Take somehow care of multiple clicks
button.setText("Saving...");
final Timer t = new Timer(10000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
button.setText("Saved");
}
});
t.setRepeats(false);
t.start();
}
});
This question & first 3 answers are heading down the wrong track.
Use a JProgressBar to show something is happening. Set it to indeterminate if the length of the task is not known, but presumably you know how much needs to be saved and how much is currently saved.
Don't block the EDT (Event Dispatch Thread) - the GUI will 'freeze' when that happens. Use a SwingWorker for long running tasks. See Concurrency in Swing for more details.
The best is to use a timer and its method execute with a delay : http://developer.apple.com/library/mac/documentation/java/reference/javase6_api/api/java/util/Timer.html#schedule(java.util.TimerTask, long). Use a timertask to wrap your runnable and that's it.