0

I'm new to the community and I don't really know how to ask for help here. I was trying to create a close button for my alert pop Up window, but I'm getting a syntax error. i also would like to perform some actions before the window closes completely.

This is the driver that calls the window to appear:

package sample;

import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

import java.awt.*;
import java.io.IOException;


public class Controller {

    public static String name;

    public void removeButtonPressed() throws IOException {
        name = "Hello world";
        alertController a = new alertController().starWindow();

    }

}

This is the alert's controller

package sample;

import javafx.application.Platform;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Label;

import java.awt.event.MouseEvent;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;

public class alertController implements Initializable {

    @FXML
    private Label label = new Label();
    private String s = Controller.name;


    public alertController starWindow() throws IOException {

        Parent root = FXMLLoader.load(getClass().getResource("alert.fxml"));
        Stage window = new Stage();
        window.initModality((Modality.APPLICATION_MODAL));
        window.setTitle("");
        Scene scene = new Scene(root);
        window.setScene(scene);
        window.show();
        return null;
    }

    private void closeButton(MouseEvent event){
        Stage s = (Stage) ((Node)event.getSource().getScene().getWindow()); 
/*I'm getting problems with this part of my code
 the IDE gives me trouble with getScene()*/
        s.close();
    }


    @Override
    public void initialize(URL location, ResourceBundle resources) {
        label.setText(s);
    }
}

this is the alert's FXML file

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.effect.*?>
<?import javafx.scene.text.*?>
<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<VBox maxHeight="141.0" maxWidth="394.0" prefHeight="119.0" prefWidth="307.0" style="-fx-background-radius: 5;" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.alertController">
   <children>
      <AnchorPane>
         <children>
            <Label fx:id="label" layoutX="28.0" layoutY="20.0" maxHeight="35.0" maxWidth="149.0" text="Are You Sure?">
               <font>
                  <Font name="System Bold" size="20.0" />
               </font>
            </Label>
         </children>
      </AnchorPane>
      <Separator maxWidth="307.0">
         <VBox.margin>
            <Insets bottom="10.0" />
         </VBox.margin>
      </Separator>
      <HBox prefHeight="38.0" prefWidth="297.0" spacing="10.0">
         <children>
            <Region HBox.hgrow="ALWAYS" />
            <Button maxHeight="44.0" maxWidth="58.0" mnemonicParsing="false" text="Yes">
               <font>
                  <Font size="15.0" />
               </font>
            </Button>
            <Button maxHeight="44.0" maxWidth="55.0" mnemonicParsing="false" onMouseClicked="#closeButton" text="No">
               <HBox.margin>
                  <Insets right="30.0" />
               </HBox.margin>
               <font>
                  <Font size="15.0" />
               </font>
            </Button>
         </children>
         <VBox.margin>
            <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
         </VBox.margin>
      </HBox>
   </children>
</VBox>

I also tried to use setOnAction but the same error happened.

thank you so much!!

Juan S.
  • 3
  • 2
  • 2
    `awt` mouseevent import. I don't know if that's the problem, but you should not be using it. – SedJ601 Dec 03 '19 at 15:27
  • After looking at the rest of your code, it's most likey the problem. – SedJ601 Dec 03 '19 at 15:29
  • 1
    To add to @Sedrick since your new awt is used for swing applications with gui's as well and awt doesn't play nice with Javafx remove the `import java.awt.*;` and swap it with `import javafx.scene.input.MouseEvent;` – Matt Dec 03 '19 at 15:31
  • 2
    there are several things wrong with your code (f.i. you must not instantiate a field that's injected, you should not have static access anywhere, there's a missing closing parenthesis in getting the stage, missing fxml annotation at closebutton ... ) - in your shoes I would take a couple of steps back, re-read your favorite text book and start tackling one problem after the other :) – kleopatra Dec 03 '19 at 15:32
  • 1
    Does this answer your question? [JavaFX Error when trying to make Tableview Clickable](https://stackoverflow.com/questions/23001170/javafx-error-when-trying-to-make-tableview-clickable) – SedJ601 Dec 03 '19 at 15:33
  • You may want to take a look at this post before continuing to use `static` for passing the parameters and most certainly creating 2 instances of `alertController` to show the scene: https://stackoverflow.com/questions/14187963/passing-parameters-javafx-fxml – fabian Dec 03 '19 at 17:33
  • To be honest with you guys, I’ve been just 2 days learning about JavaFX, and I’m aware that I have many bad practices in my code. Thank you for the feedback though. I solved my problem by replacing the awt imports for the appropriate ones. I also used setOnAction instead of MouseEvent. I changed the method’s parameter to closeButton(Event event). – Juan S. Dec 04 '19 at 16:43

3 Answers3

0

Try using onAction="#closeButton" in your FXML code. And I think that this method should be public as well as every node on your stage (s.a. the label that you've annotated with @FXML).

Furthermore you can access the stage by any object on that stage with

Stage stage = (Stage) label.getScene().getWindow();

Hope this helps!

raphaelmue
  • 21
  • 4
  • 1
    _this method should be public as well as every node on your stage_ that's possible but not the best option (internals shouldn't be made public): what's missing is the @fxml annotation on private methods/fields – kleopatra Dec 03 '19 at 15:57
  • Thank you Raphael, your answer was really helpful! – Juan S. Dec 04 '19 at 16:36
0

Let's use brackets to clarify how the compiler interprets

Stage s = (Stage) ((Node)event.getSource().getScene().getWindow());
Stage s = (Stage) ((Node) (((event.getSource()).getScene()).getWindow()));

i.e. the cast to Node has lower precedence than the . operator leaving you with an expression of type Object you try to call .getSource() on. Object does not contain a getScene method. Make sure the cast is applied first by adding brackets:

Stage s = (Stage) ((Node) event.getSource()).getScene().getWindow();

Also note that even after applying this fix you'll still have issues that will result in exceptions at runtime: You're using some java.awt imports. You need to replace those with the appropriate javafx imports.

I also strongly recommend adhering to the java naming conventions. Starting type names with a lowercase letter can make your code hard to read.

fabian
  • 80,457
  • 12
  • 86
  • 114
0

This was the solution to my problem.

Controller:

  @FXML
    private void closeButton(Event event){
        Stage s = (Stage) ((Node) event.getSource()).getScene().getWindow();
        s.close();
    }

FXML code:

<Button maxHeight="44.0" maxWidth="55.0" mnemonicParsing="false" onAction="#closeButton" text="No">

I deleted:

import java.awt.event.MouseEvent;
Juan S.
  • 3
  • 2