[英]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.