Please, consider the following code:
public class JavaFxTest4 extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
Button button = new Button();
button.setText("dialog");
button.setOnAction((e) -> {
Dialog<?> d = new Dialog<>();
final Window window = d.getDialogPane().getScene().getWindow();
Stage stage = (Stage) window;
stage.setMinHeight(450);
stage.setMaxHeight(450);
stage.setHeight(450);
stage.setMinWidth(600);
stage.setMaxWidth(600);
stage.setWidth(600);
window.setY(300); //<---- note this line
window.setX(660); //<---- note this line
d.showAndWait();
});
VBox root = new VBox();
root.getChildren().addAll(button);
var scene = new Scene(root, 1920, 1000);
primaryStage.setScene(scene);
primaryStage.show();
}
}
As you can see window position is 660 (x) and 300 (y). And this is the result:
As you can see x position is correct, but y position is not. Is this a bug or I misunderstand something? I use javafx 19-ea+3 and openjdk version "14.0.2" on Ubuntu 20.
It is a bug in JavaFX. Issue is here
Related
I'm trying to make TreeView with CheckBoxTreeItems. When I collapse/expand a CheckBoxTreeItems the image I set up does not display correctly. I googled but I couldn't find correct answer. On Stack Overflow, I found a similar problem, but I didn't get a valid answer.
E.g
JavaFX CheckBoxTreeItem graphic disappear when siblings collapse
JavaFX CheckBoxTreeItem: Graphic disappears if graph is extended
Any ideas?
public class ClientApplication extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(final Stage stage) {
ImageView folderIcon = new ImageView();
Image folderImage = new Image("image/folder.png");
folderIcon.setImage(folderImage);
folderIcon.setFitWidth(16);
folderIcon.setFitHeight(16);
CheckBoxTreeItem<String> rootItem = new CheckBoxTreeItem<String>("folder", folderIcon);
rootItem.setExpanded(true);
for (int i = 0; i < 4; i++) {
CheckBoxTreeItem<String> checkBoxTreeItem = new CheckBoxTreeItem<String>("Sample" + (i + 1), folderIcon);
rootItem.getChildren().add(checkBoxTreeItem);
}
final TreeView<String> tree = new TreeView<String>(rootItem);
tree.setCellFactory(CheckBoxTreeCell.<String>forTreeView());
tree.setRoot(rootItem);
tree.setShowRoot(true);
StackPane root = new StackPane();
root.getChildren().add(tree);
stage.setScene(new Scene(root, 300, 250));
stage.show();
}
}
enter image description here
I tried to use the ideas provided by #Jai,But when I click the expand/collapse icon, there is still a problem.Attachment is a screenshot.Thanks in advance.
enter image description here
ImageView is a JavaFX control. This means that each instance represents a unique control you see on your screen. You should never use the same instance for multiple locations in your GUI.
On the other hand, Image represents an image (i.e. an array of pixel data), so it is reusable.
This should work:
#Override
public void start(final Stage stage) {
final Image folderImage = new Image("image/folder.png");
CheckBoxTreeItem<String> rootItem = new CheckBoxTreeItem<String>("folder", createImageView(folderImage));
rootItem.setExpanded(true);
for (int i = 0; i < 4; i++) {
CheckBoxTreeItem<String> checkBoxTreeItem = new CheckBoxTreeItem<String>("Sample" + (i + 1), createImageView(folderImage));
rootItem.getChildren().add(checkBoxTreeItem);
}
final TreeView<String> tree = new TreeView<String>(rootItem);
tree.setCellFactory(CheckBoxTreeCell.<String>forTreeView());
tree.setRoot(rootItem);
tree.setShowRoot(true);
StackPane root = new StackPane();
root.getChildren().add(tree);
stage.setScene(new Scene(root, 300, 250));
stage.show();
}
private ImageView createImageView(Image folderImage) {
ImageView folderIcon = new ImageView();
folderIcon.setImage(folderImage);
folderIcon.setFitWidth(16);
folderIcon.setFitHeight(16);
return folderIcon;
}
I have strange problems with JavaFX that look a lot like a bug. I want to do the following:
Entering fullscren when starting my application
Press escape to exit the application (not fullscreen, the entire application)
So far, I have the following code:
public class AppTest extends Application {
public static void main(String[] args) {
launch(args);
}
public void start(Stage stage) {
stage.setOnCloseRequest(t -> {
Platform.exit();
System.exit(0);
});
stage.setFullScreenExitHint("Press ESCAPE to exit");
stage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
stage.setFullScreen(true);
Rectangle2D screenBounds = Screen.getPrimary().getBounds();
stage.setX(screenBounds.getMinX());
stage.setY(screenBounds.getMinY());
double screenWidth = screenBounds.getWidth();
double screenHeight = screenBounds.getHeight();
stage.setWidth(screenWidth);
stage.setHeight(screenHeight);
Group root = new Group();
Scene scene = new Scene(root);
stage.setScene(scene);
scene.setOnKeyTyped(event -> {
if(event.getCode() == KeyCode.ESCAPE) {
stage.close();
}
});
Canvas canvas = new Canvas(screenWidth, screenHeight);
root.getChildren().add(canvas);
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.setFill(Color.BLUE);
gc.fillRect(0,0, screenWidth, screenHeight);
stage.show();
}
}
I'm on macOS.
In general it goes fullscreen. I'm saying in general because the real version of this code doesn't always. Sometimes, it is just a maximized window.
Then, when pressing escape, I get a maximized window instead of exiting the application.
How can I fix that?
Change:
scene.setOnKeyTyped
To:
scene.setOnKeyReleased
This explains why.
I am new to Java and JavaFX all together, so please be patient with me if I am asking the wrong question here.
I am trying to add preloader Scene to an application I built: I was able to add the preloader using the code below. It's the default preloader and it looks very basic. So, here is my question. 1) how to add percentage progress status instead of progressbar. 2) Is it possible to load this progress bar on top of an FXML scene
Preloader
public class JavaFXPreloader3 extends Preloader {
ProgressBar bar;
Stage stage;
private Scene createPreloaderScene() throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("FXML.fxml"));
ProgressIndicator pi = new ProgressIndicator();
BorderPane p = new BorderPane();
p.setCenter(pi);
return new Scene(p, 300, 150);
}
#Override
public void start(Stage stage) throws Exception {
this.stage = stage;
stage.setScene(createPreloaderScene());
stage.show();
}
#Override
public void handleStateChangeNotification(StateChangeNotification scn) {
if (scn.getType() == StateChangeNotification.Type.BEFORE_START) {
stage.hide();
}
}
#Override
public void handleProgressNotification(ProgressNotification pn) {
bar.setProgress(pn.getProgress());
}
}
How do I return root scene instead of the BorderPane p including the Progress Indicator:
ProgressIndicator pi = new ProgressIndicator();
BorderPane p = new BorderPane();
p.setCenter(pi);
return new Scene(p, 300, 150);
This is a excellent tutorial for creating a PreLoader.
https://docs.oracle.com/javafx/2/deployment/preloaders.htm
I currently use the following code to switch between scenes. I want to switch between windows and KEEP the window size (so when the users change the windows size manually by resizing the window, it will stay at the chosen size even after scene change).
Scene scene = new Scene(pane); // new Scene(pane, userChosenWidth??, userChosenHeight??);
stage.setScene(scene);
stage.sizeToScene();
Does anyone know how to accomplish this?
Just call getWidth() and getHeight() on the current Scene. If you don't have a reference to the current scene, you can get one with stage.getScene().
Setting width and height in Stage worked for me.
double prevWidth = stage.getWidth();
double prevHeight = stage.getHeight();
stage.setScene(scene);
stage.setHeight(prevHeight);
stage.setWidth(prevWidth);
I created this class:
public class AppSize {
private static final String HEIGHT = "Height";
private static final String WIDTH = "Width";
private static final String Y = "Y";
private static final String X = "X";
private final static Preferences prefs = Preferences.userNodeForPackage(AppSize.class);
public static void setSize(Stage stage) {
Optional.ofNullable(prefs.getDouble(X, -1)).filter(x->x>=0).ifPresent(stage::setX);
Optional.ofNullable(prefs.getDouble(Y, -1)).filter(y->y>=0).ifPresent(stage::setY);
Optional.ofNullable(prefs.getDouble(WIDTH, -1)).filter(width->width>=0).ifPresent(stage::setWidth);
Optional.ofNullable(prefs.getDouble(HEIGHT, -1)).filter(height->height>=0).ifPresent(stage::setHeight);
stage.setOnCloseRequest(
e->{
if(stage.isFullScreen()) {
return;
}
prefs.putDouble(X, stage.getX());
prefs.putDouble(Y, stage.getY());
prefs.putDouble(WIDTH, stage.getWidth());
prefs.putDouble(HEIGHT, stage.getHeight());
});
}
}
its use:
public class App extends Application {
#Override
public void start(Stage stage) {
var label = new Label("AppSize test.");
var scene = new Scene(new StackPane(label), 640, 480);
stage.setScene(scene);
AppSize.setSize(stage);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
I am working on a project and I need you help.
I want to know that is this possible to set anchorpane constraints in percentage as something like
AnchorPane.setLeftAnchor(content1, 35%);
Yes it can be by updating constraint values on every scene size change:
public class AnchorDemo extends Application {
private final Button button = new Button("Add");
private final ListView list = new ListView();
#Override
public void start(Stage primaryStage) {
AnchorPane root = new AnchorPane();
AnchorPane.setTopAnchor(list, 10.0);
AnchorPane.setLeftAnchor(list, 10.0);
AnchorPane.setTopAnchor(button, 10.0);
AnchorPane.setRightAnchor(button, 10.0);
root.getChildren().addAll(list, button);
Scene scene = new Scene(root, 300, 250);
scene.widthProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
updateWidthConstaints(newValue.doubleValue());
}
});
primaryStage.setScene(scene);
primaryStage.show();
updateWidthConstaints(scene.getWidth());
}
private void updateWidthConstaints(double width) {
// roughly give to the list 66% while to the button 33% of available
// space, besides paddings.
// +5s are for extra padding
AnchorPane.setRightAnchor(list, width * 1 / 3 + 5);
AnchorPane.setLeftAnchor(button, width * 2 / 3 + 5);
}
public static void main(String[] args) {
launch(args);
}
}