我正在尝试自定义javafx控件,我在使用ScatterChart时遇到了一些问题。 我想要做的是扩展标准ScatterChart,以便我可以添加一个属性,我稍后将绑定到ImageView的视口。 在开始绑定之前(这对我来说也是新的)我尝试了一个最小的实现,看看我是否把事情做对了。这是自定义BindableChart
的代码<property environment="env"/>
这里是它的fxml代码
public class BindableChart<X,Y> extends ScatterChart<X,Y>
public BindableChart(@NamedArg("xAxis")Axis<X> xAxis,@NamedArg("yAxis")Axis<Y> yAxis){
super(xAxis,yAxis);
FXMLLoader fxmlLoader = new FXMLLoader(
getClass().getResource("/fxml/BindableChart.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
}
当我尝试运行包含BindableChart类的测试应用程序时,我得到一个PropertyNotFoundException,表示xAxis属性不存在或是只读的。 有什么想法吗?
答案 0 :(得分:1)
您尝试定义轴两次:一次在FXML文件中,一次在Java代码中。请注意,当您在FXML加载程序上调用load()
时(即解析FXML文件时),已经通过调用超类构造函数来定义轴。
如果你要继承ScatterChart
,那么你几乎必须通过Java代码初始化轴。如果要强制轴为NumberAxis
的实例,则可以通过在super()
的调用中创建它们来实现。当然,NumberAxis
是子类Axis<Number>
,因此强制BindableChart
成为ScatterChart<Number, Number>
的子类,因此您最终会使用
package bindablechart ;
import java.io.IOException;
import javafx.fxml.FXMLLoader;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.ScatterChart;
public class BindableChart extends ScatterChart<Number, Number> {
public BindableChart(){
super(new NumberAxis(), new NumberAxis());
FXMLLoader fxmlLoader = new FXMLLoader(
getClass().getResource("BindableChart.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
}
并且FXML变为
<?xml version="1.0" encoding="UTF-8"?>
<fx:root xmlns:fx="http://javafx.com/fxml/1" type="bindablechart.BindableChart">
</fx:root>
(此时,FXML可能会变得完全多余;我不知道你还有什么,如果有的话。)
此版本的测试如下:
package bindablechart;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class BindableChartTest extends Application {
@Override
public void start(Stage primaryStage) {
Scene scene = new Scene(new BindableChart());
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
或者您可以使用
将其包含在另一个FXML文件中<BindingChart />
如果你想让这个类的用户指定轴,你可以这样做,但你仍然可以从FXML中删除它们(因为用户指定了它们)......:
package bindablechart;
import java.io.IOException;
import javafx.beans.NamedArg;
import javafx.fxml.FXMLLoader;
import javafx.scene.chart.Axis;
import javafx.scene.chart.ScatterChart;
public class BindableChart<X,Y> extends ScatterChart<X, Y> {
public BindableChart(@NamedArg("xAxis") Axis<X> xAxis, @NamedArg("yAxis") Axis<Y> yAxis){
super(xAxis, yAxis);
FXMLLoader fxmlLoader = new FXMLLoader(
getClass().getResource("BindableChart.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
}
使用与上述相同的FXML文件。
在这种情况下,测试用例看起来像
package bindablechart;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.chart.NumberAxis;
import javafx.stage.Stage;
public class BindableChartTest extends Application {
@Override
public void start(Stage primaryStage) {
Scene scene = new Scene(
new BindableChart<Number, Number>(new NumberAxis(), new NumberAxis()));
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
或者您可以使用
在FXML中创建一个<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.chart.NumberAxis?>
<?import bindablechart.BindableChart?>
<StackPane xmlns:fx="http://javafx.com/fxml/1">
<BindableChart>
<xAxis><NumberAxis/></xAxis>
<yAxis><NumberAxis/></yAxis>
</BindableChart>
</StackPane>