当前位置: 首页 > 知识库问答 >
问题:

当我添加计时器时,图像将不再加载

夹谷腾
2023-03-14

我试图创建一个小行星游戏,但我已经在一开始就很挣扎了:我想在游戏开始前创建一个倒计时。为了做到这一点,我使用了一个计时器,当按下按钮“开始”时开始,它(应该)每秒钟加载一个BufferedImage,然后显示在一个JFrame上。

在我加上计时器之前,整个程序运行得很好。然而,图像仍在绘制中,TimerTask的方法run()仍在完全使用。但是,图像不会出现在我的JFrame上。

public class Main implements ActionListener {

    private static File load = null;
    private static BufferedImage image = null;
    private JFrame frame;
    private JButton start;
    private JLabel game_name;
    private JLabel screen;
    private ImageIcon icon;
    private Asteroids aster = new Asteroids();
    private static Main m = new Main();

    protected static int height = 550;
    protected static int width = 800;
    protected static int cd = 0;

    /*
     * Here the JFrame frame gets created and set up, and the main method 
     * does its job. I believe only the actionPerformed method to be 
     * important, so I removed this part from the post.
     *
     */


    private void addScreen() {
        frame.add(screen);
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        // Cleaning the screen
        start.setVisible(false);
        game_name.setVisible(false);

        // Creating the image
        aster.spawn(5);

        // creating the countdown timer
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {            
            public void run() {
                // creating countdown
                aster.initialScreen();

                // Reading the image
                load = new File(aster.filePath + aster.fileName + ".png");
                image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
                try {
                image = ImageIO.read(load); 
                } catch (IOException i) {
                    System.out.println("Reading has encountered an error: \n" + i); }

                // Implementing the Image
                screen = new JLabel();
                screen.setSize(width, height);
                icon = new ImageIcon(image);
                screen.setIcon(icon);
                m.addScreen();
                System.out.println("roger");
            }

        }, 0, 1000);

    } // end actionPerfomed()

} // end class

有人能发现错误吗?我真的不明白问题是什么,虽然我对计时器不熟悉,所以如果我做的事情真的很愚蠢,请告诉我。

共有2个答案

萧德庸
2023-03-14

好吧,我以某种方式解决了这个问题:首先,我确实改变了util。定时到秋千。然而,这本身并没有帮助。之前,我在桌面上绘制完每个图像后保存,然后在应该显示的时候将其加载到屏幕上。我对代码进行了一些修改,发现我不需要保存它,但实际上可以通过使其静态直接引用它。当我这么做的时候,问题就消失了。下面是我的意思的代码示例:

之前:

// In the drawing class
save = new File(aster.filePath + aster.fileName + ".png");
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
try {
    ImageIO.write(image, "png", save); 
    } catch (IOException i) {
    System.out.println("Writing has encountered an error: \n" + i); }

// In the displaying class
load = new File(aster.filePath + aster.fileName + ".png");
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
try {
    image = ImageIO.read(load); 
    } catch (IOException i) {
    System.out.println("Reading has encountered an error: \n" + i); }
ImageIcon icon = new ImageIcon(image);
displayingJLabel.setIcon(icon);
frame.add(displayingJLabel);

之后:

// One static declaration and initialization of an BufferedImage in the drawing class
public static BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
// Drawing Code

// Accessing the image
ImageIcon icon = new ImageIcon(DrawingClass.image);
displayingJLabel.setIcon(icon);
frame.add(displayingJLabel);

本质上,除了跳过整个保存和读取过程之外,一切都是一样的,而不是几个本地BufferedImage,我只使用一个静态BufferedImage

我不知道为什么这样做有效,但我猜整个读写过程花费的时间太长,以至于计时器每秒都会响,而这种新方法要快得多。我还没试着用util做这件事。计时器又来了,但我想是秋千。定时器在解决这个问题上可能有它的公平份额。

澹台俊材
2023-03-14

您的问题很可能是因为您正在使用java.util.Timer,它启动自己的后台线程,并在访问Swing组件时导致并发问题。

在任何情况下,我建议使用javax.swing.Timer,它将您的任务作为动作侦听器安排在Swing事件调度线程上执行:

new javax.swing.Timer(1000, new ActionListener() {
    public void actionPerformed(ActionEvent e) {
            // Your code here
        }
    }).start();
 类似资料:
  • 问题内容: 我想先在Javafx中为我的图像添加计时器,例如,大约3秒钟显示我的第一张图像,然后大约5秒钟显示我的第二张图像,此后什么也没有显示。对此有什么想法吗? 问题答案: 使用更新的:

  • 我正在使用PDFBox从我的webapp中提取数据并将其放入PDF。我有一个方法,在每个PDF页面上绘制标题。但是,当我向每个页面添加图像时,文档的内存就会耗尽。我想知道有没有人有什么解决的办法?下面是我的drawHeader方法: public static void drawHeader(PDDocument doc,PDPage page,PDPageContentStream conten

  • 我的GridbagLayout有些问题。我创建了一个JPanel(在本例中称为mainPanel),它的布局被设置为GridBagLayout。我已经为每个JButton指定了约束,并将约束添加到每个Button。现在,当我运行代码时,按钮总是紧挨着的,而不考虑我在约束中指示的Gridx/Gridy值。此外,按钮总是位于JFrame的中心,我希望一个按钮出现在右上角、左上角和南边。 这是我运行代码

  • 尝试添加POST操作时,我的jenkinsfile不再编译。最后一个应该在构建结束时显示到jenkins控制台输出。 第一部分是关于我的jenkinsfile代码,它的构建做得很好。 第二部分是添加到第一部分的补丁,任何构建都失败。 我想集成第一部分和第二部分以获得下文描述的预期输出,但无论如何插入,集成都失败了。我已经尝试了很多事情,现在我卡住了,所以任何帮助都将不胜感激。 //第一部分:我的基

  • 问题内容: 我发现,当我编写“ pnlMap.add(map [i] [j])”时,键侦听器将无法工作。map是JButton的集合,pnlMap是JPanel。 公共游戏(玩家播放器){ 问题答案: 为了工作,必须将其注册为可聚焦的组件并使其具有键盘焦点。默认情况下,大多数容器都喜欢和无法将其聚焦(在考虑使它们成为容器之前,我会非常小心)。这意味着,一旦您添加了一个可以接受键盘焦点的组件(并且它

  • 这是我的类的全部代码。我正在尝试有一个带有JScrollPane的JTable,我也尝试了在JTable和JScrollPane上设置setVisible。我认为问题可能是我将JScrollPane添加到JPanel而不是JFrame中,但我希望在我的面板上添加该得分表。在我的JPanel(背景)中,我为背景绘制一个图像,仅此而已。 安妮的想法?