同步“前端".和“后端"在Java(和SWT)中 [英] Synchronizing "Frontend" and "Backend" in Java (and SWT)

查看:91
本文介绍了同步“前端".和“后端"在Java(和SWT)中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So the code is actually working fine - all objects are modified as they should be. It's only the surface that seems to have issues updating itself while the method is still running...

我正在研究一个atm项目,该项目基本上是关于解决推箱子问题的.现在,我们已经实现了GUI和算法方面的功能来解决这个难题,但是连接似乎很棘手. 例如,在GUI中,我选择"solve",并且算法解决了谜语(在控制台中可见),但是GUI不会更改为InGame视图(在solve()调用之前已初始化). /switchToRoboControl(),它将立即显示InGame!).完成solve()后,它将切换到InGame,这不方便,因为它应该显示图标在地图上移动并解决谜题.

I'm working on a project atm which is basically about solving a Sokoban-riddle. Now, we've implemented both the GUI and the algorithm stuff to solve the riddle, but the connection seems to be tricky. For example, in the GUI I choose "solve" and the algorithm solves the riddle (visible in the console), but the GUI doesn't change into the InGame view (which is initialized BEFORE solve() is called. If I do //switchToRoboControl() it will show the InGame immediately!). It will switch into InGame after solve() is done, which is inconventient since it's supposed to show the icons moving on the map and solving the riddle.

所以我的实际问题是:如何正确同步前端和后端,以便如果后端采取行动并通知前端,则前端实际上会显示发生了什么.

So my actual question is: how do I sychronize frontend and backend properly, so that if the backend makes a move and notifies the frontend, the frontend actually SHOWS what happened.

此外,如果有人对此有任何想法,那么为什么在insolve()完成后InGame仍会显示出来,即使它已在isVisible()返回true之前进行了初始化?

Also, if anyone has any ideas about that, why on earth does the InGame show up after solve() is done, even though it's initialized before and even though isVisible() returns true?

如果有帮助,我可以发布代码,但是有成千上万行,所以我认为也许可以解释问题并得到提示,可以帮助我解决问题...

I can post the code if that helps, but there are thousands of lines so I thought maybe explaining the problem and getting a hint that would help me solve this could be enough...

谢谢!



    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()"之类的真实方法调用来代替,这就是为什么在代码中实现了解决方案的原因.)

(The last part is a simulation for the integrationtest and will later be replaced by real method calls like "getSolution()" and so on... That's why the solution is implemented in the code.)

推荐答案

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

Well, as far as I can see your problem is that the calculation logic runs in the same thread as the GUI. This causes no updates during the calculation. You need to put the calculation in a background thread. Also, your Thread.sleep() will cause the GUI to do nothing.

因此,将您的计算结果例如在一个Runnable中.

So, put your calculation e.g. in a 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将会更新.

Display.asyncExec will forward you changes to the gui and return immediatly to the calling method. The UI will be updated when there is time in the display thread.

这篇关于同步“前端".和“后端"在Java(和SWT)中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