I have control that extends HBox called TablePagination that I created purely in code that I want to include in a FXML file, so when I do this:
<VBox fx:id="box" spacing="15" styleClass="sectionStyle">
<StackPane>
<TablePagination fx:id="pagination" StackPane.alignment="CENTER"/>
</StackPane>
</VBox>
nothing appears. But when I do it in code like this:
pagination = new TablePagination(itemTable,items);
StackPane pane = new StackPane();
pane.setAlignment(pagination, Pos.CENTER);
pane.getChildren().add(pagination);
box.getChildren().add(pane);
My control gets rendered but not in center. So what am I missing?
In your code version TablePagination is centered within StackPane, but nodes inside TablePagination are not. Call:
pagination.setAlignment(Pos.CENTER);
Note that StackPane.setAlignment method is static, and you sould call:
StackPane.setAlignment(pagination, Pos.CENTER);
Related
Picture of my application now
I would like to have "Tools" in the menubar to align right but I've searched a lot on the internet and could not find anything useful so I'm trying it here. The next thing I wanted to fix and did not find is Gridpane which is not filling its parent's size. If any of you know the properties or code to make this happen. Let me know!
public MyMenuBar(StackPane root) {
menu1 = new Menu("KunstwerkLijst");
menuItem1 = new MenuItem("Lijst van kunstwerken");
menuItem1.setOnAction(event ->{
root.getChildren().clear();
new Home(root);
});
menu2 = new Menu("Tools");
menuItem2 = new MenuItem("Admin Panel");
menuItem2.setOnAction(event ->{
root.getChildren().clear();
// new APanel(root);
});
menu1.getItems().addAll(menuItem1, menuItem4, menuItem6, menuItem5);
menu2.getItems().addAll(menuItem2, menuItem3);
this.getMenus().add(menu1);
this.getMenus().add(menu2);
Right align menu in menubar in JavaFX
This should help you for your first problem. If not you could maybe replace the menuubar with a toolbar and do something like this:
How to right align a button in Java FX toolbar
For your second problem it depends on what the actual parent of the Gridpane is.
Using an AnchorPane as parent is the easiest solution here and then use it like this:
<AnchorPane fx:id="parent">
<GridPane AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
...
</GridPane>
</AnchorPane>
I have a parent scrollpane which contains a webview as one of its children. When I scroll over the webview by having the mouse pointer on the webview area, it continues scrolling as expected till the end of the webview. However, is there a way where I can make the parent scrollpane scroll down, once the end of the child-webview is reached, while still the mouse pointer is on the webview-area ?
Sample Structure :
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.web.*?>
<ScrollPane prefHeight="455.0" prefWidth="602.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="wes.we.fx.view.ui.express.reports.generic.Demo">
<content>
<AnchorPane prefHeight="400.0" prefWidth="600.0">
<children>
<VBox layoutX="26.0">
<children>
<WebView prefHeight="316.0" prefWidth="530.0" />
</children>
</VBox>
</children>
</AnchorPane>
</content>
</ScrollPane>
Explanation of my solution: When using a WebView you can inject javascript which is what I used to pull values of the page to figure out when I was at the bottom. I am no JavaScript wiz so Im am not sure if there is a better solution here(I could not find one). I used the formula of screenTopPosition + screenTotalHeight to get the screenBottomPosition and compared that to the totalPageHeight if they are equal then you are at the bottom of the page this all worked as expected. This is where I feel it gets "Hacky" I couldn't figure out how to get the focus of the scrollbar from the scrollPane when at the bottom of the page. So my only other idea was to increment the scrollPane Vvalue by a fixed value when you were at the bottom of the webpage. The problem is the value you choose to increment it by may be different than the actual scrolling value incrementing I chose .1 once the Vvalue hits 1 it is at the bottom of the scrollPane
This is not exactly how I wanted to solve this problem hopefully someone can recommend a better solution that feels less "Hacky" and I would be glad to edit my answer if provided with guidance on how to figure out what the default incrementing is for the Vvalue
public class Main extends Application {
#Override
public void start(Stage stage) {
ScrollPane scrollPane = new ScrollPane();
scrollPane.setPrefSize(602, 455);
AnchorPane anchorPane = new AnchorPane();
anchorPane.setPrefSize(600, 400);
scrollPane.setContent(anchorPane);
VBox vBox = new VBox();
vBox.setPrefWidth(530);
vBox.setLayoutX(26);
anchorPane.getChildren().add(vBox);
WebView webView = new WebView();
webView.setPrefSize(530,316);
webView.getEngine().load("http://www.google.com");
webView.setOnScroll(event -> {
Integer screenTopPosition = (Integer) (webView.getEngine().executeScript("document.body.scrollTop"));
Integer screenTotalHeight = (Integer) webView.getEngine().executeScript("document.body.clientHeight");
Integer screenBottomPosition = screenTopPosition + screenTotalHeight;
Integer totalPageHeight = (Integer) webView.getEngine().executeScript("document.body.scrollHeight");
if(screenBottomPosition.equals(totalPageHeight)){
System.out.println("Bottom of Page Reached");
scrollPane.setVvalue(scrollPane.getVvalue()+.1);
}
});
vBox.getChildren().add(webView);
Label label = new Label("Content\nContent");
label.setFont(new Font(100));
vBox.getChildren().add(label);
stage.setScene(new Scene(scrollPane));
stage.show();
}
}
The center of my BorderPane has a stackpane called designView (an FXML defined stackpane). I'm trying to get a draggable pane in the designView. If I add that pane to the rootView (my BordePane) all is well. If however I try to add it to the designView like this:
// This works fine except the pnae is on the wrong place obviously
....
Pane p = displayField.createDraggablePane(800.0, 800.0, 400.0, 300.0);
rootView.getChildren().add(p);
// Now the pane is in the right place, but it's 'stuck'
....
rootView.setCenter(designView);
Pane p = displayField.createDraggablePane(800.0, 800.0, 400.0, 300.0);
designView.getChildren().add(p);
The pane appears correctly in the designView, BUT it is no longer draggable. The MouseEvents fire, but the position of the pane is not updated. I think the problem is with the fact that layoutX, getSceneX, layoutXProperty etc. have no reference to designView, but how do I get that? Can anyone help?
I found a solution. Instead of adding a StackPane to my BorderPane center, I have added a Pane and all is well :-) So my draggable Pane is added to a Pane instead of added to a StackPane.
Don't quite understand why this should change the behaviour of the draggable pane, but practice shows that it does.
I have a SplitPane with a TreeView on the left and a content area on the right. When I click on an item in my TreeView I want to display content on the right. How I do this now is to load an FXML which I create in SceneBuilder. My problem is that the FXML doesn't fit to the SplitPane. This is how I load the FXMl file
if (selectedItem.getValue() == "Sample") {
try {
AnchorPane pane = (AnchorPane) FXMLLoader.load(getClass().getResource("Sample.fxml"));
splitPane.getItems().set(1, pane);
} catch (IOException e) {
e.printStackTrace();
}
}
How do I make this AnchorPane which I created to fit to the original SplitPane size?
I have been struggling with this as well,
I finally solved by problem by avoiding nested wrapping of AnchorPanes.
I've removed the AnchorPane as the child container of the SplitPane, because the root of the included FXML also starts with an AncherPane:
Now my main FXML has something like:
<SplitPane>
<items>
<fx:include fx:id="navigationPanel" source="FX2NaviPanel.fxml"/>
<fx:include fx:id="dataPanel" source="FX2dataPanel.fxml"/>
</items>
</SplitPane>
and each child FX2NaviPanel.fxml and FX2dataPanel.fxml still start with an AnchorPane:
<AnchorPane ...>
<children>
<GridPane></GridPane>
</children>
</AnchorPane>
With this and appropriate maximum sizes, and fit-to-parent and zero-anchors where relevant the panels nicely stick to the movement of the splitter and resizing of the main window.
Aligning in FX is a pain i.t.a.
I suggest the following:
<SplitPane>
<TreeView /> //LEFT
<ANCHORPANE AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> //RIGHT, anchors make the content stick to the corner
<AnchorPane fx:id="myDynamicContent"/>
</ANCHORPANE>
</SplitPane>
With this the inner pane myDynamicContent should be stretched to all corners. Please tell if this is the answer.
You can also try to set the AncorPane.* attributes ON your content so you dont need nested AnchorPane.
Edit: After thinking about it I think you need the outer pane because it is "THE CONTAINER", without it the inner pane does not what to stick to.
I'm trying to load a FXML into a FXML. The main FXML has a borderpane, and the second contains a VBox. I load both of these with the FXMLLoader. When I try to set the center of the boarderpane, the entire screen gets replaced with the second FXML. Here is the code
BorderPane riskAnalysis = new BorderPane((BorderPane) FXMLLoader.load(getClass().getResource("./proposaldevelopment/riskAnalysis.fxml")));
VBox center = new VBox((VBox) FXMLLoader.load(getClass().getResource("./proposaldevelopment/openRiskAssessmentVbox.fxml")));
riskAnalysis.setCenter(center);
root = riskAnalysis;
stage.getScene().setRoot(root);
Any ideas that could cause this? I also tried making a new label and putting that into the borderpane center with the same result.
Try as
BorderPane riskAnalysis = (BorderPane) FXMLLoader.load(getClass().getResource("./proposaldevelopment/riskAnalysis.fxml"));
VBox center = (VBox) FXMLLoader.load(getClass().getResource("./proposaldevelopment/openRiskAssessmentVbox.fxml"));
riskAnalysis.setCenter(center);
stage.getScene().setRoot(riskAnalysis);