I have a laptop with a touchpad. The zoom functionality works on some programs and not others. For example, with the Chrome and Edge browsers, zoom resizes content on the screen but my Firefix browser zoom does nothing.
My question is if there is anything I can do to get the following simple JavaFX tutorial example to respond to the zoom gesture. I added the println() and can report that nothing is printed to the console when I do a zoom gesture.
public class ZoomAndRotate extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
HBox hBox = new HBox();
hBox.setAlignment(Pos.CENTER);
hBox.getChildren().add(new Button("Button 1"));
hBox.getChildren().add(new Button("Button 2"));
hBox.setOnZoom(e -> {
System.out.println("zoom code engaged");
hBox.setScaleX(hBox.getScaleX() * e.getZoomFactor());
hBox.setScaleY(hBox.getScaleY() * e.getZoomFactor());
});
Scene mySceneGraph = new Scene(hBox, 800, 600);
primaryStage.setScene(mySceneGraph);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I'm using JavaFX 15, Java 11, on Windows 10, with a Dell touchpad. Can provide more specifics if needed. I don't see anything in the windows control panel for the touchpad that helps. The Dell Touchpad configuration panel has gestures enabled and zoom selected. As I said at the top, zoom does work for some programs.
Related
I use a JavaFX Popup in my application to change the Shipping Address of a customer. That often requires copy pasting the Address from the web browser. If I click on the Popup after the application lost focus it will not regain focus. I first need to click the parent window behind the popup and then click the Popup again to be able to interact with it.
Is there any way to solve that problem, besides using an undecorated stage instead of a Popup?
EDIT:
Here I made a minimal example:
public class HelloApplication extends Application {
#Override
public void start(Stage stage) throws IOException {
Scene scene = new Scene(new VBox(), 600, 600);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
Popup popup = new Popup();
Button btn = new Button("This is a very nice button!");
btn.setOnAction(actionEvent -> System.out.println("button clicked"));
TextField textField = new TextField();
textField.setOnMouseClicked(mouseEvent -> System.out.println("textField clicked"));
VBox popupVBox = new VBox(btn, textField);
popupVBox.setStyle("-fx-background-color: white");
popupVBox.setPadding(new Insets(10));
popup.getContent().add(popupVBox);
popup.show(scene.getWindow());
}
public static void main(String[] args) {
launch();
}
}
If you click outside of the application (for example the web browser, to copy some value) then you can not enter Text into the TextField anymore. The button action listener and even the TextField mouse Listener still work and output "button clicked" and "textField clicked" but the blue halo around them does not apppear and you can not enter (or paste) text into the TextField. After you click somewhere on the main Stage of the application it works again.
I tried adding textField.requestFocus();
to the mouse Listener of the textfield but that does not do anything.
EDIT 2 after the comment from kleopatra:
I tried adding the following code:
popupVBox.setOnMouseEntered(mouseEvent -> {
popup.getOwnerWindow().requestFocus();
parentVBox.toFront(); //This is created above and passed to the new Scene instead of diectly passing new VBox() as in the code snippet posted above
});
With that code added, popup and its children seem to have focus if the mouse is hoverd over it after an other application had focus, i.e. if clicked with the mouse the blue border appears around the button and textField, and if there is any text in the textField I can move the cursor with the mouse and select the text with the mouse, buy any keyboard inputs are ignored. Actually they are executed in the other application which had focus before. If I ctrl+c in Intellij and try to ctrl+v into the textfield it will be pasted to the Intellij editor. Also the arrow keys move the cursor in the intellij window instead of the textField.
The only way to be able to type anything in the TextField is to click the parent window first.
Also
textField.setOnMouseClicked(mouseEvent -> {
textField.requestFocus();
});
does not do anything
not an answer, just to clarify the comment (will delete if seen by OP :)
public class PopupFocus extends Application {
#Override
public void start(Stage stage) throws IOException {
Scene scene = new Scene(new VBox(), 300, 300);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.setX(10);
stage.show();
Popup popup = new Popup();
Button btn = new Button("This is a very nice button!");
btn.setOnAction(actionEvent -> System.out.println("button clicked"));
TextField textField = new TextField();
textField.setOnMouseClicked(mouseEvent -> {
System.out.println("textField clicked");
stage.toFront();
});
VBox popupVBox = new VBox(btn, textField);
popupVBox.setStyle("-fx-background-color: white");
popupVBox.setPadding(new Insets(10));
popup.getContent().add(popupVBox);
// original
popup.show(scene.getWindow());
}
public static void main(String[] args) {
launch();
}
}
I am trying to create a simple splash screen. In fact I have a stackpane with an image as background. I do not want to show the default javafx decorations.
So I tried StageStyle.TRANSPARENT but it makes the whole thing transparent. On the other hand StageStyle.UNDECORATED show the image but with a white background. Here is the code in my start method.
public class SplashScreen extends Preloader {
private Stage stage;
#Override
public void start(Stage stage) throws Exception {
this.stage = stage;
StackPane root = (StackPane) FXMLLoader.load(getClass().getClassLoader().getResource("layouts/splash.fxml"));
Scene scene = new Scene(root, 690, 380,true, SceneAntialiasing.BALANCED);
scene.setFill(Color.TRANSPARENT);
stage.initStyle(StageStyle.TRANSPARENT);
stage.setScene(scene);
stage.show();
}
...
I am using java 11.0.8 and javafx 14
JavaFX 15 fixed this. Seems it was a bug.
I have read several questions/solutions here that are related to my problems. but nothing seems to work.
so I have a primarystage in fullscreen mode, say if i click a button it changes the scene. but the stage seems to display the taskbar. also I resolved the issue by adding this to all of the scene methods..
stage.setFullScreen(false);
stage.setFullScreen(true);
BUT, the transition in scenes is not that fluid. first it goes to desktop and back to fullscreen.. which is not the ideal solution.
here is my code for the primary stage:
public static Stage stage;
private static AnchorPane mainLayout;
#Override
public void start(Stage primaryStage) throws IOException
{
Main.stage = primaryStage;
Main.stage.setTitle("Raven App");
stage.initStyle(StageStyle.UNDECORATED);
stage.setFullScreen(true);
stage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
Main.showMain();
}
here is my code for changing the scene:
public static void UserLogin() throws IOException
{
FXMLLoader loader=new FXMLLoader();
loader.setLocation(Main.class.getResource("page/UserHomeLogin.fxml"));
mainLayout=loader.load();
Scene scene=new Scene(mainLayout);
stage.setScene(scene);
stage.show();
}
I don't know if this is a bug or something. But i thought if you set your primary stage to full screen. and should be fullscreen all through out regardless of scene.
also, if i have a primary stage in full screen mode.. and a secondary stage NOT in full screen mode. the primary stage seems to disappear if i click a button to show the secondary stage. I wanted to show the secondary page on top of the primary stage, and the primary stage should not be clickable unless the secondary page is closed.
my code for showing the secondary stage:
public static void PasswordVerify() throws IOException
{
Stage stage = new Stage();
Parent root = FXMLLoader.load(Main.class.getResource("page/PassConfirm.fxml"));
stage.setScene(new Scene(root));
stage.setTitle("popup window");
stage.initModality(Modality.APPLICATION_MODAL);
stage.showAndWait();
stage.show();
}
Instead of creating a new scene, just change the root of the existing scene:
public static void UserLogin() throws IOException {
FXMLLoader loader=new FXMLLoader();
loader.setLocation(Main.class.getResource("page/UserHomeLogin.fxml"));
mainLayout=loader.load();
stage.getScene().setRoot(mainLayout);
// or just
// scene.setRoot(mainLayout);
// if you already have a reference to the scene
}
The second thing you are asking is not really possible. In JavaFX, on many platforms "full screen mode" is really implemented as "exclusive screen mode"; so there is a unique window visible. So you would need another solution entirely to this, that didn't involve displaying a new window at all.
I have
a primary stage which the user can configure to be in fullscreen mode
secondary stages (tool windows) which the user can open. These windows should be always on top the the primary stage (regardless of whether its in fullscreen mode or not).
The latter does not work, even if I use setAlwaysOnTop(true) for the secondary stages they will disappear behind the primary stage once the user clicks on the primary stage.
This only happens when the primary stage is in full screen mode, everything works fine if the primary stage is not in fullscreen mode.
How can I enable this concept of tools windows in front of a fullscreen stage? Example code:
public class Test extends Application {
#Override
public void start(Stage stage) {
VBox vbox = new VBox();
Scene scene = new Scene(vbox);
stage.setScene(scene);
Button button1 = new Button("New Tool Window");
button1.setOnAction((e) -> {
Stage toolStage = new Stage();
Scene toolScene = new Scene(new Label("Am I on top?"), 300, 250);
toolStage.setScene(toolScene);
toolStage.initOwner(stage);
toolStage.setAlwaysOnTop(true);
toolStage.show();
});
Button button2 = new Button("Close");
button2.setOnAction((e) -> System.exit(0));
vbox.getChildren().addAll(button1, button2);
stage.show();
stage.setFullScreen(true);
}
public static void main(String[] args) {
launch(args);
}
}
Update 8/20/2016: Confirmed as a bug: JDK-8164210
A way to bypass this limitation is to:
Deactivate fullscreen mode
Create a keyCombination for psuedo fullscreen
Set the stage style undecorated and not resizable
Se the screen to the size of the user screen and position it at 0,0.
It is easy to create your own border for minimizing and closing the program as shown here:
JavaFX Stage.setMaximized only works once on Mac OSX (10.9.5)
And here:
JavaFX 8 Taskbar Icon Listener
you need to set initmodality after set initowner
toolStage.initOwner(stage);
toolStage.initModality(Modality.APPLICATION_MODAL);
I'm trying to use the translateZ property on a VBox to move the panel "into the screen".
If I use setTranslateZ() on the root node this works fine. However if I change root.setTranslateZ(200); to panel.setTranslateZ(200); the window is blank.
public class Demo01HelloWorld3D extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
Button button = new Button("Press me");
VBox panel = new VBox(button);
panel.setAlignment(Pos.CENTER);
panel.setDepthTest(DepthTest.ENABLE);
VBox root = new VBox(panel);
root.setAlignment(Pos.CENTER);
root.setDepthTest(DepthTest.ENABLE);
root.setTranslateZ(200);
// panel.setTranslateZ(200); <== I want this to work
Scene scene = new Scene(root, 320, 240, true);
primaryStage.setScene(scene);
scene.setCamera(new PerspectiveCamera(false));
primaryStage.show();
}
}
Setting translateZ on the root node
Setting translateZ on the panel node
Things I've tried
Setting depthTest attribute to enable - although I don't think this is necessary as it defaults to DepthTest.INHERIT
Lots of searching for similar questions!
Checking SCENE3D is enabled - yes it is
Checking the javadoc for translateZProperty
checked Z value is less than camera clippingFar property
Looked at Oracle JavaFX 3D tutorial - this does not specifically address 3D with standard controls and containers etc.
With panel.setTranslateZ(200); you're pushing the panel behind the root, so the root obscures it.
Add root.setStyle("-fx-background-color: transparent;"); and it works:
#Override
public void start(Stage primaryStage) throws Exception {
Button button = new Button("Press me");
VBox panel = new VBox(button);
panel.setAlignment(Pos.CENTER);
panel.setDepthTest(DepthTest.ENABLE);
VBox root = new VBox(panel);
root.setAlignment(Pos.CENTER);
root.setDepthTest(DepthTest.ENABLE);
root.setStyle("-fx-background-color: transparent;");
panel.setTranslateZ(200);
Scene scene = new Scene(root, 320, 240, true);
primaryStage.setScene(scene);
scene.setCamera(new PerspectiveCamera(false));
primaryStage.show();
}