簡體   English   中英

僅在Java Swing中重繪后觸發事件?

[英]Trigger event only after repaint in Java Swing?

我在java中制作一個簡單的棋盤游戲,我想要制作一個骰子動畫。 所以我用這樣的骰子閃光照片:

public Timer roll_dice = new Timer(50, this);
...
public void actionPerformed(ActionEvent evt) {
        if(roll_dice.getDelay() > 500){
            roll_dice.setDelay(50);
            roll_dice.stop();
            movePiece();
        }else{
            roll_dice.setDelay(roll_dice.getDelay() + 50);
            dice_panel.repaint(0);
        }
    }
}

movePiece(){
    //do some more painting
}

因此,模具將如此顯示隨機數幾次,然后慢慢地確定一個數字。 完成之后我想調用movePiece()方法。 然而,實際上,重新出現偶爾並將所有內容擰緊,以便在骰子卷實際完成動畫之前調用movePiece()

有沒有人有任何想法,我怎么能在最后的重繪發生后調用movePiece?

因此,模具將如此顯示隨機數幾次,然后慢慢地確定一個數字。 完成之后我想調用movePiece()方法。 然而,實際上,重新出現偶爾並將所有內容擰緊,以便在骰子卷實際完成動畫之前調用movePiece()。

這里讓我擔心的是你的繪畫偶爾發生的原因 - 它根本不應該這樣做,也許就是你需要解決的問題。 我想知道你每次進行繪圖時是否正在讀取文件中的圖像,或者其他原因是為了減慢繪圖速度。 如果您在此問題上需要更多幫助,那么您必須向我們提供有關您如何進行繪畫的更多信息。 無論如何,你應該避免使程序邏輯依賴於繪畫,因為你無法完全控制何時或甚至是否會發生繪畫。

為什么不在程序啟動時簡單地將滾動骰子圖像放入ImageIcons,然后在Swing Timer中,在JLabel中交換圖標,而不是重繪圖像並調用repaint()。 然后在延遲時間足夠長的時候停止你的計時器,如果阻止,移動你的作品。

因此,假設您有幾個骰子,每個骰子都可以由JLabel顯示,該JLabel保存在名為diceLabels的JLabel數組中,ImageIcons可以保存在名為diceIcons的數組中。 然后你可以這樣做:

  public void actionPerformed(ActionEvent e) {
     if (roll_dice.getDelay() > 500) {
        roll_dice.setDelay(50);
        roll_dice.stop();
        movePiece(); // I like this -- this shouldn't change
     } else {
        roll_dice.setDelay(roll_dice.getDelay() + 50);
        // dice_panel.repaint(0);
        for (JLabel dieLabel : diceLabels) {
           int randomIndex = random.nextInt(diceIcons.length);
           dieLabel.setIcon(diceIcons[randomIndex]);
        }
     }
  }

當你調用movePiece()時我喜歡你的邏輯,我認為這應該保持不變。

您可以在另一個線程中調用滾動並將當前線程連接()到滾動線程。 這樣主代碼將等待滾動螺紋死亡(完成滾動)。

public void actionPerformed(ActionEvent evt) {
    if(roll_dice.getDelay() > 500){
        Thread rollerThread = new RollerThread();
        rollerThread.start();
        rollerThread.join();
        movePiece();
    }
    else{
        roll_dice.setDelay(roll_dice.getDelay() + 50);
        dice_panel.repaint(0);
    }
}

private RollerThread extends Thread
{
    public void run(){
        roll_dice.setDelay(50);
        roll_dice.stop();
    }
}

但是,這可能不適用於EDT - 因為重繪應該安排到隊列中。 也許你可以使用SwingUtilities.invokeAndWait()舉辦活動:

public void actionPerformed(ActionEvent evt) {
    Thread thread = new Thread(){
        public void run(){
            if(roll_dice.getDelay() > 500){
                SwingUtilities.invokeAndWait(new Runnable(){
                     public void run(){
                         roll_dice.setDelay(50);
                         roll_dice.stop();
                     }
                });
                movePiece();
            }
            else{
                 roll_dice.setDelay(roll_dice.getDelay() + 50);
                 dice_panel.repaint(0);
            }
        }
    };
    thread.start();
}

如果你把這個調用放到movePiece();什么變化嗎movePiece(); SwingUtilities.invokeLater(Runnable);

if(roll_dice.getDelay() > 500){
    roll_dice.setDelay(50);
    roll_dice.stop();

    SwingUtilities.invokeLater(new Runnable() {
        public void run() { movePiece(); }
    });
}
...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM