[英]Swing Timer not working as planned
I Think this is a Timer issue, first time ive used them and i feel like im doing it wrong.我认为这是一个计时器问题,我第一次使用它们,我觉得我做错了。
I have a method that for testings sake, input 6 images and with the help of a timer paints them to a JPanel:我有一个方法,为了测试起见,输入 6 个图像,并在计时器的帮助下将它们绘制到 JPanel:
private void drawDice(Graphics2D g2d) throws IOException, InterruptedException {
image = ImageIO.read(getClass().getResourceAsStream("/1.png"));
m_dice.add(image);
image = ImageIO.read(getClass().getResourceAsStream("/2.png"));
m_dice.add(image);
image = ImageIO.read(getClass().getResourceAsStream("/3.png"));
m_dice.add(image);
image = ImageIO.read(getClass().getResourceAsStream("/4.png"));
m_dice.add(image);
image = ImageIO.read(getClass().getResourceAsStream("/5.png"));
m_dice.add(image);
image = ImageIO.read(getClass().getResourceAsStream("/6.png"));
m_dice.add(image);
time.start();
for(int i = 0; i < m_dice.size(); i++){
g2d.drawImage(m_dice.get(i), 700, 400, null, null);
repaint();
}
time.stop();
}
Timer time = new Timer(1000,this); < at the top of the class
The desired output is that all 6 dice images are shown at one second intervals but only "6.png" shows up.所需的输出是以一秒为间隔显示所有 6 个骰子图像,但仅显示“6.png”。
thank you.谢谢你。
I think that you may be unclear on how a Timer works.我认为您可能不清楚 Timer 的工作原理。 Suggestions:建议:
ArrayList<Icon>
of ImageIcons.我自己的投票是 ImageIcons 的ArrayList<Icon>
。setIcon(...)
on the JLabel, passing in the newest icon.交换图像的最简单方法是在 JLabel 中显示 ImageIcons 并简单地调用 JLabel 上的setIcon(...)
,传入最新的图标。setIcon(...)
on your JLabel (again, this is all done inside of the actionPerformed method for the Timer).在 JLabel 上调用setIcon(...)
(同样,这一切都在 Timer 的 actionPerformed 方法内完成)。stop()
on your Timer.并在您的计时器上调用stop()
。Something like:就像是:
int timerDelay = 1000;
new Timer(timerDelay, new ActionListener(){
int count = 0;
@Override
public void actionPerformed(ActionEvent e) {
if (count < IMAGE_COUNT) {
someLabel.setIcon(icons[count]);
count++;
} else {
// stop the timer
((Timer)e.getSource()).stop();
}
}
}).start();
For example, this program "rolls" a die by randomly swapping ImageIcons in a JLabel maxCount number of times:例如,这个程序通过随机交换 JLabel maxCount 中的 ImageIcons 次数来“滚动”一个骰子:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.*;
@SuppressWarnings("serial")
public class RollDice extends JPanel {
// nice public domain dice face images. All 6 images in one "sprite sheet" image.
private static final String IMG_PATH = "https://upload.wikimedia.org/"
+ "wikipedia/commons/4/4c/Dice.png";
private static final int TIMER_DELAY = 200;
private List<Icon> diceIcons = new ArrayList<>(); // list to hold dice face image icons
private JLabel diceLabel = new JLabel(); // jlabel to display images
private Timer diceTimer; // swing timer
public RollDice(BufferedImage img) {
// subdivide the sprite sheet into individual images
// use them to create ImageIcons
// and add them to my diceIcons ArrayList<Icon>.
double imgW = img.getWidth() / 3.0;
double imgH = img.getHeight() / 2.0;
for (int row = 0; row < 2; row++) {
int y = (int) (row * imgH);
for (int col = 0; col < 3; col++) {
int x = (int) (col * imgW);
BufferedImage subImg = img.getSubimage(x, y, (int)imgW, (int)imgH);
diceIcons.add(new ImageIcon(subImg));
}
}
// panel to hold roll dice button
JPanel btnPanel = new JPanel();
btnPanel.setOpaque(false);
btnPanel.add(new JButton(new RollDiceAction("Roll Dice")));
// set the JLabel's icon to the first one in the collection
diceLabel.setIcon(diceIcons.get(0));
setLayout(new BorderLayout());
setBackground(Color.WHITE);
add(diceLabel);
add(btnPanel, BorderLayout.PAGE_END);
}
public void rollDice() {
// if the timer's already running, exit this method
if (diceTimer != null && diceTimer.isRunning()) {
return;
}
// else create a new Timer and start it
diceTimer = new Timer(TIMER_DELAY, new TimerListener());
diceTimer.start();
}
// ActionListener for the Swing Timer
private class TimerListener implements ActionListener {
private int count = 0; // count how many times dice changes face
private final int maxCount = 20;
@Override
public void actionPerformed(ActionEvent e) {
// once there are max count changes, stop the timer
if (count >= maxCount) {
((Timer) e.getSource()).stop();
}
// get a random index from 0 to 5
int randomIndex = (int) (Math.random() * diceIcons.size());
// show that random number's dice face
diceLabel.setIcon(diceIcons.get(randomIndex));
count++; // increment the count
}
}
// ActionListener for our button
private class RollDiceAction extends AbstractAction {
public RollDiceAction(String name) {
super(name); // text to show in the button
}
@Override
public void actionPerformed(ActionEvent e) {
rollDice(); // simply call the roll dice method
}
}
private static void createAndShowGui(BufferedImage img) {
RollDice mainPanel = new RollDice(img);
JFrame frame = new JFrame("RollDice");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
try {
URL imgUrl = new URL(IMG_PATH);
final BufferedImage img = ImageIO.read(imgUrl);
SwingUtilities.invokeLater(() -> {
createAndShowGui(img);
});
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.