I'm making an application that uses a SubScene instance on the BorderPane center, and on the right side i want to put a vbox with some content. The subscene starts with the correct size, and resizes perfectly when maximizing the window. before maximizing, maximized
The problem is, when minimizing the window this happens:
minimized
What can I do?
Here's how I managed the resizing system:
SubScene subScene = new SubScene(group, 1200, 700, true, SceneAntialiasing.BALANCED);
HBox centerBox = new HBox();
subScene.widthProperty().bind(centerBox.widthProperty());
subScene.heightProperty().bind(centerBox.heightProperty());
centerBox.getChildren().add(subScene);
For anyone with the same problem. I solved it by binding the SubScene width and height properties with the scene's, and then subtracting the width(200) and height(75) of adjacent nodes:
// Scene scene = new Scene(root, 1200, 800, true);
// SubScene subScene = new SubScene(group, 1200, 700, true, SceneAntialiasing.BALANCED);
// centerBox is an instance of HBox
subScene.widthProperty().bind(scene.widthProperty().subtract(200));
subScene.heightProperty().bind(scene.heightProperty().subtract(75));
centerBox.getChildren().add(subScene);
Related
I have BorderPane and 2 circles. One is added to left space of the BorderPane and second on right. I want to have space of 100 pixels between them. So I create VBox and I use setPrefWidth(100) on HBox. I struggle to move circles. Left circle to right and right circle to left so space between them is 100px. I don't want use padding, so it will be dynamically changing based on monitor resolution.
Circle centerCardCircle = new Circle(300);
centerCardCircle.setFill(Color.DEEPSKYBLUE);
Circle userCardCircle = new Circle(300);
userCardCircle.setFill(Color.DEEPSKYBLUE);
BorderPane borderPane = new BorderPane();
borderPane.setLeft(centerCardCircle);
BorderPane.setAlignment(centerCardCircle, Pos.CENTER_RIGHT);
borderPane.setRight(userCardCircle);
BorderPane.setAlignment(userCardCircle, Pos.CENTER_LEFT);
HBox hbox = new HBox();
hbox.setPrefWidth(100);
borderPane.setCenter(hbox);
Scene scene = new Scene(borderPane);
I am trying to force the child of a GridPane to fit the size of the cell it is in. In this case, I am creating a month view calendar and the columns and rows are a set size regardless of what is in it.
On this calendar, each cell contains a normal VBox and each VBox contains a label that displays the day of the month and each of the events for that day. Many of the days have no events; some of them have one event; and a few have more than one event.
The calendar size is dependent on the window size and will grow and shrink in accordance to the window. Right now, if the cell is too small to fit all of the events, then the height of that one VBox for that day in the cell becomes larger than the cell.
The header row has the following constraint:
HEADER_CONSTRAINT = new RowConstraints(10, -1, 500,
Priority.NEVER, VPos.BASELINE, true);
and the other rows have this constraint:
ROW_CONSTRAINT = new RowConstraints(30, 30, Integer.MAX_VALUE,
Priority.ALWAYS, VPos.TOP, true);
What I think I need to do is:
grid.add(cell, c, r);
vbox.maxHeightProperty().bind(grid.getRow(r).heightProperty()); // <-- this line is not right, but something like this.
As #fabian mentioned correctly, the size of a VBox is entirely dependent the sizes of its children. If you wish to have a container that does not resize depending on its children, you can use a Pane instead. Like this:
public void start(Stage primaryStage)
{
GridPane root = new GridPane();
Scene scene = new Scene(root, 300, 300);
int c = 0, r = 0;
Pane c0 = new Pane();
c0.setPrefSize(200, 200);
c0.setBorder(new Border(new BorderStroke(Color.RED, BorderStrokeStyle.SOLID, CornerRadii.EMPTY,
new BorderWidths(1))));
root.add(c0, c, r);
primaryStage.setScene(scene);
primaryStage.show();
}
Add a shape to test:
Pane c0 = new Pane();
c0.setPrefSize(200, 200);
c0.setBorder(new Border(new BorderStroke(Color.RED, BorderStrokeStyle.SOLID, CornerRadii.EMPTY,
new BorderWidths(1))));
{
Circle circle = new Circle(160, Color.BLUE);
circle.setCenterX(160);
circle.setCenterY(160);
c0.getChildren().add(circle);
}
root.add(c0, c, r);
Note that although the shape protrudes outside of the bounds of c0, the borders of c0 stay in place, indicating that its size is unaffected. To prevent the content from protruding out, you need to add a clip:
c0.setClip(new Rectangle(c0.getPrefWidth(), c0.getPrefHeight()));
If you want a more fancy clip instead of a simple trim, such as fade-in, fade-out, and shadows, you can read this very good tutorial here.
Now just replace this Circle with your VBox, so that the VBox is a child of this Pane, and add the Pane to your GridPane and you're done. I will provide my final code here as a reference:
public void start(Stage primaryStage)
{
GridPane root = new GridPane();
Scene scene = new Scene(root, 300, 300);
int c = 0, r = 0;
Pane c0 = new Pane();
c0.setPrefSize(200, 200);
c0.setClip(new Rectangle(c0.getPrefWidth(), c0.getPrefHeight()));
c0.setBorder(new Border(new BorderStroke(Color.RED, BorderStrokeStyle.SOLID, CornerRadii.EMPTY,
new BorderWidths(1))));
{
Circle circle = new Circle(160, Color.BLUE);
circle.setCenterX(160);
circle.setCenterY(160);
c0.getChildren().add(circle);
}
root.add(c0, c, r);
primaryStage.setScene(scene);
primaryStage.show();
}
Update:
#Jai pointed out that the size is static in this implementation. If you wish to dynamically adjust the size of the cells if the size of the GridPane changes, you can add a listener to its widthProperty and heightProperty like this:
int rowCount = 5, columnCount = 7; // You should know these values.
ChangeListener<Number> updater = (o, oV, nV) ->
{
double newWidth = root.getWidth() / columnCount;
double newHeight = root.getHeight() / rowCount;
root.getChildren().forEach(n ->
{
// Assuming every child is a Pane.
Pane p = (Pane) n;
p.setPrefSize(newWidth, newHeight);
p.setClip(new Rectangle(newWidth, newHeight));
});
};
root.widthProperty().addListener(updater);
root.heightProperty().addListener(updater);
Alternatively...
If you wish to use ColumnConstraints and RowConstraints to determine the cell size you can set the Panes to expand, and only update their clips in the listener, which now listens to ColumnConstraints and RowConstraints:
ColumnConstraints cc = new ColumnConstraints(200);
RowConstraints rc = new RowConstraints(200);
c0.setPrefSize(Double.MAX_VALUE, Double.MAX_VALUE);
c0.setClip(new Rectangle(cc.getPrefWidth(), rc.getPrefHeight()));
and...
ChangeListener<Number> updater = (o, oV, nV) ->
{
root.getChildren().forEach(n ->
{
// Assuming every child is a Pane.
Pane p = (Pane) n;
p.setClip(new Rectangle(cc.getPrefWidth(), rc.getPrefHeight()));
});
};
cc.prefWidthProperty().addListener(updater);
rc.prefHeightProperty().addListener(updater);
I am trying to change the brightness of the whole scene in javafx. This is what my code looks like at the moment:
public void start(Stage primaryStage) {
StackPane root = new StackPane();
Rectangle rec1 = new Rectangle();
rec1.setWidth(300);
rec1.setHeight(300);
rec1.setFill(javafx.scene.paint.Color.RED);
ColorAdjust colorAdjust = new ColorAdjust();
colorAdjust.setBrightness(-0.8);
root.setEffect(colorAdjust);
Scene scene = new Scene(root, 1920, 1080);
root.getChildren().add(rec1);
primaryStage.setFullScreen(true);
primaryStage.setScene(scene);
primaryStage.show();
}
The problem is, like this only the brightness of the rectangle changes, but not the brightness of the whole scene. I also need to change the brightness of the "background". Is there any way to do that?
Strangely this seems to be fixed by adding a node to the StackPane in order for it to adjust the color to everything, not just shapes. When shapes are the only thing visible, that is all that's ColorAdjusted. At least one Node must be present. Changing the one line to the following will do what you want:
root.getChildren().addAll(rec1, new Label());
However, this could have consequences to your project by shift something slightly even though it's empty. We can get around this by making it invisible and not-managed so that it isn't considered in layout calculations.
Label fix = new Label("Fix colorAdjust whole scene.");
fix.setVisible(false);
fix.setManaged(false);
Scene scene = new Scene(root, 500, 500);
root.getChildren().addAll(rec1, fix);
My easy application has two layout panes. First is VBox pane. It is root node. Second pane is child pane (Pane layout). I want to use DropShadow effect for root pane only. I do it according to the documentation . Unfortunately I have the Drop shadow effect for both panes. For root and for child. Is it a bug or there is a way to set it for one pane only? I was trying to use pane.setEffect( null ) but without success. When I add some child to pane, the new node has shadow also.
I use JavaFX8 (Windows 7 - 64).
Thank you.
public void start( Stage stage )
{
VBox vbox = new VBox();
vbox.setPadding( new Insets( 30 ) );
BorderStrokeStyle style = new BorderStrokeStyle( StrokeType.INSIDE, StrokeLineJoin.MITER, StrokeLineCap.BUTT, 10, 0, null );
BorderStroke stroke = new BorderStroke( Color.BLUE, style, CornerRadii.EMPTY, new BorderWidths( 1 ), null );
vbox.setBorder( new Border( stroke ) );
DropShadow dropShadow = new DropShadow();
dropShadow.setOffsetX( 10 );
dropShadow.setOffsetY( 10 );
vbox.setEffect( dropShadow );
Pane pane = new Pane();
pane.setBorder( new Border( stroke ) );
pane.setPrefWidth( 500 );
pane.setPrefHeight( 500 );
vbox.getChildren().add( pane );
stage.setScene( new Scene( vbox ) );
stage.show();
}
addition:
Was trying to use css:
vbox.setStyle( "-fx-effect: dropshadow(gaussian, gray, 10, 0.6, 10, 10);" );
The same shit - the effect was applied for both panes. ((
Here I am trying to answer to my own question.
I made some easy investigations and It looks like it is not a bug. It is an attempt to provide a real life behavior for a pane.
If a pane doesn't have non-transparent background - the all pane's children should have a shadow also (if the owner pane has it). On the other hand - if the pane has solid background, the children can't have a shadow. Till you put shadow specially.
So... You just need to provide a non-transparent background for pane, to avoid shadows for pane's children shapes and panes.
Sure, It would be good to notice it in the docemtntation.
I am new to JavaFX (been working with swing for a long time) and am trying to work with BorderPane. One would assume BorderPane is similar to BorderLayout but the big difference is the center of BorderPane will expand to fit its contents while BorderLayout will shrink to fit the window.
I am using JFXPanel in a JFrame and have a 3 part interface: A panel on the left (some text), some buttons on the bottom (flow control), and in the center want to have a dynamic panel/pane, that for the most part will be just an imageview. I set it all up and it works fine, but I'm working with camera images here which are way bigger than my monitor. I've tried scaling the images down by binding the imageview width to different things (such as anchor pane, scene size (works, but not properly), etc. The issue I am having is that since borderpane's center panel expands to fit its content, it will expand and never have a proper value I can bind to. I need the image to be fully visible in the window at any size.
Here's the code I've been working with.
protected void setupFXWindow(JFXPanel mainPanel) {
butNext = new Button("Next Step");
butBack = new Button("PreviousStep Step");
butQuit = new Button("Cancel Signature Generation");
butNext.setTooltip(new Tooltip("Next step..."));
butBack.setTooltip(new Tooltip("Previous Step..."));
butQuit.setTooltip(new Tooltip("Quit generating a signature"));
Group root = new Group();
Scene scene = new Scene(root, javafx.scene.paint.Color.ALICEBLUE);
javafx.scene.image.Image fximage = new javafx.scene.image.Image(new File(image.getSourceFilePath()).toURI().toString());
ImageView iv1 = new ImageView();
iv1.setImage(fximage);
iv1.setPreserveRatio(true);
VBox directionsPanel = new VBox();
HBox authorflowPanel = new HBox(); //bottom buttons for next, back, etc.
mainPanel.setScene(scene);
//INSTRUCTIONS
directionsStepLabel = new Text();
directionsLabel = new Text();
setDirectionsText("Directions will be placed here.");
exampleLabel = new Text("Example");
exampleIconLabel = new Text("An example image will be shown here.");
directionsPanel.setPadding(new javafx.geometry.Insets(5, 5, 5, 5));
directionsPanel.getChildren().addAll(directionsStepLabel, directionsLabel, exampleLabel);
authorflowPanel.getChildren().addAll(butBack, butQuit, butNext);
BorderPane bp = new BorderPane();
bp.prefHeightProperty().bind(scene.heightProperty());
bp.prefWidthProperty().bind(scene.widthProperty());
bp.setLeft(directionsPanel);
bp.setBottom(authorflowPanel);
bp.setCenter(iv1);
root.getChildren().add(bp);
}
This code sample doesn't have iv1 (imageview) binded to anything, cause at this point I have no idea what I can bind to that will give me the remaining space in the scene. Since I cannot use the full width or height of the scene, I'm at a loss of what I am supposed to do here.
The code above makes it look like this:
Wrap the ImageView in some kind of Pane (e.g. a StackPane). Then the pane will fill the center region of the border pane and you can bind to its width and height:
ImageView iv1 = new ImageView();
iv1.setImage(fximage);
iv1.setPreserveRatio(true);
StackPane imageContainer = new StackPane(iv1);
iv1.fitWidthProperty().bind(imageContainer.widthProperty());
iv1.fitHeightProperty().bind(imageContainer.heightProperty());
// ...
bp.setCenter(imageContainer);