JavaFX container in ScrollPane not showing - java

I have heard that, to add more controls/JavaFX Nodes to a ScrollPane, one must set the ScrollPane's content to a container, then add all Nodes to said container. However, when trying this, I only get a small, grey bar without any content. How can I fix this? (Trying to make something larger, but even this MWE doesn't work for me... - Working with OpenJDK OpenJFX 11 on Manjaro, if that helps)
Code:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(final Stage primaryStage) {
Label test = new Label();
test.setText("Testing JavaFX........");
VBox box = new VBox();
ScrollPane pane = new ScrollPane(box);
pane.setPrefSize(300.0, 300.0);
box.getChildren().add(test);
Scene main = new Scene(pane);
primaryStage.setScene(main);
primaryStage.show();
}
}
Result:

Related

JavaFX: Line goes automatically to center of the scene

I want to draw Lines in JavaFX but the program seems not to listen to the coordinates and directly draws it in the middle (i.e. center) with the same length.
Code:
package application;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage stage) {
Line line = new Line(200,200,250,250);
StackPane root = new StackPane();
root.setPadding(new Insets(15));
final Scene scene = new Scene(root, 400, 250);
scene.setFill(null);
root.getChildren().addAll(line);
stage.setTitle("JavaFX Line");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Result:
Line in Center
A StackPane is a layout pane which means that it will place any node according to its own rules which may come as a surprise as in your case. Instead you could just use a Pane which will place your line at the place you have specified. It may be a good idea to place this Pane inside your StackPane so that it fills the whole space.

Is there a way to "autofit" elements on a page so they take up the entire canvas

In JavaFX, is there a way to "autofit" elements on a page so they take up the entire thing?
Currently, I'm trying to make the window have two buttons that together take up the entire canvas, but I am not sure how to do that, given that it is possible to stretch the window, etc. I've tried playing around with Button.setPrefSize, but the button size stays the same, it just shows you a window with two outsized buttons, the text of which is not visible.
What I currently have
What I want (but for any window size)
Here's one way (code here but also possible in Scene Builder and FXML):
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.stage.Stage;
public class TestApplication extends Application {
#Override
public void start(Stage stage) throws Exception {
Button button1 = new Button("Button1");
HBox.setHgrow(button1, Priority.SOMETIMES);
button1.setMaxWidth(Double.MAX_VALUE);
button1.setMaxHeight(Double.MAX_VALUE);
Button button2 = new Button("Button2");
HBox.setHgrow(button2, Priority.SOMETIMES);
button2.setMaxWidth(Double.MAX_VALUE);
button2.setMaxHeight(Double.MAX_VALUE);
HBox hBox = new HBox(button1, button2);
AnchorPane.setLeftAnchor(hBox, 0.0);
AnchorPane.setRightAnchor(hBox, 0.0);
AnchorPane.setTopAnchor(hBox, 0.0);
AnchorPane.setBottomAnchor(hBox, 0.0);
AnchorPane rootContainer = new AnchorPane(hBox);
Scene scene = new Scene(rootContainer, 600, 600);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}

Binding label to bottom-center of scene - JavaFX

I am trying to figure out how to center and bind a label perfectly at the bottom of a scene. I have a simple test application here to show what I am working with and what my issue is.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class LabelTest extends Application {
#Override
public void start(Stage stage) throws Exception {
Pane root = new Pane();
Scene scene = new Scene(root, 400, 400);
Label label = new Label("Testing testing 1 2 3");
label.layoutXProperty().bind(scene.widthProperty().divide(2).subtract(label.getWidth() / 2)); //Should align label to horizontal center, but it is off
label.layoutYProperty().bind(scene.heightProperty().subtract(label.getHeight() + 35)); //Aligns the label to bottom of scene
root.getChildren().add(label);
stage.setScene(scene);
stage.show();
}
}
The logic behind my positioning makes sense to me, so I am not sure why it is not horizontally centered. I have included a screenshot below to show what the output looks like:
And below is more of what I am wanting it to look like (still off by a bit, but you get the point)
Thanks in advance to anyone who helps me out!
Let layout managers do the layout for you:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class LabelTest extends Application {
#Override
public void start(Stage stage) throws Exception {
Label label = new Label("Testing testing 1 2 3");
BorderPane root = new BorderPane();
//center label by
//BorderPane.setAlignment(label, Pos.CENTER);
//root.setBottom(label);
//OR
root.setBottom(new StackPane(label));
Scene scene = new Scene(root, 400, 400);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
The issue is you are taking the values of width/height at the time of binding. And at this instance it will be 0 as they are not yet rendered. You need bind those properties as well for computing.
label.layoutXProperty().bind(scene.widthProperty().divide(2).subtract(label.widthProperty().divide(2)));
label.layoutYProperty().bind(scene.heightProperty().subtract(label.heightProperty().add(35)));

JavaFX HTML node elements

How do I add a new HTMLTableRowElement to the HTMLTableElement, and HTMLLIElement to a HTMLUListElement?
It seems to me that I can not just new something that I want and there does not seem to be a getInstance() method anywhere.
Thanks.
You can use the org.w3c.dom API (which is part of the core java libraries). To be honest, I find this API pretty ugly to use, but nevertheless it does the job.
Here's a minimal example:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class DynamicWebViewTest extends Application {
#Override
public void start(Stage primaryStage) {
WebView webView = new WebView();
webView.getEngine().loadContent("<html><body><table border='1' id='table'>"+
"<tr><th>Name</th><th>Value</th></tr></table></body></html>");
TextField nameTF = new TextField();
TextField valueTF = new TextField();
Button addRowButton = new Button("Add row");
addRowButton.setOnAction(event -> {
Document doc = webView.getEngine().getDocument();
Element table = doc.getElementById("table");
Element newRow = doc.createElement("tr");
Element nameCell = doc.createElement("td");
Element valueCell = doc.createElement("td");
nameCell.appendChild(doc.createTextNode(nameTF.getText()));
valueCell.appendChild(doc.createTextNode(valueTF.getText()));
newRow.appendChild(nameCell);
newRow.appendChild(valueCell);
table.appendChild(newRow);
nameTF.setText("");
valueTF.setText("");
});
HBox controls = new HBox(5, nameTF, valueTF, addRowButton);
controls.setAlignment(Pos.CENTER);
controls.setPadding(new Insets(5));
BorderPane root = new BorderPane(webView, null, null, controls, null);
Scene scene = new Scene(root, 600, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Supposing you are using the Java Fx Web View to add those elements , so i would recommend to build the whole page or just add the components you need via javascript calls , cause the web view gives you the js engine to perform js methods.
I am not sure if the scene builder supports customizing on the web view.

JavaFX primaryStage remove windows borders? [duplicate]

This question already has an answer here:
JavaFX: Undecorated Window
(1 answer)
Closed 8 years ago.
I am making JavaFX destop application. I want to remove the default windows border and also I want to customize the 3 standard icons of minimize , maximize and close.
The original motivation of this kind of looks or customization is new Kaspersky 2012 User Interface.... I want to design something like that... :)
This example might be a good starting point. All window decoration is removed. A class extending HBox can be used to place custom buttons for standard window operations.
package javafxdemo;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ToolBar;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class JavaDemo extends Application {
public static void main(String[] args) {
launch(args);
}
class WindowButtons extends HBox {
public WindowButtons() {
Button closeBtn = new Button("X");
closeBtn.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent actionEvent) {
Platform.exit();
}
});
this.getChildren().add(closeBtn);
}
}
#Override
public void start(Stage primaryStage) {
//remove window decoration
primaryStage.initStyle(StageStyle.UNDECORATED);
BorderPane borderPane = new BorderPane();
borderPane.setStyle("-fx-background-color: green;");
ToolBar toolBar = new ToolBar();
int height = 25;
toolBar.setPrefHeight(height);
toolBar.setMinHeight(height);
toolBar.setMaxHeight(height);
toolBar.getItems().add(new WindowButtons());
borderPane.setTop(toolBar);
primaryStage.setScene(new Scene(borderPane, 300, 250));
primaryStage.show();
}
}
You can also download the JavaFX Samples where you can find many more useful examples.

Categories