dadadima
dadadima

Reputation: 938

Setting and Getting parameters in a JavaFX application

I have this method in my application which is constructing RadioButtons using an helper class: Mode. I would like to call out of the createModesRadios method .getText() for the user's selected RadioButton. Also I would like to save the user's choices in order to remember them in a following use. Is there an easy way to call them and set the choices into the CheckBoxes, into the RadioButtons and into the PrefixSelectionComboBoxs? I am using a Model Class Configuration.java in order to store the information, because I will need to process some calculations with the user inputs. I would like to store in it also the choices made from the controllers mentioned above.

Part of my Class

public class ConfigurationEditDialogController {

// General Tab
@FXML
private TextField configurationNameField;
@FXML
private TextField commentField;
@FXML
private TextField creationTimeField;
@FXML
private TextField startAddress;

@FXML
private ToggleSwitch triggerEnable;
@FXML
private ToggleSwitch softwareTrigger;
@FXML
private ToggleSwitch ctsEnable;


// Data Acquisition Tab
@FXML
private Pane dataAcquisitionTab;

@FXML
private Button okButton;

private Mode[] modes = new Mode[]{
        new Mode("Vertical", 4),
        new Mode("Hybrid", 2),
        new Mode("Horizontal", 1)
};
private int count = Stream.of(modes).mapToInt(Mode::getCount).max().orElse(0);
private ToggleGroup group = new ToggleGroup();
private IntegerProperty elementCount = new SimpleIntegerProperty();
private ObservableMap<Integer, String> elements = FXCollections.observableHashMap();
CheckBox[] checkBoxes = new CheckBox[count];

private ObservableList<String> options = FXCollections.observableArrayList(
        "ciao",
        "hello",
        "halo");





private Stage dialogStage;
private Configuration configuration;
private boolean okClicked = false;


/**
 * Initializes the controller class. This method is automatically called
 * after the fxml file has been loaded.
 */
@FXML
private void initialize() {





    HBox radioBox = createModesRadios(elementCount, modes);
    GridPane grid = new GridPane();
    VBox root = new VBox(20, radioBox);
    root.setPrefSize(680, 377);
    grid.setHgap(40);
    grid.setVgap(30);
    grid.setAlignment(Pos.CENTER);



    elementCount.addListener((o, oldValue, newValue) -> {
        // uncheck checkboxes, if too many are checked
        updateCheckBoxes(checkBoxes, newValue.intValue(), -1);
    });

    for (int i = 0; i < count; i++) {
        final Integer index = i;
        CheckBox checkBox = new CheckBox();
        checkBoxes[i] = checkBox;

        PrefixSelectionComboBox<String> comboBox = new PrefixSelectionComboBox<>();
        comboBox.setItems(options);
        comboBox.setPromptText("Select Test Bus " + i);
        comboBox.setPrefWidth(400);
        comboBox.setVisibleRowCount(options.size() -1);
        comboBox.valueProperty().addListener((o, oldValue, newValue) -> {
            // modify value in map on value change
            elements.put(index, newValue);
        });
        comboBox.setDisable(true);

        checkBox.selectedProperty().addListener((o, oldValue, newValue) -> {
            comboBox.setDisable(!newValue);
            if (newValue) {
                // put the current element in the map
                elements.put(index, comboBox.getValue());

                // uncheck checkboxes that exceed the required count keeping the current one unmodified
                updateCheckBoxes(checkBoxes, elementCount.get(), index);
            } else {
                elements.remove(index);
            }

        });
        grid.addRow(i, comboBox, checkBox);


    }


    // enable Ok button iff the number of elements is correct
    okButton.disableProperty().bind(elementCount.isNotEqualTo(Bindings.size(elements)));

    root.getChildren().add(grid);
    dataAcquisitionTab.getChildren().add(root);



}

/**
 * Create Radio Buttons with Mode class helper
 *
 * @param count
 * @param modes
 * @return
 */
private HBox createModesRadios(IntegerProperty count, Mode... modes) {
    ToggleGroup group = new ToggleGroup();
    HBox result = new HBox(50);
    result.setPadding(new Insets(20, 0, 0, 0));
    result.setAlignment(Pos.CENTER);
    for (Mode mode : modes) {
        RadioButton radio = new RadioButton(mode.getText());
        radio.setToggleGroup(group);
        radio.setUserData(mode);
        result.getChildren().add(radio);
        radio =

    }
    if (modes.length > 0) {
        group.selectToggle((Toggle) result.getChildren().get(0));
        count.bind(Bindings.createIntegerBinding(() -> ((Mode) group.getSelectedToggle().getUserData()).getCount(), group.selectedToggleProperty()));

        } else {
        count.set(0);
    }
    return result;
}


/**
 * Method for updating CheckBoxes depending on the selected modek
 *
 * @param checkBoxes
 * @param requiredCount
 * @param unmodifiedIndex
 */
private static void updateCheckBoxes(CheckBox[] checkBoxes, int requiredCount, int unmodifiedIndex) {
    if (unmodifiedIndex >= 0 && checkBoxes[unmodifiedIndex].isSelected()) {
        requiredCount--;
    }
    int i;
    for (i = 0; i < checkBoxes.length && requiredCount > 0; i++) {
        if (i != unmodifiedIndex && checkBoxes[i].isSelected()) {
            requiredCount--;
        }
    }

    for (; i < checkBoxes.length; i++) {
        if (i != unmodifiedIndex) {
            checkBoxes[i].setSelected(false);
        }
    }
}

/**
 * Sets the stage of this dialog.
 *
 * @param dialogStage
 */
public void setDialogStage(Stage dialogStage) {
    this.dialogStage = dialogStage;
}


/**
 * Sets the configuration to be edited in the dialog.
 *
 * @param configuration
 */
public void setConfiguration(Configuration configuration) {
    this.configuration = configuration;

    configurationNameField.setText(configuration.getConfigurationName());
    commentField.setText(configuration.getComment());

    //Set the comboboxes and the checkboxes and the radiobutton

    creationTimeField.setText(LocalDateTime.now().format(DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm")));
}

/**
 * Returns true if the user clicked OK, false otherwise.
 *
 * @return
 */
public boolean isOkClicked() {
    return okClicked;
}

/**
 * Called when the user clicks ok.
 */
@FXML
private void handleOk() {
    if (isInputValid()) {
        configuration.setConfigurationName(configurationNameField.getText());
        configuration.setComment(commentField.getText());
        configuration.setTestBus1(elements.get(0));
        configuration.setTestBus2(elements.get(1));
        configuration.setTestBus3(elements.get(2));
        configuration.setTestBus4(elements.get(3));
        configuration.setCreationTime(DateTimeUtil.parse(creationTimeField.getText()));

        // Store the information of the sample mode (vertical, hybrid or horizontal).


        okClicked = true;
        dialogStage.close();
    }
}

Mode Helper Class

public class Mode {

private final String text;
private final int count;

public Mode(String text, int count) {
    this.text = text;
    this.count = count;
}

public String getText() {
    return text;
}

public int getCount() {
    return count;
}
}

Configuration.java

public class Configuration {

private final StringProperty configurationName;
private final StringProperty comment;
private final StringProperty testBus1;
private final StringProperty testBus2;
private final StringProperty testBus3;
private final StringProperty testBus4;
private final StringProperty triggerSource;
private final StringProperty sampleMode;
private final StringProperty icDesign;
private final StringProperty triggerMode;
private final DoubleProperty acquisitionTime;
private final ObjectProperty<LocalDateTime> creationTime;

/**
 * Default constructor.
 */
public Configuration() {
    this(null, null);
}

/**
 * Constructor with some initial data.
 *
 * @param configurationName
 * @param comment
 */
public Configuration(String configurationName, String comment) {      //todo initialize null values
    this.configurationName = new SimpleStringProperty(configurationName);
    this.comment = new SimpleStringProperty(comment);

    // Some initial sample data, just for testing.
    this.testBus1 = new SimpleStringProperty("");
    this.testBus2 = new SimpleStringProperty("");
    this.testBus3 = new SimpleStringProperty("");
    this.testBus4 = new SimpleStringProperty("");
    this.triggerSource = new SimpleStringProperty("");
    this.sampleMode = new SimpleStringProperty("");
    this.icDesign = new SimpleStringProperty("Ceres");
    this.triggerMode = new SimpleStringProperty("Internal");
    this.acquisitionTime = new SimpleDoubleProperty(2346.45);
    this.creationTime = new SimpleObjectProperty<>(LocalDateTime.of(2010, 10, 20,
            15, 12));
}


/**
 *  Getters and Setters for the variables of the model class. '-Property' methods for the lambdas
 *  expressions to populate the table's columns (just a few used at the moment, but everything
 *  was created with scalability in mind, so more table columns can be added easily)
 */

// If more details in the table are needed just add a column in
// the ConfigurationOverview.fxml and use these methods.

// Configuration Name
public String getConfigurationName() {
    return configurationName.get();
}
public void setConfigurationName(String configurationName) {
    this.configurationName.set(configurationName);
}
public StringProperty configurationNameProperty() {
    return configurationName;
}

// Comment
public String getComment() {
    return comment.get();
}
public void setComment (String comment) {
    this.comment.set(comment);
}
public StringProperty commentProperty() {
    return comment;
}

// Test Bus 1
public String getTestBus1() {
    return testBus1.get();
}
public void setTestBus1(String testBus1) {
    this.testBus1.set(testBus1);
}
public StringProperty testBus1Property() {
    return testBus1;
}

// Test Bus 2
public String getTestBus2() {
    return testBus2.get();
}
public void setTestBus2(String testBus2) {
    this.testBus2.set(testBus2);
}
public StringProperty testBus2Property() {
    return testBus2;
}

// Test Bus 3
public String getTestBus3() {
    return testBus3.get();
}
public void setTestBus3(String testBus3) {
    this.testBus3.set(testBus3);
}
public StringProperty testBus3Property() {
    return testBus3;
}

// Test Bus 4
public String getTestBus4() {
    return testBus4.get();
}
public void setTestBus4(String testBus4) {
    this.testBus4.set(testBus4);
}
public StringProperty testBus4Property() {
    return testBus4;
}

// Trigger Source
public String getTriggerSource(){
    return triggerSource.get();
}
public void setTriggerSource (String triggerSource){
    this.triggerSource.set(triggerSource);
}
public StringProperty triggerSourceProperty() {
    return triggerSource;
}

// Sample Mode
public String getSampleMode() {
    return sampleMode.get();
}
public void setSampleMode (String sampleMode){
    this.sampleMode.set(sampleMode);
}
public StringProperty sampleModeProperty() {return sampleMode;}

// IC Design
public String getIcDesign() {
    return icDesign.get();
}
public void setIcDesign (String icDesign){
    this.icDesign.set(icDesign);
}
public StringProperty icDesignProperty() {
    return icDesign;
}

// Trigger Mode
public String getTriggerMode() {
    return triggerMode.get();
}
public void setTriggerMode (String triggerMode){
    this.triggerMode.set(triggerMode);
}
public StringProperty triggerModeProperty() {return triggerMode;}

// Acquisition Time
public double getAcquisitionTime() {
    return acquisitionTime.get();
}
public void setAcquisitionTime(double acquisitionTime){
    this.acquisitionTime.set(acquisitionTime);
}
public DoubleProperty acquisitionTimeProperty() {
    return acquisitionTime;
}

// Last modified - Creation Time
@XmlJavaTypeAdapter(LocalDateTimeAdapter.class)
public LocalDateTime getCreationTime() {
    return creationTime.get();
}
public void setCreationTime(LocalDateTime creationTime){
        this.creationTime.set(creationTime);
    }
public ObjectProperty<LocalDateTime> creationTimeProperty() {
    return creationTime;
}
}

Upvotes: 3

Views: 1552

Answers (1)

Zephyr
Zephyr

Reputation: 10253

You can use the java.util.Properties class to easily read/write settings like this to/from an XML file.

Save To Properties

    Properties props = new Properties();

    // Set the properties to be saved
    props.setProperty("triggerMode", triggerMode.get());
    props.setProperty("acquisitionTime", String.valueOf(acquisitionTime.get()));

    // Write the file
    try {
        File configFile = new File("config.xml");
        FileOutputStream out = new FileOutputStream(configFile);
        props.storeToXML(out,"Configuration");
    } catch (IOException e) {
        e.printStackTrace();
    }

This creates the config.xml file and populates it with all the properties you set using the props.setProperty() method.

Within the props.setProperty() method, you have two parameters. The first is the name of the property, the second is the actual value. The name is important as you will use it to read the appropriate value later.

The above code outputs the following XML file:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <comment>Configuration</comment>
    <entry key="acquisitionTime">12.0</entry>
    <entry key="triggerMode">My Trigger Mode</entry>
</properties>

Read from Properties

Reading from the XML file is just as simple. Use the loadFromXML() method:

    FileInputStream in;

    // Load the settings file
    in = new FileInputStream(DataFiles.LOCAL_SETTINGS_FILE);
    properties.loadFromXML(in);

From there, you can set your Configuration model object by getting each property:

configuration.setAcquisitionTime(props.getProperty("acquisitionTime", "0.0"));
configuration.setTriggerMode(props.getProperty("triggerMode", "Manual"));

The getProperty() method also takes two parameters. The first is obviously the name of the property we saved earlier. The second is the default value to use if the requested property name does not exist in the XML file.

Pretty simple!

I do recommend updating all the values in your Configuration.java model and saving properties from there (instead of trying to save the properties directly from your textfields, comboboxes, etc).

EDIT

In order to retrieve the values from your controls within the for loop, you need to add them to a list that is accessible from outside that loop.

Create appropriate lists to hold the controls as their created:

List<PrefixSelectionComboBox<String>> comboBoxes = new ArrayList<PrefixSelectionComboBox<String>>();
List<CheckBox> checkBoxes = new ArrayList<>();

At the bottom of your loop, add the new controls to these lists:

comboBoxes.add(comboBox);
checkBoxes.add(checkBox);
grid.addRow(i, comboBox, checkBox);

Now, when you need their values, you can iterate over those lists to extract them:

for (PrefixSelectionComboBox cb : comboBoxes) {
    cb.getValue(); // Do with this what you must
}
for (CheckBox cb : checkBoxes) {
    cb.isSelected();
}

Upvotes: 2

Related Questions