I need to make a slot machine that implements thread in java and jframe
this is what iv'e done so far kindly tell me what i need to do in order make the images change per .5 seconds when i press the the play and stop when i press stop. If all the three images are the same it'll say you won. This is what iv'e got so far how will i change this numbers or text to images in jlabel.
public class MySlotNumber extends JFrame{
private MyJLabel x;
private MyJLabel y;
private MyJLabel z;
private JButton btn;
public MySlotNumber(){
super("ABC");
setLayout(new FlowLayout());
Font font = new Font("arial",Font.ITALIC,50);
x = new MyJLabel();
x.setFont(font);
y = new MyJLabel();
y.setFont(font);
z = new MyJLabel();
z.setFont(font);
btn = new JButton("PLAY");
btn.setFont(font);
add(x);
add(y);
add(z);
add(btn);
final Thread thx = new Thread(x);
final Thread thy = new Thread(y);
final Thread thz = new Thread(z);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(e.getActionCommand().equals("PLAY")){
if(thx.isAlive()){
thx.resume();
thy.resume();
thz.resume();
} else {
thx.start();
thy.start();
thz.start();
}
btn.setText("STOP");
} else {
thx.suspend();
thy.suspend();
thz.suspend();
btn.setText("PLAY");
System.out.println(x.getText());
}
}
});
}
- - - - - - --
public class MyJLabel extends JLabel implements Runnable{
private Random r;
private int ctr;
private final int T = 500;
public MyJLabel(){
setText("0");
ctr = 0;
r= new Random();
}
#Override
public void run() {
while(true){
try {
Thread.sleep(T);
} catch (InterruptedException ex) {
Logger.getLogger(MyJLabel.class.getName()).log(Level.SEVERE, null, ex);
}
//ctr++;
ctr = r.nextInt(9)+1;
setText(String.valueOf(ctr));
}
}
}
Here is one way to put a picture on a JLabel and change it when you click a button. (I am using window builder for eclipse, so it may look a little odd.) It is not recommended you use absolute paths because when you move your project or the file, it breaks (I did this just for proof of concept).
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class Test {
private JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Test window = new Test();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public Test() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 1379, 643);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel lblNewLabel = new JLabel("");
lblNewLabel.setIcon(new ImageIcon("C:\\Users\\Andrew\\Pictures\\Random Pictures\\Capture.JPG"));
frame.getContentPane().add(lblNewLabel, BorderLayout.CENTER);
JButton btnClickMe = new JButton("click me");
btnClickMe.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
lblNewLabel.setIcon(new ImageIcon("C:\\Users\\Andrew\\Pictures\\Random Pictures\\I'm pretty sure he did.JPG"));
}
});
frame.getContentPane().add(btnClickMe, BorderLayout.EAST);
}
}
Related
I'm trying to make a GUI timer without using javax.swing.Timer(kind of a strange task), but I am having trouble making it work. It's supposed to sleep the thread for 1 second, add 1 to seconds, and repeat(infinitely). When I run my program, the icon shows up, but the window does not appear. I'm guessing my error is in the Thread.sleep(1000); line or in that area, but I'm not sure why it doesn't work. Is Thread.sleep(millis)not compatible with swing applications? Do I have to multithread? Here's my program:
import java.awt.*;
import javax.swing.*;
public class GUITimer extends JFrame {
private static final long serialVersionUID = 1L;
private int seconds = 0;
public GUITimer() {
initGUI();
pack();
setVisible(true);
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
private void initGUI(){
JLabel title = new JLabel("Timer");
Font titleFont = new Font(Font.SERIF, Font.BOLD, 32);
title.setFont(titleFont);
title.setHorizontalAlignment(JLabel.CENTER);
title.setBackground(Color.BLACK);
title.setForeground(Color.WHITE);
title.setOpaque(true);
add(title, BorderLayout.NORTH);
JLabel timeDisplay = new JLabel(Integer.toString(seconds));//this label shows seconds
add(timeDisplay, BorderLayout.CENTER);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
seconds++;
initGUI();
}
public static void main(String[] args) {
try {
String className = UIManager.getCrossPlatformLookAndFeelClassName();
UIManager.setLookAndFeel(className);
}
catch (Exception e) {}
EventQueue.invokeLater(new Runnable() {
public void run() {
new GUITimer();
}
});
}
}
EDIT:
I noticed when I print seconds in my method initGUI() to console, it prints them incrementally by one second correctly. So when it looks like:
private void initGUI() {
System.out.println(seconds);
//...
it prints the value of seconds after every second(How the JLabel should). This shows that my loop is working fine, and my Thread.sleep(1000) is OK also. My only problem now, is that the frame is not showing up.
Your main window does not appear, because you called infinite recursion inside constructor. GUITimer will not be created and this lock main thread.
You need use multithreading for this aim. Main thread for drawing time, second thread increment and put value to label
For example:
import javax.swing.*;
import java.awt.*;
public class GUITimer extends JFrame
{
private static final long serialVersionUID = 1L;
private int seconds = 0;
private Thread timerThread;
private JLabel timeDisplay;
public GUITimer()
{
initGUI();
pack();
setVisible(true);
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
private void initGUI()
{
JLabel title = new JLabel("Timer");
Font titleFont = new Font(Font.SERIF, Font.BOLD, 32);
title.setFont(titleFont);
title.setHorizontalAlignment(JLabel.CENTER);
title.setBackground(Color.BLACK);
title.setForeground(Color.WHITE);
title.setOpaque(true);
add(title, BorderLayout.NORTH);
timeDisplay = new JLabel(Integer.toString(seconds));//this label shows seconds
add(timeDisplay, BorderLayout.CENTER);
}
public void start()
{
seconds = 0;
timerThread = new Thread(new Runnable()
{
#Override
public void run()
{
while(true)
{
timeDisplay.setText(Integer.toString(seconds++));
try
{
Thread.sleep(1000L);
}
catch(InterruptedException e) {}
}
}
});
timerThread.start();
}
public void stop()
{
timerThread.interrupt();
}
public static void main(String[] args)
{
try
{
GUITimer timer = new GUITimer();
timer.start();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
The core issue is, you're blocking the UI by continuously calling initGUI, which will eventually fail with a StackOverFlowException, as the method calls never end
The preference would be to use a Swing Timer, but since you've stated you don't want to do that, a better solution would be to use a SwingWorker, the reason for this - Swing is NOT thread safe and SwingWorker provides a convenient mechanism for allowing us to update the UI safely.
Because both Swing Timer and Thead.sleep only guarantee a minimum delay, they are not a reliable means for measuring the passage of time, it would be better to make use of Java 8's Date/Time API instead
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JLabel label = new JLabel("00:00:00");
private TimeWorker timeWorker;
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(label, gbc);
JButton button = new JButton("Start");
add(button, gbc);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (timeWorker == null) {
timeWorker = new TimeWorker(label);
timeWorker.execute();
button.setText("Stop");
} else {
timeWorker.cancel(true);
timeWorker = null;
button.setText("Start");
}
}
});
}
}
public class TimeWorker extends SwingWorker<Void, Duration> {
private JLabel label;
public TimeWorker(JLabel label) {
this.label = label;
}
#Override
protected Void doInBackground() throws Exception {
LocalDateTime startTime = LocalDateTime.now();
Duration totalDuration = Duration.ZERO;
while (!isCancelled()) {
LocalDateTime now = LocalDateTime.now();
Duration tickDuration = Duration.between(startTime, now);
publish(tickDuration);
Thread.sleep(500);
}
return null;
}
#Override
protected void process(List<Duration> chunks) {
Duration duration = chunks.get(chunks.size() - 1);
String text = format(duration);
label.setText(text);
}
public String format(Duration duration) {
long hours = duration.toHours();
duration = duration.minusHours(hours);
long minutes = duration.toMinutes();
duration = duration.minusMinutes(minutes);
long millis = duration.toMillis();
long seconds = (long)(millis / 1000.0);
return String.format("%02d:%02d:%02d", hours, minutes, seconds);
}
}
}
I'm trying to figure out this for ages, starting to wonder if it is possible!
I have a starting window for my app - I need it so that when I click on a button I have created, the window either closes and opens a new window or the window resizes and leaves just the canvas (ready to put new widgets, sprites etc... ).
I know I need a handler event for this but I just can't get the code to work.
Im not quite sure whats your question but i coded a example with a JFrame and 3 Buttons.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class OpenWindowAndResizeWindow
{
private JFrame frame;
private JButton btnOpenNewWindow;
private JButton btnResizeWindow;
private JButton btnRemoveAllButtons;
/**
* Launch the application.
*/
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
try
{
OpenWindowAndResizeWindow window = new OpenWindowAndResizeWindow();
window.frame.setVisible(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public OpenWindowAndResizeWindow()
{
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize()
{
frame = new JFrame();
frame.setBounds(100, 100, 300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(getBtnOpenNewWindow(), BorderLayout.NORTH);
frame.getContentPane().add(getBtnResizeWindow(), BorderLayout.SOUTH);
frame.getContentPane().add(getBtnRemoveAllButtons(), BorderLayout.CENTER);
frame.setVisible(true);
}
private void openNewWindow()
{
OpenWindowAndResizeWindow newWindow = new OpenWindowAndResizeWindow();
frame.dispose();
}
private void removeButtons()
{
getBtnOpenNewWindow().setVisible(false);
getBtnRemoveAllButtons().setVisible(false);
getBtnResizeWindow().setVisible(false);
}
private void resizeWindow()
{
Rectangle rectangle = frame.getBounds();
rectangle.width = (int)rectangle.getWidth() + 100;
rectangle.height = (int)rectangle.getHeight() + 100;
frame.setBounds(rectangle);
}
private JButton getBtnOpenNewWindow() {
if (btnOpenNewWindow == null) {
btnOpenNewWindow = new JButton("Open new Window");
btnOpenNewWindow.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
openNewWindow();
}
});
}
return btnOpenNewWindow;
}
private JButton getBtnResizeWindow() {
if (btnResizeWindow == null) {
btnResizeWindow = new JButton("Resize Window");
btnResizeWindow.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
resizeWindow();
}
});
}
return btnResizeWindow;
}
private JButton getBtnRemoveAllButtons() {
if (btnRemoveAllButtons == null) {
btnRemoveAllButtons = new JButton("Remove All Buttons");
btnRemoveAllButtons.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
removeButtons();
}
});
}
return btnRemoveAllButtons;
}
}
This code is ready to compile with javac or just paste it in your IDE.
Maybe this helps a bit. The Java SE API Documentation is useful too.
I am trying to make this work. I create a window, with one text field and button, then I run the run() method which should refresh text in textfield, and when I click on button it should iterate number by 1. I want to make this work simultaneously but I am stuck. It just iterates the number but do not refresh a value in textfield.Could you please help me somehow? I thought its easy to learn about Threads but...no :-D Here is the code.
Window class
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
#SuppressWarnings("serial")
public class Okno extends JFrame implements ActionListener,Runnable {
private JFrame o = new JFrame();
private static JTextField t = new JTextField();
private JTextField t2 = new JTextField();
private static int x = 0;
protected JButton b = new JButton("KLIK");
Okno() {
o.setVisible(true);
o.setBounds(0, 0, 300, 200);
o.setLayout(null);
o.setDefaultCloseOperation(EXIT_ON_CLOSE);
t.setBounds(10, 10, 60, 20);
t2.setBounds(80, 10, 60, 20);
b.setBounds(50, 80, 60, 30);
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
while (true) {
Okno.work();
System.out.println("Klik");
}
}
});
o.add(t);
o.add(b);
o.add(t2);
}
public static int iter(){
x++;
return x;
}
public static void work(){
try {
iter();
System.out.println(x);
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void actionPerformed(ActionEvent e) {
}
#Override
public void run() {
while(true){
try {
Thread.sleep(1200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t.setText(Integer.toString(x));
System.out.println("RUN");
}
}
}
Main Class
public class ThreadDemo {
public static void main(String args[]) {
Okno o = new Okno();
while(true){
o.run();
}
}
}
Swing is single threaded. Calling Thread.sleep prevents UI updates. Use a Swing Timer instead.
From GETah's answer to java stopwatch that updates gui every second:
Something along these lines should do it:
import java.awt.EventQueue;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JLabel;
/** #see https://stackoverflow.com/a/11058263/230513 */
public class Clock {
private Timer timer = new Timer();
private JLabel timeLabel = new JLabel(" ", JLabel.CENTER);
public Clock() {
JFrame f = new JFrame("Seconds");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(timeLabel);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
timer.schedule(new UpdateUITask(), 0, 1000);
}
private class UpdateUITask extends TimerTask {
int nSeconds = 0;
#Override
public void run() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
timeLabel.setText(String.valueOf(nSeconds++));
}
});
}
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
final Clock clock = new Clock();
}
});
}
}
The timeLabel will always display the number of seconds the timer
has been running.
You will need to correctly format it to display "hh:mm:ss"; one approach is shown here.
Create a container and add the label to it so that you can display it as part of the GUI.
Compare the result to this alternate using javax.swing.Timer.
I have two Java(.java) files. One has a JButton and JTextField and the other has a Thread. In first Java file, I have added an ActionListener to the JButton so that, when the button is pressed, a thread (object for 2nd .java file in created and thread is initiated) runs which modifies an integer variable continuously. How to display the value of that integer variable (of 2nd .java file) in the JTextField (of 1st .java file) ?
Detection.java
package sample;
public class Detection implements Runnable
{
public String viewers;
public int count;
public void run()
{
try
{
while (true)
{
// i have written code for displaying video.
// and it say how many no. of people in the video
// the no of people is stored in a variable "count"
viewers=""+count; //storing count as string so as to display in the JTextField
}
}
catch (Exception e)
{
System.out.println("Exception: "+e);
}
}
}
UsrInterfac.java
//build using WindowBuilder eclipse juno
package sample;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JTextField;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class UsrInterfac
{
private JFrame frame;
private JTextField textField;
Detection dd = new Detection();
Thread th = new Thread(dd);
/**
* Launch the application.
*/
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
try
{
UsrInterfac window = new UsrInterfac();
window.frame.setVisible(true);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public UsrInterfac()
{
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize()
{
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
JButton btnStartThread = new JButton("Start Thread");
btnStartThread.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
th.start();
}
});
btnStartThread.setBounds(59, 133, 117, 23);
frame.getContentPane().add(btnStartThread);
textField = new JTextField();
textField.setBounds(270, 134, 104, 20);
frame.getContentPane().add(textField);
textField.setColumns(10);
}
}
Starting from the basics, while using Swing, it is always best to use LayoutManagers, which can make your work much more easier, in comparison to using Absolute Positioning.
Whenever one needs to change something in the View from some another thread, it is always advisable to do that using EventQueue.invokeLater(...)/EventQueue.invokeAndWait(...).
This small sample program, might be able to help you get an idea, how to accomplish what you so desire :-)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ThreadCounter
{
private CustomThread cThread;
private JTextField tField;
private JButton button;
private int counter;
public ThreadCounter()
{
counter = 0;
}
private void displayGUI()
{
JFrame frame = new JFrame("Thread Counter Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
tField = new JTextField(10);
tField.setText("0");
button = new JButton("Start");
button.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent ae)
{
if (counter == 0)
{
cThread = new CustomThread(tField);
cThread.setFlagValue(true);
cThread.start();
counter = 1;
button.setText("Stop");
}
else
{
try
{
cThread.setFlagValue(false);
cThread.join();
}
catch(InterruptedException ie)
{
ie.printStackTrace();
}
counter = 0;
button.setText("Start");
}
}
});
contentPane.add(tField);
contentPane.add(button);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
new ThreadCounter().displayGUI();
}
});
}
}
class CustomThread extends Thread
{
private int changingVariable;
private JTextField tField;
private boolean flag = true;
public CustomThread(JTextField tf)
{
changingVariable = 0;
tField = tf;
}
public void setFlagValue(boolean flag)
{
this.flag = flag;
}
#Override
public void run()
{
while (flag)
{
EventQueue.invokeLater(new Runnable()
{
#Override
public void run()
{
tField.setText(
Integer.toString(
++changingVariable));
}
});
try
{
Thread.sleep(1000);
}
catch(InterruptedException ie)
{
ie.printStackTrace();
}
}
System.out.println("I am OUT of WHILE");
}
}
Ideally you should post your code. Anyway, when you are calling the thread code, either pass the instance of the first class (object) or an instance of JTextField, so that the thread can set the new value in the text field.
I'm trying to get a SwingWorker to work.
I've the following code at the moment:
public class ImageWorker extends SwingWorker<Void, Void> implements KeyListener
{
private JLabel imageLabel;
private ImageIcon basicImage;
private ImageIcon whiteImage;
public static void main(String[] args)
{
new ImageWorker();
}
public ImageWorker()
{
final JFrame frame = new JFrame();
imageLabel = new JLabel();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.getContentPane().add(imageLabel);
frame.setVisible(true);
try
{
basicImage = new ImageIcon(ImageIO.read(new File("src\\img\\basis1.jpg")).getScaledInstance(1024, 768, Image.SCALE_SMOOTH));
whiteImage = new ImageIcon(ImageIO.read(new File("src\\img\\wit.jpg")).getScaledInstance(1024, 768, Image.SCALE_SMOOTH));
}
catch(IOException ex)
{
ex.getMessage();
}
this.execute();
}
#Override
protected Void doInBackground()
{
try
{
while (true)
{
displayImage(basicImage);
Thread.sleep(1000L);
if(isCancelled())
return null;
}
}
catch(InterruptedException e)
{
e.getMessage();
}
return null;
}
private void displayImage(final Icon image)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
imageLabel.setIcon(image);
}
});
}
I was expecting the images to appear in the JLabel, but I only see the JFrame popping up. The files are loaded correctly Ive tested that in another setup.
Any pointers?
Here is an example using a Timer rather than using the SwingWorker which really isn't appropriate to your situation. Note that it's not too different from your existing code.
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;
public class ImageWorker implements KeyListener
{
private JLabel imageLabel;
private ImageIcon basicImage;
private ImageIcon whiteImage;
private boolean isBasic = true;
private int delay = 1000; //milliseconds
private Timer timer;
public static void main(String[] args)
{
new ImageWorker();
}
public ImageWorker()
{
final JFrame frame = new JFrame();
imageLabel = new JLabel();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.getContentPane().add(imageLabel);
frame.setVisible(true);
try
{
basicImage = new ImageIcon(ImageIO.read(new File("src\\img\\basis1.jpg")).getScaledInstance(1024, 768, Image.SCALE_SMOOTH));
whiteImage = new ImageIcon(ImageIO.read(new File("src\\img\\wit.jpg")).getScaledInstance(1024, 768, Image.SCALE_SMOOTH));
}
catch (IOException ex)
{
ex.getMessage();
ex.printStackTrace();
}
frame.addKeyListener(this);
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if(isBasic) {
//display basic image
imageLabel.setIcon(basicImage);
}
else {
//display white image
imageLabel.setIcon(whiteImage);
}
//toggle the flag
isBasic = !isBasic;
}
};
//use a timer instead of SwingWorker
timer = new Timer(delay, taskPerformer);
timer.start();
}
#Override
public void keyPressed(KeyEvent e)
{
//key pressed, we want to stop toggling so stop the timer
timer.stop();
//do whatever else you were doing to set the value for isCancelled();
}
#Override
public void keyReleased(KeyEvent e)
{
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e)
{
// TODO Auto-generated method stub
}
}
A SwingWorker is not appropriate for your situation look into a Timer in the swing package. Here is a link to the API: http://download.oracle.com/javase/6/docs/api/javax/swing/Timer.html
You have the timer run and change an image every second since that is what you need.
Also, whenever you have exceptions, print out a stacktrace or the message at least. Otherwise you won't know if an exception occurs and is caught.