import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class slide extends JFrame
{
ImageIcon[] iconArray = new ImageIcon[25];
int iconIndex = 0;
JLabel label;
JPanel panel;
slide ()
{
panel = new JPanel();
label = new JLabel();
add(panel);
setTitle("Slide Show");
panel.add(label);
for(int i = 0; i < iconArray.length; i++)
{
iconArray[i] = new ImageIcon("C:/SlideShow/slide0.jpg");
}
Timer timer = new Timer(1000, new TimerListener());
timer.start();
}
private class TimerListener implements ActionListener
{
public void actionPerformed(ActionEvent actionEvent)
{
label.setIcon(iconArray[iconIndex]);
iconIndex++ ;
if(iconIndex == 25)
iconIndex = 0;
}
}
public static void main(String[] args)
{
slide frame = new slide();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(800, 600);
frame.setLocationRelativeTo(null);
}
}
Any idea how to make a slideshow to show pictures with different > > time intervals? For example 1 sec for the first picture, 200 ms for > > the next, 3 sec for the third and etc. > > > > many thanks for the help!!!
A Swing timer has at most two delays. You can set the initial delay and the interval delay.
A Thread gives you more control over how long you sleep between images.
Here's one way to develop a slide show viewer that allows you to set the delay for each image. I used 3 images from the Internet to test the viewer.
package com.ggl.testing;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Slideshow implements Runnable {
private JFrame frame;
private SSImage[] imageArray;
private SSShower showImages;
private SSViewer imageViewer;
public Slideshow() {
this.imageArray = new SSImage[3];
Image image0 = null;
Image image1 = null;
Image image2 = null;
try {
image0 = ImageIO.read(new URL(
"http://www.ericofon.com/collection/collection1.jpg"));
image1 = ImageIO
.read(new URL(
"http://magiclinks1.wikispaces.com/file/view"
+ "/collection11_lg.jpg/219833158/collection11_lg.jpg"));
image2 = ImageIO
.read(new URL(
"http://www.pokelol.com/wp-content/uploads/2011/12"
+ "/my_pokemon_collection_by_pa_paiya-d4iiuo5.jpg"));
} catch (IOException e) {
e.printStackTrace();
return;
}
imageArray[0] = new SSImage(image0, 4000L);
imageArray[1] = new SSImage(image1, 2500L);
imageArray[2] = new SSImage(image2, 1500L);
}
#Override
public void run() {
frame = new JFrame("Check Box Test");
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent event) {
exitProcedure();
}
});
imageViewer = new SSViewer(700, 700);
frame.add(imageViewer);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
showImages = new SSShower(imageArray, imageViewer);
new Thread(showImages).start();
}
private void exitProcedure() {
showImages.setRunning(false);
frame.dispose();
System.exit(0);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Slideshow());
}
public class SSImage {
private final long delay;
private final Image image;
public SSImage(Image image, long delay) {
this.image = image;
this.delay = delay;
}
public long getDelay() {
return delay;
}
public Image getImage() {
return image;
}
}
public class SSViewer extends JPanel {
private static final long serialVersionUID = -7893539139464582702L;
private Image image;
public SSViewer(int width, int height) {
this.setPreferredSize(new Dimension(width, height));
}
public void setImage(Image image) {
this.image = image;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, (this.getWidth() - image.getWidth(this)) / 2,
(this.getHeight() - image.getHeight(this)) / 2, this);
}
}
public class SSShower implements Runnable {
private int counter;
private volatile boolean running;
private SSViewer ssviewer;
private SSImage[] imageArray;
public SSShower(SSImage[] imageArray, SSViewer ssviewer) {
this.imageArray = imageArray;
this.ssviewer = ssviewer;
this.counter = 0;
this.running = true;
}
#Override
public void run() {
while (running) {
SSImage ssimage = imageArray[counter];
ssviewer.setImage(ssimage.getImage());
repaint();
sleep(ssimage.getDelay());
counter = ++counter % imageArray.length;
}
}
private void repaint() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ssviewer.repaint();
}
});
}
private void sleep(long delay) {
try {
Thread.sleep(delay);
} catch (InterruptedException e) {
}
}
public synchronized void setRunning(boolean running) {
this.running = running;
}
}
}
Related
I am trying to make elements of an array to be displayed in different locations with random time periods (with fade in and fade out effect).
What i ve done so far, made an array of text labels. Made transitions. But i can't figure out, how to create a for loop that will display other labels in different locations on JFrame. And they should not appear all at the same time but one after another.
Please, help out?
Here is my code:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class FadingLabel {
private int alpha = 255;
private int increment = -5;
public JLabel label = new JLabel("Fading Label");
public JLabel label2 = new JLabel("Fading Label 2");
public JLabel label3 = new JLabel("Fading Label 3");
public JLabel label4 = new JLabel("Fading Label 4");
JLabel labels[] = new JLabel[]{ label, label2, label3 };
Dimension size = label.getPreferredSize();
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new FadingLabel().makeUI();
}
});
}
public void makeUI() {
new Timer(80, new ActionListener() {
public void actionPerformed(ActionEvent e) {
for (int i = 0; i <= 3; i++){
alpha += increment;
if (alpha >= 255) {
alpha = 255;
increment = -increment;
}
if (alpha <= 0) {
try {
Thread.sleep(100);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
alpha = 0;
increment = -increment;
}
label3.setForeground(new Color(0, 0, 0, alpha));
label3.setLocation(50,60);
}
}
}).start();
JFrame frame = new JFrame();
frame.add(labels[2]);
frame.setPreferredSize(new Dimension(700,500));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Animation is hard, good animation is harder.
A stepped animation (like you've done) is not particularly efficient and can suffer from interruptions (from the OS or other parts of the system) and can be difficult to scale.
Instead, you should aim for a "duration" based animation. Where something happens over a given period of time, this way, you can more easily drop frames you can't render.
One of the difficult concepts to get around is the idea that you can't perform long running or blocking operations in the "main thread" of the GUI, but neither can you update UI from outside of the "main thread" (in Swing this is known as the Event Dispatching Thread).
So, instead, you need some way monitor each label and as it fades out, start the next label fading in. This is where a good observer pattern (AKA listener) comes in.
import java.awt.AlphaComposite;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
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.Instant;
import java.util.EventListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.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 FadableLabel[] labels = new FadableLabel[]{
new FadableLabel("A long time ago"),
new FadableLabel("in a galaxy far, far, away..."),
new FadableLabel("It is a period of civil war."),
new FadableLabel("Rebel spaceships striking from a hidden base,"),
new FadableLabel("have won their first victory against the evil Galactic Empire"),
new FadableLabel("During the battle,"),
new FadableLabel("Rebel spies managed to steal secret plans to the Empire's ultimate weapon,"),
new FadableLabel("the Death Star")
};
private int labelIndex = -1;
public TestPane() {
setBorder(new EmptyBorder(50, 50, 50, 50));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
for (FadableLabel label : labels) {
label.setAlpha(0);
add(label, gbc);
}
}
#Override
public void addNotify() {
super.addNotify();
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
nextLabel();
}
});
}
#Override
public void removeNotify() {
super.removeNotify();
}
protected void nextLabel() {
labelIndex++;
if (labelIndex >= labels.length) {
return;
}
FadableLabel label = labels[labelIndex];
label.addFadableLableListener(new FadableLableListener() {
#Override
public void didFadeLabelIn(FadableLabel label) {
Timer timer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
label.fadeOut();
}
});
timer.setRepeats(false);
timer.start();
}
#Override
public void didFadeLabelOut(FadableLabel label) {
label.removeFadableLableListener(this);
nextLabel();
}
});
label.fadeIn();
}
}
public interface FadableLableListener extends EventListener {
public void didFadeLabelIn(FadableLabel label);
public void didFadeLabelOut(FadableLabel label);
}
public class FadableLabel extends JLabel {
private float alpha = 1.0f;
private Timer fadeTimer;
private FadeRange fadeRange;
private Instant fadeStartedAt;
private Duration desiredFadeTime = Duration.ofMillis(1000);
public FadableLabel() {
super();
}
public FadableLabel(String text) {
super(text);
}
public void addFadableLableListener(FadableLableListener listener) {
listenerList.add(FadableLableListener.class, listener);
}
public void removeFadableLableListener(FadableLableListener listener) {
listenerList.remove(FadableLableListener.class, listener);
}
public float getAlpha() {
return alpha;
}
public void setAlpha(float alpha) {
this.alpha = alpha;
repaint();
}
protected void fireDidFadeOut() {
FadableLableListener[] listeners = listenerList.getListeners(FadableLableListener.class);
if (listeners.length == 0) {
return;
}
for (FadableLableListener listener : listeners) {
listener.didFadeLabelOut(this);
}
}
protected void fireDidFadeIn() {
FadableLableListener[] listeners = listenerList.getListeners(FadableLableListener.class);
if (listeners.length == 0) {
return;
}
for (FadableLableListener listener : listeners) {
listener.didFadeLabelIn(this);
}
}
protected void stopFadeTimer() {
if (fadeTimer != null) {
fadeStartedAt = null;
fadeTimer.stop();
}
}
protected void startFadeTimer() {
if (fadeRange == null) {
throw new RuntimeException("Fade range can not be null when starting animation");
}
fadeStartedAt = Instant.now();
fadeTimer = new Timer(5, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Duration runTime = Duration.between(fadeStartedAt, Instant.now());
double progress = Math.min(1d, Math.max(0d, runTime.toMillis() / (double) desiredFadeTime.toMillis()));
setAlpha(fadeRange.valueAt(progress));
if (progress >= 1.0) {
stopFadeTimer();
if (getAlpha() >= 1.0) {
fireDidFadeIn();
} else {
fireDidFadeOut();
}
}
}
});
fadeTimer.start();
}
public void fadeIn() {
stopFadeTimer();
if (alpha < 1.0) {
fadeRange = new FadeRange(alpha, 1.0f);
startFadeTimer();
}
}
public void fadeOut() {
stopFadeTimer();
if (alpha > 0.0) {
fadeRange = new FadeRange(alpha, 0);
startFadeTimer();
}
}
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(alpha));
super.paintComponent(g2d);
g2d.dispose();
}
protected class FadeRange {
private float from;
private float to;
public FadeRange(float from, float to) {
this.from = from;
this.to = to;
}
public float getFrom() {
return from;
}
public float getTo() {
return to;
}
public float getDistance() {
return getTo() - getFrom();
}
public float valueAt(double progress) {
double distance = getDistance();
double value = distance * progress;
value += getFrom();
return (float) value;
}
}
}
}
Now, to your next problem. A poor approach might be to use an "absolute" or "null" layout
A better choice would be to either make use of something like GridBagLayout (and possibly EmptyLayout) and randomise the Insets of the GridBagConstraints. Alternatively, you could create your own layout manager to do the job for you
See Absolute Positioning Graphic JPanel Inside JFrame Blocked by Blank Sections and Moving JPasswordField to absolute position for some ideas
A cray example
When I say animation is "hard" and it can become complicated very fast, I'm not kidding. To that I end I wrote myself an animation library, which does all the things I keep finding myself doing.
https://github.com/RustyKnight/SuperSimpleSwingAnimationFramework
So, this is an example, based on the above library, which moves the label across a random range, while it's been faded in/out. Without the above library, this kind of work would be, a lot.
import java.awt.AlphaComposite;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import java.util.EventListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import org.kaizen.animation.Animatable;
import org.kaizen.animation.AnimatableAdapter;
import org.kaizen.animation.DefaultAnimatableDuration;
import org.kaizen.animation.curves.AnimationCurve;
import org.kaizen.animation.curves.Curves;
import org.kaizen.animation.ranges.AnimatableRange;
import org.kaizen.animation.ranges.FloatAnimatableRange;
import org.kaizen.animation.ranges.FloatRange;
import org.kaizen.animation.ranges.PointAnimatableRange;
import org.kaizen.animation.ranges.PointRange;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.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 String[] textValues = new String[] {
"A long time ago",
"in a galaxy far, far, away...",
"It is a period of civil war.",
"Rebel spaceships striking from a hidden base,",
"have won their first victory against the evil Galactic Empire",
"During the battle,",
"Rebel spies managed to steal secret plans to the Empire's ultimate weapon,",
"the Death Star"
};
private int labelIndex = -1;
// You'd need two if you wanted to do cross fades
private FadableLabel label;
private Random rnd = new Random();
// The desired duration of the animation, 1 second for fade in,
// 1 second for fade out and 1 second for delay between swicthing state
private Duration desiredDuration = Duration.ofSeconds(3);
// The desired animation curve (ease in/out)
private AnimationCurve curve = Curves.SINE_IN_OUT.getCurve();
// The movement animator
private DefaultAnimatableDuration animator;
public TestPane() {
setLayout(null);
label = new FadableLabel();
label.setAlpha(0);
add(label);
label.addFadableLableListener(new FadableLableListener() {
#Override
public void didFadeLabelIn(FadableLabel label) {
Timer timer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
label.fadeOut();
}
});
timer.setRepeats(false);
timer.start();
}
#Override
public void didFadeLabelOut(FadableLabel label) {
nextText();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 400);
}
#Override
public void addNotify() {
super.addNotify();
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
nextText();
}
});
}
#Override
public void removeNotify() {
stopAnimation();
super.removeNotify();
}
protected void stopAnimation() {
if (animator != null) {
animator.stop();
}
}
protected void nextText() {
stopAnimation();
labelIndex++;
if (labelIndex >= textValues.length) {
return;
}
String text = textValues[labelIndex];
label.setText(text);
label.setSize(label.getPreferredSize());
// Randomise the from and to locations
Point from = new Point(rnd.nextInt(getWidth() - label.getSize().width), rnd.nextInt(getHeight() - label.getSize().height));
Point to = new Point(rnd.nextInt(getWidth() - label.getSize().width), rnd.nextInt(getHeight() - label.getSize().height));
// Generate the range
PointRange range = new PointRange(from, to);
// Setup an animatable range of the PointRange
animator = new PointAnimatableRange(range, desiredDuration, curve, new AnimatableAdapter<Point>() {
#Override
public void animationChanged(AnimatableRange<Point> animatable) {
label.setLocation(animatable.getValue());
}
});
label.setLocation(from);
// Make it so
label.fadeIn();
animator.start();
}
}
public interface FadableLableListener extends EventListener {
public void didFadeLabelIn(FadableLabel label);
public void didFadeLabelOut(FadableLabel label);
}
public class FadableLabel extends JLabel {
private FloatAnimatableRange animator;
private AnimationCurve curve = Curves.SINE_IN_OUT.getCurve();
private Duration desiredDuration = Duration.ofSeconds(1);
private float alpha = 1.0f;
public FadableLabel() {
super();
}
public FadableLabel(String text) {
super(text);
}
public void addFadableLableListener(FadableLableListener listener) {
listenerList.add(FadableLableListener.class, listener);
}
public void removeFadableLableListener(FadableLableListener listener) {
listenerList.remove(FadableLableListener.class, listener);
}
public float getAlpha() {
return alpha;
}
public void setAlpha(float alpha) {
this.alpha = alpha;
repaint();
}
protected void fireDidFadeOut() {
FadableLableListener[] listeners = listenerList.getListeners(FadableLableListener.class);
if (listeners.length == 0) {
return;
}
for (FadableLableListener listener : listeners) {
listener.didFadeLabelOut(this);
}
}
protected void fireDidFadeIn() {
FadableLableListener[] listeners = listenerList.getListeners(FadableLableListener.class);
if (listeners.length == 0) {
return;
}
for (FadableLableListener listener : listeners) {
listener.didFadeLabelIn(this);
}
}
protected void stopFadeTimer() {
if (animator != null) {
animator.stop();
}
}
protected void startFadeTimer(FloatRange range, AnimationListener animationListener) {
stopFadeTimer();
animator = new FloatAnimatableRange(range, desiredDuration, curve, new AnimatableAdapter<Float>() {
#Override
public void animationChanged(AnimatableRange<Float> animatable) {
alpha = animatable.getValue();
repaint();
}
#Override
public void animationCompleted(Animatable animator) {
if (animationListener != null) {
animationListener.animationCompleted();
}
}
});
animator.start();
}
public void fadeIn() {
stopFadeTimer();
startFadeTimer(new FloatRange(alpha, 1f), new AnimationListener() {
#Override
public void animationCompleted() {
fireDidFadeIn();
}
});
}
public void fadeOut() {
stopFadeTimer();
startFadeTimer(new FloatRange(alpha, 0f), new AnimationListener() {
#Override
public void animationCompleted() {
fireDidFadeOut();
}
});
}
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(alpha));
super.paintComponent(g2d);
g2d.dispose();
}
protected interface AnimationListener {
public void animationCompleted();
}
}
}
The library is based on Netbeans, it wouldn't be hard to just extract the source into some other IDE.
Swing based "perform after delay"
made up silly solution, #MadProgrammer. added Thread.sleep(ms); in removeFadeableLabelListener. it works but i believe there is much brighter and smart solution. could you show please how to use delay timer for such task?
Don't, ever, use Thread.sleep from within the Event Dispatching Thread. This is going to cause a cascade of issues which will basically make you program look like it's frozen (because, essentially, it is)
Instead, you need to become familiar with the mechanisms you have available to you via the API. You could use a SwingWorker, but a simpler solution might be to just use a non-repeating Swing Timer, which is demonstrated above.
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.Duration;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.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 {
public TestPane() {
JButton btn = new JButton("Click me");
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
btn.setText("...");
SwingHelper.after(Duration.ofSeconds(1), new Runnable() {
#Override
public void run() {
btn.setEnabled(false);
btn.setText("Don't do that");
}
});
}
});
setBorder(new EmptyBorder(10, 10, 10, 10));
setLayout(new GridBagLayout());
add(btn);
}
}
public class SwingHelper {
public static void after(Duration duration, Runnable runnable) {
Timer timer = new Timer((int)duration.toMillis(), new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
runnable.run();
}
});
timer.setRepeats(false);
timer.start();
}
}
}
I've been trying to create separate classes, 1 with methods, 1 with the main App and 1 with graphics.
But I keep getting this error "Exception in thread "main" java.lang.StackOverflowError" How can I solve this problem?
public class App {
public static void main(String[] args) {
Stopwatch sw = new Stopwatch();
sw.setVisible();
}
}
This is the frame class
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
#SuppressWarnings("serial")
public class Stopwatch {
Frame123 f = new Frame123 ();
private static final String imgIcon = "data/icon.png";
private static final int WIDTH = 300;
private static final int HEIGHT = 150;
private final JTextField fieldTime;
private final JButton buttonPlay;
private final JButton buttonPause;
private final Action actionPlay;
private final Action actionPause;
private final Action actionReset;
private final JFrame frame;
private final Runnable ticker = new Runnable() {
public void run() {
f.tick();
}
};
public JButton getButtonPlay() {
return buttonPlay;
}
public JButton getButtonPause() {
return buttonPause;
}
public Action getActionPlay() {
return actionPlay;
}
public Action getActionPause() {
return actionPause;
}
public Action getActionReset() {
return actionReset;
}
public Runnable getTicker() {
return ticker;
}
public Stopwatch() {
frame = new JFrame("Stop Watch V 1.2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setIconImage(new ImageIcon(imgIcon).getImage());
frame.setSize(WIDTH, HEIGHT);
frame.setResizable(false);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
frame.setContentPane(mainPanel);
fieldTime = new JTextField(f.getResettime());
fieldTime.setEditable(false);
Font bigFont = fieldTime.getFont().deriveFont(Font.PLAIN, 50f);
fieldTime.setFont(bigFont);
mainPanel.add(fieldTime);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
mainPanel.add(buttonPanel, BorderLayout.SOUTH);
actionPlay = new AbstractAction("Start") {
#Override
public void actionPerformed(ActionEvent e) {
f.start();
}
};
actionPause = new AbstractAction("Pause") {
#Override
public void actionPerformed(ActionEvent e) {
f.pause();
}
};
actionReset = new AbstractAction("Reset") {
#Override
public void actionPerformed(ActionEvent e) {
f.reset();
}
};
buttonPlay = new JButton(actionPlay);
buttonPanel.add(buttonPlay);
buttonPause = new JButton(actionPause);
buttonPanel.add(buttonPause);
buttonPanel.add(new JButton(actionReset));
}
public final void setVisible() {
frame.setVisible(true);
buttonPlay.requestFocusInWindow();
}
public void displayTime(final String todisplay) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
fieldTime.setText(todisplay);
}
});
}
}
And this is the method class
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class Frame123 {
Stopwatch a = new Stopwatch();
private long lasttick = 0L;
private boolean paused = false;
private long elapsed = 0L;
private final ReentrantLock lock = new ReentrantLock();
private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
private ScheduledFuture<?> running = null;
private static final String RESETTIME = buildTime(0);
public void start() {
lock.lock();
try {
if (running!= null) {
return;
}
paused = false;
lasttick = System.currentTimeMillis();
running = executor.scheduleAtFixedRate(a.getTicker(), 10, 10, TimeUnit.MILLISECONDS);
a.getActionPlay().setEnabled(false);
a.getActionPause().setEnabled(true);
a.getActionReset().setEnabled(false);
a.getButtonPause().requestFocusInWindow();
} finally {
lock.unlock();
}
}
public void pause() {
lock.lock();
try {
if (running == null) {
return;
}
running.cancel(false);
paused = true;
running = null;
a.getActionPlay().setEnabled(true);
a.getActionPause().setEnabled(false);
a.getActionReset().setEnabled(true);
a.getButtonPlay().requestFocusInWindow();
} finally {
lock.unlock();
}
}
public void reset() {
lock.lock();
try {
if (running != null) {
return;
}
elapsed = 0;
a.displayTime(RESETTIME);
a.getActionPlay().setEnabled(true);
a.getActionPause().setEnabled(false);
a.getActionReset().setEnabled(true);
a.getButtonPlay().requestFocusInWindow();
} finally {
lock.unlock();
}
}
public String getResettime() {
return RESETTIME;
}
public static final String buildTime(final long elapsed) {
long hundredths = elapsed / 10;
long seconds = hundredths / 100;
long minutes = seconds / 60;
long hours = minutes / 60;
return String.format("%02d:%02d:%02d:%02d", hours, minutes % 60, seconds % 60, hundredths % 100);
}
public void tick() {
lock.lock();
try {
long now = System.currentTimeMillis();
long delta = now - lasttick;
lasttick = now;
if (!paused) {
elapsed += delta;
a.displayTime(buildTime(elapsed));
}
} finally {
lock.unlock();
}
}
}
And this is the working class, all classes together!
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class Frame1 {
private static final int WIDTH = 700;
private static final int HEIGHT = 350;
private static final String RESETTIME = buildTime(0);
public class App {
public static void main(String[] args) {
Stopwatch sw = new Stopwatch();
sw.setVisible();
}
}
private static final String buildTime(final long elapsed) {
long hundredths = elapsed / 10;
long seconds = hundredths / 100;
long minutes = seconds / 60;
long hours = minutes / 60;
return String.format("%02d:%02d:%02d:%02d", hours, minutes % 60, seconds % 60, hundredths % 100);
}
private final JTextField fieldTime;
private final JTextField fieldTime_2;
private final JButton buttonPlay;
private final JButton buttonPause;
private final JButton buttonLaptime;
private final Action actionPlay;
private final Action actionPause;
private final Action actionReset;
private final Action actionLaptime;
private final JFrame frame;
private final ReentrantLock lock = new ReentrantLock();
private long lasttick = 0;
private boolean paused = false;
private long elapsed = 0;
private ScheduledFuture<?> running = null;
private final ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
private final Runnable ticker = new Runnable() {
public void run() {
tick();
}
};
public Frame1() {
frame = new JFrame("Stop Watch");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(WIDTH, HEIGHT);
frame.setResizable(false);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.PAGE_AXIS));
frame.setContentPane(mainPanel);
fieldTime = new JTextField(RESETTIME);
fieldTime.setEditable(false);
Font bigFont = fieldTime.getFont().deriveFont(Font.PLAIN, 110f);
fieldTime.setFont(bigFont);
mainPanel.add(fieldTime);
fieldTime_2 = new JTextField();
fieldTime_2.setEditable(false);
Font bigFont_2 = fieldTime_2.getFont().deriveFont(Font.PLAIN, 110f);
fieldTime_2.setFont(bigFont_2);
mainPanel.add(fieldTime_2);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
mainPanel.add(buttonPanel, BorderLayout.NORTH);
actionPlay = new AbstractAction("Start") {
#Override
public void actionPerformed(ActionEvent e) {
start();
}
};
actionPause = new AbstractAction("Pause") {
#Override
public void actionPerformed(ActionEvent e) {
pause();
}
};
actionReset = new AbstractAction("Reset") {
#Override
public void actionPerformed(ActionEvent e) {
reset();
}
};
actionLaptime = new AbstractAction("Laptime") {
#Override
public void actionPerformed(ActionEvent e) {
lap(buildTime(elapsed));
}
};
buttonPlay = new JButton(actionPlay);
buttonPanel.add(buttonPlay);
buttonPause = new JButton(actionPause);
buttonPanel.add(buttonPause);
buttonPanel.add(new JButton(actionReset));
buttonLaptime = new JButton(actionLaptime);
buttonPanel.add(buttonLaptime);
}
public final void setVisible() {
frame.setVisible(true);
buttonPlay.requestFocusInWindow();
}
private void start() {
lock.lock();
try {
if (running != null) {
return;
}
paused = false;
lasttick = System.currentTimeMillis();
running = executor.scheduleAtFixedRate(ticker, 10, 10, TimeUnit.MILLISECONDS);
actionPlay.setEnabled(false);
actionPause.setEnabled(true);
actionReset.setEnabled(false);
actionLaptime.setEnabled(true);
buttonPause.requestFocusInWindow();
} finally {
lock.unlock();
}
}
public void lap(final String todisplay) {
if (running != null) {
fieldTime_2.setText(todisplay);
} else {
}
}
public JTextField getFieldTime_2() {
return fieldTime_2;
}
private void pause() {
lock.lock();
try {
if (running == null) {
return;
}
running.cancel(false);
paused = true;
running = null;
actionPlay.setEnabled(true);
actionPause.setEnabled(false);
actionReset.setEnabled(true);
actionLaptime.setEnabled(false);
buttonPlay.requestFocusInWindow();
} finally {
lock.unlock();
}
}
private void reset() {
lock.lock();
try {
if (running != null) {
return;
}
elapsed = 0;
displayTime(RESETTIME);
fieldTime_2.setText(RESETTIME);
actionPlay.setEnabled(true);
actionPause.setEnabled(false);
actionReset.setEnabled(true);
buttonPlay.requestFocusInWindow();
} finally {
lock.unlock();
}
}
private void tick() {
lock.lock();
try {
long now = System.currentTimeMillis();
long delta = now - lasttick;
lasttick = now;
if (!paused) {
elapsed += delta;
displayTime(buildTime(elapsed));
}
} finally {
lock.unlock();
}
}
private void displayTime(final String todisplay) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
fieldTime.setText(todisplay);
}
});
}
}
Error lines
Exception in thread "main" java.lang.StackOverflowError
at jjhjh.Stopwatch.<init>(Stopwatch.java:18)
at jjhjh.Frame123.<init>(Frame123.java:11)
at jjhjh.Stopwatch.<init>(Stopwatch.java:18)
at jjhjh.Frame123.<init>(Frame123.java:11)
at jjhjh.Stopwatch.<init>(Stopwatch.java:18)
at jjhjh.Frame123.<init>(Frame123.java:11)
at jjhjh.Stopwatch.<init>(Stopwatch.java:18)
I have just written a program in Netbeans that moves/copies/deletes files, and I wanted to give it a "diagnostic mode" where information about selected files, folders, variables, etc is displayed in a Text Area. Now, I could set this to only be visible when the "diagnostic mode" toggle is selected, but I think it would look awesome if the text area started behind the program, and "slid" out from behind the JFrame when the button is toggled. Is there any way to do this?
Thanks!
-Sean
Here is some starter code for you. This will right-slide a panel
of just about any content type. Tweak as necessary. Add error
checking and exception handling.
Tester:
static public void main(final String[] args) throws Exception {
SwingUtilities.invokeAndWait(new Runnable() {
#Override
public void run() {
final JPanel slider = new JPanel();
slider.setLayout(new FlowLayout());
slider.setBackground(Color.RED);
slider.add(new JButton("test"));
slider.add(new JButton("test"));
slider.add(new JTree());
slider.add(new JButton("test"));
slider.add(new JButton("test"));
final CpfJFrame42 cpfJFrame42 = new CpfJFrame42(slider, 250, 250);
cpfJFrame42.slide(CpfJFrame42.CLOSE);
cpfJFrame42.setSize(300, 300);
cpfJFrame42.setLocationRelativeTo(null);
cpfJFrame42.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
cpfJFrame42.setVisible(true);
}
});
}
Use GAP & MIN to adjust spacing from JFrame and closed size.
The impl is a little long...it uses a fixed slide speed but
that's one the tweaks you can make ( fixed FPS is better ).
package com.java42.example.code;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyAdapter;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
public class CpfJFrame42 extends JFrame {
public static int GAP = 5;
public static int MIN = 1;
public static final int OPEN = 0x01;
public static final int CLOSE = 0x02;
private JDialog jWindow = null;
private final JPanel basePanel;
private final int w;
private final int h;
private final Object lock = new Object();
private final boolean useSlideButton = true;
private boolean isSlideInProgress = false;
private final JPanel glassPane;
{
glassPane = new JPanel();
glassPane.setOpaque(false);
glassPane.addMouseListener(new MouseAdapter() {
});
glassPane.addMouseMotionListener(new MouseMotionAdapter() {
});
glassPane.addKeyListener(new KeyAdapter() {
});
}
public CpfJFrame42(final Component component, final int w, final int h) {
this.w = w;
this.h = h;
component.setSize(w, h);
addComponentListener(new ComponentListener() {
#Override
public void componentShown(final ComponentEvent e) {
}
#Override
public void componentResized(final ComponentEvent e) {
locateSlider(jWindow);
}
#Override
public void componentMoved(final ComponentEvent e) {
locateSlider(jWindow);
}
#Override
public void componentHidden(final ComponentEvent e) {
}
});
jWindow = new JDialog(this) {
#Override
public void doLayout() {
if (isSlideInProgress) {
}
else {
super.doLayout();
}
}
};
jWindow.setModal(false);
jWindow.setUndecorated(true);
jWindow.setSize(component.getWidth(), component.getHeight());
jWindow.getContentPane().add(component);
locateSlider(jWindow);
jWindow.setVisible(true);
if (useSlideButton) {
basePanel = new JPanel();
basePanel.setLayout(new BorderLayout());
final JPanel statusPanel = new JPanel();
basePanel.add(statusPanel, BorderLayout.SOUTH);
statusPanel.add(new JButton("Open") {
private static final long serialVersionUID = 9204819004142223529L;
{
setMargin(new Insets(0, 0, 0, 0));
}
{
addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
slide(OPEN);
}
});
}
});
statusPanel.add(new JButton("Close") {
{
setMargin(new Insets(0, 0, 0, 0));
}
private static final long serialVersionUID = 9204819004142223529L;
{
addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
slide(CLOSE);
}
});
}
});
{
//final BufferedImage bufferedImage = ImageFactory.getInstance().createTestImage(200, false);
//final ImageIcon icon = new ImageIcon(bufferedImage);
//basePanel.add(new JButton(icon), BorderLayout.CENTER);
}
getContentPane().add(basePanel);
}
}
private void locateSlider(final JDialog jWindow) {
if (jWindow != null) {
final int x = getLocation().x + getWidth() + GAP;
final int y = getLocation().y + 10;
jWindow.setLocation(x, y);
}
}
private void enableUserInput() {
getGlassPane().setVisible(false);
}
private void disableUserInput() {
setGlassPane(glassPane);
}
public void slide(final int slideType) {
if (!isSlideInProgress) {
isSlideInProgress = true;
final Thread t0 = new Thread(new Runnable() {
#Override
public void run() {
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
disableUserInput();
slide(true, slideType);
enableUserInput();
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
isSlideInProgress = false;
}
});
t0.setDaemon(true);
t0.start();
}
else {
Toolkit.getDefaultToolkit().beep();
}
}
private void slide(final boolean useLoop, final int slideType) {
synchronized (lock) {
for (int x = 0; x < w; x += 25) {
if (slideType == OPEN) {
jWindow.setSize(x, h);
}
else {
jWindow.setSize(getWidth() - x, h);
}
jWindow.repaint();
try {
Thread.sleep(42);
} catch (final Exception e) {
e.printStackTrace();
}
}
if (slideType == OPEN) {
jWindow.setSize(w, h);
}
else {
jWindow.setSize(MIN, h);
}
jWindow.repaint();
}
}
}
Hey guys I'm new to Java game programming and I'm working with the Runnable interface right now. For some reason, my run() method never gets called and I'm not sure why. I've tried putting many System.out.println statements in there but they never get printed. Any help would be greatly appreciated!
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JPanel;
public class GamePanel extends JPanel implements Runnable
{
private final int WIDTH = 160;
private final int HEIGHT = WIDTH/12 *9;
private final int RATIO = 3;
private Thread animator;
private volatile boolean running;
private volatile boolean gameOver;
private double FPS = 60D;
private double period = 1000/FPS;
private Image dbImage;
private Graphics dbg;
public GamePanel()
{
setPreferredSize(new Dimension(WIDTH *3, HEIGHT*3));
setBackground(Color.WHITE);
setFocusable(true);
requestFocus();
terminate();
}
public void addNotify()
{
super.addNotify();
startGame();
}
public void startGame()
{
System.out.println("Thread started");
animator = new Thread();
animator.start();
}
public void stopGame()
{
System.out.println("Thread stopped");
running = false;
}
public void run()
{
long beforeTime, timeDiff, sleepTime;
beforeTime = System.currentTimeMillis();
System.out.println(beforeTime);
running = true;
while (running)
{
System.out.println("Running");
gameUpdate();
gameRender();
paintScreen();
timeDiff = System.currentTimeMillis() - beforeTime;
sleepTime = (long) period - timeDiff;
if(sleepTime <= 0)
sleepTime = 5;
try
{
Thread.sleep(sleepTime);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
beforeTime = System.currentTimeMillis();
}
System.exit(0);
}
public void gameRender()
{
if (dbImage == null)
{
dbImage = createImage(WIDTH, HEIGHT);
}
else
dbg = dbImage.getGraphics();
dbg.setColor(Color.WHITE);
dbg.fillRect(0, 0, WIDTH, HEIGHT);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(dbImage, 0, 0, null);
}
public void gameUpdate()
{
}
private void paintScreen()
{
Graphics g;
try
{
g = this.getGraphics();
if (g!= null && dbImage!= null)
g.drawImage(dbImage, 0, 0, null);
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
catch (Exception e)
{
System.out.println("Error: " + e.getMessage());
}
}
public void terminate()
{
addKeyListener (new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_ESCAPE)
{
stopGame();
}
}
});
}
}
import javax.swing.JFrame;
public class GameFrame extends JFrame
{
private final int WIDTH = 160;
private final int HEIGHT = WIDTH/12*9;
private final int RATIO = 3;
public GameFrame()
{
setTitle("User Input Game");
setSize(WIDTH*3,HEIGHT*3);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
GamePanel mainPanel = new GamePanel();
add(mainPanel);
}
}
public class Main
{
public static void main(String[] args)
{
new GameFrame().setVisible(true);
}
}
You need to change your startGame() method:
animator = new Thread(new GamePanel());
You need to pass a Runnable (of which GamePanel is one) into the Thread constructor. The thread then runs the runnable when it starts.
You don't seem to have a main method anywhere. Either in this class or an external class you need a main method that creates an instance of GamePanel and pass it as an argument to a Thread class. Like so:
public class Test
{
public static void main(String[] args)
{
Thread t = new Thread(new GamePanel()).start();
}
}
I'm creating an animation that looks like this.
I'd like the swirly icon on the left (which is an ImageIcon) to display for 3 seconds and disappear. However, the swirly icon does not disappear.
Here's my code.
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JFrame f = new JFrame("random title");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setResizable(false);
f.add(new MyPanel());
f.pack();
f.setVisible(true);
}
}
class MyPanel extends JPanel {
private static final long serialVersionUID = 1L;
public int x;
public int y;
public int remoteControllerX = 473;
public int remoteControllerY = 340;
public int buttonX = 166;
public int buttonY = 208;
Image img;
Image remoteController;
ImageIcon button = new ImageIcon("graphics/button.gif");
Component buttonTrigger = this;
public MyPanel() {
try {
img = ImageIO.read(new File("graphics/close_0.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
try {
remoteController = ImageIO.read(new File("graphics/pilot.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
setBorder(BorderFactory.createLineBorder(Color.black));
new Timer(3000, paintTimer).start();
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
x = e.getX();
y = e.getY();
// Here goes action on background, which is unrelated to this example.
}
});
}
public Dimension getPreferredSize() {
return new Dimension(1048, 484);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, null);
g.drawImage(remoteController, remoteControllerX, remoteControllerY, null);
Toolkit.getDefaultToolkit().sync();
button.paintIcon(buttonTrigger, g, buttonX, buttonY);
}
Action paintTimer = new AbstractAction() {
private static final long serialVersionUID = -2121714427110679013L;
public void actionPerformed(ActionEvent e) {
buttonTrigger = null;
repaint();
}
};
}
You'll also need these 3 images for the code to run:
http://ajks.pl/graveyard/close_0.jpg
http://ajks.pl/graveyard/pilot.png
http://ajks.pl/graveyard/button.gif
They are placed in a graphics folder under the main Java project.
I added a boolean to determine whether or not to paint the swirly image icon.
Here's the corrected code.
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JFrame f = new JFrame("random title");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setResizable(false);
f.add(new MyPanel());
f.pack();
f.setVisible(true);
}
}
class MyPanel extends JPanel {
private static final long serialVersionUID = 1L;
public boolean paintButton = true;
public int x;
public int y;
public int remoteControllerX = 473;
public int remoteControllerY = 340;
public int buttonX = 166;
public int buttonY = 208;
Image img;
Image remoteController;
ImageIcon button = new ImageIcon(
"graphics/button.gif");
Component buttonTrigger = this;
public MyPanel() {
try {
img = ImageIO.read(new File("graphics/close_0.jpg"));
remoteController = ImageIO.read(new File("graphics/pilot.png"));
} catch (IOException e) {
e.printStackTrace();
}
setBorder(BorderFactory.createLineBorder(Color.black));
new Timer(3000, paintTimer).start();
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
x = e.getX();
y = e.getY();
// Here goes action on background, which is unrelated to this
// example.
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(1048, 484);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, null);
g.drawImage(remoteController, remoteControllerX, remoteControllerY,
null);
Toolkit.getDefaultToolkit().sync();
if (paintButton) {
button.paintIcon(buttonTrigger, g, buttonX, buttonY);
}
}
Action paintTimer = new AbstractAction() {
private static final long serialVersionUID = -2121714427110679013L;
#Override
public void actionPerformed(ActionEvent e) {
paintButton = false;
repaint();
}
};
}