I have a titled pane, and I'm displaying an image in this pane, but the image is very big so I resize it, to fit the pane. Since the image becomes smaller, the user might want to view it in original size, so I implemented a method on mouse click opening the original image in new bigger window.
imgViewPicture.setFitWidth(titledPanePicture.getPrefWidth());
imgViewPicture.setPreserveRatio(true);
imgViewPicture.setSmooth(true);
imgViewPicture.setCache(true);
titledPanePicture.setContent(imgViewPicture);
The problem is, when I click on titledPanePicture the small image disappears, its content is cleared. Why? For the solution I added a reloading of the content on mouseclick event. But I dont like it, I think the content should stay the same for titledPanePicture.
Here is my mouseclick event:
Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
Group root = new Group();
Scene scene = new Scene(root);
scene.setFill(Color.BLACK);
HBox box = new HBox();
imgViewPicture.setFitWidth(0);
box.getChildren().add(imgViewPicture);
root.getChildren().add(box); // before tPane
stage.setTitle("Picture Original Size");
stage.setScene(scene);
stage.sizeToScene();
stage.show();
reloadContentofTitledPane(); // This line is the fix but I find it unnecessary
Tips would be appreciated.
You seem to use the same ImageView in both scenes. However a Node can only be placed at a single place in a single scene graph.
Create a new node for your new Scene.
ImageView newImageView = new ImageView(imgViewPicture.getImage());
...
box.getChildren().add(newImageView);
Related
I'm working on a school project in Java FX, I'd like to add an icon next to my primarystage title and center the title, just like the one in the picture. I have looked around in the javadoc for Stage but i can only find the setTitle() method. Here is a link to what i'd like to do :
You can set your stage to undecorated, set your scene root to a border pane and create your own custom top bar.
BorderPane root = new BorderPane();
root.setTop(new Pane(bb, label));
Scene scene = new Scene(root, 400, 400);
ButtonBar topBar = new ButtonBar(… insert buttons in here....);
// eg: Button b = new Button("X); b.setOnAction(e->{stage.close();});
root.setTop(topBar);
stage.initStyle(StageStyle.UNDECORATED);
I've been working in JavaFX for the first time to try to make an app which I can use to demonstrate a simple animation with button controls. To do this I've used a BoarderPane for the primary stage, with both the left,right, and bottom using Gridpanes.
However, for the center I need to be able to draw a sphere with a line within it which I can rotate for different views while simultaneously being able to animated, or at the very least snap-move, the line within.
I've tried using a Pane for the center which doesn't work. I've tried making it it's own scene and sub scene which doesn't work. And I can't use a canvas as that is only for 2D animation.
Is there a way I can animate the line or rotate the camera while maintaining the BoarderPane layout I've created?
I've tried looking at the following before to understand what I could do but most just seem incompatible with the BoarderPane:
JavaFX Rotating Camera Around a Pivot
JavaFX Canvas rotate image with fixed center (and without bouncing)
Whenever you want to mix 2D and 3D (and camera) you have to use a SubScene container for the 3D content:
SubScene provides separation of different parts of a scene, each of which can be rendered with a different camera, depth buffer, or scene anti-aliasing. A SubScene is embedded into the main scene or another sub-scene.
If you have a BorderPane container, you can perfectly add the subScene to its center.
For a similar use case, you can check the Qubit3D class from here, which is mainly a group that holds a sub scene with an Sphere and a cylinder (both from the FXyz 3D library).
You can add this group easily to your 2D scene:
private final Rotate rotate = new Rotate(0, 0, 0, 0, javafx.geometry.Point3D.ZERO.add(1, 1, 1));
#Override
public void start(Stage primaryStage) throws Exception {
final Timeline timeline = new Timeline(
new KeyFrame(Duration.seconds(10),
new KeyValue(rotate.angleProperty(), 360)));
final Qubit3D qubit = new Qubit3D();
final BorderPane root = new BorderPane(qubit);
final Button buttonAnimate = new Button("Animate");
buttonAnimate.setOnAction(e -> {
rotate.setAngle(0);
timeline.playFromStart();
});
root.setLeft(new StackPane(buttonAnimate));
final Button buttonStop = new Button("Stop");
buttonStop.setOnAction(e -> timeline.stop());
root.setRight(new StackPane(buttonStop));
Scene scene = new Scene(root, 600, 400, true, SceneAntialiasing.BALANCED);
scene.setFill(Color.BISQUE);
primaryStage.setScene(scene);
primaryStage.setTitle("Qubit3D Sample");
primaryStage.show();
qubit.rotateRod(rotate);
}
The only modification I've added to Qubit3D is:
public void rotateRod(Rotate rotate) {
rodSphere.getTransforms().setAll(rotate);
}
If you run it:
Note that you can interact with the sphere (via mouse dragged events), while you can also start/stop a full rotation of sphere and rod.
Just wondering if anyone know how to implement a vertical scrollbar that spans the entire scene in JavaFX? Been trying to figure it out for a few days now and I just can't seem to figure it out.
If you mean make it your root you can do it like this
Stage stage = new Stage();
ScrollPane pane = new ScrollPane();
TextField yourcontent = new TextField("this is an example");
pane.setContent(yourcontent);
pane.setVbarPolicy(ScrollBarPolicy.ALWAYS);
Scene scene = new Scene(pane,300,300);
stage.setScene(scene);
stage.showAndWait();
and then put the rest of your content in it via setContent();
I'm making a Javafx game with a pane to hold my elements. The background color is set to black (instead of the default white) using the Scene.setFill(); method.
public class backgroundColor extends Application{
#Override
public void start(Stage stage) throws Exception {
Pane background = new Pane();
Scene scene = new Scene(background, 800, 600);
scene.setFill(Color.BLACK);
//Button button = new Button("Just a button");
stage.setScene(scene);
stage.show();
}
}
This works fine and the background is displayed as black... However, when I un-comment the button line, the fill color is suddenly displayed as white. Notice that the button is only initialized, it isn't being used, eclipse even gives me the warning that the data field "button" is unused.
Is this a weakness of Scene.setFill()? Or is this a unintended feature of creating a controller?
I am working on a game where I switch between different displays by changing the scene's "root" property using Scene.setRoot(), and before I created a button the color was fine no matter how many times I set different panes as the scene's new root node. However, after I created the button I discovered that I had to use a significantly more complicated workaround:
background.setBackground(new Background(new BackgroundFill(Color.BLACK, null, null)));
to fix the issue. Is there a better way to fix the background for the scene, or do I really have to set the background manually for all panes?
I have this code (simplified/shortend/pseudo):
StackPane background = new StackPane();
GridPane overlay = new GridPane();
BorderPane pane = new BorderPane(background);
pane.setLeft(overlay);
I want the background/Stack pane to cover the entire window (in the background, surprise), and the overlay/Grid to cover a part of the background. The issue is that when I add an ImageView to the StackPane, the image shows up and nothing else. The overlay is not visible. I have tried overlay.toFront, overlay.preferredHeight, and background.toBack, with no success.
Try putting the border pane into the stack pane, instead of the other way around, and then making sure you add the image as the first element of the stack pane's children.
GridPane overlay = new GridPane();
BorderPane pane = new BorderPane();
pane.setLeft(overlay);
StackPane background = new StackPane(pane);
// ...
ImageView imageView = ... ;
background.getChildren().add(0, imageView);
// ...
scene.setRoot(background);
Alternatively, just use a BorderPane as the root and add the nodes in the usual way. Then, in an external style sheet, do
.root {
-fx-background-image: url(relative/path/to/image);
}