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);
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 GridPane
s 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 GridPane
s 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
Twitter Bootstrap Text Field's Height Too Small
How to Center an Image Horizontally and Align It to The Bottom of The Container
How to Combine Position: Relative and Float: Left
Bootstrap 3: Using Img-Circle, How to Get Circle from Non-Square Image
Styling Not Applied to Vue Web Component During Development
Bootstrap, Making Responsive Changes to Layout
CSS Footer Position Stick to Bottom of Browser
In CSS Is There a Selector for Referencing a Specific Input Type That Also Has a Class
How to Create Text Border in React Native
CSS3 Box Shadow Size - Percent Units
Bootstrap Not Working Properly in Angular 6
Using Bootstrap Cards as a Hyperlink