This might be a wierd question but is it possible to draw some sort of graphics without a window using javafx?
To clarify I want to write a circle at the bottom left corner of the screen where everything but the circle is the underlying window. So just removing the titlebar is not really enough
Are you looking for a transparent stage - this puts a red circle on the bottom left of the primary monitor. This might help you in the direction you want to go.
public class TransparentStage extends Application {
#Override
public void start(Stage stage) throws Exception {
stage.initStyle(StageStyle.TRANSPARENT);
Circle c = new Circle(30);
c.setFill(Color.RED);
VBox box = new VBox();
box.getChildren().add(c);
final Scene scene = new Scene(box,300, 250);
scene.setFill(null);
stage.setScene(scene);
stage.setX(20);
stage.setY(Screen.getPrimary().getBounds().getHeight() - 100);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Some sort of transparent window like below
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class Main extends Application {
#Override
public void start(Stage stage) {
stage.initStyle(StageStyle.TRANSPARENT);
Text text = new Text("!");
text.setFont(new Font(40));
VBox box = new VBox();
box.getChildren().add(text);
final Scene scene = new Scene(box,300, 250);
scene.setFill(null);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
source : http://www.java2s.com/Code/Java/JavaFX/TRANSPARENTwindow.htm
Related
I have a GUI, however, when I try to add a Label the screen it does not seem to add correctly.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.stage.Stage;
public class GUI extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
Label labe = new Label("Test");
Button button = new Button("ASDf");
TilePane tilePane = new TilePane();
tilePane.getChildren().addAll(labe, button);
Scene scene = new Scene(tilePane, 100, 100);
primaryStage.setScene(scene);
primaryStage.show();
}
}
I get the following result When I run the above code
I am running this in IntelliJ with java version 1.7
How do I get my label to show also?
I made a javafx program using a horizontal SplitPane with a Canvas on one side in which something is drawn. When the SplitPane is resized the Canvas resizes with it.
Everything worked fine until I switched to Java 10. Suddenly the Canvas-side can only be expanded, not reduced.
Anyone has an idea why that is?
(The working Java version was 1.8.0_181)
package test;
import javafx.application.Application;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.SplitPane;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class Test extends Application {
private static Display display;
#Override
public void start(Stage primaryStage) {
display = new Display();
StackPane stackPaneDisplay = new StackPane();
stackPaneDisplay.getChildren().add(display);
stackPaneDisplay.setStyle("-fx-background-color: white");
AnchorPane anchorPaneDisplay = new AnchorPane();
anchorPaneDisplay.getChildren().add(stackPaneDisplay);
AnchorPane.setBottomAnchor(stackPaneDisplay, Double.MIN_VALUE);
AnchorPane.setTopAnchor(stackPaneDisplay, Double.MIN_VALUE);
AnchorPane.setLeftAnchor(stackPaneDisplay, Double.MIN_VALUE);
AnchorPane.setRightAnchor(stackPaneDisplay, Double.MIN_VALUE);
display.widthProperty().bind(stackPaneDisplay.widthProperty());
display.heightProperty().bind(stackPaneDisplay.heightProperty());
StackPane stackPaneLeft = new StackPane();
SplitPane splitPane = new SplitPane();
splitPane.setOrientation(Orientation.HORIZONTAL);
splitPane.getItems().addAll(stackPaneLeft, anchorPaneDisplay);
BorderPane root = new BorderPane();
root.setCenter(splitPane);
Scene scene = new Scene(root);
primaryStage.setMaximized(true);
primaryStage.setScene(scene);
primaryStage.show();
splitPane.setDividerPositions(0.2);
}
public static void main(String[] args) {
launch(args);
}
}
and the Canvas-Class
package test;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
public class Display extends Canvas {
GraphicsContext gc = this.getGraphicsContext2D();
public Display() {
widthProperty().addListener(e -> {
draw();
});
}
public void draw() {
gc.strokeOval(500, 500, 100, 100);
}
}
Thanks in advance
So I'm trying to simply change between two scenes in javafx, but I've come into this re-occurring problem that I can't seem to fix. It is demonstrated in the following code:
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.Group;
import javafx.scene.paint.Color;
public class TestApplication extends Application
{
private Stage stage;
private Scene scene, scene2;
public void start(Stage s)
{
scene=new Scene(new Group());
scene2=new Scene(new Group());
scene.setFill(Color.GREEN);
scene2.setFill(Color.ORANGE);
scene.setOnMouseClicked(e-> changeScene(scene2));
scene2.setOnMouseClicked(e-> changeScene(scene));
stage=s;
s.setScene(scene);
s.show();
}
public void changeScene(Scene nex)
{
stage.setScene(nex);
System.out.println("here");
}
public static void main(String[] args)
{
launch(args);
}
}
Am I doing something wrong? How can I fix this?
What's going wrong
You are not placing anything in the scenes (just an empty group). By default scenes are (usually) going to size to the preferred size of their contained content. As your scenes have no content of any size, then the scenes shouldn't really have any size. I think the fact that the first scene even shows up is a bit of a quirk of the JavaFX system where it seems to set some default size to the initial scene when it can't work out any preferred size for the scene (just so that the initial window shows up).
How to fix it
To fix it, put some content in the enclosed scenes (and/or set the initial scene size in your scene constructors).
import javafx.application.Application;
import javafx.scene.control.Label;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.Group;
import javafx.scene.paint.Color;
public class TestApplication extends Application {
private Stage stage;
private Scene scene, scene2;
public void start(Stage s) {
scene = new Scene(new Group(new Label("1")), 200, 150);
scene2 = new Scene(new Group(new Label("2")), 200, 150);
scene.setFill(Color.GREEN);
scene2.setFill(Color.ORANGE);
scene.setOnMouseClicked(e -> changeScene(scene2));
scene2.setOnMouseClicked(e -> changeScene(scene));
stage = s;
s.setScene(scene);
s.show();
}
private void changeScene(Scene nex) {
stage.setScene(nex);
}
public static void main(String[] args) {
launch(args);
}
}
When I run the following program
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Ellipse;
import javafx.stage.Stage;
public class Test1 extends Application {
public static void main(String[] args) throws Exception {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
Pane topPane = new Pane();
Scene scene = new Scene(topPane, 600, 400);
StackPane sp = new StackPane();
Label l1 = new Label("1 2");
Ellipse e1 = new Ellipse(100, 50);
e1.setOpacity(0.5);
sp.getChildren().addAll(l1, e1);
e1.radiusXProperty().bind(l1.widthProperty());
e1.radiusYProperty().bind(l1.heightProperty());
topPane.getChildren().add(sp);
sp.relocate(200, 100);
sp.setStyle("-fx-border-color: RED;");
Platform.runLater(() -> {
//l1.setText("123");
//l1.setText("1 2");
});
stage.setScene(scene);
stage.show();
}
}
I get a red box surrounding the text label only, but when I uncomment the two lines inside the Platform.runLater() block above, I get a red box surrounding the outer ellipse, which is what I want.
So it seems to me the layout bounds of the stack pane is not set correctly from the model description, since the bounds are determined only from the label control. But when I force an invalidation in Platform.runLater() the layout bounds are where they should be.
Why is this happening and how do I prevent it? I would like to be able to just specify my model/graph and then it should render correctly on the first show, or?
add this sp.requestLayout(); after stage.Show();
I would like to place an HBox with a red rectangle in the middle of a BorderPane, and I would like that rectangle to grow or shrink with its container (the HBox).
This is my code:
public class Test extends Application {
#Override
public void start(Stage primaryStage) {
BorderPane borderPane = new BorderPane();
HBox hBox = new HBox();
hBox.setAlignment(Pos.CENTER);
Rectangle rect = new Rectangle(hBox.getWidth(),50);
rect.setFill(Color.RED);
rect.widthProperty().bind(hBox.widthProperty().subtract(20));
hBox.getChildren().add(rect);
borderPane.setCenter(hBox);
Scene scene = new Scene(borderPane, 900, 600, Color.WHITE);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
But it doesn't work. When I slowly resize my Frame, it works, nevertheless, when I quickly resize my Frame, the rectangle is not in the middle (not the same size too) and we can see the same things when we minimize and maximize the Frame.
I don't understand why it doesn't work.
This is what is happening:
When rect is asked for the preferred/minimum/maximum width during layout, it replies with its current width, which is before resize, because by that time hBox has not been resized yet. As a result, hBox's minimum width is reported to be its current width minus 20. Therefore, when you shrink the window, the hBox will still be resized to its previous width minus 20.
There are a number of ways how to go around this, but a more accurate answer depends on what you are trying to do, and may involve using Region instead of a Rectangle, or overriding layoutChildren method of the rectangle's parent.
Here is a way that is close to what you have now. It defines a resizable rectangle and overrides its minimum width to be 0.0, so it allows the HBox to be downsized.
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class RectangleAutosize extends Application {
static class ResizableRectangle extends Rectangle {
ResizableRectangle(double w, double h) {
super(w, h);
}
#Override
public boolean isResizable() {
return true;
}
#Override
public double minWidth(double height) {
return 0.0;
}
}
#Override
public void start(Stage primaryStage) {
BorderPane borderPane = new BorderPane();
HBox hBox = new HBox();
hBox.setAlignment(Pos.CENTER);
Rectangle rect = new ResizableRectangle(hBox.getWidth(),50);
rect.setFill(Color.RED);
rect.widthProperty().bind(hBox.widthProperty().subtract(20));
hBox.getChildren().add(rect);
borderPane.setCenter(hBox);
Scene scene = new Scene(borderPane, 900, 600, Color.WHITE);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}