Differences in Pane and Group in JavaFX? - javafx

Suppose you have a block of code:
Pane pane = new Pane();
pane.getChildren().add(circle);
pane.getChildren().add(rectangle);
Scene scene = new Scene(pane, 400, 400);
Do you have to write pane.getChildren().add(===); every time you want to add something to the pane? Similarly, what is the difference in just writing ..
Pane pane = new Pane(circle, rectangle);
Scene scene = new Scene(pane, 400, 400);
As I have found that it does the exact same thing when I run the program and have the shapes display. Additionally, what is the different in writing with the use of Pane instead of:
Group root = new Group(circle, rectangle);
Scene scene = new Scene(root, 400, 400);
Any help would be greatly appreciated! I have been looking online and have not seemed to have found anything that truly answers all of my questions.

There's not really any difference between:
Pane pane = new Pane(node1, node2);
And:
Pane pane = new Pane();
pane.getChildren().add(node1);
pane.getChildren().add(node2);
Both approaches add the nodes the the children list of the layout. It's just that the first approach does this via the constructor; it's basically a shortcut for the second approach. However, the second approach can be used at any time so long as you have a reference to the layout.
Here are some differences between Pane and Group, though I can't promise this is an exhaustive list:
A Group will take into account any transforms or effects on its children when computing its layout bounds. This can have a profound affect on how your UI behaves when nodes are transformed (or have an effect applied on them). For instance, when you rotate a square the width and height grows and shrinks over time. If that square was in a Group then the Group's width and height would correspondingly grow and shrink; a Pane would not do this.
The Group class extends directly from Parent. The Pane class extends from Region (and Region extends from Parent). That means a Group has none of the styling options provided by Region (e.g. backgrounds, borders, etc.).
The Javadoc of Group also says:
Any transform, effect, or state applied to a Group will be applied to all children of that group.
I've never really experimented with this, so I'm not sure if this is truly different behavior than Pane.
Also, keep in mind that you'll typically want to use Pane or, more specifically, subclasses of Pane. This includes layouts such as BorderPane, VBox, and StackPane. Those layouts automatically manage their children to resize and position them according to the layout's rules. You can use nested layouts to achieve more complex designs. Personally, I've really only used Group if I want the behavior mentioned in point one above or if I'm using 3D shapes.

Related

Javafx line connecting two circles in a stackpane [duplicate]

I was learning javafx and came across these two statements which I don't know their difference.
Pane pane = new Pane();
and
StackPane pane = new StackPane();
Can somebody enlighten me about the difference and when to use which?
Both are layouts but the Pane is the basis of all the other layouts, the difference is that the Pane offers a free positioning of nodes, and The StackPane (and other Node with the suffix Pane called Built-in Layout) in return, follow their own logic (Positions/Constraints...). The 'StackPane' for example lays out its children in a back-to-front stack StackPane. This is only superficial and limited information, here's a good tutorial : Layout in JavaFX
The difference between both layouts is positioning of the children and the resizing of resizeable children.
Pane does not do any positioning. The child's layoutX and layoutY are left unmodified. Furthermore resizeable children are resized to their preferred sizes.
StackPane determines the position of children based on the alignment set for the child itself or the one set for the StackPane itself, if no position is set for the child. Resizable children are resized to a size that fits the StackPane's size best (still taking into account max size). Both can be modified by a margin set for individual children...

fit QGraphicsScene to QGraphicsView

I'm trying to draw a stacked bar graph on Qt, i followed the tutorial on the documentation but when i try to put the graph inside a QGraphicsView i get a lo of unused space and can't manage to make the scene fit the view.
My code is the same as the documentation one plus the following to make the scene show up in the view:
QGraphicsScene *scene = new QGraphicsScene(this);
scene->addWidget(chartView);
ui->view->setScene(scene);
And what i get is this
As you can see there is a lot of unused space and it makes the text disappear, i wanted to make the graph fit the view but i can't seem to find a way to do so.
I tried in many different ways using
ui->view->ensureVisible ( scene->sceneRect() );
ui->view->fitInView( scene->sceneRect(),Qt::KeepAspectRatio);
and
ui->view->setSceneRect(0,0,ui->view->frameSize().width(),ui->view->frameSize().height());
but nothing seems to work (the second solution just moves the graph to the top left)
As per the comment... the real issue is the basic sizing of chartView rather than anything to do with QGraphicsView or QGraphicsScene.
When a QWidget is added to a QGraphicsScene the resulting QGraphicsProxyWidget will generally honour the size hint and policy of that widget.
In addition, though, the QGraphicsScene will set the scene rect to the bounding rectangle of all scene items and the QGraphicsView will then position the scene according to whatever viewport anchor is in force. The end result can be visually misleading if the scene has a complex set of items or has a bounding rectangle smaller than that displayed within the GraphicsView.
So if a widget does look odd when added to a QGraphicsScene it's normally a good idea to test by just showing it as a top level window on the desktop and make sure it behaves as expected before going any further.

