Javafx Gridpane: Shrink If Content Is Disabled and Invisible

JavaFX GridPane: Shrink if content is disabled and invisible

If you do not want the parent to layout a node, you can set the managed property of the node to false.

Here is an image showing the difference in layout when I used the following line in your code:

label2.setManaged(false);

Sample Image

Add invisible row in javafx gridpane

As mentioned in the comment (link to comment):

Change the height to 0 when hidden.

set content on stackpane instead of using visible and invisible

You can add an imageview object to your stackpane and change the image within when the button is clicked.

UPDATED ANSWER

@Override
public void start(Stage primaryStage) {
Button btn = new Button("One");
Button btn2 = new Button("Two");
btn2.setTranslateX(btn.getTranslateX() + 60);
Image img1 = new Image ("https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/Thumbs_up_font_awesome.svg/512px-Thumbs_up_font_awesome.svg.png");
Image img2 = new Image ("https://cdn2.iconfinder.com/data/icons/windows-8-metro-style/512/thumbs_down.png");

Image loadImg = new Image("http://www.ledr.com/colours/white.jpg");
ImageView imgHolder = new ImageView(loadImg);
imgHolder.setVisible(false);
imgHolder.setFitHeight(100);
imgHolder.setFitWidth(100);
//Offset stackapane
imgHolder.setTranslateY(-80);

Random rand = new Random();

btn.setOnAction(e->{
int randomNum = rand.nextInt(10) + 1;
imgHolder.setVisible(true);
if(randomNum % 2 == 0){

imgHolder.setImage(img1);
}
else{
imgHolder.setImage(img2);
}
});
//Repeat action for btn2

StackPane root = new StackPane();
root.getChildren().addAll(btn,btn2,imgHolder);
Scene scene = new Scene(root, 300, 250);
primaryStage.setScene(scene);
primaryStage.show();
}

How to add empty row in GridPane in JavaFx?

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();
}
}

How can I prevent a window from being too small in JavaFX?

Calling Stage.sizeToScene() and then setting the minimum width and height to the current width and height after showing the stage works for me:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Login extends Application {

@Override
public void start(Stage primaryStage) throws Exception {
Scene scene = new Scene(FXMLLoader.load(getClass().getResource("LoginForm.fxml")));
primaryStage.setScene(scene);
primaryStage.sizeToScene();
primaryStage.show();
primaryStage.setMinWidth(primaryStage.getWidth());
primaryStage.setMinHeight(primaryStage.getHeight());
}

public static void main(String[] args) {
launch(args);
}
}

sizeToScene() is redundant here, as this is the default behavior in this scenario, though you might need this if you replace the stage's scene at a later time (and making things explicit is never a bad thing).

If you want to explicitly set the size of the stage to something other than the size that allows the scene to be its preferred size, but still enforce the same minimum size requirements, it gets a bit trickier. After showing the stage, you can calculate the difference between the size of the stage and the size of the root of the scene (essentially the space taken up by the window decorations), and compute the preferred size of the root, and then use those to compute the minimum size of the stage. This looks like

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.geometry.BoundingBox;
import javafx.geometry.Bounds;
import javafx.geometry.Orientation;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Login extends Application {

@Override
public void start(Stage primaryStage) throws Exception {
Scene scene = new Scene(FXMLLoader.load(getClass().getResource("LoginForm.fxml")));

primaryStage.setScene(scene);

primaryStage.setWidth(400);
primaryStage.setHeight(280);

primaryStage.show();

Node root = scene.getRoot();
Bounds rootBounds = root.getBoundsInLocal();
double deltaW = primaryStage.getWidth() - rootBounds.getWidth();
double deltaH = primaryStage.getHeight() - rootBounds.getHeight();

Bounds prefBounds = getPrefBounds(root);

primaryStage.setMinWidth(prefBounds.getWidth() + deltaW);
primaryStage.setMinHeight(prefBounds.getHeight() + deltaH);
}

private Bounds getPrefBounds(Node node) {
double prefWidth ;
double prefHeight ;

Orientation bias = node.getContentBias();
if (bias == Orientation.HORIZONTAL) {
prefWidth = node.prefWidth(-1);
prefHeight = node.prefHeight(prefWidth);
} else if (bias == Orientation.VERTICAL) {
prefHeight = node.prefHeight(-1);
prefWidth = node.prefWidth(prefHeight);
} else {
prefWidth = node.prefWidth(-1);
prefHeight = node.prefHeight(-1);
}
return new BoundingBox(0, 0, prefWidth, prefHeight);
}

public static void main(String[] args) {
launch(args);
}
}

I haven't tested this on all platforms.

How to get access to a bunch of elements (Gridpane type in my case) stored into an observableList?

The ObservableList is created in the initializer, since you assign the value in the field declaration. However the GridPanes are injected later. At the time

ObservableList<GridPane> mesas = FXCollections.observableArrayList(fila1,fila2,fila3,fila4,fila5);

is executed, the fields still contain the initial values of null.

To get a list of the injected GridPane, you need to create/assign the ObservableList after the GridPanes have been injected, e.g. in the initialize method:

@FXML
ObservableList<GridPane> mesas;

@Override
public void initialize(URL location, ResourceBundle resources) {
mesas = FXCollections.observableArrayList(fila1,fila2,fila3,fila4,fila5);
}


Related Topics



Leave a reply



Submit