我正在尝试创建Integer
Spinner
,而是创建一个Double
。
的Test.class
package com.neonorb.test;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Insets;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class Test extends Application{
@Override
public void start(Stage stage) throws Exception {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("Demo.fxml"));
Parent root = fxmlLoader.load();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
DemoController.class
package com.neonorb.test;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Spinner;
import java.net.URL;
import java.util.ResourceBundle;
public class DemoController implements Initializable{
@FXML
private Spinner<Integer> spinner;
@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
System.out.println(spinner.getValue());
}
}
Demo.fxml
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.Spinner?>
<?import java.lang.Integer?>
<BorderPane xmlns:fx="http://javafx.com/fxml" fx:controller="com.neonorb.test.DemoController">
<Spinner fx:id="spinner" min="1" initialValue="1" amountToStepBy="1">
<max>
<Integer fx:constant="MAX_VALUE"/>
</max>
</Spinner>
</BorderPane>
当我执行它时会输出1.0
,这就是我知道它是如何制作Double
微调器。
我猜是FXMLLoader
正在为Spinner
选择错误的构造函数。如何选择Integer
?
答案 0 :(得分:12)
您需要为微调器设置值工厂。否则你将面临类型强制。如果您无法在那里设置它,则可以定义将由static valueOf()调用的Integer值。
JavaFX FXML简介关于Type Coercion的说明:
类型强制
FXML使用“类型强制”将属性值转换为 适当的类型。类型强制是必需的,因为唯一的 XML支持的数据类型是元素,文本和属性(其中的 值也是文本)。但是,Java支持许多不同的 数据类型包括内置原始值类型以及 可扩展的引用类型。
FXML加载器使用BeanAdapter的coerce()方法执行任何操作 必需的类型转换。该方法能够执行基本操作 原始类型转换,如String to boolean或int to double, 并且还会将String转换为Class或String转换为Enum。额外 可以通过定义静态 valueOf()方法来实现转换 在目标类型上。
<小时/>
已存在IntegerSpinnerValueFactory。因为它是SpinnerValueFactory的嵌套类,所以必须在标记名中使用一个点。
有三个可用的构造函数,您可以设置min / max和min / max / initialValue和min / max / initialValue / amountToStepBy。这是通过将其设置为属性来完成的。
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.util.* ?>
<?import javafx.scene.*?>
<?import javafx.scene.control.* ?>
<?import javafx.scene.layout.* ?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" fx:controller="demoapp.DemoController">
<center>
<Spinner fx:id="spinner" BorderPane.alignment="CENTER" >
<valueFactory>
<SpinnerValueFactory.IntegerSpinnerValueFactory min="0" max="10"/>
</valueFactory>
</Spinner>
</center>
</BorderPane>
<小时/>
您还可以定义两个变量并将它们用作静态valueOf()。如上面引用的静态valueOf()方法所述。因此,您的FXMLLoader不必猜测您可能意味着哪种类型。它使用int值调用构造函数。
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.util.* ?>
<?import javafx.scene.*?>
<?import javafx.scene.control.* ?>
<?import javafx.scene.layout.* ?>
<BorderPane xmlns:fx="http://javafx.com/fxml/1" fx:controller="demoapp.DemoController" xmlns="http://javafx.com/javafx/8.0_40" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" >
<center>
<fx:define>
<Integer fx:id="min" fx:value="0"/>
<Integer fx:id="max" fx:value="10"/>
</fx:define>
<Spinner fx:id="spinner" BorderPane.alignment="CENTER" min="$min" max="$max">
</Spinner>
</center>
</BorderPane>
答案 1 :(得分:3)
FXML文件的小更新......
包含
<?import javafx.scene.control.SpinnerValueFactory.IntegerSpinnerValueFactory?>
然后
<Spinner fx:id="spinner" BorderPane.alignment="CENTER" editable="true" >
<valueFactory>
<SpinnerValueFactory.IntegerSpinnerValueFactory min="0" max="10" initialValue="5" amountToStepBy="1"/>
</valueFactory>
</Spinner>