簡體   English   中英

無法從另一個類重新繪制 JPanel

[英]Can't repaint JPanel from another class

遵循我之前關於在循環內繪制矩形的問題

現在我想在 for 循環內從另一個類繪制 Rectangle 。 這是循環的類:

public class FaceDetect extends SwingWorker {
    
    IntegralCalc3 ic3 = new IntegralCalc3();
    MainFrame mf = new MainFrame();
  
    Rectangle R;

       protected FaceDetect doInBackground() throws Exception {
       //Initial width and height is 60, 60
       outerloop:
       for(int w = 50; w <= ic3.integral.length && w <= ic3.integral[0].length; w = (int) Math.round(w*1.2)  ) {  
            int h = w;

            for(int x = 0; x <= ic3.integral.length-w; x+=5 ) { 
            for(int y = 0; y <= ic3.integral[0].length-w; y+=5 ) {
            
             R = new Rectangle (x, y, w, h);
             mf.lm.add(R);
             mf.lm.revalidate();
             mf.lm.repaint();
            } 
            }             
        } 
        return null;
    }

}

這是我的矩形類:

public class Rect extends JComponent {
    public int x;
    public int y;
    public int w;
    public int h;
    
    public Rect (int x, int y, int w, int h) {
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
        repaint();
    }

    @Override
    public void paintComponent(Graphics g)  {
        Graphics2D g2 = (Graphics2D) g;
        super.paintComponent(g);
        g2.setColor(Color.green);
        g2.drawRect(x+15, y+15, w, h);
    }
}

最后這是我在 JFrame 類中的按鈕:

public class MainFrame extends JFrame {
    Rect R = new Rect(15, 15, 50, 50);
    JPanel lm = new JPanel();
    LayoutManager lay = new OverlayLayout(lm);
    JButton animate = new JButton("animate");

    public MainFrame () {
        setSize(1200, 700);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        lm.setLayout(lay);
        lm.add(R);
}
        animate.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) { 
               try {   
               new FaceDetect().execute();
                } catch (Exception ex) {
                    Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
                }
               }   
      });

    public static void main(String[] args) {
            EventQueue.invokeLater(() -> new MainFrame());
        }
    }

但是當我單擊animate按鈕時什么也沒發生。 我的代碼的缺陷在哪里?

我的代碼的缺陷在哪里?

在 main() 方法中創建 MainFrame 的一個實例:

public static void main(String[] args) {
        EventQueue.invokeLater(() -> new MainFrame());
    }
}

然后在 FaceDetect 類中創建另一個實例:

public class FaceDetect extends SwingWorker {
    IntegralCalc3 ic3 = new IntegralCalc3();
    MainFrame mf = new MainFrame();

您不能只是不斷地創建對象的新實例。 您需要將 MainFrame 類的引用傳遞給 FaceDetect 類。

但是我建議這仍然不是正確的設計,因為您的 SwingWorker 邏輯不正確。 您錯誤地使用了 SwingWorker! doInBackground邏輯不應更新 Swing 組件的狀態!

按照我之前的問題...

建議是使用Swing Timer來制作動畫。 這就是你的代碼應該如何設計。 Swing Timer 所做的就是定期生成一個事件。 然后您響應該事件。

因此,在您的情況下,您可能希望在 Rect 類中創建一個move()方法,該方法將更新 x/y 位置並 repaint() 組件。 Timer 的邏輯是簡單地調用move()方法。

有關使用 Swing Timer 的基本示例,請參閱: 如何使 JScrollPane(在 BorderLayout 中,包含 JPanel)平滑地自動滾動

暫無
暫無

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

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