JavaFX MenuBar has a large gap between it and any Menus until a resize is performed.
After resize, the Menus sit flush against the MenuBar as expected. Assuming this is not widespread behavior because a search doesn't turn anything up (or I'm searching the wrong terms).
Java: 1.8.0_20
OS: Ubuntu 14.04
Before resize:
After resize:
Any ideas on how to get consistent behaviour here?
Code used to make the screenshots:
public class DemoFX extends Application {
#Override
public void start(Stage stage) throws Exception {
BorderPane root = new BorderPane();
root.setPrefSize(400, 400);
Menu a = new Menu("A");
a.getItems().addAll(new MenuItem("A1"), new MenuItem("A2"));
MenuBar bar = new MenuBar();
bar.getMenus().add(a);
root.setTop(bar);
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Related
Im working on a java FX application were I switch between my start up scene, startScreen() and my game play scene, create(). I have looked at multiple tutorials on how to switch scenes to make sure I had the right idea, and it seems simple enough.
However, if I start the application with the create() scene the format and alignment of all the nodes within are fine. If I try to start with the startScreen() scene and then switch to the create() using the action event, the alignment of the nodes in the game play scene gets messed up (the boards shift and the labels are placed on top of the boards). As far as I've seen in tutorials, switching scenes shouldn't affect the alignment of nodes of scenes assuming the scenes normally work separately.
Original (just calling create()) and Second Version calling both startScreen() and create()
public Parent create() {
BorderPane root = new BorderPane();
root.setPrefSize(800, 800);
setButtons(root);
enemy = new Board(event -> {...}, true);
player = new Board(event -> {...}, false);
VBox vbox = new VBox(50, enemyLabel, enemy, playerLabel, player);
vbox.setAlignment(Pos.CENTER);
root.setCenter(vbox);
return root;
}
public Parent startScreen(Stage primaryStage) {
BorderPane pane = new BorderPane();
pane.setPrefSize(800, 800);
pane.setId("pane");
Button button = new Button("START");
button.setOnAction(e-> primaryStage.setScene(new Scene(create())));
pane.setCenter(button);
return pane;
}
#Override
public void start(Stage primaryStage) {
try {
primaryStage.setTitle("Boat Wars");
primaryStage.setResizable(false);
//Scene scene = new Scene(startScreen(primaryStage));
//scene.getStylesheets().addAll(this.getClass().getResource("application.css").toExternalForm());
Scene scene = new Scene(create());
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
As the title suggests, I want to make window in JavaFX and make it permanently maximized (i.e. fullscreen).
This is sample code that produces error... well, unexpected behavior.
public class Resize extends Application {
#Override
public void start(Stage primaryStage) {
StackPane root = new StackPane();
Scene scene = new Scene(root);
primaryStage.setMaximized(true);
primaryStage.setResizable(false);
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Please note setMaximized and setResizable. Everything works until... I press ⊞↓ (WinKey+DownArrow), at which point my window gets resized, and I can't get it maximized again. I'm running the code from NetBeans on Windows 10.
Here's a screenshot. .
You can force the application to be either full screen or minimized, but never windowed, as per your comment, by first doing
primaryStage.setFullScreen(true);
and then disabling the ability to exit full screen by doing
primaryStage.setFullScreenExitKeyCombination(KeyCombination.NO_MATCH);
I'm having trouble with the start of an JavaFX application. When loading the application the Icon in the windows taskbar is the Java icon instead of my own icon for a split second.
#Override
public final void start(final Stage stage) {
MainController controller = new MainController();
Scene scene = new Scene(controller.getRoot());
stage.setTitle("Geex");
stage.getIcons().addAll(
new Image(App.class.getResourceAsStream("/application/images/icon_16.png")),
new Image(App.class.getResourceAsStream("/application/images/icon_32.png")),
new Image(App.class.getResourceAsStream("/application/images/icon_48.png")),
new Image(App.class.getResourceAsStream("/application/images/icon_64.png")),
new Image(App.class.getResourceAsStream("/application/images/icon_128.png")),
new Image(App.class.getResourceAsStream("/application/images/icon_256.png"))
);
stage.setScene(scene);
stage.setMinHeight(FRAME_HEIGHT);
stage.setMinWidth(FRAME_WIDTH);
stage.setMaximized(true);
stage.show();
}
I am basically new to Java FX 2.
Scenario:
I have 3 Scenes and I want a way to add menu-bar such that I don't i don't want to explicitly remove the menu bar from previous scene and add it to new one. Like Some thing a Parent Scene or some way menu-bar is attached to Stage. I mean menu-bar is added just one time and always be present whatever scene is in front or not.
If This is Possible How Can I do this.
Here is the Default Example Provided by Oracle Docs of JavaFX http://docs.oracle.com/javafx/2/ui_controls/MenuSample.java.html
public class Main extends Application {
final ImageView pic = new ImageView();
final Label name = new Label();
final Label binName = new Label();
final Label description = new Label();
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
stage.setTitle("Menu Sample");
Scene scene = new Scene(new VBox(), 400, 350);
scene.setFill(Color.OLDLACE);
MenuBar menuBar = new MenuBar();
// --- Graphical elements
final VBox vbox = new VBox();
vbox.setAlignment(Pos.CENTER);
vbox.setSpacing(10);
vbox.setPadding(new Insets(0, 10, 0, 10));
makeContentsForVBox();// in this vBox area will be fill with name pic desrciption
vbox.getChildren().addAll(name, binName, pic, description); // name is lable
// --- Menu File
Menu menuFile = new Menu("File");
MenuItem add = new MenuItem("Shuffle",
new ImageView(new Image(getClass().getResourceAsStream("new.png"))));
add.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
shuffle();
vbox.setVisible(true);
}
});
MenuItem clear = new MenuItem("Clear");
clear.setAccelerator(KeyCombination.keyCombination("Ctrl+X"));
clear.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
vbox.setVisible(false);
}
});
MenuItem exit = new MenuItem("Exit");
exit.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent t) {
System.exit(0);
}
});
menuFile.getItems().addAll(add, clear, new SeparatorMenuItem(), exit);
((VBox) scene.getRoot()).getChildren().addAll(menuBar, vbox);
stage.setScene(scene);
stage.show();
}
}
So Here menuBar is added to a scene. if i swap the scene and bring an other scene in front ... What will i do. i think I remove menuBar from this scene and add to other or simply add to new one. so every time i have to do this when i change. Is there any way to avoid this??
The approach I would prefer is to use a Scene with BorderPane as its root
scene.setRoot(borderPane);
You can add the MenuBar to the top of the BorderPane and at its Center you can place SplitPane
BorderPane borderPane = new BorderPane();
borderPane.setTop(menuBar);
borderPane.setCenter(splitPane);
Whenever you need to switch to WebView just replace it with SplitPane :
borderPane.setCenter(webView);
Following this approach, your MenuBar will always remain on TOP and you can switch between SplitPane and WebView
I have problem when trying to close current scene and open up another scene when menuItem is selected. My main stage is coded as below:
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Shop Management");
Pane myPane = (Pane)FXMLLoader.load(getClass().getResource
("createProduct.fxml"));
Scene myScene = new Scene(myPane);
primaryStage.setScene(myScene);
primaryStage.show();
}
Then within createProduct.fxml, when menuItem is onclick, it will perform this:
public void gotoCreateCategory(ActionEvent event) throws IOException {
Stage stage = new Stage();
stage.setTitle("Shop Management");
Pane myPane = null;
myPane = FXMLLoader.load(getClass().getResource("createCategory.fxml"));
Scene scene = new Scene(myPane);
stage.setScene(scene);
stage.show();
}
It does opened up createCategory.fxml. However, the previous panel which is createProduct.fxml does not close. I know there's something called stage.close() to do this but I have no idea where to implement it since I not passing the scene from main right from the start. I wonder how should I fix this.
Thanks in advance.
You have to make some changes in start method, like..
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Shop Management");
FXMLLoader myLoader = new FXMLLoader(getClass().getResource("createProduct.fxml"));
Pane myPane = (Pane)myLoader.load();
CreateProductController controller = (CreateProductController) myLoader.getController();
controller.setPrevStage(primaryStage);
Scene myScene = new Scene(myPane);
primaryStage.setScene(myScene);
primaryStage.show();
}
and your CreateProductController.java will be,
public class CreateProductController implements Initializable {
Stage prevStage;
public void setPrevStage(Stage stage){
this.prevStage = stage;
}
#Override
public void initialize(URL location, ResourceBundle resources) {
}
public void gotoCreateCategory(ActionEvent event) throws IOException {
Stage stage = new Stage();
stage.setTitle("Shop Management");
Pane myPane = null;
myPane = FXMLLoader.load(getClass().getResource("createCategory.fxml"));
Scene scene = new Scene(myPane);
stage.setScene(scene);
prevStage.close();
stage.show();
}
}
You have multiple ways to solve your problem, few of them I tell you. What I understood from your question is that you want to create an application which contains a navigation (menu bar) on the top and by using it user can switch to any screen.
The easiest method is to make your Navigation Bar available globally, either by you make it static or by passing it to screens, or by any other method. Second, make a single screen (say Border Pane) and load other screens on it (its center).
You can also use spring integration in project so that it provide you better injection of controllers. See Ref : http://www.zenjava.com/2011/10/25/views-within-views-controllers-within-controllers/
You can also create your own single screen controller and manage other screens using that.
See Ref: https://blogs.oracle.com/acaicedo/entry/managing_multiple_screens_in_javafx1
But for this (above) you have to change or update your current architecture.
you can get the current open window/stage from the fx:id . just make sure you have an item in your createProduct.fxml that has fx:id like below
<TextField fx:id="username" labelFloat="true" layoutX="80.0" layoutY="300.0" prefHeight="32.0" prefWidth="260.0" promptText="Login Username" />
Hope you see the fx:id attribute.
Then in your start controller, leave as it is
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Shop Management");
Pane myPane = (Pane)FXMLLoader.load(getClass().getResource("createProduct.fxml"));
Scene myScene = new Scene(myPane);
primaryStage.setScene(myScene);
primaryStage.show();
}
Then in your CreateProductController.java
//make sure you import the javafx item you have used, eg have used TextField
import javafx.scene.control.TextField;
public class CreateProductController implements Initializable {
// make sure the variable has the same type as the item in the fxml "TextField" and same name "username"
#FXML
private TextField username;
//we use the above variable since its referencing the window to which it belongs because of the fx:id attribute, then we close it
private void closeStage()
{
((Stage) username.getScene().getWindow()).close();
}
#Override
public void initialize(URL location, ResourceBundle resources) {
}
public void gotoCreateCategory(ActionEvent event) throws IOException {
closeStage();// we close the old stage
Stage stage = new Stage();
stage.setTitle("Shop Management");
Pane myPane = null;
myPane = FXMLLoader.load(getClass().getResource("createCategory.fxml"));
Scene scene = new Scene(myPane);
stage.setScene(scene);
stage.show();
}
}