JavaFX: getChildren().addAll() argument not applicable - javafx

I have a basic question for JavaFX but coudn't figure it out. For HBox, When I'm using getChildren().addAll() for Label and ImageView, I get the following message:
The method addAll(int, Collection<? extends Node>) in the type List<Node> is not applicable for the argument (Label, ImageView[])
I'm not sure what's the issue. I can use normally if its (TextField, ImageView[]), but it doesn't work for (Label, ImageView[]).
This is my simplified code:
ImageView[] imagesRow = new ImageView[2];
Image[] img = new Image[2];
String title = "Result";
img[0] = new Image("sample1.png", 60, 35, true, true);
img[1] = new Image("sample2.png", 60, 35, true, true);
imagesRow[0] = new ImageView();
imagesRow[1] = new ImageView();
imagesRow[0].setImage (img[0]);
imagesRow[1].setImage (img[1]);
Label label = new Label();
label.setText(title + ": ");
// Create horizontal box
HBox box = new HBox();
box.setPadding(new Insets(20, 5 , 2, 50));
box.getChildren().addAll(label, imagesRow); // issue here
May I seek the reason and what should I do instead to align label and image horizontally?
Thanks in advance.

A Collection needs to be of one type (or inheriting from a common parent somewhere in the heirarchy).
A Label is a type of Node and therefore anything else you try to pass as a part of the Collection parameter must also be a Node. An array is obviously not.
In your case, you would need to use two calls to populate the children of the HBox:
box.getChildren().add(label);
box.getChildren().addAll(imagesRow);
The reason you can call addAll(imagesRow) without a problem is because with only the one argument, you're only passing in one Collection, an array.
By calling addAll(label, imagesRow), you're telling Java that you're passing a Collection of one type, but you actually passed it a Node and an array.

Related

Access objects inside a dinamically created HBox

In the controller of my view, I created a list of HBoxes for the input of different values, each hbox consists of a textfield with an index number and two text boxes with information I want to retrieve. This is how I dynamically create each HBox.
void addRowToList() {
HBox hb = new HBox(50);
Text num = new Text(Integer.toString(numEdges + 1));
hb.getChildren().add(num);
TextField sep = new TextField();
makeNumeric(sep);
hb.getChildren().add(sep);
TextField area = new TextField();
makeNumeric(area);
hb.getChildren().add(area);
rows.add(hb);
}
After this, there is a point in which I need the information from those textBoxes in order to continue the execution of my program, my question is what is the method should I follow to access these since they don't have any given id? Thanks in advance.

JavaFX How to check 2 observable values and run code if they match conditions, and how to get pair of values from custom jfx window

