I am just beginning to learn JAVAFX and I have run into a problem now. I have a login screen and after I clicked login, a dialog box appeared and the problem is I don't know how to eliminate the login screen after the dialog has showed up. Please help me. This is my code
Main.java (contains login screen)
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("../view/LoginScreen.fxml"));
primaryStage.setTitle("Weltes Mart O2 Tank Module");
primaryStage.setScene(new Scene(root));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
LoginController.java (showing a dialog box)
public class LoginController {
#FXML private Text loginStatusMessage;
#FXML private Button btnLogin;
#FXML public void handleLoginButton(ActionEvent event){
System.out.println("BUTTON PRESSED");
try {
Parent root = FXMLLoader.load(getClass().getResource("../view/LoginSuccessDialog.fxml"));
Stage primaryStage = new Stage();
primaryStage.setScene(new Scene(root));
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
return;
}
}
}
You can use any Node in a Scene to get a reference to that scene. You can use a Scene to get the Window that contains it. You can close that window.
Assuming the Node fields are actually injected by the loader, you can close the Stage using this code:
btnLogin.getScene().getWindow().hide();
Related
I am completly lost atm. I have been working with scenebuilder and javaFX in the past but I am stuck like 5 hours now and I didnt get a step further. Let me explain:
I have a working java Eclipse Project, using maven dependencies
The Main is where I want to use JavaFX or load a fxml into
The programm takes many many VCC Files and extracts the data to put it all together in an excel
The programm works but I cant load a FXML file into the main or even show a pane in there
Now does my Java Main class has to extend Application? I tried both ways - doenst work.
Some example code:
public void start(Stage primaryStage) {
try {
bpmain = new BorderPane(FXMLLoader.load(new File("src\\fxml\\UserInterface.fxml").toURI().toURL()));
primaryStage.setScene(new Scene(bpmain));
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
or this (from original Docs)
public void start(Stage stage) {
Circle circ = new Circle(40, 40, 30);
Group root = new Group(circ);
Scene scene = new Scene(root, 400, 300);
stage.setTitle("My JavaFX Application");
stage.setScene(scene);
stage.show();
}
but this start method is just not getting called... where do I put that?
What my Programm should look like is pretty simple actually. I want a small UI Windows that lets you pick a Folder where the VCC data lives in and a OK Button that basically should run the Main method.
So a TextField that when its picked a Path in the Main gets replaced (filepath) and just a simple OK Button that says: yeah run the main - because the main works perfectly it is just that I cant show that ui and I dont know how to really connect it to the Main.java
Any help is appreciated - Ty
Option 1
public class Launch extends Application {
public static Stage stage = null;
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/fxml/Main.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
this.stage = stage;
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Option 2:
public class SidebarController implements Initializable {
#Override
public void initialize(URL url, ResourceBundle rb) {
}
#FXML
void btnHome_OnMouseClicked(MouseEvent event) throws IOException {
BorderPane borderPane = (BorderPane) ((Node) event.getSource()).getScene().getRoot();
Parent sidebar = FXMLLoader.load(getClass().getResource("/fxml/ContentArea.fxml"));
borderPane.setCenter(sidebar);
}
}
I'm making an application with JavaFX and Scene Builder.
I have Main class and controller that is called from main class.
I have a button in the controller that has width - 45 and height - 90
Toggle button is wrapped in StackPane and StackPane is wrapped in AnchorPane
How can I change buttonPrefWidth to 25 when application is not fullscreen and change button's prefWidth again to 45 when application is fullscreen?
Or can I change prefWidth of a button according to size of application?
Main Class:
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
try {
Parent root =
FXMLLoader.load(getClass().getResource("/card/resources/fxml/card.fxml"));
Scene scene = new Scene(root, 1600, 600);
primaryStage.setScene(scene);
scene.getStylesheets().add(getClass().getResource("style.css")
.toExternalForm());
primaryStage.initStyle(StageStyle.UNDECORATED);
primaryStage.setMaximized(true);
primaryStage.setResizable(true);
primaryStage.getIcons().add(new Image("card/resources/logo-icon.png"));
primaryStage.show();
//adding resize and drag primary stage
ResizeHelper.addResizeListener(primaryStage);
//assign ALT+ENTER to maximize window
final KeyCombination kb = new KeyCodeCombination(KeyCode.ENTER, KeyCombination.CONTROL_DOWN);
scene.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
if (kb.match(event)) {
primaryStage.setMaximized(!primaryStage.isMaximized());
primaryStage.setResizable(true);
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}
Controller:
public class Controller implements Initializable {
#FXML private AnchorPane anchorRow;
#FXML private StackPane hBoxCat0;
#FXML private Button btnPalette;
#FXML
public void initialize(URL location, ResourceBundle resources) {
}
}
EDIT:
#Slaw it doesn't work
If you just want to change the prefWidth between two numbers based on whether or not the window is full screen, then you can listen to the fullScreen property of the Stage the Button belongs to.
import javafx.beans.binding.Bindings;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
public class Controller {
#FXML private Button btnPallet;
#FXML
private void initialize() {
btnPallet.prefWidthProperty().bind(
Bindings.when(Bindings.selectBoolean(btnPallet.sceneProperty(), "window", "fullScreen"))
.then(45)
.otherwise(25)
);
}
}
This will give you warnings at first since the Button won't be part of a Scene or Window at this point of the application. While these warnings are annoying the code should still work.
I am trying to make a program using JavaFX, unfortunately I have this problem that has been driving me crazy these past hours.
I have created a small program to describe it to you.
The program starts with the Main.java : it boots up the UI.
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
VBox root = (VBox)FXMLLoader.load(getClass().getResource("sanic.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("app.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.setTitle("sanic");
primaryStage.show();
primaryStage.sizeToScene();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
On the UI, there is just a simple button which leads us to another page:
public class SanicController {
#FXML
public void goesToKnakles(ActionEvent event) {
try {
HBox root = (HBox)FXMLLoader.load(getClass().getResource("knakles.fxml"));
Stage stage = (Stage) ((Node)event.getSource()).getScene().getWindow();
Scene s = new Scene(root);
s.getStylesheets().add(getClass().getResource("app.css").toExternalForm());
stage.setScene(s);
stage.show();
}
catch(Exception e) {
e.printStackTrace();
}
}
}
Simple enough so far.
On this new page, I have this controller:
public class KnaklesController {
#FXML
private HBox box;
public void initialize() {
try {
Label l = new Label("ur my best friend");
l.getStylesheets().addAll("test");
this.box.getChildren().add(l);
}
catch(Exception e) {
e.printStackTrace();
}
}
}
I just have an HBox and I want to add a Label to it.
The Label gets added, however when I want to apply a style to it, Eclipse tells me the following error:
Dec 27, 2017 12:01:48 AM com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged
WARNING: Resource "test" not found.
And finally, here is my CSS:
HBox{
-fx-background-color: #FF00FF;
}
#test {
-fx-background-color: #FFFFFF;
}
Would anyone know WHY the program can't find the appropriate CSS class? This makes me very confused as I have actually successfully applied CSS classes on other parts of my actual program...
If anyone could take the time to solve this I would be extremely grateful.
Alright nevermind I am a goddamn dumbass, it is
getStyleClass()
and not
getStylesheets()
Is there any way of getting the Stage/Window object of an FXML loaded file from the associated class controller?
Particularly, I have a controller for a modal window and I need the Stage to close it.
I could not find an elegant solution to the problem. But I found these two alternatives:
Getting the window reference from a Node in the Scene
#FXML private Button closeButton ;
public void handleCloseButton() {
Scene scene = closeButton.getScene();
if (scene != null) {
Window window = scene.getWindow();
if (window != null) {
window.hide();
}
}
}
Passing the Window as an argument to the controller when the FXML is loaded.
String resource = "/modalWindow.fxml";
URL location = getClass().getResource(resource);
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(location);
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());
Parent root = (Parent) fxmlLoader.load();
controller = (FormController) fxmlLoader.getController();
dialogStage = new Stage();
controller.setStage(dialogStage);
...
And FormController must implement the setStage method.
#FXML
private Button closeBtn;
Stage currentStage = (Stage)closeBtn.getScene().getWindow();
currentStage.close();
Another way is define a static getter for the Stage and Access it
Main Class
public class Main extends Application {
private static Stage primaryStage; // **Declare static Stage**
private void setPrimaryStage(Stage stage) {
Main.primaryStage = stage;
}
static public Stage getPrimaryStage() {
return Main.primaryStage;
}
#Override
public void start(Stage primaryStage) throws Exception{
setPrimaryStage(primaryStage); // **Set the Stage**
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
primaryStage.setScene(new Scene(root, 300, 275));
primaryStage.show();
}
}
Now you Can access this stage by calling
Main.getPrimaryStage()
In Controller Class
public class Controller {
public void onMouseClickAction(ActionEvent e) {
Stage s = Main.getPrimaryStage();
s.close();
}
}
The first stage that I load it always open properly as fullscreen.
stage.setFullScreen(true);
stage.setScene(login_scene);
But when I change to another FXML the applications stays fullscreen (no top toolbar.. ), but the actual view content gets resized on the prefWidth/prefHeight of the root AnchorPane from FXML (I can see the desktop in my bottom right corner :|), and I want it to be dynamic to my screen resolution.
Thanks.
#Later Edit:
So on the start method of my main Class I load a Scene (created from an FXML doc) and set it to the Stage (the start method param). I save this stage for later use.
When I press a button with the same stage I save previously I change the scene to another FXML document
#Screenshots:
http://tinypic.com/r/2079nqb/6 - 1st scene works normally - code from start override method of the main class
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
stage.setScene(new Scene(root));
stage.setFullScreen(true);
stage.show();
currentStage = stage;
}
http://tinypic.com/r/szfmgz/6 - after reloading the second scene - the code below from sample controller class
#FXML
private void handleButtonAction(ActionEvent event) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
JavaFXApplication12.currentStage.setScene(new Scene(root));
}
I have no idea about the real cause but here are 2 quick workarounds.
In the handleButtonAction method:
1) Don't create new scene just replace its content
#FXML
private void handleButtonAction(ActionEvent event) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
JavaFXApplication12.currentStage.getScene().setRoot(root);
}
2) If you really nead to create new scene then toggle fullscreen
#FXML
private void handleButtonAction(ActionEvent event) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
JavaFXApplication12.currentStage.setScene(new Scene(root));
Platform.runLater(new Runnable() {
#Override
public void run() {
JavaFXApplication12.currentStage.setFullScreen(false);
JavaFXApplication12.currentStage.setFullScreen(true);
}
});
}
If I am right to know your concern then You should use your primary stage as static or you can make it available to other controller by making getters and setters. So to get same stage to load other fxmls you can set it to when you are loading a fxml and also make sure that do not create another scene. Because due to new scene you actual content resized.
So you can use this
In Main.java:
YourController objYourController = loader.getController();
objYourController.setDialogStage(primaryStage);
In YourController.java:
public void setMystage(Stage primaryStage) {
this.primaryStage= primaryStage;
}
//To load another FXML
Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
primaryStage.getScene().setRoot(rootLayout);
Hope it will help you.