In my javafx application I want to create a scene where I can show the usernames of all the users in my database.
Precisely, I want to show a list of labels where every label get a username.
(the number of labels depend on the number of users).
Note: I can do this in java with a list and a foreach loop, but this is the first time that I work with javafx and I want to know how to create a loop of graphic component.
Thanks.
Here are a couple of alternatives, one sample is just looping and adding new labels to the children of a layout pane, the other is using the in-built ListView component. There are other alternatives of course. Which you choose to use will depend upon the functionality you need to achieve.
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class UserDisplay extends Application {
#Override public void start(Stage stage) {
String[] users = { "Huey", "Dewey", "Louie" };
VBox layout = new VBox(10);
// ALTERNATIVE 1: add labels in a loop.
for (String user: users) {
Label userLabel = new Label(user);
layout.getChildren().add(userLabel);
}
// ALTERNATIVE 2: use the built-in ListView component.
ListView<String> listView = new ListView<>(
FXCollections.observableArrayList(users)
);
layout.getChildren().add(listView);
layout.setPadding(new Insets(10));
layout.setPrefSize(100,200);
stage.setScene(new Scene(layout));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Related
I have this view designed via Scene Builder for JavaFX. There are 4 ComboBox in it. I would like to have the possibility to have something to let the user choose how many and which ComboBox use.
For example, my aim is having 3 modes:
allow the user to use all the 4 ComboBox;
allow the user to use only one ComboBox and let him choose it;
allow the user to use only two ComboBox and let them choose the preferred combination of the four Controls
Any design or idea (and its implementation) are well welcomed since I am not having a very good solution at this moment. I was thinking something like using the CheckBox element near to every ComboBox to enable or disable them, but anyway it is not very good. Also I was thinking about putting 3 Buttons to select the 3 modes and dynamically populate my Container, but I do not know where to start with the implementation.
If you want to let the user select a specific ComboBox, you can enable it using the JavaFX function setDisable() that is on all classes that inherit from the Node class.
(See difference between: setDisabled() vs setDisable())
In the case below, I bind the disabledProperty() to the inverse selectedProperty() on each CheckBox. This way you can select specific ComboBoxes to choose from. Hopefully this will get you started on seeing how JavaFX bindings work.
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Test extends Application
{
public static void main(String[] args){
launch(args);
}
#Override
public void start (Stage primaryStage) throws Exception {
VBox vBox = new VBox();
HBox hBox1 = generateComboBoxHBox();
HBox hBox2 = generateComboBoxHBox();
HBox hBox3 = generateComboBoxHBox();
HBox hBox4 = generateComboBoxHBox();
vBox.getChildren().addAll(hBox1, hBox2, hBox3, hBox4);
primaryStage.setScene(new Scene(vBox));
primaryStage.show();
}
// Create 4 of the same HBoxes for an example. Each HBox has a checkbox and combobox
private HBox generateComboBoxHBox(){
HBox hBox = new HBox();
CheckBox checkBox = new CheckBox();
ComboBox<String> comboBox = new ComboBox<>(FXCollections.observableArrayList("Option1", "Option2", "Option3", "Option4"));
comboBox.disableProperty().bind(checkBox.selectedProperty().not());
hBox.getChildren().addAll(checkBox, comboBox);
return hBox;
}
}
I am developing a chat application on JavaFX and I stuck with a little problem. In short, I want to have a possibility to insert an image(for example smiles) inside TextField which is intended for text input.But as I know, there is no possibility to insert images inside this element. Does JavaFX have some alternatives for that or maybe you know something else, what I can use for this?
Thank you, in advance.
You can try to use HTMLEditor. It supports styled text and other html features, which include adding images.
There is example of using HTMLEditor as inputField for chat:
package org.laptech.sample;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.web.HTMLEditor;
import javafx.stage.Stage;
public class ChatFieldSample extends Application{
private HTMLEditor htmlEditor;
public void hideHTMLEditorToolbars() {
htmlEditor.setVisible(false);
Platform.runLater(() -> {
Node[] nodes = htmlEditor.lookupAll(".tool-bar").toArray(new Node[0]);
for (Node node : nodes) {
node.setVisible(false);
node.setManaged(false);
}
htmlEditor.setVisible(true);
});
}
#Override public void start(Stage primaryStage) throws Exception {
htmlEditor = new HTMLEditor();
hideHTMLEditorToolbars();
htmlEditor.setHtmlText("Text<img src='urltosmile'/>Text Text Text");
primaryStage.setScene(new Scene(htmlEditor, 300, 300));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I create htmlEditor and hide toolbar in method(hideHTMLEditorToolbars)
The only, which I faced , was the problem of losing focus, when i handle keyEvents and setText there.
I'm new at using JavaFX and I'm trying to add an ObservableList to a table view.
The list contains only String.
My goals is to show list of connected devices and let the user choose on which to perform the action (1 or more), is there any better way to achieve this?
Edit:
Ive chaned to ListView and now it shows the list, how can I create a new list from the selected Items ?
Here's an example based on your comments
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class ListSelect extends Application {
#Override
public void start(Stage stage) {
ObservableList<String> items = FXCollections.observableArrayList(
"one","two","three","four","five","six","seven");
ListView<String> list = new ListView<>(items);
ListView<String> selected = new ListView<>();
HBox root = new HBox(list, selected);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
//set this to SINGLE to allow selecting just one item
list.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
list.getSelectionModel().selectedItemProperty().addListener((obs,ov,nv)->{
selected.setItems(list.getSelectionModel().getSelectedItems());
});
}
public static void main(String[] args) {launch(args);}
}
If you are looking for a solution that does not use Java's new Lamba and related features here it is:
In my example the assume the table was set up to work with an arbitrary class Person which defined a first name, last name and email.
//Set the table to multi selection mode
table.getSelectionModel().setSelectionMode( SelectionMode.MULTIPLE);
//Regiseter the listener on the ObervableList<Person>
table.getSelectionModel().getSelectedItems().addListener(multiSelection);
/**A listener for list selections, multiple selections in the TableView**/
ListChangeListener< Person> multiSelection = new ListChangeListener<Person>(){
#Override
public void onChanged( ListChangeListener.Change<? extends Person> changed){
for( Person p : changed.getList())
System.out.println(p);
}
};
Is there any way to add a changelistener to group of nodes for following changes?
For example, we can add a changelistener to a tabpane for getting tabselectedproperty.
I want to add changelistener a to a group of buttons for getting buttonActionedProperty! I want to get old button and new button....
Is there any way to do this?
When you compare the tabs in a tab pane to a collection of buttons, you're not really comparing like to like. A tab pane naturally has a sense of which tab is currently selected; buttons just generate events when they are pressed.
If you want your buttons to have a "selected" state, and want a collection of those grouped together so that only one is selected, then consider using ToggleButtons instead. You can put the toggle buttons into a ToggleGroup and register a listener with the toggle group's selectedToggle property:
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class ToggleButtonDemo extends Application {
#Override
public void start(Stage primaryStage) {
ToggleButton apples = new ToggleButton("Apples");
ToggleButton oranges = new ToggleButton("Oranges");
ToggleButton pears = new ToggleButton("Pears");
ToggleGroup fruitToggleGroup = new ToggleGroup();
fruitToggleGroup.getToggles().addAll(apples, oranges, pears);
fruitToggleGroup.selectedToggleProperty().addListener((obs, oldToggle, newToggle) ->
System.out.println("Selected toggle changed from "+oldToggle+" to "+newToggle));
HBox root = new HBox(5, apples, oranges, pears);
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, 350, 75);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
If you really just want buttons, and don't have the notion of one of them being selected (I find it hard to see a use case for this), you can just create an ObjectProperty<Button> to store the last button on which an action occurred. Register an event listener with each button to update the property:
import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class LastActionTrackingDemo extends Application {
#Override
public void start(Stage primaryStage) {
Button apples = new Button("Apples");
Button oranges = new Button("Oranges");
Button pears = new Button("Pears");
ObjectProperty<Button> lastActionedButton = new SimpleObjectProperty<>();
EventHandler<ActionEvent> buttonActionHandler = event ->
lastActionedButton.set((Button) event.getSource());
apples.addEventHandler(ActionEvent.ACTION, buttonActionHandler);
oranges.addEventHandler(ActionEvent.ACTION, buttonActionHandler);
pears.addEventHandler(ActionEvent.ACTION, buttonActionHandler);
lastActionedButton.addListener((obs, oldButton, newButton) ->
System.out.println("Button changed from "+oldButton+" to "+newButton));
HBox root = new HBox(5, apples, oranges, pears);
root.setAlignment(Pos.CENTER);
Scene scene = new Scene(root, 350, 75);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Note there is a subtle different between the appearance of the two demos. The first (with toggle buttons) has a visual representation of which button is selected. The second does not. In both cases you can still set action listeners on the buttons if you need that functionality. There is also a (less subtle) difference in behavior: the toggle buttons can be "unselected"; so if you press the same toggle button twice, the selection goes back to null. This doesn't happen with the buttons.
This question already has answers here:
JavaFX accordion with multiple open panes
(3 answers)
Closed 8 years ago.
I've a Accordion with having multiple titledPane and there has a lots of data within titledPane's ListView panel. I just want to expand all the titledPane of Accordion when searching the data. I don't know how to do this. any idea?
Here, I've attached my real project's screen shots and it shows actually what I want to do.
Quick answer: You can't.
The Accordion has an expandedPane property, that is a single TitledPane. There is no way for an Accordion to have multiple expanded panes.
Instead, you can use multiple TitledPanes directly (inside a VBox or similar), to get the behavior you want. Unfortunately, this won't look just like an Accordion, because TitledPanes by default uses different styling. But with some custom CSS (look at caspian.css to see how accordions are styled) you could make it look just like the panes look in an Accordion.
With slightly more work, you could work this into your own "multiple selection accordion" control, for easier reuse.
Like harald said. You cant. But you can use multiple TitledPane's in another Container. VBox for instance. Try this code snippet.
import java.util.ArrayList;
import java.util.Collection;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Accordion;
import javafx.scene.control.TextArea;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TitledPanes extends Application {
public static void main(String [] args){ launch(args); }
#Override
public void start(Stage primaryStage) throws Exception {
HBox root = new HBox();
VBox noaccordion = new VBox();
noaccordion.getChildren().addAll(this.createPanes());
VBox yesaccordion = new VBox();
Accordion acc = new Accordion();
acc.getPanes().addAll(this.createPanes());
yesaccordion.getChildren().add(acc);
root.getChildren().addAll(noaccordion, yesaccordion);
primaryStage.setScene(new Scene(root,800,400));
primaryStage.show();
}
private Collection<TitledPane> createPanes(){
Collection<TitledPane> result = new ArrayList<TitledPane>();
TitledPane tp = new TitledPane();
tp.setText("Pane 1");
tp.setContent(new TextArea("Random text..."));
result.add(tp);
tp = new TitledPane();
tp.setText("Pane 2");
tp.setContent(new TextArea("Random text..."));
result.add(tp);
tp = new TitledPane();
tp.setText("Pane 3");
tp.setContent(new TextArea("Random text..."));
result.add(tp);
return result;
}
}