“同步”;前端“;及;后端“;在Java(和SWT)中

“同步”;前端“;及;后端“;在Java(和SWT)中,java,swt,frontend,backend,Java,Swt,Frontend,Backend,编辑:所以代码实际上工作得很好-所有对象都按应有的方式修改。只有曲面在方法仍在运行时更新自身时出现问题 我在做一个atm项目,基本上就是解决一个索科班之谜。现在,我们已经实现了GUI和算法来解决这个难题,但是连接似乎很棘手。 例如,在GUI中,我选择“solve”,算法解决了这个谜题(在控制台中可见),但GUI不会更改为InGame视图(在调用solve()之前初始化。如果我这样做//switchToRoboControl(),它将立即显示InGame!)。在solve()完成后,它将切换到I

编辑:所以代码实际上工作得很好-所有对象都按应有的方式修改。只有曲面在方法仍在运行时更新自身时出现问题


我在做一个atm项目,基本上就是解决一个索科班之谜。现在,我们已经实现了GUI和算法来解决这个难题,但是连接似乎很棘手。 例如,在GUI中,我选择“solve”,算法解决了这个谜题(在控制台中可见),但GUI不会更改为InGame视图(在调用solve()之前初始化。如果我这样做//switchToRoboControl(),它将立即显示InGame!)。在solve()完成后,它将切换到InGame,这是不一致的,因为它应该显示图标在地图上移动并解开谜语

所以我的实际问题是:如何正确地同步前端和后端,以便如果后端移动并通知前端,前端实际显示发生了什么

另外,如果有人对此有任何想法,为什么InGame会在solve()完成后出现,即使它是在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());

        }
    }


(最后一部分是对integrationtest的模拟,稍后将被诸如“getSolution()”之类的实际方法调用所取代……这就是在代码中实现解决方案的原因。)

嗯,据我所知,您的问题是计算逻辑与GUI在同一线程中运行。 这在计算过程中不会导致更新。 您需要将计算放在后台线程中。另外,您的Thread.sleep()将导致GUI不执行任何操作

所以,把你的计算放在一个可运行的表格中

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.asynceec将把您所做的更改转发到gui,并立即返回到调用方法。当显示线程中有时间时,UI将被更新。

寻求调试帮助的问题(“为什么此代码不起作用?”)必须包括所需的行为、特定的问题或错误以及在问题本身中重现它所需的最短代码。没有明确问题陈述的问题对其他读者没有用处。请参阅:如何创建一个最小、完整且可验证的示例。对不起!我不知道我必须说得有多具体。我添加了与我的问题直接相关的代码。感谢您的反馈。您的代码与描述不匹配?solve()在哪里?对不起,当我还没有代码的时候solve()在那里。我试图简化它。solve()与switchToRoboControl()基本相同,听起来很有逻辑,但是当我按照建议将计算放在单独的线程中并刷新gui时,它将不再显示起始页,而是显示一个混乱的inGame。计算完成后,InGame看起来会很好。。。