FXMLLoader.load()上的程序停顿

时间:2017-11-19 20:08:31

标签: java javafx

我正在尝试制作一个可以记录和绘制Android手机数据的记录程序。为了显示数据,我使用javafx在主窗口中创建子窗口,每个子窗口都有一个折线图。该程序连接到手机就好了,但是当它试图创建一个新的子窗口来记录传入的数据时,程序停止,但没有给出错误的指示。这是我的主窗口类的代码。

public class Window implements OnReceiveData, OnConnectionUpdate {

private static final int GRAPH_OFFSET = 20;

@FXML
public Button adbButton;
@FXML
private Label adbStatus, connectionStatus;
@FXML
private MenuButton devices;
@FXML
private VBox variables;
@FXML
private AnchorPane contentPane;
@FXML
private DataStreamer streamer;

private JadbConnection connection;
private Map<String, InternalWindow> windows;
private int devicesHashCode;
private double xGraphOffset, yGraphOffset;

@FXML
protected void initialize() {
    this.xGraphOffset = 0;
    this.yGraphOffset = 0;
    this.devicesHashCode = -1;
    this.windows = new HashMap<>();
    DataLogger.getService().scheduleAtFixedRate(() -> {
        boolean connected = true;
        try {
            if (connection == null)
                connection = new JadbConnection();
            List<JadbDevice> devices = connection.getDevices();
            if (devicesHashCode != devices.hashCode()) {
                devicesHashCode = devices.hashCode();
                updateDeviceList(devices.stream().collect(Collectors.toMap(x -> x, DeviceUtils::getTitle)));
            }
        } catch (Exception e) {
            if (!(e instanceof ConnectException))
                e.printStackTrace();
            devices.setDisable(true);
            connection = null;
            connected = false;
        }

        setADBStatus(connected);

    }, 0, 100, TimeUnit.MILLISECONDS);
}

@FXML
protected void onHardRest(ActionEvent event) {

}

@FXML
public void onRefreshADB(ActionEvent event) {
    DataLogger.getService().execute(() -> {
        if (connection == null) {
            ADBUtils.start();
        } else {
            ADBUtils.stop();
            ADBUtils.start();
        }
    });
}

private void connect(JadbDevice device) {
    Optional<String> optionalAddress = DeviceUtils.getIPAddress(device);
    devices.setDisable(true);
    if (optionalAddress.isPresent()) {
        streamer = new DataStreamer(optionalAddress.get())
                .addConnectionListener(this)
                .addDataListener(this)
                .start();
    } else {
        devices.setDisable(false);
        Alert alert = new Alert(AlertType.ERROR);
        alert.setTitle("Invalid IP!");
        alert.setHeaderText("App Not sSarted!");
        alert.setContentText("We were unable to parse a valid IP address from the device. Please check the console for more info!");
        alert.show();
    }
}

protected InternalWindow createGraph(String title) {
    FXMLLoader loader = new FXMLLoader(getClass().getResource("/internal-window.fxml"));
    try {
        Pane load = loader.load();
        //stalls here
        load.setLayoutX(xGraphOffset);
        load.setLayoutY(yGraphOffset);
        contentPane.getChildren().add(load);

        xGraphOffset += GRAPH_OFFSET;
        yGraphOffset += GRAPH_OFFSET;

        if (yGraphOffset + load.getPrefHeight() > contentPane.getHeight()) {
            xGraphOffset += GRAPH_OFFSET;
            yGraphOffset = 0;
        }

        if (xGraphOffset + load.getPrefWidth() > contentPane.getWidth()) {
            xGraphOffset = 0;
            yGraphOffset = 0;
        }
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }

    InternalWindow controller = loader.getController();
    controller.setTitle(title);
    controller.addWindowExitListener((listener, pane) -> contentPane.getChildren().remove(pane));
    return controller;
}

private void updateDeviceList(Map<JadbDevice, String> devices) {
    Platform.runLater(() -> {
        ObservableList<MenuItem> menuItems = this.devices.getItems();
        menuItems.clear();
        for (JadbDevice device : devices.keySet()) {
            MenuItem item = new MenuItem(devices.get(device));
            item.setOnAction(e -> connect(device));
            menuItems.add(item);
        }
        this.devices.setDisable(devices.size() <= 0);
    });
}

private void setADBStatus(boolean running) {
    Platform.runLater(() -> {
        adbButton.setText((running ? "Refresh" : "Start") + " ADB");
        adbButton.setDisable(false);
        updateStatus(running, adbStatus);
    });
}

private void updateStatus(boolean status, Label label) {
    label.setText(status ? "Yes" : "No");
    label.setTextFill(status ? Color.GREEN : Color.RED);
}

@Override
public void onConnectionUpdate(boolean connected, Exception exception) {
    Platform.runLater(() -> {
        if (exception != null) {
            Alert alert = new Alert(AlertType.ERROR);
            alert.setTitle("Device Connection Error!");
            alert.setHeaderText("We are unable to connect to the device!");
                alert.setContentText(exception.getMessage());
                alert.show();
                exception.printStackTrace();
            }
            devices.setDisable(connected);
            updateStatus(connected, connectionStatus);
        });
        System.out.println("We are connected: " + connected);
    }

