javafx borderpane aligning in left and right space - java

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

Related

Why won't javafx rectangles display their color when sizing to the parent container's getWidth/Height?

I'm trying to use rectangles as the background for text labels by putting them behind the VBox text in a StackPane, but when I try using the VBox's getWidth() or getHeight() values for the rectangle's size, the rectangle does not appear. I suppose I could
This works, displaying the blue rectangle behind the text, though not the size I want:
StackPane tadPane = new StackPane();
tadPane.setBorder(border);
Rectangle tadRec = new Rectangle();
VBox tadBox = new VBox();
Label totalXP = new Label("Total XP: ");
Label diff = new Label("Difficulty: ");
tadBox.getChildren().addAll(totalXP,diff);
tadRec.setWidth(50);
tadRec.setHeight(50);
tadRec.setFill(Color.BLUE);
tadPane.getChildren().addAll(tadRec,tadBox);
But this doesn't, the rectangle is not visible:
StackPane tadPane = new StackPane();
tadPane.setBorder(border);
Rectangle tadRec = new Rectangle();
VBox tadBox = new VBox();
Label totalXP = new Label("Total XP: ");
Label diff = new Label("Difficulty: ");
tadBox.getChildren().addAll(totalXP,diff);
tadRec.setWidth(tadBox.getWidth());
tadRec.setHeight(tadBox.getHeight());
tadRec.setFill(Color.BLUE);
tadPane.getChildren().addAll(tadRec,tadBox);
I can't understand why this would be happening. Raw numbers in the setWidth/Height work, but the getWidth/Height from the VBox should be returning numbers too if the labels with text are inside.
The reason for this is that at the time you retrieve the height and width, no layout pass has happened for the VBox so the size is still the initial one of 0 x 0.
You could use bindings to make the size update on a layout:
tadRec.widthProperty().bind(tadBox.widthProperty());
tadRec.heightProperty().bind(tadBox.heightProperty());
though it could be much simpler to simply apply a a background to the VBox instead of using a Rectangle:
tadBox.setStyle("-fx-background-color: blue;");

How do I insert text into a shape in Javafx?

Using JavaFX I have created a simple rectangle object, and I want to be able to put a text object inside that rectangle, and for it to automatically stay aligned within the rectangle. The code I have to draw the rectangle is:
public static Scene createScene() {
Group root = new Group();
Scene scene = new Scene(root, Color.ALICEBLUE);
Rectangle rectangle_red = new Rectangle();
rectangle_red.setFill(Color.TRANSPARENT);
rectangle_red.setStroke(Color.BLACK);
rectangle_red.setX(50);
rectangle_red.setY(50);
rectangle_red.setWidth(200);
rectangle_red.setHeight(100);
rectangle_red.setCursor(Cursor.HAND);
rectangle_red.setOnMousePressed(circleOnMousePressedEventHandler);
rectangle_red.setOnMouseDragged(circleOnMouseDraggedEventHandler);
root.getChildren().add(rectangle_red);
return scene;
}
The Handlers I have attached to the rectangle allow me to drag the rectangles anywhere in the window. How do I place text inside the rectangle such that it stays aligned as I drag the shape around the screen?
As illustrated in the last example seen here, the Animation Basics example TimelineEvents does this by adding a Circle and some Text to a StackPane, which centers its children by default. The stack can then be moved within an enclosing Group as a unit.
final Circle circle = new Circle(…);
final Text text = new Text (…);
final StackPane stack = new StackPane();
stack.getChildren().addAll(circle, text);
…
stack.setLayoutX(30);
stack.setLayoutY(30);

ImageView always scaling beyond scene size, can't seem to force it to fit

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

Set group of objects as background of a scene

