This should be a relatively simple problem, but it is driving me insane. I am trying to create Mine Sweeper in JavaFX (mostly just for practice) but I can not get even a simple rectangle to display. I had the game running once before, but I am trying to make the game more abstract, and hence easier to code, but I am running into the issue of nothing being displayed.
I eliminated all extraneous code so it is as simple as possible. I am basically trying to create a Rectangle with a certain color and size called Box, add the box to the pane, and display the pane. In order to make Box a node that can be displayed on the pane, I made the Box class extend Rectangle, so that a Box would have the same properties as a Rectangle. But when I run the code, it gives just an empty pane with no box in it.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class Minesweeper extends Application {
#Override
public void start(Stage stage) {
Pane pane = new Pane();
Box box = new Box();
pane.getChildren().addAll(box);
// Create the scene
Scene scene = new Scene(pane);
stage.setTitle("Minesweeper");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
public class Box extends Rectangle {
public Box() {
Rectangle box = new Rectangle(100, 100, 100, 100);
box.setFill(Color.BLUE);
}
}
I realized if I put the code from Box into the main Minesweeper class, it will display the box. But Box will have a ton of other properties and therefore needs to be a class on its own.
What am I doing wrong that does not allow the box to be displayed?
Thanks in advance for your help and consideration.
You create a new Rectangle in your Box class. This Rectangle is not added to any Parent container, so it's not visible.
Change your code to:
public Box() {
super(100, 100, 100, 100);
setFill(Color.BLUE);
}
Related
Hi I am a JavaFX newbie and I am trying to write my first application. I want to start with an empty window and provide a popup menu that allows users to add 3D elements to the window.
I have created a simple Group containing a few trivial geometric shapes and added this group as the parent to a Scene. I define a mouse event handler for the scene and call setScene to make this the scene for my Stage (passed in to my Application's start method).
Unfortunately, I can't seem to find a way of positioning the menu correctly in response to a mouse pressed event. I get it that I need to get the X and Y coordinates from the Event, but when I pass these unchanged to the context menu show method, the menu appears in the top left-hand corner of my laptop display, rather than inside my application window.
Clearly, I need to offset these values by the origin of some other window, but what? I have tried the Scene, the Group and and the Stage, but with no success :-( This ought to be a trivial problem - where am I going wrong??
Code sample shown below:
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.PointLight;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Box;
import javafx.scene.shape.Cylinder;
import javafx.scene.shape.Sphere;
import javafx.stage.Stage;
public class PopupTest extends Application {
private static final ContextMenu contextMenu = new ContextMenu();
public static void main(String[] args) {
MenuItem cut = new MenuItem("Cut");
MenuItem copy = new MenuItem("Copy");
MenuItem paste = new MenuItem("Paste");
contextMenu.getItems().addAll(cut, copy, paste);
Application.launch(args);
}
#Override
public void start(Stage stage) {
// Create a Box
Box box = new Box(100, 100, 100);
box.setTranslateX(150);
box.setTranslateY(0);
box.setTranslateZ(400);
// Create a Sphere
Sphere sphere = new Sphere(50);
sphere.setTranslateX(300);
sphere.setTranslateY(-5);
sphere.setTranslateZ(400);
// Create a Cylinder
Cylinder cylinder = new Cylinder(40, 120);
cylinder.setTranslateX(500);
cylinder.setTranslateY(-25);
cylinder.setTranslateZ(600);
// Create a Light
PointLight light = new PointLight(Color.YELLOW);
light.setTranslateX(350);
light.setTranslateY(100);
light.setTranslateZ(300);
// Create a Camera to view the 3D Shapes
PerspectiveCamera camera = new PerspectiveCamera(false);
camera.setTranslateX(100);
camera.setTranslateY(-50);
camera.setTranslateZ(300);
// Add the Shapes and the Light to the Group
Group root = new Group(box, sphere, cylinder, light);
// Create a Scene with depth buffer enabled
Scene scene = new Scene(root, 400, 300, true);
scene.setOnMousePressed(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
System.out.println("mouse click detected!");
if (event.isPopupTrigger()) {
// similar results with getX() vs getSceneX() etc.
System.out.println("Display menu at (" + event.getSceneX() + "," + event.getSceneY() + ")");
contextMenu.show(root, event.getSceneX(), event.getSceneY());
}
}
});
// Add the Camera to the Scene
scene.setCamera(camera);
// Add the Scene to the Stage
stage.setScene(scene);
// Set the Title of the Stage
stage.setTitle("Trying to get popup menu working");
// Display the Stage
stage.show();
}
}
I am trying to lose the white background on the webviewer
i have tried work around and other things but nothing seems to work
public static String url = "URL"; //lets say this has a transparent image on it (it does in my case)
public static Scene FrameWorks;
public static StackPane InnerFrame;
public static WebView viewer;
public static WebEngine webEngine;
public static void web() {
viewer = new WebView();
webEngine = viewer.getEngine();
webEngine.executeScript("document.width");
WebSite(url);
}
public static void WebSite(String URL) {
webEngine.executeScript("window.location = \""+URL+"\";");
}
public void start(Stage Level) {
web();
InnerFrame = new StackPane();
FrameWorks = new Scene(InnerFrame, 909, 609);
InnerFrame.getChildren().add(viewer);
FrameWorks.setFill(Color.TRANSPARENT);
InnerFrame.setStyle("-fx-background-color: rgba(255, 0, 0, 0);");
Level.setScene(FrameWorks);
Level.initStyle(StageStyle.TRANSPARENT);
Level.show();
}
I'm not sure that I fully understand your problem so correct me if I am wrong. Do you want everything other than the webview to be transparent? To more or less copy paste a comment from another post, on here I (we) want a Minimal, Complete, and Verifiable example demonstrating the problem. You should also remember to check if the question has already been asked and answered before asking your own question.
Now that I got that out of the way, here's an example where you can see the stack pane with a black background and the webview with a white background.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.scene.layout.Background;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Hello World!");
WebView v = new WebView();
v.setOpacity(1); // 0 = fully transparent, 1 = fully visible.
v.setPrefWidth(100);
v.setMaxWidth(100);
v.setMaxHeight(100);
v.setPrefHeight(100);
v.setStyle("-fx-background-color:black;");
StackPane root = new StackPane();
root.getChildren().add(v);
root.setStyle("-fx-background-color:black;");
/*
* Remove the setStyle above, and use either one of these to only have the webview
* visible. root.setBackground(Background.EMPTY);
* root.setStyle("-fx-background-color:TRANSPARENT;");
*/
Scene scene = new Scene(root, 300, 250);
scene.setFill(Color.TRANSPARENT);
primaryStage.setScene(scene);
primaryStage.initStyle(StageStyle.TRANSPARENT);
primaryStage.show();
}
}
If you remove the line:
root.setStyle("-fx-background-color:black;");
and replace it with either one of the lines that currently are in comments then you will now only see the webview:
/*
* Remove the setStyle above, and use either one of these to only have the webview
* visible.
* root.setBackground(Background.EMPTY);
* root.setStyle("-fx-background-color:TRANSPARENT;");
*/
And you can of course also set a transparency on the actual webview if you want to do that for some reason:
v.setOpacity(0); /*0.0 Fully Transparent - 1.0 Fully Visible*/
Please note that to do this I had to set the StageStyle to transparent, and unfortunately I'm not sure if it is possible to do it in any other way. Maybe someone else can put in comments if it is possible or not.
I hope this answers your question.
I want make JavaFX MediaView stretch to fill parent container.
I tried some methods from google before,but nothing helpful(maybe i'm not apply it right),and there is a question with same name as this,but solutions in that question maybe not suit me.
first i use the ahchorpane to anchor mediaview but find it can not stretch mediaview,and I don't know why because other controls like button can work.
Then i try bind its width and height to anchorpane(parent of mediaview)
Region region=(Region) mediaplayer.getParent();
mediaplayer.setPreserveRatio(false);
mediaplayer.fitWidthProperty().bind(region.widthProperty());
mediaplayer.fitHeightProperty().bind(region.heightProperty());
it's can expand mediaview exactly when i resize window,but can't Shrink down!
I guess it's maybe because size of region depend on it childs?
finally,i try to bind mediaview'size to stage'size,it's work,but the code looks like ugly,because i need calculate size manully.
mediaplayer.setPreserveRatio(false);
mediaplayer.fitWidthProperty().bind(stage.widthProperty().subtract(200));
mediaplayer.fitHeightProperty().bind(stage.heightProperty().subtract(135));
are there have any better solutions?
Using the code below you will see that you are able to stretch and shrink the mediaView as much as you like ( depending of the stage dimensions)
import java.io.File;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
public class TestApp extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
BorderPane pane = new BorderPane();
FileChooser fc = new FileChooser();
File mediaFile = fc.showOpenDialog(null);
MediaView moviePlayer;
if (mediaFile != null) {
MediaPlayer player = new MediaPlayer(new Media(mediaFile.toURI().toString()));
moviePlayer = new MediaView(player);
moviePlayer.setPreserveRatio(false);
moviePlayer.fitWidthProperty().bind(pane.widthProperty());
moviePlayer.fitHeightProperty().bind(pane.heightProperty());
pane.getChildren().add(moviePlayer);
player.play();
}
Scene scene = new Scene(pane, 300, 300);
stage.setScene(scene);
stage.show();
}
}
This code works with AnchorPane as well so I guess there is something else wrong with your code if you still have the issue or I haven't understand what you need. Make a simple runnable program to demonstrate the issue.
Try to add this Action-Listener for rescaling the size:
MediaView.getParent().layoutBoundsProperty().addListener(new ChangeListener<Bounds>() {
#Override
public void changed(ObservableValue<? extends Bounds> observable, Bounds oldValue, Bounds newValue) {
mediaView.setFitHeight(newValue.getHeight());
mediaView.setFitWidth(newValue.getWidth());
}
});
This should be called every time the parent-size got changed or maximized and then the view should be resized to parent, too.
In Swing I was to add JTextArea into JScrollPane in order JTextArea to have scroll bars. When I do the same in JavaFX, the behavior is different.
This example
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextArea;
import javafx.stage.Stage;
public class SlideshowForSlipryPage2 extends Application {
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("SlideshowForSlipryPage");
primaryStage.setScene(
new Scene(
new ScrollPane(
new TextArea() {{
setPromptText("[PROMPT 1]");
}}
)
, 300, 250
)
);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
gives
i.e. text area is wider than a window and shorter than it.
Why and how to fix?
This issue has nothing to do with the pref width of the text area.
You must set the wrap property to true so that the text will wrap onto two lines when the cursor hits the edge of the container. 2 ways:
1) Using scene builder is the most simple way. Simple click "Wrap Text" in the properties of the TextArea.
2) Call the following method of the TextArea:
textArea.setWrapText(true);
You have to call setFitToWidth(true) and setFitToHeight(true) on the ScrollPane, you can set those properties in the scene builder Layout tab after selecting the ScrollPane.
Try this:
textArea.setPrefSize( Double.MAX_VALUE, Double.MAX_VALUE );
and set scrollpane size same as parent like this:
scrollPane.prefWidthProperty().bind(<parentControl>.prefWidthProperty());
scrollPane.prefHeightProperty().bind(<parentConrol>.prefHeightProperty());
I hope it resolves your query !!!
I want to create a mouselistner on my javafx rectangle.
the idea is that the rectangle has to change color when i press it?
Does anyone know how to add a listner to shapes in Javafx?
so far ive tried this:
final Rectangle rect = new Rectangle();
rect.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
// TODO Auto-generated method stub
}
});
However i get an error saying that
the method setOnMouseClicked(new EventHandler(){}) is
undefined for the type Rectangle
Abit more information:
The only options i have for rect are these:
rect.add()
rect.contains()
rect.grow();
rect.hashcode()
rect.intersection();
and a few others of no importance.
The import i am using are the following:
import com.sun.glass.events.MouseEvent;
import com.sun.javafx.geom.Rectangle;
import com.sun.javafx.geom.Shape;
Your code looks correct and matches any examples I can find. To demonstrate this I have thrown together a quick example:
public class JavaFXApplication extends Application {
Rectangle rect = new Rectangle(100,100);
#Override
public void start(Stage primaryStage) {
rect.setFill(Color.BLUE);
rect.setOnMouseClicked(new EventHandler<MouseEvent>()
{
#Override
public void handle(MouseEvent t) {
rect.setFill(Color.RED);
}
});
StackPane root = new StackPane();
root.getChildren().add(rect);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
}
When the rectangle is clicked, the colour changes from blue to red.
This might be a long shot but make sure you are referencing the Rectangle type from the JavaFX library and not the AWT Rectangle i.e. make sure your import is:
import javafx.scene.shape.Rectangle;
and not
import java.awt.Rectangle;
Update
As per my original comment it looks as though you are referencing the wrong import for the Rectangle type. I don't recognise the import com.sun.javafx.geom.Rectangle, is this from an older version of JavaFX?
You are also referencing the incorrect MouseEvent type.
Change:
import com.sun.glass.events.MouseEvent;
To:
import javafx.scene.input.MouseEvent;
I understand this answer is quite old -- but as an update (Java 13, JavaFX 13):
import javafx.scene.shape.Rectangle;
// ...
public void createRectangle() {
Rectangle rect = new Rectanlge(200, 200);
// On mouse click, code within here will be run.
rect.setOnMouseClicked(mouseEvent -> {
// Read from another property to toggle
rect.setFill(Color.RED);
});
// Add to scene in start()
}