编辑:所以代码实际上工作正常 - 所有对象都应该按原样修改。当方法仍然在运行时,只有表面似乎有问题更新...
我正在开展一个项目atm,主要是解决一个推箱子谜语。现在,我们已经实现了GUI和算法的东西来解决这个谜题,但是连接似乎很棘手。 例如,在GUI中我选择“解决”并且算法解决了谜语(在控制台中可见),但GUI不会改变为InGame视图(在调用resolve()之前初始化)。如果我这样做/ / switchToRoboControl()它会立即显示InGame!)。在solve()完成后它将切换到InGame,这是不方便的,因为它应该显示在地图上移动的图标并解决谜语。
所以我的实际问题是:如何正确地同步前端和后端,这样如果后端进行移动并通知前端,前端实际上显示发生了什么。
另外,如果有人对此有任何想法,为什么InGame在完成solve()之后会出现,即使它之前被初始化,即使isVisible()返回true?
我可以发布代码,如果这有帮助,但有成千上万行,所以我想也许解释问题,并得到一个提示,这将有助于我解决这个问题就足够了......
谢谢!
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());
}
}
(最后一部分是集成测试的模拟,稍后将被实际的方法调用替换为“getSolution()”等等......这就是解决方案在代码中实现的原因。)
答案 0 :(得分:1)
好吧,据我所知,你的问题是计算逻辑在与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将被更新。