I am trying to set the background of a scene. What I want as the background is a group called stars. My scene contains a VBox that contains a Label and two buttons. When I add the group to the scene, the VBox is moved, and some of the objects are cut off. I need a way to add the group to the scene without adding it to the VBox. I have tried adding the VBox and the group to another group, but the program does not run at all.
I define the objects to be set as the background in:
public static void background()
{
Group stars = new Group();
starsLink = stars;
for (int starInt = 0; starInt < 480; starInt++)
{
Circle star = new Circle(Math.random() * 1024, Math.random() * 600, 1, Color.web("white", 1));
stars.getChildren().add(star);
}
}
and I add the objects to the VBox and set the scene of the stage in:
VBox helpVBox = new VBox();
helpVBox.getChildren().addAll(plotLabel, controlsLabel, instructionsLabel, menuButton);
helpVBox.setAlignment(Pos.CENTER);
helpVBox.setSpacing(10);
Scene helpScene = new Scene(helpVBox);
helpScene.getStylesheets().add(stellarClass.class.getResource("/CSS/style.css").toExternalForm());
helpSceneLink = helpScene;
I would recommand something like this:
Stage
--Scene
----root (Stackpane or something like that)
-------yourBackgroundGroup
-------yourForeGround (your Vbox with content)
Make sure to add your VBox after the BackgroundGroup or call vbox.toFront() otherwise the background will cover the view :P

When adding a second item to my stackpane, the first item loses its Event/MouseOn. Why? How can I fix? JavaFX

I have a stackpane. When I add a second item to my stack pane, both show up, but I can't click on my first item anymore. It becomes 'unclickable'.
what ever I defined in my .setonmouse does not work. It works for my second item. If I switch the order they are in the stack pane, the other one works, but not both.
is there a fix for this? This is what my program looks like:
I want my 'grid' centered ALWAYS. There are buttons to the left centered in a column, there will be buttons on the right later on, and there will be buttons/Text on top of the grid and buttom in the margins later on too.
I want everything to be clickable.
http://img688.imageshack.us/img688/6025/examplerg.png
StackPane orders items in Z-order: latter above the former. So, your second item gots all mouse clicks and first one (being covered by second) doesn't get anything.
For layout you've described you can use BorderPane:
public void start(Stage stage) throws Exception {
BorderPane root = new BorderPane();
root.setCenter(new Rectangle(100,100, Color.RED));
root.setLeft(new Rectangle(10,10, Color.BLUE));
root.setRight(new Rectangle(10,10, Color.CYAN));
stage.setScene(new Scene(root,300,300));
stage.show();
}
You can make any Pane "mouse transparent", so that it doesn't consume any click events, and lets them pass through to the stack under it.
Here's some example code... this example sets up 4 panes in a stack, with just the mainPane accepting clicks to begin with.
StackPane rootPane = new StackPane();
VBox mainPane = new VBox(80);
BorderPane helpOverlayPane = new BorderPane();
helpOverlayPane.setMouseTransparent(true);
Canvas fullScreenOverlayCanvas = new Canvas();
fullScreenOverlayCanvas.setMouseTransparent(true);
VBox debugPane = new VBox();
debugPane.setAlignment(Pos.BASELINE_RIGHT);
AnchorPane debugOverlay = new AnchorPane();
debugOverlay.setMouseTransparent(true);
debugOverlay.getChildren().add(debugPane);
AnchorPane.setBottomAnchor(debugPane, 80.0);
AnchorPane.setRightAnchor(debugPane, 20.0);
rootPane.getChildren().addAll(mainPane, fullScreenOverlayCanvas, debugOverlay, helpOverlayPane);
Now, when you want to use your canvas to draw on top, make sure you change mouse transparent to false for just that stack, and keep all panes on top of it mouse transparent.
fullScreenOverlayCanvas.setMouseTransparent(false);
debugOverlay.setMouseTransparent(true);
fullScreenOverlayCanvas.setVisible(true);
doSomethingWithCanvasThatNeedsMouseClicks();
P.S. I did some editing of the code I had, so it may not run as-is. Also, see discussion of making only parts of panes transparent here:
JavaFX Pass MouseEvents through Transparent Node to Children

Categories