我正在尝试使用 Graphics2D 绘制 JPanel,我希望绘制发生在 SwingWorker 的 done()
中。方法,经过一些数学运算后 doInBackGround()
, 不过这个好像画不了什么?
我的代码有什么问题?
class MyJanel extends JPanel {
@Override
public Dimension getPreferredSize() {
return new Dimension(800, 600);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
MyExecutor worker = new MyExecutor(g2);
worker.execute();
}
class MyExecutor extends SwingWorker<Void,Void> {
Graphics2D gRef;
int result;
public MyExecutor(Graphics2D g2){
gRef = g2;
}
@Override
protected Void doInBackground() {
result = 100+100;
return null;
}
@Override
protected void done() {
gRef.drawLine(20, 20, result, result);
}
}
}
最佳答案
paintComponent() 方法仅用于绘画!从 paintComponent() 方法中删除 SwingWorker 代码。
如果你想绘制一个组件,那么 done() 方法应该调用组件的一个属性。例如,在您的情况下,您试图画一条线,因此 paintComponent 方法中的代码可能如下所示:
super.paintComponent(g);
if (drawLine)
g.drawLine(...);
然后你会创建一个像这样的方法:
public void setDrawLine(Boolean drawLine)
{
this.drawLine = drawLine;
repaint();
}
所以在 done() 方法中,您只需在组件上调用 setDrawLine(true)
。
此外,无论何时进行自定义绘制,您都需要覆盖 getPreferredSize()
方法以返回组件的尺寸,以便布局管理器可以使用此信息,否则尺寸将为 (0, 0) 并且没有什么可画的。阅读 Custom Painting 上的 Swing 教程获取更多信息和工作示例。
也许您还需要一个单独的方法来在您的组件中启动 SwingWorker。
编辑:
我更改了你的代码:
@Override
public void paintComponent(final Graphics g)
{
super.paintComponent(g);
g.drawLine(10, 0, 10, 100);
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
g2.drawLine(100, 0, 100, 100);
}
});
}
这也行不通。我猜测由于代码被添加到 EDT 的末尾,所以当它执行时,Graphics 对象已经被释放。
关于java - 尝试从 SwingWorker done() 方法绘制 JPanel 什么都不做,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29354177/