Somewhere inside my FXML, I have this:
<fx:define>
<ToggleGroup fx:id="toggleGroup1"/>
</fx:define>
<Menu fx:id="toggleMyView" text="%MyView">
<items>
<RadioMenuItem text="%hide"
selected="true"
onAction="#handleLoadComponent"
toggleGroup="toggleGroup1"/>`
Somehow I get the error:
Unable to coerce toggleGroup1 to class javafx.scene.control.ToggleGroup
But why?
What I'm trying to do is to create a Menu containing several of RadioMenuItem which are all in the same ToggleGroup. How can I add them to the toggle group in my FXML file?
You have to write
toggleGroup="$toggleGroup1"
If you are using SceneBuilder then set the field ToggleGroup in properties to the name of the group.
Related
I need your help. In my entity model class I have currently
protected ObservableList<Double> marketSize = FXCollections.observableArrayList();
ListProperty<Double> marketSizeProperty = new SimpleListProperty<Priority>(marketSize);
In the UI I have a fixed number of 5 TextFields like so
In the fxml file
<TextField fx:id="sizeLYTextField" GridPane.columnIndex="2" GridPane.rowIndex="3">
<TextField fx:id="sizeLY1TextField" GridPane.columnIndex="3" GridPane.rowIndex="3">
<TextField fx:id="sizeLY2TextField" GridPane.columnIndex="4" GridPane.rowIndex="3">
and so on.
Is there a way to bind each of the TextFields in the UI to a different element of the array? Like
sizeLYTextField.textProperty().bindBidirectional(model.marketSizeProperty.get(0));
what is obviously not working.
I thought about an array of StringProperties, but since I have a number of rows beneath each other, each having 5 TextFields I would have quite a number of single StringProperty boiler plate code. Maybe TextFields are not the ideal UI element?! Let me know what you think.
Thank you in advance.
I am working with a JavaFX Menu with several RadioMenuItems. These items are in a toggle group, and work correctly when clicked with a mouse. I need hotkeys on these items, and would like them displayed in the dropdown, so added accelerators. These work as well, but if the hotkey combination for an already selected item is used again, that item is deselected, leaving no selected options in the ToggleGroup. The desired behavior would be to leave the item selected if the same combination is used again.
I've tried several versions of trying to catch when the ToggleGroup selected value is null, but since the deselect call always fires before the select call, there is no way to know whether the deselect call is valid or not for manually overriding the behavior.
FXML snippit
<Menu >
<RadioMenuItem fx:id="item1" text="item 1" >
<toggleGroup>
<ToggleGroup fx:id="theToggleGroup" />
</toggleGroup>
<accelerator>
<KeyCodeCombination alt="UP" code="d" control="DOWN" meta="UP" shift="UP" shortcut="UP" />
</accelerator>
</RadioMenuItem>
<RadioMenuItem fx:id="item2" text="item 2" toggleGroup="$theToggleGroup">
<accelerator>
<KeyCodeCombination alt="UP" code="b" control="DOWN" meta="UP" shift="UP" shortcut="UP" />
</accelerator>
</RadioMenuItem>
</Menu>
Java
theToggleGroup.selectedToggleProperty().addListener((observable, oldValue, newValue) -> doStuffBasedOnSelectedToggle(newValue));
// null pointer on newValue when nothing is selected (should never happen in a ToggleGroup)
Alternatively, I tried to set the
onAction="#doStuffBasedOnSelectedToggle"
in the FXML, but the problem remains that if you select the same one twice, it is deselected instead.
Mimic this behavior with the above code by going back and forth between hotkey 'Ctrl+B' and 'Ctrl+D' with no issues. Issue arises with 'Ctrl+D' followed by 'Ctrl+D' again, or 'Ctrl+B' followed by 'Ctrl+B' etc.
If there's no fix for this / not supported operation in Java for some reason, I can change to CheckMenuItem and do a manual implementation of Toggle functionality, but that seems unreasonable.
The workaround that I found to not have issues is a change to the onAction of each RadioMenuItem. This needs to happen in the Java, not in the FXML.
item1.setOnAction(event -> {
item1.setSelected(true);
doStuffBasedOnSelectedToggle();
}
item2.setOnAction(event -> {
item2.setSelected(true);
doStuffBasedOnSelectedToggle();
}
With this code, they appropriately toggle back and forth, and will not toggle off if the same one is selected twice.
The root cause of the original problem seems to be buried in the Java library
com.sun.javafx.scene.control.ContralAcceleratorSupport.java -> doAcceleratorInstall(...)
This method handles RadioMenuItems and CheckMenuItems identically by toggling them. The correct behavior would've been to toggle CheckMenuItem and set RadioMenuItem to true.
Long story short:
I have an assignment that is going to interact with older people (patients) for medical purposes.
I have designed everything in scenebuilder and I am stuck at the moment.
The patients are going to fyll in some medical data, some days is going to require more input than others. Input such as heart rate, blood sugar, how they slept that night and so on.
I'm going to need a system that is adaptable since each day can vary on how much they want to fyll in. (depending on them and/or their doctor)
This is how the program is right now:
The first 2-3 rows in the gridpane is my focus right now.
what i want is that when i press the ADD button, it will create an combobox in its plane and movie itself down a row in the gridpane.
I dont actually know if it good to do this with a gridpane or if anyone has any other recomendations ( all appreciated).
you can see that in the rows 6-9 are hardcoded what input is what. Since these options may change with time i will need to make it adjustable. That is why my first combobox reads its different inputpotions from the database.
My attempt so far:
#FXML
GridPane gridPane;
#FXML
Button addButton;
#FXML
ComboBox<String> addedCombo;
#FXML
String amountCombo;
int count = 0;
#FXML
public void addComboBoxButton() {
amountCombo = "addedCombo";
addedCombo = new ComboBox();
addedCombo.setName(amountCombo + count);
count++;
}
Im trying to create a function that created an combobox evertyime the ADDbutton is pressed and then add count to it.
For example if you press it 3 times you should've created 3 comboboxes that are named:
addedCombo0, addedCombo1, addedCombo2
The error i get is shown on setName() and it says:
The method setName(String) is undefined for the type ComboBox
This is how it should look like after the ADDbutton is pressed
Thank you for your time!
I would recommend to use a separate GridPane(or VBox) for handling the ComboBoxes within the grid. This way everytime when you add a comboBox, you dont need to alter the row numbers of all the rows down the grid.
Something like..
<GridPane>
<children>
<VBox GridPane.rowIndex="0" GridPane.columnIndex="0" GridPane.columnSpan="2" alignment="CENTER_LEFT">
<!-- Keep adding your combo boxes here -->
</VBox>
<Button text="Add" GridPane.rowIndex="1" GridPane.columnIndex="0" />
<Label text="Heart Rate" GridPane.rowIndex="2" GridPane.columnIndex="0" />
<TextField GridPane.rowIndex="2" GridPane.columnIndex="1" />
<!-- Followed by your other rows.....>
</children>
</GridPane>
Griffon 2.10.0
FXML:
<Button layoutX="172.0" layoutY="45.0" JavaFXUtils.griffonActionId="click2"
mnemonicParsing="false" text="Test"
prefWidth="200.0"
/>
TestView.groovy:
void initUI() {
builder.application(title: application.configuration['application.title'], name: "settingsWindow",
centerOnScreen: true, resizable: false) {
scene {
def node = loadFromFXML("views/test.fxml")
connectActions(node, controller)
inputx.textProperty().bindBidirectional(model.inputProperty())
fxml node
}
}
}
Shows this button with the text "Click2"
Why is the text="Test"configuration in the FXML overwritten by the griffonActionId name?
It works when I use this in FXML:
<Button fx:id="btn1" ...
And in TestView.groovy:
#FXML private Button btn1
...
btn1.text = 'Test'
This displays:
Is this the proper the way to set the button text?
This is expected behavior. Buttons configured via Griffon actions will bind their properties to action properties. The button's text is bound to the action's name by default. You can overrode this behavior by setting the button's text explicitly in code, like you did.
<AnchorPane>
<TreeView fx:id="locationTreeView" focusTraversable="true" prefHeight="449.0" prefWidth="725.0" style="#tree
{
-fx-border-style:solid;
-fx-border-width:1px;
-fx-border-color:#ffffff;
}"/>
In the above fxml code I want to add one more <TreeView> but through the controller. How can I do this?
You will have to:
Give a fx:id to the AnchorPane:
<AnchorPane fx:id="theAnchorPane">
Add the corresponding field in the controller:
#FXML private AnchorPane theAnchorPane;
From the code that performs the addition you have to:
Create the new TreeView however you like:
TreeView newTreeView = ...;
Add it to the childen of the AnchorPane, possibly with some constraints:
theAnchorPane.getChildren().add(newTreeView);
AnchorPane.setTopAnchor(newTreeView, ...); // etc