I have very simple window for changing password from javafx dialog collection - i use custom dialog example to build it (http://code.makery.ch/blog/javafx-dialogs-official/). Questions are bolded in below code:
Dialog<Pair<String, String>> dialog = new Dialog<>();
dialog.setTitle("Password change");
ButtonType ButtonTypeSavePassword = new ButtonType("Save",
ButtonBar.ButtonData.OK_DONE);
ButtonType ButtonTypeCancel = new ButtonType("Cancel",
ButtonBar.ButtonData.CANCEL_CLOSE);
//dialog.getDialogPane().getButtonTypes().addAll(loginButtonType,
ButtonType.CANCEL);
// Create the username and password labels and fields.
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(20, 150, 10, 10));
PasswordField pass1 = new PasswordField();
PasswordField pass2 = new PasswordField();
grid.add(new Label("Enter new password"), 0, 0);
grid.add(pass1, 1, 0);
grid.add(new Label("Re-enter new password "), 0, 1);
grid.add(pass2, 1, 1);
Node saveButton =
dialog.getDialogPane().lookupButton(ButtonTypeSavePassword);
saveButton.setDisable(true);
Platform.runLater(() -> pass1.requestFocus());
//??? How to check two observable values at once(if pass1.length>0 and pass2.length>0) with lambda expression and change saveButton to enable?
dialog.setResultConverter(dialogButton -> {
if (dialogButton == ButtonTypeSavePassword ) {
return new Pair<>(pass1.getText(), pass2.getText());
}
return null;
});
Optional<Pair<String, String>> result = dialog.showAndWait();
result.ifPresent(usernamePassword ->
{
System.out.println("Username=" + usernamePassword.getKey() + ",
Password=" + usernamePassword.getValue());
});
//??? How can I put values from the pair into 2 Strings defined outside the Custom Dialog JFX Window (not to system out like above)?
How to check two observable values at once(if pass1.length>0 and pass2.length>0) with lambda expression and change saveButton to enable?
You can do this a number of ways.
With a listener on both password fields:
saveButton.setDisable(true);
ChangeListener<String> passwordListener = (obs, oldPW, newPW) ->
saveButton.setDisable(pass1.getText().isEmpty() || pass2.getText().isEmpty());
pass1.textProperty().addListener(passwordListener);
pass2.textProperty().addListener(passwordListener);
Or with a binding, which you can do with Bindings.length(...):
saveButton.disableProperty().bind(
Bindings.length(pass1.textProperty()).isEqualTo(0)
.or(Bindings.length(pass2.textProperty()).isEqualTo(0))
);
or with Bindings.createBooleanBinding():
saveButton.disableProperty().bind(Bindings.createBooleanBinding(() ->
pass1.getText().isEmpty() || pass2.getText().isEmpty(),
pass1.textProperty(), pass2.textProperty()));
(and there are other options too).
How can I put values from the pair into 2 Strings defined outside the Custom Dialog JFX Window (not to system out like above)?
First, please don't combine multiple questions into a single post. It makes it harder for other users to find answers to questions that might have already been asked.
It's not really clear what you mean here. You can just define setUsername(...) and setPassword(...) methods in the class of whatever object you want to pass the data to, and call those methods:
someOtherThing.setUsername(usernamePassword.getKey());
someOtherThing.setPassword(usernamePassword.getValue());

Howto cast List items from VBox.getChildren() in JavaFX

I have a VBox in which many nodes of type Buttonare added.
private final VBox vbox = new VBox();
private final Button b1= new Button("1");
private final Button b2= new Button("2");
private final Button b3= new Button("3");
private final Button b4= new Button("4");
vbox.getChildren().addAll(b1,b2,b3,b4);
Is there a way to cast its child items to Button type.
I need something like this:
ObservableList<Button> children = (ObservableList<Button>) vbox.getChildren();
Yes this is possible, if you use the raw type.
ObservableList<Button> children = (ObservableList)vbox.getChildren();
Note however, that this can easily lead to ClassCastExceptions at runtime, if the types are incorrect or the child list hardcodes the parameter type for a parameter that depends on the type parameter.

javafx remove specific node from VBox

i have the following method:
CreateStrip createStrip = new CreateStrip(input);
depBox.getChildren().add(createStrip.getStripGrid());
depBox is a VBox and .getStripGrid() return a GridPane.
CreateStrip has this method too:
public String getNameStrip() { return input.getNameStrip();}
during the life of the program depBox get many GridPane, each one with a different NameStrip.
sometimes i have the necessity to remove a specific GridPane from depBox that match with .getNameStrip().
i have tried:
for (Node node: depBox.getChildren()) {
//TODO REMOVE GRIDPANE CONTAIN THE NAME THAT MATCH WITH THE MESSAGE RECEIVED..
}
but i don't know how to set the matching control.
Step 1:
Attach data to the GridPane that allows you to identify the one to remove.
You could do this by using Node.setUserData or by using the properties Map (which I'll do in the following code snippets).
Creating the GridPane
GridPane gp = createStrip.getStripGrid();
gp.getProperties().put(NAME_KEY, createStrip);
depBox.getChildren().add(gp);
// use object not equal to any other object as key (i.e. equals uses reference equality)
static final Object NAME_KEY = new Object();
Step 2:
Use the information to remove the appropriate GridPane. searchName is the String that identifies the GridPane you want to remove (to check for equality with getNameStrip()):
depBox.getChildren().removeIf(c -> {
CreateStrip strip = (CreateStrip) c.getProperties().get(NAME_KEY);
return strip != null && searchName.equals(strip.getNameStrip());
});
Depending on your CreateStrip class it may not be necessary to add a instance of it as property. It may not even be the right thing to do, if it's a factory, but I think you get the idea nontheless.
Alternative
You can also assign a value to the id property of the Node and use those to identify the correct node using Node.lookup. However those need to be unique and be a valid css id, but you could use a Map to map from message to id.

Actionscript and ViewStack = Cannot access a property or method of a null object reference

I'm writing a flex program in an OO manner and I've got to the point of creating a ViewStack to hold various panels. My problem is that when I add a panel to the ViewStack it throws the aforementioned error. No doubt the answer is pretty obvious so here's the constructor for the manager class that holds my ViewStack.
stack = new ViewStack();
loginPanel = new LoginPanel;
regPanel = new RegisterPanel;
stack.creationPolicy = "all";
stack.addChild(loginPanel);
stack.currentState = "loginPanel";
I'm not sure why you are setting the currentState property of the ViewStack. Are you trying to select that child? If so, try using the selectedChild property instead. This should work:
{
stack = new ViewStack();
loginPanel = new LoginPanel();
regPanel = new RegisterPanel();
stack.creationPolicy = "all";
stack.addChild(loginPanel);
stack.selectedChild = loginPanel;
}

Resources