Adding Shapes to GridPane results in wrong Position

I got the task to draw some points on a map. Wrote some code but currently every point I create via shapes will be added to the wrong position inside of my gridpane. Oh and I'm using JavaFX.
I added an imageView to the index 0,0 of my GridPane and every point is created through x and y position of the MouseEvent on the imageView.
After that I added the created point as a child of the GridPane and it's displayed at the center of the y-axis of the first grid.
Tried different things like anchorPanes and canvas but can't seem to get it working.
Code of my View:
http://pastebin.com/dCb7EN4d
Code of my Main:
http://pastebin.com/vp5tzxkG
I hope that's enough ^^'
pls help!
Greetings,
Ben
GridPane is a managed layout: it will position nodes that are added to it via the properties you set (using defaults if you don't set them). So when you add your circles to the grid pane, since you don't set any properties, it will place it in cell (0,0) and align it within that cell using default settings; i.e. it ignores the centerX and centerY properties.
What you should really do here is use a layout that does not manage the positioning of the nodes for you, such as a Pane (or possibly a Group). You can put the ImageView and the Circles in the pane, and then place the pane in the rest of your layout (in the scroll pane, I think).
The other option you have is to call setManaged(false) on the nodes you add to the GridPane in order to instruct the GridPane not to position them, though this feels like more of a workaround.

How to fit ScrollPane into component bounds

I have this ScrollPane which I holds many components. I want to use the ScrollPane into many components with different size.
I solved temporary the problem using Rectangle2D
Rectangle2D primaryScreenBoundsthree = Screen.getPrimary().getVisualBounds();
But this is not working properly when I insert the ScrollPane with different components. I also tested this:
scrollthree.setPrefSize(ScrollPane.USE_PREF_SIZE, ScrollPane.USE_PREF_SIZE);
But again the result is not appropriate:
How I can fir the ScrollPane into the parent components borders?
Screen.getPrimary().getVisualBounds();
This returns you the bound of the Screen(Monitor) which you are using.
Bounds is the width and height of the Screen !
Inorder to use scrollPane to fit into your parent, don't use scrollthree.setPrefSize. You don't have to specify the size of the scrollPane, it will automatically fit into Parent
Infact, all the javafx panes fit into their respective parents !

JavaFX - StackPane X, Y coordinates

I'm using StackPanel as container for my figures, panels, etc. What I discovered, that coordinates X,Y (0,0) are placed right in center of my panel.
Is it possible to move it to left top od Pane ?
Calculating all dimensions from center is much more difficult.
You can set the layout of Nodes added to the StackPane to a position within the Stackpane using the StackPane.setAlignment(node, position) method:
Label topLeftLabel = new Label("Top Left");
StackPane stack = new StackPane();
stack.getChildren().add(topLeftLabel);
StackPane.setAlignment(topLeftLabel, Pos.TOP_LEFT);
Even though this is possible, from your brief description of how you are trying to use the StackPane, it sounds like you would be better off using a regular Pane, or a Group or an AnchorPane for the kind of absolute positioning you appear to be wanting to achieve.
Possibly look into using a visual tool such as SceneBuilder as well. Even if you don't end up using the FXML it outputs, SceneBuilder should give you a much better idea of how JavaFX layout mechanisms work. SceneBuilder makes use of AnchorPane as its default layout pane used to provide absolute positioning for elements (which seems to be what you want to achieve).
The previous answer is of course the best in this situation, but it is also wise to know that you can move Nodes on the StackPane using Translation.
Ex.
Label topLeftLabel = new Label("Top Left");
StackPane stack = new StackPane();
stack.getChildren().add(topLeftLabel);
topLeftLabel.setTranslateX(stack.getWidth()/2);
topLeftLabel.setTranslateY(stack.getHeight()/2);
It would do the same thing (but may look a bit worse)

Resources