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
を選択するにはどうすればよいですか?
スピナーにバリューファクトリを設定する必要があります。そうしないと、型強制に直面することになります。そこに設定できない場合は、static valueOf()によって呼び出される整数値を定義できます。
Type Coercion に関するJavaFXのFXML入門ノート:
型強制
FXMLは「型強制」を使用して、必要に応じてプロパティ値を適切な型に変換します。 XMLでサポートされるデータ型は要素、テキスト、および属性(値もテキスト)のみであるため、型強制が必要です。ただし、Javaは、組み込みのプリミティブ値型や拡張可能な参照型など、さまざまなデータ型をサポートしています。
FXMLローダーは、BeanAdapterのcoerce()メソッドを使用して、必要な型変換を実行します。このメソッドは、Stringからboolean、intからdoubleなどの基本的なプリミティブ型変換を実行でき、StringをClassに、StringをEnumに変換します。ターゲットタイプに静的valueOf()メソッドを定義することにより、追加の変換を実装できます。
IntegerSpinnerValueFactory はすでに存在します。 SpinnerValueFactory のネストされたクラスであるため、タグ名にドットを付けて使用する必要があります。
使用可能なコンストラクターは3つあり、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>
2つの変数を定義し、それらを静的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>
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>