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>
Related
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();
}
}
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);
After resizing the window my SplitPane's divider moves to another position according to the given percentage (e.g.: dividerPositions="0.05").
But I want it to stay on the same position after resizing (like it was bound to pixel size and not percentage) where it was set before. I don't want it "move" (follow the percentage constraint) while resizing it's parent pane.
Is it possible to do this somehow?
(I would like to fix this preferably from code, the CSS solution is secondary for me)
The perfect solution for me would something be similar to this:
<SplitPane orientation="VERTICAL" dividerPositionFromTop="100px"
AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0"
AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" >
...
</SplitPane>
Where dividerPositionFromTop sadly does not exist by my knowledge.
You can add a listener to the heightProperty of your SplitPane and recalculate the percentage value:
SplitPane splitPane = new SplitPane();
splitPane.heightProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
double height = splitPane.getHeight();
double dividerPositionFromTop = 100;
splitPane.setDividerPosition(0, dividerPositionFromTop/height);
}
});
splitPane.getItems().addAll(new TextArea("1"), new TextArea("2"));
splitPane.setOrientation(Orientation.VERTICAL);
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 know it's possible to do that in FXML:
<Spinner fx:id="spinner" min="0" max="100" initialValue="3" >
<editable>true</editable>
</Spinner>
But I can't find how it's possible to do that in sceneBuilder
I got the same problem, I didn't found Spinner in Scene Build and I put in Scenne Builder manually. This is my code.
I have modified .fxml document to put the Spinner in Pane.
<Pane fx:id="paneTamano" layoutX="527.0" layoutY="46.0" prefHeight="125.0" prefWidth="141.0" stylesheets="#css.css">
<children>
<Spinner fx:id="spinnerTamano" layoutX="17.0" layoutY="49.0" onMouseClicked="#tamano" prefHeight="25.0" prefWidth="110.0" />
</children>
</Pane>
I created an ObservableList at DocumentController.java to give values to the spinner.
ObservableList<String> listaTamanos = FXCollections.observableArrayList("Grande", "Mediana", "Pequeña");
Finally insert values in to the Spinner.
SpinnerValueFactory<String> valueFactory = new SpinnerValueFactory.ListSpinnerValueFactory<String>(listaTamanos);
spinnerTamano.setValueFactory(valueFactory);
valueFactory.setValue("Pequeña");
Spinner was introduced in JavaFX 8. It has no Stylesheet handling like the one in (for ex.) Slider implemented right now, so SceneBuilder don't know the properties that are stylable.
Compare Spinner and for example Slider source code, there is missing a nested StyleableProperties class in Spinner.