下面是我之前关于在循环中绘制矩形的问题?
现在我想从另一个类中,在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
按钮。我的代码的缺陷在哪里?
1条答案
按热度按时间ie3xauqp1#
我的代码的缺陷在哪里?
在main()方法中创建大型机示例:
然后在facedetect类中创建另一个示例:
你不能一直创建一个对象的新示例。您需要将mainframe类的引用传递给facedetect类。
不过,我认为这仍然不是正确的设计,因为你的swingworker逻辑是不正确的。你不正确地使用了swingworker!这个
doInBackground
逻辑不应该更新swing组件的状态!在我之前的问题之后。。。
建议使用
Swing Timer
为动画。这就是代码的设计方法。swing计时器所做的就是以固定的间隔生成一个事件。然后你对事件做出React。所以在你的情况下,你会想要创建一个
move()
方法,该方法将更新x/y位置并重新绘制组件。计时器的逻辑是简单地调用move()
方法。请参阅:如何使jscrollpane(在borderlayout中,包含jpanel)平滑地自动滚动,这是一个使用swing计时器的基本示例。