JavaFX 8 Spinner control doesn't update value

2019-08-14 06:13发布

I am new to Java programming and opted for developing my tool UI in JavaFX8. I need to have a Spinner (new in JavaFX8u40!) for which the user can specify a integer value from 0 to 120 seconds (the easy part) but also a button which allows the user to set the spinner value directly to the given pre-set button value (here, 0).

Trouble is that when I click the button to test it, the spinner value doesn't seem to update and remains at 60 (spinner initial value) or any other value that may have been changed by the user through the spinner arrow controls.

I have understood from my searches for solution that this is because I should manipulate the factory value and not the spinner value as such, but I get to the same result.

Here is the code of my FXML file that I created to reflect the issue:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>


<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.40" fx:controller="TestViewController">
   <children>
      <BorderPane layoutX="28.0" layoutY="60.0" prefHeight="400.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
         <center>
            <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER">
               <children>
                  <Label mnemonicParsing="true" text="Clear Automatically _History After">
                     <opaqueInsets>
                        <Insets />
                     </opaqueInsets>
                     <padding>
                        <Insets right="5.0" />
                     </padding>
                  </Label>
                  <Spinner fx:id="spinnerClearHistoryDuration" initialValue="60" max="120" min="0" prefHeight="25.0" prefWidth="60.0" />
                  <Button fx:id="btnClearHistoryDuration" onAction="#clickBtnClearHistoryDuration" text="_0" />
               </children>
            </HBox>
         </center>
      </BorderPane>
   </children>
</AnchorPane>

And here is the matching controller Java class:

import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Spinner;

public class TestViewController implements Initializable {

    @FXML
    private Spinner<Integer> spinnerClearHistoryDuration;

    @FXML
    private Button btnClearHistoryDuration;

    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        spinnerClearHistoryDuration = new Spinner(0, 120, 30);
    }

    @FXML
    void clickBtnClearHistoryDuration(ActionEvent event) {
        //Tried the following, which is more extended but gets to same result 
        //(supposedly because this is just using more detailed resources but the same approach)

        /*
        SpinnerValueFactory<Integer> valueFactory = spinnerClearHistoryDuration.getValueFactory();
        valueFactory.setValue(0);
        spinnerClearHistoryDuration.setValueFactory(valueFactory);
        */
        
        spinnerClearHistoryDuration.getValueFactory().setValue(0);
    }
    
}

Of course, my main method is as simple as the following:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class JavaFXTestApplication extends Application {
    
    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("TestView.fxml"));
        
        Scene scene = new Scene(root);
        
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
    
}

As I am still new to this platform, I was not allowed to post a screen capture to illustrate further, sorry about that.

Any idea on what I am forgetting or missing out would be greatly appreciated as FXML8 is quite new and didn't find a somewhat-related solution to my issue.

All the best guys, Thierry

1条回答
手持菜刀,她持情操
2楼-- · 2019-08-14 07:20

The problem is you are instantiating twice the spinner.

With this:

@FXML
private Spinner<Integer> spinnerClearHistoryDuration;

the spinner is already instantiated when the FXML file is loaded.

And now, after that, you create a new instance:

@Override
public void initialize(URL location, ResourceBundle resources) {
    spinnerClearHistoryDuration = new Spinner(0, 120, 30);
}

Solution: just remove the second instance:

@Override
public void initialize(URL location, ResourceBundle resources) {        
}
查看更多
登录 后发表回答