Adding label into border, JavaFX - javafx

When I'm trying to add label into the gridpane as the second picture shows, it's not working. I have tried many things like adding CSS and it's still not working. Why are lines 113 and 114 not working?
(opcje.setStyle("-fx-background-color: #f4f4f4");)
Here is what I have:
Here is what I need:
My code:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
public class KCK_lab1_zad2 extends Application {
#SuppressWarnings("static-access")
public void start (Stage primaryStage) {
try {
primaryStage.setTitle("Narzedzie przetwarzania plikow");
BorderPane glownyBorderPane = new BorderPane();
Scene scene = new Scene(glownyBorderPane, 600, 200);
GridPane lewyGridPane = new GridPane();
GridPane prawyGridPane = new GridPane();
glownyBorderPane.setLeft(lewyGridPane);
glownyBorderPane.setRight(prawyGridPane);
glownyBorderPane.setMargin(lewyGridPane, new Insets(0, 15, 0, 0));
Label zrodlo = new Label("Źrodlo");
Label wynik = new Label("Wynik");
TextField text1 = new TextField();
TextField text2 = new TextField();
Button przegladaj1 = new Button("Przegladaj...");
Button przegladaj2 = new Button("Przegladaj...");
lewyGridPane.setVgap(15);
lewyGridPane.setHgap(0);
lewyGridPane.setPadding(new Insets(15));
lewyGridPane.setLayoutX(100);
lewyGridPane.setLayoutY(100);
lewyGridPane.setMinSize(100, 150);
text1.setPrefSize(100, 20);
text2.setPrefSize(100, 20);
przegladaj1.setPrefSize(100, 20);
przegladaj2.setPrefSize(100, 20);
glownyBorderPane.setPadding(new Insets(20, 10, 10, 10));
Label panelPlikow = new Label("Panel plików");
panelPlikow.getStyleClass().add("title");
panelPlikow.setPadding(new Insets(-60, -20, 0, 0));
panelPlikow.setPrefWidth(150);
lewyGridPane.add(panelPlikow, 0, 0);
lewyGridPane.add(zrodlo, 0, 0);
lewyGridPane.add(text1, 1, 0);
lewyGridPane.add(przegladaj1, 2, 0);
lewyGridPane.add(wynik, 0, 1);
lewyGridPane.add(text2, 1, 1);
lewyGridPane.add(przegladaj2, 2, 1);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//grd.prefHeightProperty().bind(root.heightProperty());
//glownyBorderPane.borderProperty();
lewyGridPane .setStyle("-fx-border-style: solid inside;");
lewyGridPane .setStyle("-fx-border-width: 1;");
lewyGridPane .setStyle("-fx-border-insets: 1;");
lewyGridPane .setStyle("-fx-border-radius: 1;");
lewyGridPane .setStyle("-fx-border-color: black;");
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Label opcje = new Label ("Opcje uruchomienia");
Button uruchom = new Button ("Uruchom przetwarza...");
Button pomoc = new Button ("Pomoc");
Button o_programie = new Button ("O programie");
Button zakoncz = new Button ("Zapisz i zakończ");
prawyGridPane.setVgap(0);
prawyGridPane.setHgap(0);
prawyGridPane.setPrefSize(150, 200);
prawyGridPane.setMaxWidth(150);
prawyGridPane.setPadding(new Insets(15));
prawyGridPane.setPrefSize(400, 300);
opcje.setPrefSize(150, 20);
uruchom.setPrefSize(150, 20);
o_programie.setPrefSize(150, 20);
zakoncz.setPrefSize(150, 20);
opcje.getStyleClass().add("title");
opcje.setPadding(new Insets(-34, -20, 0, 0));
VBox vbox = new VBox();
prawyGridPane.add(vbox, 0, 0);
opcje.setPrefWidth(150);
opcje.setStyle("-fx-background-color: #f4f4f4");
panelPlikow.setStyle("-fx-background-color: #f4f4f4");
vbox.getChildren().add(opcje);
vbox.getChildren().add(uruchom);
vbox.getChildren().add(pomoc);
vbox.getChildren().add(o_programie);
vbox.getChildren().add(zakoncz);
vbox.toBack();
//opcje.toFront();
uruchom.prefWidthProperty().bind(glownyBorderPane.widthProperty());
pomoc.prefWidthProperty().bind(glownyBorderPane.widthProperty());
o_programie.prefWidthProperty().bind(glownyBorderPane.widthProperty());
zakoncz.prefWidthProperty().bind(glownyBorderPane.widthProperty());
uruchom.prefHeightProperty().bind(glownyBorderPane.heightProperty());
pomoc.prefHeightProperty().bind(glownyBorderPane.heightProperty());
o_programie.prefHeightProperty().bind(glownyBorderPane.heightProperty());
zakoncz.prefHeightProperty().bind(glownyBorderPane.heightProperty());
/*
opcje .setStyle("-fx-font: 28px Vivaldi;");
opcje .setStyle("-fx-font-color: red;");
opcje .setStyle("-fx-background-color: white;");
opcje .setStyle("-fx-translate-y: -16;");
opcje .setStyle("-fx-content-display: top;");
opcje .setStyle("-fx-background-color: black;");
opcje.setTextFill(Color.RED);
opcje.setStyle("-fx-background-color: white");
*/
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//grd.prefHeightProperty().bind(root.heightProperty());
//glownyBorderPane.borderProperty();
prawyGridPane .setStyle("-fx-border-style: solid inside;");
prawyGridPane .setStyle("-fx-border-width: 1;");
prawyGridPane .setStyle("-fx-border-insets: 1;");
prawyGridPane .setStyle("-fx-border-radius: 1;");
prawyGridPane .setStyle("-fx-border-color: black;");
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
primaryStage.setScene(scene);
primaryStage.setMinHeight(250);
primaryStage.setMinWidth(580);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String args[]){
launch(args);
}
}

The problem is the padding of the title-labels. To recognize this, set the background-colors of the title-labels, e.g. to green, set the padding to 0 and increase it step by step towards your value. If you do that, the text shifts up (what is desired), but the content (and thus the background) becomes smaller and finally disappears (what you did not intend). Overall, it does not work right with padding:
If you really want to keep your solution you can compensate for the problem by using the graphic-property of the label usually applied to add an icon to the label.
Replace
Label panelPlikow = new Label("Panel plików");
with
Label panelPlikow = new Label();
panelPlikow.setGraphic(new Label(" Panel plików "));
panelPlikow.getGraphic().setStyle("-fx-background-color: #f4f4f4;");
and analogously for the other button. That results in:
However, I don't know if it works in combination with your title-styleclass since you haven't post it. You have to try that.
I would like to point out that there are conceptually better ways to achieve what you want!
One possibility that comes close to your solution is, not to add the GridPane directly to the BorderPane, but a Pane, with the Pane containing the GridPane and the label. Here, the label can be positioned freely without a padding.
Another possibility is to use the Borders-control from ControlsFX (http://fxexperience.com/controlsfx/features/). It does exactly what you want, i.e. it surrounds an arbitrary control with a border and you can optionally define a title.
GridPane lewyGridPane = new GridPane();
Node leftWithBorder = Borders.wrap(lewyGridPane).lineBorder().title("Panel plików").color(Color.BLACK).buildAll();
GridPane prawyGridPane = new GridPane();
Node rightWithBorder = Borders.wrap(prawyGridPane).lineBorder().title("Opcje uruchomienia").color(Color.BLACK).buildAll();
glownyBorderPane.setLeft(leftWithBorder);
glownyBorderPane.setRight(rightWithBorder);
Of course, you have to remove the currently existing GridPane-borders and title-labels and you have to adapt margins, paddings, preferred sizes etc. Moreover you have to download and add the controlsfx-jar to the build path.
With the ControlsFX-Borders-control the GUI looks almost identical:

Related

Javafx Button size, EmptyBorder, and Read txt File into TextArea

I am trying to switch to javafx instead of swing but it has been a bit bumpy trying to find methods that do the exact tasks.
I am trying to get the buttons width to fill the entire scene and adjusts accordingly when you adjust the scene size.
Get a small empty border around text area and buttons.
Getting a method that reads a plain text file and replaces the current Text Area (not append).
package gui;
mport javafx.application.Application;
mport javafx.scene.Scene;
mport javafx.scene.control.Button;
mport javafx.stage.Stage;
mport javafx.scene.layout.*;
mport javafx.scene.control.TextArea;
public class Main extends Application{
#Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("TextArea Experiment 1");
TextArea textArea = new TextArea();
// Which TextArea method would I call to set a plain
// text file into the text area ?
BorderPane border = new BorderPane();
border.setCenter(textArea);
//border.setBorder(new EmptyBorder(10,10,10,10));
// Is there a method like this in JavaFx ?
GridPane grid = new GridPane();
border.setBottom(grid);
double screensize = border.getMaxWidth();
Button option1 = new Button("Button 1");
Button option2 = new Button("Button 2");
Button option3 = new Button("Button 3");
// how can I get the buttons to be max scene size and
//adjust dynamically to scene dimensions ?
option1.setMaxSize(Double.MAX_VALUE,Double.MAX_VALUE);
//option1.setPrefWidth(Double.MAX_VALUE);
System.out.println(screensize);
grid.add(option1, 0,1);
grid.add(option2,0,2);
grid.add(option3,0,3);
Scene scene = new Scene(border, 200, 100);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
first of all I suggest that to take a look at this tutorial: http://code.makery.ch/library/javafx-8-tutorial/
If you want to build a well structured javafx application you have to make an .fxml file, a Controller class and (some) model class(es).
But for those points here are the answers.
If you want to set a Region's size you have to use .setPrefSize(double,double) method, if you want to set dynamic you have to use for example myButton.prefSizeProperty().bind(anyRegionYouWantToBindTo.widthProprty())
I don't really understand what you want, I think you would like to use some styling, then you can write a .css file then arr it to textArea's styleClass.
After you get the text from the file instead of using textArea.appendText(String) you have to user textArea.setText(String)
I think these are the sollutions for your problems but I strongly recommend to read a tutorial about javafx. So have fun :)
Rewrite your question and only ask the question for this answer. You can then ask the other questions on their own thread.
GridPane grid = new GridPane();
grid.setMaxWidth(Double.MAX_VALUE);//Make sure the GridPane MaxWidth is set to MAX_VALUE. you can use grid.gridLinesVisibleProperty().set(true); to get an idea of the GRIDPANES current borders
border.setBottom(grid);
grid.gridLinesVisibleProperty().set(true);
Button option1 = new Button("Button 1");
option1.setMaxWidth(Double.MAX_VALUE);//Set button one MaxWidth to MAX_VALUE
Button option2 = new Button("Button 2");
option2.setMaxWidth(Double.MAX_VALUE);//Set button two MaxWidth to MAX_VALUE
Button option3 = new Button("Button 3");
option3.setMaxWidth(Double.MAX_VALUE);//Set button three MaxWidth to MAX_VALUE
//Add ColumnConstraints and set the width to 100%.
ColumnConstraints columnConstraint = new ColumnConstraints();
columnConstraint.setPercentWidth(100);
grid.getColumnConstraints().add(0, columnConstraint);
grid.add(option1, 0, 1);
grid.add(option2, 0, 2);
grid.add(option3, 0, 3);

JavaFX Node will not grow in height despite constraints when buried within several panes

I've been struggling with this issue for a couple hours and managed to reproduce the problem with the sample below. The actual program changes what is set in main.add(node, 0, 1) as the content based on what button is pressed in menu. I tried several different things such as AnchorPanes, changing setMaxHeight, and setVgrow for many different nodes in the each pane but have not been very successful. How would I make the ListView in the example fill the rest of the window height where it is located?
public class Main extends Application {
public void start(Stage stage) throws Exception {
// I've tried with this as a VBox, no effect.
GridPane main = new GridPane();
main.setGridLinesVisible(true);
main.setHgap(5);
main.setVgap(10);
// Meant to change what content is displayed in the actual program.
HBox menu = new HBox();
menu.setMaxWidth(Double.MAX_VALUE);
menu.setAlignment(Pos.CENTER);
main.add(menu, 0, 0);
GridPane.setHgrow(menu, Priority.ALWAYS);
menu.getChildren().addAll(new Button("Button 1"), new Button("Button 2"), new Button("Button 3"), new Label("Hello world!"));
// Changes often.
GridPane content = new GridPane();
main.add(content, 0, 1);
// Options for the displayed content, changes the StackPane displayed below in my actual program.
HBox submenu = new HBox();
submenu.setMaxWidth(Double.MAX_VALUE);
submenu.setAlignment(Pos.CENTER);
content.add(submenu, 0, 0);
GridPane.setHgrow(submenu, Priority.ALWAYS);
submenu.getChildren().addAll(new Button("Button A"), new Button("Button B"), new Button("Button C"), new Label("Hello world!"));
// This is a custom class extended by StackPane in my actual program. Is often over overlayed with another transparent StackPane (not relevant to the problem).
StackPane subcontent = new StackPane();
subcontent.setMaxHeight(Double.MAX_VALUE);
subcontent.setMaxWidth(Double.MAX_VALUE);
content.add(subcontent, 0, 1);
// This was meant to be a TabPane in my actual program but this has the same outcome that won't fill the rest of the window height.
ListView<String> list = new ListView<>();
list.setMaxHeight(Double.MAX_VALUE);
list.setMaxWidth(Double.MAX_VALUE);
ObservableList<String> items = FXCollections.observableArrayList();
list.setItems(items);
subcontent.getChildren().add(list);
for(int i=0; i<100; i++) {
items.add("# "+i);
}
Scene scene = new Scene(main, 900, 550);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
You need both
GridPane.setVgrow(content, Priority.ALWAYS);
and
GridPane.setVgrow(subcontent, Priority.ALWAYS);
The grid panes are going to size things to their preferred heights with the default vgrow: the preferred height of content is determined by the preferred height(s) of its child nodes, and the preferred height of a ListView is a fixed (arbitrary) size (I believe 400 pixels). So if you don't instruct subcontent to grow, it will by the preferred size of the list view, and forcing content to grow will just add extra (blank) space to content: if you don't force content to grow, it will take its preferred size, which is the preferred size of subcontent plus the preferred size of submenu.
Setting the max height doesn't do anything in this example, as you just need to allow the various nodes to grow beyond their preferred size:
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Main extends Application {
public void start(Stage stage) throws Exception {
// I've tried with this as a VBox, no effect.
GridPane main = new GridPane();
main.setGridLinesVisible(true);
main.setHgap(5);
main.setVgap(10);
// Meant to change what content is displayed in the actual program.
HBox menu = new HBox();
// menu.setMaxWidth(Double.MAX_VALUE);
menu.setAlignment(Pos.CENTER);
main.add(menu, 0, 0);
GridPane.setHgrow(menu, Priority.ALWAYS);
menu.getChildren().addAll(new Button("Button 1"), new Button("Button 2"), new Button("Button 3"), new Label("Hello world!"));
// Changes often.
GridPane content = new GridPane();
main.add(content, 0, 1);
// Options for the displayed content, changes the StackPane displayed below in my actual program.
HBox submenu = new HBox();
// submenu.setMaxWidth(Double.MAX_VALUE);
submenu.setAlignment(Pos.CENTER);
content.add(submenu, 0, 0);
GridPane.setHgrow(submenu, Priority.ALWAYS);
submenu.getChildren().addAll(new Button("Button A"), new Button("Button B"), new Button("Button C"), new Label("Hello world!"));
// This is a custom class extended by StackPane in my actual program. Is often over overlayed with another transparent StackPane (not relevant to the problem).
StackPane subcontent = new StackPane();
// subcontent.setMaxHeight(Double.MAX_VALUE);
// subcontent.setMaxWidth(Double.MAX_VALUE);
content.add(subcontent, 0, 1);
// This was meant to be a TabPane in my actual program but this has the same outcome that won't fill the rest of the window height.
ListView<String> list = new ListView<>();
// list.setMaxHeight(Double.MAX_VALUE);
// list.setMaxWidth(Double.MAX_VALUE);
ObservableList<String> items = FXCollections.observableArrayList();
list.setItems(items);
subcontent.getChildren().add(list);
for(int i=0; i<100; i++) {
items.add("# "+i);
}
GridPane.setVgrow(content, Priority.ALWAYS);
GridPane.setVgrow(subcontent, Priority.ALWAYS);
Scene scene = new Scene(main, 900, 550);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Changing text color with a slider

I am trying to make a program that allows a user to select RGB colors through radio buttons, and changing the value from 0 - 255 using a slider. The color changes should apply to a text. When R, G or B is selected, only the selected color should be present in the text (i.e if green is selected, red and blue values are 0).
At the moment the program works to some extent. For example, if the slider is located at value 150, and I selected a new color and then move the slider, the text color is set to 150, or in any case the value the slider is set on before trying to move it to a new value. I have to select a new color before moving the slider if I want it to update. It only updates once for each selected color. I want it to update the selected color seamlessly. Code example below:
public class Oblig5 extends Application {
static int colorValue = 0;
static int red = 0;
static int green = 0;
static int blue = 0;
public static void main(String[] args) {
launch(args);
}
public void start(Stage primaryStage) {
// Create panes
BorderPane bPane = new BorderPane();
VBox vBox = new VBox();
bPane.setLeft(vBox);
// Create text and place it in the pane
Text text = new Text("Oblig 5");
text.setFont(Font.font("Times New Roman", FontWeight.NORMAL, FontPosture.REGULAR, 40));
bPane.setCenter(text);
// Create radio buttons and place them in the VBox
RadioButton rbRed = new RadioButton("Red");
RadioButton rbGreen = new RadioButton("Green");
RadioButton rbBlue = new RadioButton("Blue");
ToggleGroup group = new ToggleGroup();
rbRed.setToggleGroup(group);
rbGreen.setToggleGroup(group);
rbBlue.setToggleGroup(group);
// Create handlers for radiobuttons
rbRed.setOnAction(e -> {
if (rbRed.isSelected()) {
red = colorValue;
green = 0;
blue = 0;
}
});
rbGreen.setOnAction(e -> {
if (rbGreen.isSelected()) {
red = 0;
green = colorValue;
blue = 0;
}
});
rbBlue.setOnAction(e -> {
if (rbBlue.isSelected()) {
red = 0;
green = 0;
blue = colorValue;
}
});
vBox.getChildren().addAll(rbRed, rbGreen, rbBlue);
// Create a slider and place it in the BorderPane
Slider slider = new Slider(0, 255, 135);
slider.setShowTickLabels(true);
slider.setShowTickMarks(true);
bPane.setBottom(slider);
bPane.setAlignment(slider, Pos.CENTER);
// Create a handler for the slider
slider.valueProperty().addListener(ov -> {
colorValue = (int) slider.getValue();
text.setFill(Color.rgb(red, green, blue));
});
// Create a scene and place it in the stage
Scene scene = new Scene(bPane, 400, 400);
primaryStage.setScene(scene);
primaryStage.setTitle("Oblig 5");
primaryStage.show();
}
}
Any inputs are highly appreciated!
[Note: #fabian posted an answer while I was writing this one. Either answer will work, I thought I would post this too since it shows slightly different techniques. As usual in JavaFX there are multiple good ways of achieving the same thing.]
When either the selected button changes, or the slider value changes, you need to set the text fill with the appropriate values. Right now, when the selected button changes, you only update the variables red, green, and blue (but don't change the text fill) and when the slider value changes, you call setFill(...) with red, green, and blue, but don't change the values of those variables.
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.RadioButton;
import javafx.scene.control.Slider;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontPosture;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Oblig5 extends Application {
public static void main(String[] args) {
launch(args);
}
public void start(Stage primaryStage) {
// Create panes
BorderPane bPane = new BorderPane();
VBox vBox = new VBox();
bPane.setLeft(vBox);
Text text = new Text("Oblig 5");
text.setFont(Font.font("Times New Roman", FontWeight.NORMAL, FontPosture.REGULAR, 40));
bPane.setCenter(text);
RadioButton rbRed = new RadioButton("Red");
RadioButton rbGreen = new RadioButton("Green");
RadioButton rbBlue = new RadioButton("Blue");
ToggleGroup group = new ToggleGroup();
rbRed.setToggleGroup(group);
rbGreen.setToggleGroup(group);
rbBlue.setToggleGroup(group);
vBox.getChildren().addAll(rbRed, rbGreen, rbBlue);
Slider slider = new Slider(0, 255, 135);
slider.setShowTickLabels(true);
slider.setShowTickMarks(true);
bPane.setBottom(slider);
BorderPane.setAlignment(slider, Pos.CENTER);
// Create a handler for the updating text fill:
ChangeListener<Object> updateListener = (obs, oldValue, newValue) -> {
int colorValue = (int) slider.getValue() ;
int red = rbRed.isSelected() ? colorValue : 0 ;
int green = rbGreen.isSelected() ? colorValue : 0 ;
int blue = rbBlue.isSelected() ? colorValue : 0 ;
text.setFill(Color.rgb(red, green, blue));
};
slider.valueProperty().addListener(updateListener);
group.selectedToggleProperty().addListener(updateListener);
// Create a scene and place it in the stage
Scene scene = new Scene(bPane, 400, 400);
primaryStage.setScene(scene);
primaryStage.setTitle("Oblig 5");
primaryStage.show();
}
}
You could set the Color to use as userData to the toggles. This allows you to create a binding for the fill property of the text based on the slider value and the selected toggle:
// create radio buttons and add color at full brightness
RadioButton rbRed = new RadioButton("Red");
rbRed.setUserData(Color.RED);
RadioButton rbGreen = new RadioButton("Green");
rbGreen.setUserData(Color.LIME);
RadioButton rbBlue = new RadioButton("Blue");
rbBlue.setUserData(Color.BLUE);
ToggleGroup group = new ToggleGroup();
rbRed.setToggleGroup(group);
rbGreen.setToggleGroup(group);
rbBlue.setToggleGroup(group);
group.selectToggle(rbRed);
...
// create binding based on toggle user data and slider value
text.fillProperty().bind(Bindings.createObjectBinding(() -> {
Color color = (Color) group.getSelectedToggle().getUserData();
// use color determined by toggle with brightness adjusted based on slider value
return color.deriveColor(0, 1, slider.getValue() / slider.getMax(), 1);
}, slider.valueProperty(), group.selectedToggleProperty()));
Note that using these code snippets there is no need to keep the listeners. Especially the listener updating the text fill should be removes, since the attempt to assign a bound property results in an exception.

Lengthen Javafx Sliders in GridPane

Whatever I try, the slider refuses to lengthen/stretch horizontally. My theory is that the GridPane cell sizes are overriding the slider's x coordinate. Any solutions?
here's my entire class:
public class MoodMeter extends GridPane {
public MoodMeter() {
GridPane grid = new GridPane();
grid.setAlignment(Pos.TOP_CENTER);
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(25, 25, 25, 25));
Slider slider = new Slider(-100, 100, 0);
slider.setOrientation(Orientation.HORIZONTAL);
slider.setMaxWidth(100);
slider.setBlockIncrement(100);
setHgrow(slider, Priority.ALWAYS);
grid.add(slider, 1, 0);
Scene scene = new Scene(grid, 700, 100);
Stage stage = new Stage();
stage.setTitle("Diary Mood Meter");
stage.setScene(scene);
stage.setResizable(false);
stage.show();
Rectangle2D desktop = Screen.getPrimary().getVisualBounds();
stage.setY(((desktop.getMaxY() + desktop.getMinY()) / 2) + 200);
}
}
And this is the result:
(not enough population)
http://i.imgur.com/cfvdKIM.png
Solved.
Changed
slider.setMaxWidth(100);
slider.setBlockIncrement(100);
to
slider.setMaxWidth(1000);
slider.setBlockIncrement(1000);
Without knowing the rest of your GridPane code setup, there are several ways to achieve that:
set slider.setMaxWidth(Double.MAX_VALUE)
add ColumnConstraints for horizontal resizing to the GridPane
set the Hgrow of your slider accordingly.
Just set the hgrow property for the slider to ALWAYS:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.stage.Stage;
public class SliderInGridPane extends Application {
#Override
public void start(Stage primaryStage) {
GridPane root = new GridPane();
root.add(new Label("Value:"), 0, 0);
Slider slider = new Slider(0, 100, 50);
GridPane.setHgrow(slider, Priority.ALWAYS);
root.add(slider, 1, 0);
primaryStage.setScene(new Scene(root, 250, 75));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

How to add empty row in GridPane in JavaFx?

I would like to add little space between rows every x row in the loop. I find this is better to add empty row to GridPane than setting particular constrains on rows. Problem is I don't know what node should I put into that row to fake empty element. I could do by putting let say Text node. But is this really correct? Can anyone provide more elegant solution?
gridPane.addRow(i, new Text(""));
Using a Text node with an empty string for creating the empty gridpane row is fine.
As an alternative, the sample below uses a Pane to create a "spring" node for the empty grid row which could have it's preferred height set to any required value to achieve whatever gap size you want. Additionally the spring node can also be styled via css if necessary.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
// GridPane with a blank row
// http://stackoverflow.com/questions/11934045/how-to-add-empty-row-in-gridpane-in-javafx
public class GridPaneWithEmptyRowSample extends Application {
public static void main(String[] args) { launch(args); }
#Override public void start(final Stage stage) throws Exception {
// create nodes for the grid.
final Label label1 = new Label("Label 1");
final Label label2 = new Label("Label 2");
final Label label3 = new Label("Label 3");
final Pane spring = new Pane();
spring.minHeightProperty().bind(label1.heightProperty());
// layout the scene.
final GridPane layout = new GridPane();
layout.add(label1, 0, 0);
layout.add(spring, 0, 1);
layout.add(label2, 0, 2);
layout.add(label3, 0, 3);
layout.setPrefHeight(100);
stage.setScene(new Scene(layout));
stage.show();
}
}
I think the best way to solve this is by adding RowConstraints, setting the height of each row in the Gridpane. Then you wont have to add "empty" rows, because each row will acquire the same space regardless of whether it contains anything or not.
Here's a minimal, complete and verifiable example:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.RowConstraints;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class SSCCE extends Application {
#Override
public void start(Stage stage) {
VBox root = new VBox();
GridPane gridPane = new GridPane();
gridPane.add(new Label("First"), 0, 0);
gridPane.add(new Label("Second"), 0, 2);
gridPane.add(new Label("Third"), 0, 3);
// Add one RowConstraint for each row. The problem here is that you
// have to know how many rows you have in you GridPane to set
// RowConstraints for all of them.
for (int i = 0; i <= 3; i++) {
RowConstraints con = new RowConstraints();
// Here we set the pref height of the row, but you could also use .setPercentHeight(double) if you don't know much space you will need for each label.
con.setPrefHeight(20);
gridPane.getRowConstraints().add(con);
}
root.getChildren().add(gridPane);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
The problem with this method is that there's - to my knowledge - no easy way to to get the amount rows in a GridPane, and there's no easy way to add the same RowConstraint to every row in the GridPane. This makes the code rather messy. But you could solve this by e.g. creating your own subclass to GridPane that keeps track of the size.
In the example above we set the pref height of the row, but you could also use .setPercentHeight(double) if you don't know much space you will need for each label.
GridPane gp = new GridPane();
gp.add(" ",2, 2);

Resources