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

萨夫特克

编辑:因此代码实际上工作正常-所有对象均按应有的方式进行了修改。该方法仍在运行时,只是表面似乎在更新自身时出现问题...


我正在开发一个项目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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

Related 相关文章

热门标签

归档