I want to put a WorldWindowGLJPanel into a Pane, and I want to make it resizable, but I can't, even when I call resize or setSize method.
Here's what I'm doing :
wwd = new WorldWindowGLJPanel();
wwd.setPreferredSize(new java.awt.Dimension(300, 300));
wwd.setModel(new BasicModel());
swingNode = new SwingNode();
swingNode.setContent(wwd);
wwdPane = new Pane();
wwdPane.getChildren().add(swingNode);
Then I use this wwdPane to display World Wind.
I want my world wind panel to have the size of the pane which contains it, and I want to make this world wind panel resizable.
I thought about give the size to my world wind panel of my pane with a setSize(PaneDimenson) and then bind the size of my worldwindpanel with my pane , but the setSize function doesn't work.
EDIT : I found an alternative solution by not using a pane, but directly the swingNode, the resize is now automatic. But if you want to use a pane there's still a problem, and you're force to use a group.
The setSize is working, try this code:
scene.widthProperty().addListener(new ChangeListener<Number>() {
#Override public void changed( ObservableValue<? extends Number> o, Number b, Number a ) {
Platform.runLater(new Runnable() {
public void run() {
wwd.setSize((int)(a.intValue()*0.5), wwd.getHeight());
}
});
or with Java8
scene.widthProperty().addListener((o,b,a)->Platform.runLater(()->
wwd.setSize((int)(a.intValue()*0.5), wwd.getHeight())));
But I couldn't make the resize work in my sample code, because the SwingNode somehow mess up the resizing, I think you should try the solution advised here.
Related
In JavaFx I'm currently trying to change the height of
primaryStage via binding.
primaryStage.setScene(scene);
primaryStage.setHeight(400.0);
primaryStage.widthProperty().bindBidirectional(textField.textProperty());
It's just a homework problem, not meaningful.
Unfortunately primaryStage is readOnlyDoubleProperty. May I change this settings to gain write-permissions?
I know, there is the possibility to change the window size via EventHandler, but I would like to change the window size on the fly through the TextField with bindings.
So any newly entered number enlarges the window.
Any ideas?
It's definitely possible and I hope there is a better way and no one should ever use this code ever but this is what I managed to make work
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
TextField textField = new TextField();
//Allows for only numeric input
textField.setTextFormatter(new TextFormatter<>(change -> {
if (change.getText().matches("[0-9]*"))
return change;
else
return null;
}));
primaryStage.setScene(new Scene(textField));
primaryStage.setHeight(200.0);
//Allows Program to start without error
primaryStage.setMaxWidth(200);
//Binds min and max to ensure stage width change due to only 1 possible size
primaryStage.minWidthProperty().bind(primaryStage.maxWidthProperty());
//Bind textfield to width
textField.textProperty().bindBidirectional(primaryStage.maxWidthProperty(), new NumberStringConverter());
primaryStage.show();
}
}
I am working on a paint program in which a button is clicked that toggles the button that draws lines. My code doesn't do what I want it to and instead draws a strange fan shape whenever I try to draw multiple lines. I want it to be able to draw multiple straight lines with the mouse.
canvas.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
initialTouch = new Pair<>(event.getX(), event.getY());
}
});
canvas.addEventHandler(MouseEvent.MOUSE_DRAGGED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
gc.strokeLine(initialTouch.getKey(), initialTouch.getValue(), event.getX(), event.getY());
}
});
canvas.addEventHandler(MouseEvent.MOUSE_RELEASED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
}
});
}```
That method is called when a button is pushed to draw the line. I am expecting multiple lines, but I stead get a fan shape.
What you do, is:
You create start Point.
And then for each DRAG movement you create a OWN line from the Start location to the new Location. Hence you create a lot of lines that resemble a shape.
What you want is:
Create a start point and than draw to the end Point.
So you should ONLY draw a line to the Graphical Context when the Mouse released.
just Move what you do in "dragged" to the "released" part and it sould work.
When you want "Preview" you should Use a Line Object and add it to the View, and then when release the mouse you should delete the Object it.
I've been trying for days and days now to get a BorderPane region go over another region...
The problem is as follow: My app is set in a BorderPane root, With:
A header in its TOP region
A menu in its LEFT region
The content, depending on the page, in it's CENTER
And an optional panel on its RIGHT region
That right region is the problem. It should appear/disappear when clicking on a "notification button" that is in the TOP region. So far so good. The thing is that the app doesn't use the RIGHT region, so I'm trying to make the RIGHT region that contains an AnchorPane go over the CENTER region. The normal state of the app is without the RIGHT region and I don't want to resize the whole app when opening the noitifications. Tried several things, such as:
When clicking the notification button, send the CENTER part toBack() and set the RIGHT width to the 300 wanted pixels
Sending the RIGHT region toFront()
Sending the whole BorderPane toFront()
None of them work, as they all either not show, or resize the center part which I don't want. I'd like the RIGHT to float above the CENTER region when the notification menu is showing.... Is there any way to do that? Or maybe another idea to trigger a container that would show above the CENTER part? Of course, I go design the panel in every CENTER pane and make it visible or not, but my app is about 15 different center windows so it would be really bad in terms of modifications...
I think you should not be trying to make the borderpane do this for you or you will end up with behavior you do not want like the center NOT resizing when the application is resized while the panel is visible.
Remember that JavaFX is really 3D. How about you try to wrap the BorderPane inside of an AnchorPane, GridPane or ScrollPane (whichever makes sense) instead of trying to get the right insert to do your thing. e.g. add an ScrollPane (your Slider) to the containing AnchorPane and bring that to the front and anchor it's top, right and bottom.
This should give you a right-aligned ScrollPane on top of your borderpane.
Then of course if you want it to be fancy with an animated slide you can try this out : https://gist.github.com/jewelsea/1437374
or this:
http://blog.physalix.com/javafx2-borderpane-which-slides-in-and-out-on-command/
Here is a very rough example to show the idea:
public class JavaFXApplication2 extends Application {
ScrollPane slider;
AnchorPane root;
#Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Slide in");
btn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
root.getChildren().add(slider);
AnchorPane.setRightAnchor(slider, 0.);
AnchorPane.setTopAnchor(slider, 0.);
AnchorPane.setBottomAnchor(slider, 0.);
slider.toFront();
}
});
Label l = new Label();
l.setText("Test Label to Show inside content");
Label l2 = new Label();
l2.setText("Peek-a-Boo");
slider = new ScrollPane();
slider.setStyle("-fx-border-color: orangered;");
slider.setContent(l2);
root = new AnchorPane();
root.getChildren().add(btn);
root.getChildren().add(l);
AnchorPane.setRightAnchor(l, 0.);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
I have the following code which maximizes the window when the maximize button is clicked (the green one in the title bar). However it does not comes back to the original size (900x600) when it is clicked again while in maximize position. I see only the left side is shrinked.
//set the original size
final Scene homeScene = new Scene(homePane,900,600);
...
primaryStage.maximizedProperty().addListener(new ChangeListener<Boolean>() {
#Override
public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
primaryStage.setX(bounds.getMinX());
primaryStage.setY(bounds.getMinY());
primaryStage.setWidth(bounds.getWidth());
primaryStage.setHeight(bounds.getHeight());
}
});
How do I get back the original position ? The "Changed" method is not triggered when maximize button is clicked again , otherwise I would have set the original size programmatically.
Following code works just fine to listen for the maximized state of a Stage:
primaryStage.maximizedProperty().addListener((w,o,n)->System.out.println(n));
Are using a custom (undecorated) Stage, then you might want to take a look at the Undecorator which has done just this.
I used this code
#FXML
private void btnMaximize(MouseEvent event) {
Stage s = (Stage) borderpane.getScene().getWindow();
s.setFullScreen(true);
}
#FXML
private void btnRestoreDown(MouseEvent event) {
Stage s = (Stage) borderpane.getScene().getWindow();
s.setFullScreen(false);
}
Hope it may help someone who sees this post 😊😊
A few days ago I started studying JavaFX, and came across the desire to perform 2 experiments. Firstly, I would like to know if it is possible to put an animated background behind an user interface. I've succeeded in creating an animated background, and now I'm having great difficulties to position some controls in the middle of my interface.
I'd like to introduce you 2 pictures of my program. The first demonstrates the undesirable result that I'm getting:
I believe this is my nodes tree:
This is the code of my application:
public class AnimatedBackground extends Application
{
// #########################################################################################################
// MAIN
// #########################################################################################################
public static void main(String[] args)
{
Application.launch(args);
}
// #########################################################################################################
// INSTÂNCIAS
// #########################################################################################################
private Group root;
private Group grp_hexagons;
private Rectangle rect_background;
private Scene cenario;
// UI
private VBox lay_box_controls;
private Label lab_test;
private TextArea texA_test;
private Button bot_test;
// #########################################################################################################
// INÍCIO FX
// #########################################################################################################
#Override public void start(Stage stage) throws Exception
{
this.confFX();
cenario = new Scene(this.root , 640 , 480);
this.rect_background.widthProperty().bind(this.cenario.widthProperty());
this.rect_background.heightProperty().bind(this.cenario.heightProperty());
stage.setScene(cenario);
stage.setTitle("Meu programa JavaFX - R.D.S.");
stage.show();
}
protected void confFX()
{
this.root = new Group();
this.grp_hexagons = new Group();
// Initiate the circles and all animation stuff.
for(int cont = 0 ; cont < 15 ; cont++)
{
Circle circle = new Circle();
circle.setFill(Color.WHITE);
circle.setEffect(new GaussianBlur(Math.random() * 8 + 2));
circle.setOpacity(Math.random());
circle.setRadius(20);
this.grp_hexagons.getChildren().add(circle);
double randScale = (Math.random() * 4) + 1;
KeyValue kValueX = new KeyValue(circle.scaleXProperty() , randScale);
KeyValue kValueY = new KeyValue(circle.scaleYProperty() , randScale);
KeyFrame kFrame = new KeyFrame(Duration.millis(5000 + (Math.random() * 5000)) , kValueX , kValueY);
Timeline linhaT = new Timeline();
linhaT.getKeyFrames().add(kFrame);
linhaT.setAutoReverse(true);
linhaT.setCycleCount(Animation.INDEFINITE);
linhaT.play();
}
this.rect_background = new Rectangle();
this.root.getChildren().add(this.rect_background);
this.root.getChildren().add(this.grp_hexagons);
// UI
this.lay_box_controls = new VBox();
this.lay_box_controls.setSpacing(20);
this.lay_box_controls.setAlignment(Pos.CENTER);
this.bot_test = new Button("CHANGE POSITIONS");
this.bot_test.setAlignment(Pos.CENTER);
this.bot_test.setOnAction(new EventHandler<ActionEvent>()
{
#Override public void handle(ActionEvent e)
{
for(Node hexagono : grp_hexagons.getChildren())
{
hexagono.setTranslateX(Math.random() * cenario.getWidth());
hexagono.setTranslateY(Math.random() * cenario.getHeight());
}
}
});
this.texA_test = new TextArea();
this.texA_test.setText("This is just a test.");
this.lab_test = new Label("This is just a label.");
this.lab_test.setTextFill(Color.WHITE);
this.lab_test.setFont(new Font(32));
this.lay_box_controls.getChildren().add(this.lab_test);
this.lay_box_controls.getChildren().add(this.texA_test);
this.lay_box_controls.getChildren().add(this.bot_test);
this.root.getChildren().add(this.lay_box_controls);
}
}
I've tried to make the use of a StackPane as the root of my scene graph, but also found an undesired result. Despite the controls have stayed in the center of the window, the circles begin to move in as they grow and shrink, making it appear that everything is weird.
The second thing I would like to know is if it is possible to customize the controls so they perform some animation when some event happens. Although we can change the appearance of controls using CSS, it's harder to create something complex. For example, when a control changes its appearance due to a change of state, the transition state change is not made in an animated way, but in an abrupt and static way. Is there a way to animate, for example, a button between its states? This would be done using the JavaFX API? Or would that be using CSS? Or would not be possible in any way?
Thank you for your attention.
after much struggle, I and some users of the Oracle community could resolve this issue. I see no need to repeat here all the resolution made by us, so I'll post the link so you can access the solution of the problem. I hope this benefits us all. Thanks for your attention anyway.
https://community.oracle.com/thread/2620500