编辑:因此代码实际上工作正常-所有对象均按应有的方式进行了修改。该方法仍在运行时,只是表面似乎在更新自身时出现问题...
我正在开发一个项目atm,该项目基本上是关于解决推箱子难题的。现在,我们已经实现了GUI和算法方面的功能来解决这个难题,但是连接似乎很棘手。例如,在GUI中,我选择“ solve”,并且算法解决了谜语(在控制台中可见),但是GUI不会更改为InGame视图(在solve()调用之前已初始化)。 / switchToRoboControl(),它将立即显示InGame!)。完成solve()后,它将切换到InGame,这不方便,因为它应该显示图标在地图上移动并解决谜题。
因此,我的实际问题是:如何正确同步前端和后端,以便如果后端做出动作并通知前端,前端实际上会显示发生了什么。
此外,如果有人对此有任何想法,那么即使solveVisible()之前已初始化且isVisible()返回true,为什么InGame仍会在solve()完成后显示出来?
如果有帮助,我可以发布代码,但是有成千上万行,所以我认为也许可以解释问题并得到提示,可以帮助我解决此问题……
谢谢!
public class SokobanGUIManager {
public SokobanGUIManager() {
this.display = new Display();
//initialsiere Shell
this.shell = new Shell(this.display);
shell.setText("Sokobots - The absolute best Sokoban-Solver you've ever seen!");
shell.setSize(735, 460);
//initialisiere Stack-Layout
this.layout = new StackLayout();
shell.setLayout(layout);
shell.layout();
//öffne Main-Menü;
goToMainMenu();
//Starte Fenster
this.shell.open();
//Lebensschleife
while (!this.shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
}
public class InGameGUI extends Composite {
...
public void initRoboControl() {
this.roboControl = new RoboControlGUI(this, manager, map, map.twoRobos(), this, this.roboStream); //RoboControlGUI is a child-Composite of InGameGUI
this.roboControl.setLayoutData(new RowData(300, 400));
this.layout();
this.guiCoordinator.setRoboControl(this.roboControl);
this.guiCoordinator.switchToRoboControl();
}
...
}
public class GUICoordinator {
...
protected void switchToRoboControl() {
if(this.roboControl != null) {
this.roboControl.setVisible(true);
System.out.println("RoboControl is visible");
this.roboCoordinator.switchToRoboControl();
} else {
System.out.println("Epic fail");
}
}
...
}
public class RoboCoordinator {
public void switchToRoboControl() { //TODO
this.gui.addToStreamEnd("switched to automatic control");
this.gui.deleteFirstLine();
this.gui.addToStreamEnd("the robots are calculating a solution. please wait");
try{ Thread.sleep(5000); } catch(Exception e) {}
this.map.setSolution(new Solution("1u:1l:1r:1d"));
this.gui.deleteFirstLine();
this.gui.deleteFirstLine();
this.gui.addToStreamEnd("robot 1 in direction u");
this.gui.addToStreamEnd("robot 1 in direction l");
this.gui.addToStreamEnd("robot 1 in direction r");
this.gui.addToStreamEnd("robot 1 in direction d");
try{ Thread.sleep(2000); } catch (Exception e) {}
this.map.moveRobo(1, 'u');
this.gui.updateMoves();
this.gui.updateSurface();
this.gui.deleteFirstLine();
System.out.println(this.map.toString());
System.out.println("Erster Zug fertig!");
try{ Thread.sleep(2000); } catch (Exception e) {}
this.map.moveRobo(1, 'l');
this.gui.updateMoves();
this.gui.updateSurface();
this.gui.deleteFirstLine();
System.out.println(this.map.toString());
System.out.println("Zweiter Zug fertig!");
try{ Thread.sleep(2000); } catch (Exception e) {}
this.map.moveRobo(1, 'r');
this.gui.updateMoves();
this.gui.updateSurface();
this.gui.deleteFirstLine();
System.out.println(this.map.toString());
try{ Thread.sleep(2000); } catch (Exception e) {}
this.map.moveRobo(1, 'd');
this.gui.updateMoves();
this.gui.updateSurface();
this.gui.deleteFirstLine();
System.out.println(this.map.toString());
}
}
(最后一部分是Integrationtest的模拟,以后将被诸如“ getSolution()”之类的真实方法调用所替代,等等。这就是在代码中实现解决方案的原因。)
好吧,据我所知,您的问题是计算逻辑与GUI在同一线程中运行。在计算期间,这不会导致任何更新。您需要将计算放在后台线程中。同样,您的Thread.sleep()将导致GUI不执行任何操作。
因此,将您的计算结果放到Runnable中。
Runnable runnable = new Runnable(Display display) {
... some methods ...
@Override run() {
... your logic ...
display.asyncExec(new Runnable() {
run() {
// update your gui here
});
... some more logic ...
};
Display.asyncExec将把您的更改转发到gui并立即返回到调用方法。当显示线程中有时间时,UI将被更新。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句