Home > Software engineering >  Impossible to click on a Button
Impossible to click on a Button

Time:01-17

I am trying to add a button in a HBox itself in a borderpane : the top is the hbox and the center is a rotating Earth. However, I can't click on the button or even the TextField...\

I looked into it for a long time, trying to change the property of FocusTraversable, MouseTransparant, adding an EventFilter etc. but it's impossible to click on the button.
I thought it was maybe the events set on the scene but even removing them don't solve the problem, I'm at the point where I am thinking about creating a separate windows... Do you have an idea ? Here is the code :

Main.java

public class Main extends Application {

    private final String SPACE_BACKGROUND = getClass().getResource("images/space_background.png").toExternalForm() ;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {

        // Création du borderpane parent

        BorderPane root = new BorderPane() ;
        root.setBackground(new Background(new BackgroundImage(new Image(SPACE_BACKGROUND),
                BackgroundRepeat.REPEAT, BackgroundRepeat.REPEAT,
                BackgroundPosition.CENTER, BackgroundSize.DEFAULT))) ; // Mise en place de l'image de fond
        root.setPadding(new Insets(10)) ;

        // Ajout des champs gérant la timeline

        HBox hbox = new HBox() ;
        Button button_date = new Button("Travel To") ;
        TextField date = new TextField("Enter a date") ;
        ChoiceBox<String> country_choice = new ChoiceBox<String>() ;
        Button button_go = new Button("Go !") ;
        
        new DefaultUIControler(button_date, date, country_choice, button_go) ;

        hbox.getChildren().addAll(button_date, date, country_choice, button_go) ;
        hbox.setAlignment(Pos.TOP_RIGHT) ;

        // Ajout du globe dans le borderpane

        StackPane globeContainer = new StackPane();
        root.setCenter(globeContainer) ;
        root.setTop(hbox) ;
        globeContainer.setPickOnBounds(false) ;

        // Création de la scène & Paramètrage du stage, pour la Terre
        
        Scene scene = new Scene(root, 800, 600, true, SceneAntialiasing.BALANCED) ;
        scene.setFill(Color.BLACK) ;
        scene.getStylesheets().add(getClass().getResource("css/style.css").toExternalForm()) ;

        primaryStage.setScene(scene) ;
        primaryStage.setTitle("A history of the world") ;
        primaryStage.getIcons().add(new Image(Main.class.getResourceAsStream("images/icon.png"))) ;
        
        primaryStage.show() ;

        // Ajouts à la scène principale

        EarthUX earthux = new EarthUX() ;
        Sphere earth = earthux.getEarth() ;
        AnimationTimer timer = earthux.getTimer() ;
        globeContainer.getChildren().add(earth) ;
        
        // Zoom
        scene.setOnScroll(new ZoomEventHandler(earth)) ;
        // Drag pour tourner la Terre
        scene.setOnMouseDragged(new DragEventHandler(earth, timer)) ;
        scene.setOnMouseReleased(event -> { timer.start() ; }) ;

    }

}

ButtonTravelEventHandler.java

public class ButtonTravelEventHandler implements EventHandler<ActionEvent> {

    private TextField tf_date ;
    private ChoiceBox<String> country_choice ;
    private Button button_go ;

    public static final String ANSI_RED = "\u001B[31m" ; 
    public static final String ANSI_RESET = "\u001B[0m" ;

    public ButtonTravelEventHandler(TextField date, ChoiceBox<String> country_choice, Button button_go) {
        this.tf_date = date ;
        this.country_choice = country_choice ;
        this.button_go = button_go ;
    }

    @Override
    public void handle(ActionEvent event) {

        System.out.println("test");

        // Récupère le texte   Gestion erreur
        
        String text_date = tf_date.getText() ;

        try {

            int date = Integer.parseInt(text_date) ;

        } catch (Exception e) {

            // DO NOTHING
            ZonedDateTime now = ZonedDateTime.now() ;
            System.out.println(ANSI_RED   "[LOG "   now.format(DateTimeFormatter.ofPattern("dd/MM/yyyy z")) 
                  "] Error while parsing the value in the textfield. A date should be an integer !"   ANSI_RESET) ;

        }

        // Récupèration des infos sur les pays par rapport à la date  

        
        
        // Affichage reste composants   Affectations aux choix


        
        country_choice.setVisible(true) ;
        country_choice.setManaged(true) ;
        button_go.setVisible(true) ;
        button_go.setManaged(true) ;
        
    }

}

And DefaultUIController :

public class DefaultUIControler {

    private Button button_date ;
    private TextField date ;
    private ChoiceBox<String> country_choice ;
    private Button button_go ;

    public DefaultUIControler(Button button_date, TextField date, ChoiceBox<String> country_choice, Button button_go) {

        // Affecte les composants

        this.button_date = button_date ;
        this.date = date ;
        this.country_choice = country_choice ;
        this.button_go = button_go ;

        // Spécialise les composants
        actualiser() ; 

    }

    private void actualiser() {

        // Choix du pays invisible au début par défaut
        country_choice.setVisible(false) ;
        button_go.setVisible(false) ;
        country_choice.setManaged(false) ;
        button_go.setManaged(false) ;

        // Style

        button_date.getStyleClass().add("button_date") ;

        // Actions
        button_date.setOnAction(new ButtonTravelEventHandler(date, country_choice, button_go)) ;

    }

}

Thank you in advance ! :)

PS : I tried this in the CSS,

        .button_date {
            -fx-background-color: lime ;
        }
        
        .button_date:hover {
            -fx-background-color: red ;
        }

The color is set to lime by default but doesn't change when hovered.

CodePudding user response:

Thank you both for your answer, Slaw (you made me discover Scenic View) and trashgod (for forcing me to do a minimal reproducible example) !

I solved my problem while doing the example, I removed every "not necessary" line and parameters and it worked when I replaced:

Scene scene = new Scene(root, 800, 600, true, SceneAntialiasing.BALANCED);

by

Scene scene = new Scene(root, 800, 600);

The true is the depthBuffer, I didn't look into the details but I guess it's because of this parameter.

  • Related