无法从另一个类重新绘制jpanel

qc6wkl3g  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(313)

下面是我之前关于在循环中绘制矩形的问题?
现在我想从另一个类中,在for循环中绘制矩形。下面是循环的类:

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 按钮。我的代码的缺陷在哪里?

ie3xauqp

ie3xauqp1#

我的代码的缺陷在哪里?
在main()方法中创建大型机示例:

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计时器所做的就是以固定的间隔生成一个事件。然后你对事件做出React。
所以在你的情况下,你会想要创建一个 move() 方法,该方法将更新x/y位置并重新绘制组件。计时器的逻辑是简单地调用 move() 方法。
请参阅:如何使jscrollpane(在borderlayout中,包含jpanel)平滑地自动滚动,这是一个使用swing计时器的基本示例。

相关问题