    @Override
    public void onReceiveData(String graph, double[] values) {
        System.out.println("Received: " + Arrays.toString(values));
        if(windows.containsKey(graph)){
            windows.get(graph).update(values, graph);
        }
        else windows.put(graph, createGraph(graph));
    }
}

这是内部窗口类的代码

public class InternalWindow {

private static final int RESIZE_MARGIN = 10;

@FXML
public BorderPane node;
@FXML
private LineChart<Number, Number> lineGraph;
@FXML
private Label titleLabel;
@FXML
private SplitMenuButton mergeDropdown;

private HashMap<String, XYChart.Series> series;

private double xDragDelta, yDragDelta, mouseX, mouseY;
private List<OnInternalWindowExit> exitListeners;
private boolean resizing, resizingX, resizingY;

@FXML
void initialize() {
    xDragDelta = 0;
    yDragDelta = 0;
    mouseX = 0;
    mouseY = 0;
    exitListeners = new ArrayList<>();
    resizing = false;
    resizingY = false;
    resizingX = false;

    node.setMinWidth(node.getPrefWidth());
    node.setMinHeight(node.getPrefHeight());

    series = new HashMap<>();
}

public void setTitle(String title) {
    this.titleLabel.setText(title);
}

public void addWindowExitListener(OnInternalWindowExit listener) {
    exitListeners.add(listener);
}

@FXML
protected void onExit(ActionEvent event) {
    for (OnInternalWindowExit listener : exitListeners) {
        listener.onInternalWindowExit(this, node);
    }
}

@FXML
protected void onClearGraph(ActionEvent event) {

}

@FXML
protected void onExportGraph(ActionEvent event) {

}

/******************************************
 *
 *                Dragging
 *
 ******************************************/

@FXML
protected void onBarDragged(MouseEvent event) {
    double offsetX = event.getSceneX() - mouseX;
    double offsetY = event.getSceneY() - mouseY;

    xDragDelta += offsetX;
    yDragDelta += offsetY;

    Pane pane = (Pane) node.getParent();
    node.setLayoutX(constrain(xDragDelta, 0, pane.getWidth() - node.getWidth()));
    node.setLayoutY(constrain(yDragDelta, 0, pane.getHeight() - node.getHeight()));

    // again set current Mouse x AND y position
    mouseX = event.getSceneX();
    mouseY = event.getSceneY();
}

@FXML
protected void onBarPressed(MouseEvent event) {
    mouseX = event.getSceneX();
    mouseY = event.getSceneY();

    xDragDelta = node.getLayoutX();
    yDragDelta = node.getLayoutY();

    node.toFront();
}

/******************************************
 *
 *                Resizing
 *
 ******************************************/

@FXML
protected void onResizeReleased(MouseEvent event) {
    resizing = false;
    node.setCursor(Cursor.DEFAULT);
}

@FXML
protected void onResizeOver(MouseEvent event) {
    Cursor cursor = Cursor.DEFAULT;
    if (updateResizeState(event) || resizing) {
        if (resizingX && resizingY) {
            cursor = Cursor.NW_RESIZE;
        } else if (resizingX) {
            cursor = Cursor.E_RESIZE;
        } else if (resizingY) {
            cursor = Cursor.S_RESIZE;
        }
    }

    node.setCursor(cursor);
}

@FXML
protected void onResizeDragged(MouseEvent event) {
    if (!resizing) {
        return;
    }

    Pane pane = (Pane) node.getParent();
    if (resizingX) {
        double width = node.getMinWidth() + (event.getX() - mouseX);
        node.setMinWidth(constrain(width, node.getPrefWidth(), pane.getWidth() - node.getLayoutX()));
        mouseX = event.getX();
    }
    if (resizingY) {
        double height = node.getMinHeight() + (event.getY() - mouseY);
        node.setMinHeight(constrain(height, node.getPrefHeight(), pane.getHeight() - node.getLayoutY()));
        mouseY = event.getY();
    }
}

@FXML
protected void onResizePressed(MouseEvent event) {
    if (!updateResizeState(event)) {
        return;
    }

    resizing = true;

    mouseY = event.getY();
    mouseX = event.getX();
}

protected boolean updateResizeState(MouseEvent event) {
    resizingX = event.getX() > node.getWidth() - RESIZE_MARGIN;
    resizingY = event.getY() > node.getHeight() - RESIZE_MARGIN;
    return resizingX || resizingY;
}

private double constrain(double value, double min, double max) {
    if (value < min) {
        return min;
    }

    if (value > max) {
        return max;
    }

    return value;
}

public void update(double[] values, String tag) {
    if(!series.containsKey(tag)){
        XYChart.Series series = new XYChart.Series();
        series.setName(tag);
        lineGraph.getData().add(series);
        this.series.put(tag, series);
    }
    series.get(tag).getData().addAll(values);
}
}

谢谢。

0 个答案:

没有答案