在搜索了很多类似问题的答案后,我仍然没有找到适合我需要的解决方案。
基本上,我有一个while循环,我想等待repaint()方法完成,然后再开始该循环的另一次迭代。
更详细地说,我有一些片段是在扩展JComponent的MapPanel类的paintComponent方法中绘制的。然后,当用户单击按钮时,算法开始搜索从“上部”线段开始的交点(使用endpoint作为事件点)。这个算法基本上就是我所说的while循环,它调用这个while循环中的另一个算法,在每次迭代时发送一个事件点(这些事件点按顺序从上到下发送)。
我想做的是通过在当前事件点画一条线来显示算法的当前“位置”。当算法找到新的交叉点时,我也想显示它们。我确实绘制了画组件()方法中需要的东西。
问题是,当我在循环中为MapPanel调用repaint()方法时,它会等待整个循环结束,然后再更新UI(我发现了很多关于它为什么这样做的原因,但没有发现在我的特定情况下如何修复这一问题)。
好的,我已经解释完了,下面是实际的算法:
private void findIntersection(ArrayList<Segment> segments){
QTree Q=new QTree();
for (Segment s : segments){
Q.initialise(s);
}
TreeT T=new TreeT();
while (Q.getRoot()!=null){
Point p = Q.maxEventPoint(Q.getRoot());
Q.delete(p.getX(), p.getY());
mapPanel.setSweeplinePosition(p.getY());
handleEventPoint(p, T, Q);
mapPanel.repaint()
//should wait here for repaint() to complete
}
System.out.println("all intersections found, found " + mapPanel.getIntersections().size());
}
您是否尝试了方法线程。睡眠(毫秒)???例如,我习惯在代码中执行以下操作:
btnNewButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
pca.setIcon(new ImageIcon("icon.png"));
for(int i=0; i<4; i++) {
try{Thread.sleep(700);} catch(InterruptedException er){}
x+=20;
p.repaint();
}}
}).start();
}
});
问题是您的长时间运行的代码可能会在Swing事件线程上调用,这是一个阻止事件线程执行其操作(包括绘制GUI)的操作。
该解决方案可能与您在搜索中找到的类似,但我们不知道您为什么不能将其用于程序,也就是在SwingWorker后台线程中执行while循环,使用SwingWorker的发布/处理方法对发布临时结果,然后使用临时数据绘制图形。
有关这方面的更多信息,请阅读Swing中的并发
比如说
private void findIntersection(final ArrayList<Segment> segments) {
final SwingWorker<Void, Double> myWorker = new SwingWorker<Void, Double>() {
@Override
protected Void doInBackground() throws Exception {
QTree Q = new QTree();
for (Segment s : segments) {
Q.initialise(s);
}
TreeT T = new TreeT();
while (Q.getRoot() != null) {
Point p = Q.maxEventPoint(Q.getRoot());
Q.delete(p.getX(), p.getY());
publish(p.getY()); // push data to process method
// take care that this method below does not
// make Swing calls
handleEventPoint(p, T, Q);
}
return null;
}
@Override
protected void process(List<Double> chunks) {
for (Double yValue : chunks) {
// this is called on the EDT (Swing event dispatch thread)
mapPanel.setSweeplinePosition(yValue);
mapPanel.repaint();
}
}
};
myWorker.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
// get notified when Worker is done
if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
// TODO: any clean up code for when worker is done goes here
try {
myWorker.get(); // must call to trap exceptions that occur inside worker
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
});
myWorker.execute(); // execute worker
}
问题内容: 为什么每当我将ajax放入for循环中时,它都无法很好地同步? 例如,我的代码是: 为什么它先调用Ajax查询?是否有可能让ajax查询在继续之前完成?因为它在完成填充之前就清除了数组。:/ 问题答案: 首先,您确实需要了解Ajax调用是如何异步的(这就是Ajax中的“ A”所代表的意思)。这意味着调用仅启动ajax调用(它将请求发送到服务器),其余代码愉快地继续运行。有时,在其余代码
问题内容: 我想编写一个后台作业(EJB 3.1),该作业每分钟执行一次。为此,我使用以下注释: 工作正常。 但是,有时该工作可能需要一分钟以上。在这种情况下,计时器仍会触发,从而导致线程问题。 如果当前执行未完成,是否可以终止调度程序? 问题答案: 如果可能只有一个计时器同时处于活动状态,则有两种解决方案。 首先,应该在。在Singleton中,方法默认情况下是写锁定的,因此,当容器中仍有活动时
问题内容: 我正在使用bluebird,方法 getAll 和 update return promises。我如何说“等到两个承诺返回,然后更新currentProduct值”?我对JS很陌生… 问题答案: 如果可以使用/,这将很简单。 或者,如果您只能使用简单的承诺,则可以遍历所有产品,并将每个承诺置于最后一个循环中。这样,仅当前一个问题解决时,它才会前进到下一个问题(即使它将首先迭代整个循环
我有一个递归算法,我用它来迭代分层数据结构,但不幸的是,对于一些数据,分层结构太深,以至于我得到了一个StackOverflow错误。我见过这种情况发生在大约150个节点的深度上,而数据可能会增长到更远的程度。对于上下文,这段代码将在有限的环境中运行,改变JVM堆栈大小不是一个选项,数据结构是给定的,代表不同的文件系统和目录和文件。 为了解决堆栈溢出问题,我尝试将算法转换为迭代算法。这不是我以前必
本节我们探索的主题是迭代与循环。循环通常在计算机编程用用于自动执行重复性任务。 在Python中最常用的迭代形式就是for循环了。for循环允许你迭代出列表中所有的项,迭代出来后你可以做任何你想做的事情。 比如,我们创建了一个列表,并打印出其中所有元素的平方。 >>> for value in [0, 1, 2, 3, 4, 5]: ... print(value * value) ... 0 1