更新JavaFX gui以实现高速操作的最佳方法是什么?

时间:2012-03-16 02:23:46

标签: javafx-2

我有一个通过串口与硬件设备通信的应用程序。该设备每30ms发送一个json对象。这个json对象是设备“状态”它的运动控制器。

消息基本上如下:

{"sr":{"line":2524,"posx":1.000,"posy":21.000,"posz":20.000,"posa":11.459,"feed":0.000,"vel":0.000,"unit":1,"coor":1,"dist":0,"frmo":0,"momo":0,"stat":2}}

我每隔30ms就得到1x。我必须解析它们。然后将它们“绘制”到JavaFX gui上。

以下是我解析的方式:

Platform.runLater(new Runnable() {

            public void run() {
                //We are now back in the EventThread and can update the GUI
                try {
                    JsonRootNode json = JDOM.parse(l);

                    xAxisVal.setText(json.getNode("sr").getNode("posx").getText());
                    yAxisVal.setText(json.getNode("sr").getNode("posy").getText());
                    zAxisVal.setText(json.getNode("sr").getNode("posz").getText());
                    aAxisVal.setText(json.getNode("sr").getNode("posa").getText());
                    drawLine();

                } catch (argo.saj.InvalidSyntaxException ex) {
                    //Json line invalid.
                }
            }
        });

这是我正在使用的绘图代码:

public void drawLine() {
    xl.setX(Float.parseFloat(xAxisVal.getText()) + 400);
    y1.setY(Float.parseFloat(yAxisVal.getText()) + 400);
    LineTo tmpL = new LineTo((Float.parseFloat(xAxisVal.getText()) * 2) + 400, (Float.parseFloat(yAxisVal.getText()) * 2) + 400);
    path.getElements().add(tmpL);

}

所以基本上我每30ms创建一个可运行的对象,然后进行解析和绘制。这是最好的方法吗?你可以看到它的视频:

http://www.youtube.com/watch?v=dhBB3QcmHOg&feature=youtu.be

但似乎它的“生涩”和资源非常饥饿。我希望有人能就如何优化此代码向我提出建议?也许指出一些我错过的东西?

作为一个FYI,我们制作的运动控制器板称为TinyG。它的开源硬件 更多信息在这里: http://www.synthetos.com/wiki/index.php?title=Projects:TinyG

此处固件: https://github.com/synthetos/TinyG

谢谢!

2 个答案:

答案 0 :(得分:3)

您似乎在事件队列上执行了太多计算,在解析数据时会阻止图形渲染。您应该在单独的线程中进行计算,并仅针对相关的ui代码调用Platform.runLater()

    try {

        JsonRootNode json = JDOM.parse(l);
        final String xVal = json.getNode("sr").getNode("posx").getText();
        final String yVal = json.getNode("sr").getNode("posy").getText();
        final String zVal = json.getNode("sr").getNode("posz").getText();
        final String aVal = json.getNode("sr").getNode("posa").getText();

        // here you are calling UI getter, and parse it each time
        // it would be more optimal to store `x` value in separate variable
        // between updates
        final float x = Float.parseFloat(xAxisVal.getText());
        final float y = Float.parseFloat(yAxisVal.getText());

        Platform.runLater(new Runnable() {

            public void run() {
                //We are now back in the EventThread and can update the GUI
                try {

                    xAxisVal.setText(xVal);
                    yAxisVal.setText(yVal);
                    zAxisVal.setText(zVal);
                    aAxisVal.setText(aVal);
                    xl.setX(x + 400);
                    y1.setY(y + 400);
                    LineTo tmpL = new LineTo(x * 2 + 400, y * 2 + 400);
                    path.getElements().add(tmpL);

                }
            }
        }

    } catch (argo.saj.InvalidSyntaxException ex) {
        //Json line invalid.
    }

答案 1 :(得分:1)

如果您还没有,请尝试developer preview release。对smooth animation and rendering performance的JavaFX 2.1预览分支进行了一些修改并优化path logic

替代方法是在WebView中写入HTML5画布,或者在JavaFX 2.2中使用JavaFX canvas node后使用{{3}}。