How to set vbox size to window size in javafx? - javafx-2

I am using JavaFX for UI.How to set Vbox layout's size to window size?
I tried the below code,but couldnot view the components added in vbox.
VBox vbox = new VBox();
vbox.setPadding(new Insets(10, 10, 10, 10));
vbox.setSpacing(10);

This sets VBOX on 80% of the Stage width:
Stage window = PrimaryStage;
VBox layout = new VBox(10);
//multiply to set size (0.80 is like 80% of the window)
layout.prefWidthProperty().bind(window.widthProperty().multiply(0.80));

To set your vBox size to the main window's size just add it to the scene
primaryStage.setScene(new Scene(vBox, 200, 200));
Add nodes to your VBox to show them inside the box
vBox.getChildren().add(label);
Try this example:
package javafxapplication1;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class JavaFXApplication1 extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
VBox vBox = new VBox();
vBox.setStyle("-fx-background-color: #ABABAB");
Label label = new Label("Test");
vBox.getChildren().add(label); //Add new node to vBox
primaryStage.setScene(new Scene(vBox, 200, 200)); //Add vbox to scene
primaryStage.show();
}
}

You can use:
VBox vbox = new VBox();
vbox.setPrefWidth(400);// prefWidth
vbox.setPrefHeight(500);// prefHeight
or
VBox vbox = new VBox();
vbox.setPrefSize(400, 500);// prefWidth, prefHeight
Read more here!

Related

JavaFX resizing root stackpane

