I want to make a code that makes a square move from the left side of the panel to the right side of the panel... I realized that you could simply make a image appear in on block of code and then in the next block of code have the image be overlapped by a exactly the same square just with the same color as the background... To do that I need a timer like code that makes it so that the image appears and then 1 second later it gets over lapped and then the new image appears right beside it
我想制作一个代码,从面板的左侧到面板的右侧进行正方形移动...我意识到你可以简单地使图像出现在代码块上然后在下一个块中代码让图像与完全相同的正方形重叠,只是与背景颜色相同...为此,我需要一个像代码一样的计时器,使图像出现,然后1秒钟后,它会重叠然后新图像出现在它旁边
Realizing that sleep.thread doesn't work nice with gui i'm resorting to Javax.Swing.Timer
意识到sleep.thread不适合gui我正在使用Javax.Swing.Timer
I just want it to make one box appear beside it for now
我只想让它现在旁边出现一个方框
However i have no experience with it and need some help getting it to work with my code -Andrew
但是我没有使用它的经验,需要一些帮助才能使用我的代码-Andrew
{
g.setColor(Color.GREEN);
g.fillRect(50, 100, 100, 100); //first box on a red background
//Timer goes here
g.setColor(Color.RED);
g.fillRect(50, 100, 100, 100);//overlapps the first box
g.setColor(Color.GREEN);
g.fillRect(50, 110, 100, 100);//sets a new box right beside it
}
}
4 个解决方案
#1
2
Creating a javax.swing.Timer
is quite simple actually. You don't have to worry about the threads yourself, because the scheduling happens automatically in a background thread, but the code of the listener you implement is executed in the GUI thread. Therefore you can work with whatever swing components you need in the listener body.
实际上创建一个javax.swing.Timer非常简单。您不必自己担心线程,因为调度在后台线程中自动发生,但您实现的侦听器的代码在GUI线程中执行。因此,您可以使用侦听器正文中所需的任何swing组件。
int interval = 1000; // repeating every 1000 ms
new Timer(interval, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// do whatever painting that you want
}
}).start();
#2
1
You initialize it with:
你初始化它:
Timer <timernamegoeshere> = new Timer(<delayinmilis>,<actionlistener>);
So every amount of miliseconds you entered into timers constucter an action will performed.
因此,您在定时器中输入的每个毫秒数都会执行一个动作。
That means that you can simply put your update code into the actionPerformed
and have a variable being incremented by the amount of pixels that you move your square by and a boolean, switching from true
to false
, with true
being that it draws it, and false
that it sets it to the color of the background.
这意味着您可以简单地将更新代码放入actionPerformed中,并使变量增加您移动平方的像素数和布尔值,从true切换为false,其中true表示绘制它,并且为false它将它设置为背景的颜色。
#3
1
I'm not sure if this is the best way, but you could easily redefine a square to have a location. In turn, you could have the timer update the location of your square instance and then call repaint(). This would mean the paint method just draws the background and the same square in its new location instead of creating a new square every time.
我不确定这是否是最佳方式,但您可以轻松地重新定义一个方块以获得位置。反过来,您可以让计时器更新方形实例的位置,然后调用repaint()。这意味着paint方法只是在新位置绘制背景和相同的方块,而不是每次都创建一个新的方块。
Your paint method could then have something like:
你的绘画方法可以有类似的东西:
g.drawRect(referenceToSquare.getLocation().getX(), referenceToSquare.getLocation().getY(), 100, 100)
You initialize your timer with :
您使用以下命令初始化计时器:
Timer timer = new Timer(delayInMillis);
timer.add(new ActionListener());
then in same class have a...
然后在同一个班级有......
actionPerformed(ActionEvent e) {
if(e.getSource() == timer) {
referenceToSquare.getLocation().getX()++;
}
frame.repaint();
}
http://docs.oracle.com/javase/6/docs/api/java/awt/event/ActionListener.html
http://docs.oracle.com/javase/6/docs/api/java/awt/event/ActionListener.html
#4
1
I would suggest you use an ExecutorService
我建议你使用ExecutorService
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html
e.g you can do something similar to that
例如,你可以做类似的事情
private static ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);
scheduledThreadPool.scheduleAtFixedRate(new DrawingTask(), 1000, 1000 TimeUnit.MILLISECONDS);
Your drawing task can look similar to below:
您的绘图任务可能类似于以下内容:
public class DrawingTask extends TimerTask {
@Override
public void run() {
// previous co ordinates. This should be static
// sleep for a second
// re draw the old one
// draw the new one
}
}
#1
2
Creating a javax.swing.Timer
is quite simple actually. You don't have to worry about the threads yourself, because the scheduling happens automatically in a background thread, but the code of the listener you implement is executed in the GUI thread. Therefore you can work with whatever swing components you need in the listener body.
实际上创建一个javax.swing.Timer非常简单。您不必自己担心线程,因为调度在后台线程中自动发生,但您实现的侦听器的代码在GUI线程中执行。因此,您可以使用侦听器正文中所需的任何swing组件。
int interval = 1000; // repeating every 1000 ms
new Timer(interval, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// do whatever painting that you want
}
}).start();
#2
1
You initialize it with:
你初始化它:
Timer <timernamegoeshere> = new Timer(<delayinmilis>,<actionlistener>);
So every amount of miliseconds you entered into timers constucter an action will performed.
因此,您在定时器中输入的每个毫秒数都会执行一个动作。
That means that you can simply put your update code into the actionPerformed
and have a variable being incremented by the amount of pixels that you move your square by and a boolean, switching from true
to false
, with true
being that it draws it, and false
that it sets it to the color of the background.
这意味着您可以简单地将更新代码放入actionPerformed中,并使变量增加您移动平方的像素数和布尔值,从true切换为false,其中true表示绘制它,并且为false它将它设置为背景的颜色。
#3
1
I'm not sure if this is the best way, but you could easily redefine a square to have a location. In turn, you could have the timer update the location of your square instance and then call repaint(). This would mean the paint method just draws the background and the same square in its new location instead of creating a new square every time.
我不确定这是否是最佳方式,但您可以轻松地重新定义一个方块以获得位置。反过来,您可以让计时器更新方形实例的位置,然后调用repaint()。这意味着paint方法只是在新位置绘制背景和相同的方块,而不是每次都创建一个新的方块。
Your paint method could then have something like:
你的绘画方法可以有类似的东西:
g.drawRect(referenceToSquare.getLocation().getX(), referenceToSquare.getLocation().getY(), 100, 100)
You initialize your timer with :
您使用以下命令初始化计时器:
Timer timer = new Timer(delayInMillis);
timer.add(new ActionListener());
then in same class have a...
然后在同一个班级有......
actionPerformed(ActionEvent e) {
if(e.getSource() == timer) {
referenceToSquare.getLocation().getX()++;
}
frame.repaint();
}
http://docs.oracle.com/javase/6/docs/api/java/awt/event/ActionListener.html
http://docs.oracle.com/javase/6/docs/api/java/awt/event/ActionListener.html
#4
1
I would suggest you use an ExecutorService
我建议你使用ExecutorService
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html
e.g you can do something similar to that
例如,你可以做类似的事情
private static ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(2);
scheduledThreadPool.scheduleAtFixedRate(new DrawingTask(), 1000, 1000 TimeUnit.MILLISECONDS);
Your drawing task can look similar to below:
您的绘图任务可能类似于以下内容:
public class DrawingTask extends TimerTask {
@Override
public void run() {
// previous co ordinates. This should be static
// sleep for a second
// re draw the old one
// draw the new one
}
}