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);
Related
Im trying to clear simple canvas in JavaFX.
Start function
Canvas canvas = new Canvas();
Group root = new Group(canvas);
Scene scene = new Scene(root, 1400, 1000);
If user want to load game, then loadSave boolean variable sets to 'true'
if(loadSave){
//Clear scene and load new with circles from file
}
Else, it loads new game
else if(!loadSave){
drawSquares(scene, root);
}
I'll really appreciate your help.
I have special group for my Scene - root.
I can delete only this group using
root.getChildren().clear();
This feature has many uses, I can now eg add items that I want to remove into this group.
To remove only e.g Circles from group(where my Canvas is) I used
void clearScene(Group root) {
for (Circle circle : circles) {
root.getChildren().remove(circle);
}
circles.clear();
}
I build a simple JavaFX App and I wan't to create a circle in the center of an ellipse when the Mouse enters the ellipse.
This is some of the Code:
ellipse = new Ellipse(30,30,40,40);
ellipse.setFill(Color.TRANSPARENT);
ellipse.setStroke(Color.BLACK);
ellipse.setOnMouseEntered(event -> {
Circle circle = new Circle();
circle.setCenterX(30);
circle.setCenterY(30);
circle.setFill(Color.GREEN);
group.getChildren().add(circle);
group.getChildren().removeAll(ellipse);
System.out.println("Added Circle");
});
group = new Group();
group.getChildren().add(ellipse);
vBox = new VBox();
vBox.getChildren().add(group);
The Vbox is added to a Scene and the Scene is added to the PrimaryStage.
If I run the program and my Mouse enters the ellipse the ellipse will be removed but the circle will not be added.
Can anyone explain me why?
First of all this seems to be the wrong way of implementing an dynamic node Adding / removing thing. What would be the right way?
But I'm also interested in why can I remove a Node so easy but I can't added it so easy?
My mistake, the Circle has no radius...
If I add a radius to the circle everything works fine,
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);
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);
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