i'd like to have a StackPane as the root node, it makes overlay effects easy.
But by using a stackpane as the root, inner controls can move out of the window.
In the following example you can see the controls moving out of the window ,
if you shrink the window small enough, e.g. both the menubar and the listview go out to the left. I want to prevent this, how can i do that?
package test;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.ListView;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class App extends Application {
#Override
public void start(Stage stage) throws Exception {
stage.setTitle("controls move out of window :(");
Menu menu = new Menu("Menu");
MenuBar menubar = new MenuBar(menu);
ListView<String> listView = new ListView<>(FXCollections.observableArrayList("Args, it moves away."));
BorderPane borderPane = new BorderPane();
borderPane.setTop(menubar);
borderPane.setLeft(listView);
StackPane rootStackPane = new StackPane(borderPane);
Scene scene = new Scene(rootStackPane);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Update:
setting the alignment for the BorderPane inside the StackPane seems to help:
public void start(Stage stage) throws Exception {
stage.setTitle("controls stay in window :)");
Menu menu = new Menu("Menu");
MenuBar menubar = new MenuBar(menu);
ListView<String> listView = new ListView<>(FXCollections.observableArrayList("it stays!"));
BorderPane borderPane = new BorderPane();
borderPane.setTop(menubar);
borderPane.setLeft(listView);
StackPane rootStackPane = new StackPane(borderPane);
StackPane.setAlignment(borderPane, Pos.TOP_LEFT);
Scene scene = new Scene(rootStackPane);
stage.setScene(scene);
stage.show();
}
Place your stack in a Group and bind the stack's preferred size to the scene's preferred size.
As you can see from the second image, the overlay is not centered on the visible screen, it is centered on the StackPane. The StackPane's minimum size will be the minimum size of it's largest component (even if it overflows the screen), so the overlay is centered on that. To find out minimum sizes of things, you could use either design the UI in SceneBuilder or debug the UI using ScenicView.
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class App extends Application {
#Override
public void start(Stage stage) throws Exception {
stage.setTitle("controls stay in window :)");
Menu menu = new Menu("Menu");
MenuBar menubar = new MenuBar();
menubar.getMenus().add(menu);
ListView<String> listView = new ListView<>(FXCollections.observableArrayList("Args, it moves away."));
BorderPane borderPane = new BorderPane();
borderPane.setTop(menubar);
borderPane.setLeft(listView);
borderPane.setStyle("-fx-background-color: palegreen;");
Node overlayContent = new Label("centered");
StackPane stack = new StackPane(borderPane, overlayContent);
Scene scene = new Scene(new Group(stack));
stage.setScene(scene);
stage.show();
stack.prefWidthProperty().bind(scene.widthProperty());
stack.prefHeightProperty().bind(scene.heightProperty());
}
public static void main(String[] args) {
launch(args);
}
}

Set TextField width in JavaFX

How I can set the width of a TextField in JavaFX?
TextField userTextField = new TextField();
I tried this:
TextField userTextField = new TextField();
userTextField.setPrefWidth(80);
But I don't see any change.
Works pretty fine:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
public class TextFieldWidthApp extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
TextField userTextField = new TextField();
userTextField.setPrefWidth(800);
primaryStage.setScene(new Scene(userTextField));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Just set this methods after you create the TextField:
TextField myTf = new TextField();
myTf.setPrefWidth(80);
myTf.setMaxWidth(80);
I had the same problem (that's how I landed on this page) and I fixed it by putting the textfield in a HBox. The problem might occur if the texfield is just put in a parent component alone where the siblings are layout managers. For example, putting it in a GridLayout alongside a VBox or HBox or a child GridLayout. Here is the code that did it;
HBox hbForTextField = new HBox();
TextField sample = new TextField();
sample.setAlignment(Pos.CENTER);//Align text to center
sample.setPrefWidth(120);//Set width
//Add the texfield to the HBox
hbForTextField.getChildren().addAll(generatedPassword);
You can then add the HBox to the root or other parent layout manager.

Background is not changed when I switch buttons

I want to implement this example: http://docs.oracle.com/javafx/2/ui_controls/toggle-button.htm#
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Toggle;
import javafx.scene.control.ToggleButton;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class test extends Application
{
private void init(Stage primaryStage)
{
Group root = new Group();
primaryStage.setScene(new Scene(root));
String pillButtonCss = DX57DC.class.getResource("PillButton.css").toExternalForm();
// create 3 toggle buttons and a toogle group for them
ToggleButton tb1 = new ToggleButton("Left Button");
tb1.setId("pill-left");
ToggleButton tb2 = new ToggleButton("Center Button");
tb2.setId("pill-center");
ToggleButton tb3 = new ToggleButton("Right Button");
tb3.setId("pill-right");
final ToggleGroup group = new ToggleGroup();
tb1.setToggleGroup(group);
tb2.setToggleGroup(group);
tb3.setToggleGroup(group);
// select the first button to start with
group.selectToggle(tb1);
//////////////////////////////////////////
tb1.setUserData(Color.LIGHTGREEN);
tb2.setUserData(Color.LIGHTBLUE);
tb3.setUserData(Color.SALMON);
final Rectangle rect = new Rectangle(300, 300);
group.selectedToggleProperty().addListener(new ChangeListener<Toggle>()
{
#Override
public void changed(ObservableValue<? extends Toggle> ov,
Toggle toggle, Toggle new_toggle)
{
if (new_toggle == null)
{
rect.setFill(Color.WHITE);
}
else
{
rect.setFill(
(Color) group.getSelectedToggle().getUserData());
}
}
});
///////////////////////////////////////////
rect.setArcHeight(10);
rect.setArcWidth(10);
HBox hBox = new HBox();
hBox.getChildren().addAll(tb1, tb2, tb3);
hBox.setPadding(new Insets(20, 20, 260, 20));
hBox.getStylesheets().add(pillButtonCss);
VBox vbox = new VBox();
vbox.getChildren().add(hBox);
vbox.getChildren().add(rect);
root.getChildren().add(vbox);
}
#Override
public void start(Stage primaryStage) throws Exception
{
init(primaryStage);
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
But for some reason I can see the buttons but the rectangle is not displayed when I try to switch the buttons. Can you help me to find where is my mistake? And also how I can implement this example with several rectangles holding different content?
You have to add rect to your scene graph :
root.getChildren().addAll(hBox, rect);
Also, think of using an appropriate layout for your root, BorderPane instead of Group for example.

How to restrict visibility of items?

Imagine that we have an AnchorPane, it has child Pane and there we have Button, for example.
I want this Button to be shown only inside this Pane.
In other words, it whould be cut by the Pane edges if it is not completely within Pane. Now the Button can be visible even if it is out of Pane rectangle.
this is what the clip of a node is made for.
Example:
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class ClipTest extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
Group root = new Group();
StackPane pane = new StackPane();
pane.setMaxWidth(100);
pane.setMaxHeight(100);
pane.setLayoutX(50);
pane.setLayoutY(50);
Rectangle rect = new Rectangle(100, 100);
rect.setFill(null);
rect.setStroke(Color.RED);
Rectangle rect2 = new Rectangle(150, 150);
rect2.setFill(Color.BLUE);
pane.getChildren().addAll(rect2, rect);
root.getChildren().add(pane);
// Rectangle clip = new Rectangle(100, 100);
// clip.setLayoutX(25);
// clip.setLayoutY(25);
// pane.setClip(clip);
Scene scene = new Scene(root, 250, 250);
primaryStage.setScene(scene);
primaryStage.show();
}
}
This produces:
Uncommenting the lines regarding the clip produces:
You can use clipping functionality to achieve this.
public class ClipPane extends Application {
#Override
public void start(Stage stage) throws Exception {
Pane clipPane = new Pane();
clipPane.setStyle("-fx-border-color: red;");
clipPane.setPrefSize(200, 200);
Rectangle rect = new Rectangle(200, 200);
clipPane.setClip(rect);
Button btn = new Button("Hello, world!");
btn.relocate(120, 0);
clipPane.getChildren().add(btn);
AnchorPane root = new AnchorPane();
root.getChildren().add(clipPane);
AnchorPane.setTopAnchor(clipPane, 50.);
AnchorPane.setLeftAnchor(clipPane, 50.);
stage.setScene(new Scene(root, 300, 300));
stage.show();
}
public static void main(String[] args) { launch(); }
}
Another approach, with using of observables. To clip items outside pane bounds (like css oveflow:hidden):
// create rectangle with sizes of pane,
// dont need to set x and y explictly
// as positions of clip node are relative to parent node
// (to pane in our case)
Rectangle clipRect = new Rectangle(pane.getWidth(), pane.getHeight());
// bind properties so height and width of rect
// changes according pane's width and height
clipRect.heightProperty().bind(pane.heightProperty());
clipRect.widthProperty().bind(pane.widthProperty());
// set rect as clip rect
pane.setClip(clipRect);

Is there anyway i could create a transparent root element?

I want to create a borderpane what is transparent.I tried setting background color to transparent but it appears white. plz let me know if there is a way.
Code i tried.
BorderPane root=new BorderPane();
root.setStyle("-fx-background-color:transparent");
Scene scene=new Scene(root);
stage.setScene(scene);
stage.show();
Thank you...
Try setting the stage to transparent:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class TransparentStage extends Application {
#Override
public void start(Stage stage) {
// important line
stage.initStyle(StageStyle.TRANSPARENT);
Text text = new Text("Transparent!");
text.setFont(new Font(40));
VBox box = new VBox();
box.getChildren().add(text);
final Scene scene = new Scene(box,300, 250);
scene.setFill(null);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Resources