我有4个不同系列的LineChart。有复选框应显示/隐藏图表中的对应系列。但是,当我按下“ Euler”,“ Euler改进”,“ Runge-Kutta”复选框时,它们完全不会影响图表,直到我按下“精确”复选框。绝对不能解决问题。
这是我尝试隐藏/显示的方式:
@FXML private NumberAxis xAxis = new NumberAxis();
@FXML private NumberAxis yAxis = new NumberAxis();
@FXML private LineChart<Number, Number> chartAll = new LineChart<>(xAxis, yAxis);
private XYChart.Series<Number, Number> exactSeries = new XYChart.Series<>();
private XYChart.Series<Number, Number> eulerSeries= new XYChart.Series<>();
private XYChart.Series<Number, Number> improvedEulerSeries = new XYChart.Series<>();
private XYChart.Series<Number, Number> rungeKuttaSeries = new XYChart.Series<>();
@FXML private CheckBox exactChartCheckbox;
@FXML private CheckBox eulerChartCheckbox;
@FXML private CheckBox improvedEulerChartCheckbox;
@FXML private CheckBox rungeKuttaChartCheckbox;
@FXML
protected void handlePlotButton(ActionEvent event) {
chartAll.getData().clear();
double x0 = Double.parseDouble(x0Input.getText());
double y0 = Double.parseDouble(y0Input.getText());
double x = Double.parseDouble(xInput.getText());
double step = Double.parseDouble(stepInput.getText());
IVP ivpForExact = new IVP(x0, y0, x, step);
Exact exact = new Exact(ivpForExact);
Euler euler = new Euler(ivpForExact);
ImprovedEuler improvedEuler = new ImprovedEuler(ivpForExact);
RungeKutta rungeKutta = new RungeKutta(ivpForExact);
exactSeries.setName("Exact");
eulerSeries.setName("Euler");
improvedEulerSeries.setName("Improved Euler");
rungeKuttaSeries.setName("Runge-Kutta");
for (int i = 0; i < exact.getGrid().getSize(); i++) {
exactSeries.getData().add(new XYChart.Data<>(exact.getGrid().getXat(i), exact.getGrid().getYat(i)));
eulerSeries.getData().add(new XYChart.Data<>(euler.getGrid().getXat(i), euler.getGrid().getYat(i)));
improvedEulerSeries.getData().add(new XYChart.Data<>(improvedEuler.getGrid().getXat(i), improvedEuler.getGrid().getYat(i)));
rungeKuttaSeries.getData().add(new XYChart.Data<>(rungeKutta.getGrid().getXat(i), rungeKutta.getGrid().getYat(i)));
}
chartAll.getData().add(exactSeries);
chartAll.getData().add(eulerSeries);
chartAll.getData().add(improvedEulerSeries);
chartAll.getData().add(rungeKuttaSeries);
stepInput.clear();
}
@FXML
protected void exactChartCheckboxPressed(ActionEvent event) {
if(!exactChartCheckbox.isSelected()) {
chartAll.getData().get(0).getNode().setVisible(false);
} else {
chartAll.getData().get(0).getNode().setVisible(true);
}
}
@FXML
protected void eulerChartCheckboxPressed(ActionEvent event) {
if(!eulerChartCheckbox.isSelected()) {
chartAll.getData().get(1).getNode().setVisible(false);
} else {
chartAll.getData().get(1).getNode().setVisible(true);
}
}
这是FXML:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.chart.*?>
<?import javafx.scene.layout.*?>
<GridPane fx:id="scene" alignment="center" hgap="10" vgap="10" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
<columnConstraints>
<ColumnConstraints />
</columnConstraints>
<rowConstraints>
<RowConstraints />
</rowConstraints>
<children>
<Pane fx:id="pane" prefHeight="600.0" prefWidth="1080.0">
<children>
<LineChart fx:id="chartAll" createSymbols="false" layoutX="48.0" layoutY="135.0" prefHeight="427.0" prefWidth="698.0">
<xAxis>
<NumberAxis label="x" fx:id="xAxis" />
</xAxis>
<yAxis>
<NumberAxis fx:id="yAxis" autoRanging="false" label="y" lowerBound="-10.0" upperBound="40.0" />
</yAxis>
<opaqueInsets>
<Insets />
</opaqueInsets>
</LineChart>
<Button layoutX="48.0" layoutY="54.0" mnemonicParsing="false" prefHeight="41.0" prefWidth="120.0" text="Solutions" />
<TextField layoutX="883.0" layoutY="211.0" prefHeight="25.0" prefWidth="96.0" text="0" fx:id="x0Input" />
<TextField fx:id="y0Input" layoutX="883.0" layoutY="254.0" prefHeight="25.0" prefWidth="96.0" text="3" />
<TextField layoutX="883.0" layoutY="296.0" prefHeight="25.0" prefWidth="96.0" text="5.5" fx:id="xInput" />
<TextField fx:id="stepInput" layoutX="883.0" layoutY="336.0" prefHeight="25.0" prefWidth="96.0" text="0.1" />
<Label layoutX="841.0" layoutY="215.0" text="x0" />
<Label layoutX="841.0" layoutY="258.0" text="y0" />
<Label layoutX="841.0" layoutY="300.0" text="X" />
<Label layoutX="835.0" layoutY="340.0" text="step" />
<Button fx:id="plotButton" layoutX="896.0" layoutY="385.0" mnemonicParsing="false" onAction="#handlePlotButton" prefHeight="41.0" prefWidth="71.0" text="Plot" />
<CheckBox fx:id="exactChartCheckbox" layoutX="347.0" layoutY="562.0" mnemonicParsing="false" onAction="#exactChartCheckboxPressed" selected="true" text="Exact" />
<CheckBox fx:id="improvedEulerChartCheckbox" layoutX="523.0" layoutY="562.0" mnemonicParsing="false" onAction="#improvedEulerChartCheckboxPressed" selected="true" text="Improved Euler" />
<CheckBox fx:id="rungeKuttaChartCheckbox" layoutX="646.0" layoutY="562.0" mnemonicParsing="false" onAction="#rungeKuttaChartCheckboxPressed" selected="true" text="Runge-Kutta" />
<CheckBox fx:id="eulerChartCheckbox" layoutX="444.0" layoutY="562.0" mnemonicParsing="false" onAction="#eulerChartCheckboxPressed" selected="true" text="Euler" />
</children>
</Pane>
</children>
</GridPane>
这是结果
问题实际上是仅当我选中/取消选中“精确”复选框时才会更新图表,所有其他三个都不影响图表。但是,当我按下“精确”复选框时,它们也在尝试进行更新,但操作不正确。
答案 0 :(得分:1)
要有效隐藏节点,请尝试设置托管属性
series.getNode().setManaged(false);
定义此节点的布局是否将由其父节点管理。如果节点是托管节点,则其父节点将把节点的几何形状纳入其自身的首选大小和layoutBounds计算中,并将在场景的布局过程中对其进行布局。如果受管节点的layoutBounds发生更改,它将自动触发将场景图向上中继到最近的布局根(通常是场景的根节点)。
如果节点不受管理,则其父节点将在首选大小计算和布局中都忽略子节点。 layoutBounds的更改不会触发其上方的重新布局。如果非托管节点的类型为Parent,则它将充当“布局根”,这意味着对它下面的Parent.requestLayout()的调用将仅中继出该节点根目录下的分支,从而隔离对该布局的更改根及以下。设置非托管节点的大小和位置是应用程序的责任。
答案 1 :(得分:0)
根据评论的时长,我将其发布在答案中而不是评论中。
首先,如果您查看XYChart.Series中的 node 文档,
要为此系列显示的节点。这是由图表创建的,如果 它使用节点表示整个系列。例如折线图 使用此线,但散点图不使用它。这个节点 系列一旦添加到图表中,便会设置。那你可以 获取它以添加鼠标侦听器等。
从上面显而易见,如果它是折线图,则可以轻松依赖于节点。从屏幕截图中,我可以看到您已经在使用LineChart。这不是问题。如果检查节点类型,则其类型将为路径。但是如果折线图上显示数据点,情况就会变得有些混乱。有时仅切换节点(路径)的可见性并不能达到预期的效果。例如,检查以下屏幕截图。
因此,要从图表中隐藏系列,我建议从数据中添加/删除系列,而不要切换系列节点的可见性。
谈到您的问题,我进行了快速检查,以切换行的可见性,并且在所有系列中均能正常工作。可能是代码中的一些问题。正如@Slaw所提到的,Minimal, Complete, and Verifiable example可以帮助我们理解问题,甚至可以自己解决问题。
答案 2 :(得分:0)
看来,这取决于您的运气或某些旧版JavaFX代码。当我将每个系列更改为系列数组时:
private ArrayList<XYChart.Series<Number, Number>> exactSeries = new ArrayList<>();
private ArrayList<XYChart.Series<Number, Number>> eulerSeries = new ArrayList<>();
private ArrayList<XYChart.Series<Number, Number>> improvedEulerSeries = new ArrayList<>();
private ArrayList<XYChart.Series<Number, Number>> rungeKuttaSeries = new ArrayList<>();
,然后为所有情况创建通用功能:
private void turnVisibility(CheckBox checkBox, ArrayList<XYChart.Series<Number, Number>> seriesList) {
if (!checkBox.isSelected()) {
for(XYChart.Series<Number, Number> series: seriesList) {
series.getNode().setVisible(false);
}
} else {
for(XYChart.Series<Number, Number> series: seriesList) {
series.getNode().setVisible(true);
}
}
}
可见性开始正常工作。