为什么我的控制器 class 中的事件没有触发

Why is the event in my controller class not firing

我说的事件方法是changeBackgroundScreen。在我的 css 文件之一中,该按钮被背景图像覆盖。起初我以为是背景阻止了按钮的交互。我把背景图去掉了,还是不行。现在我一点头绪都没有了。

这是 FXML 文件的一部分供您重点关注:

 <HBox alignment="CENTER" spacing="200">
      <children>
          <Button fx:id="optionButton1" onAction="#changeBackgroundScreen" prefWidth="80" prefHeight="50" id="SmallBlueBackground1"/>
          <Button fx:id="optionButton2" onAction="#changeBackgroundScreen" prefWidth="80" prefHeight="50" id="SmallBlueBackground2"/>
          <Button fx:id="optionButton3" onAction="#changeBackgroundScreen" prefWidth="80" prefHeight="50" id="SmallBlueBackground3"/>
      </children>
</HBox>

如果您感兴趣,这里是完整的 FXML 文件:

<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.image.*?>
<?import java.net.URL?>

<StackPane  fx:id="Optionmenu" id="BlueBackground1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="millionairetriviagame.OptionscreenController">
    <stylesheets>
        <URL value="@BackgroundImages.css" />
    </stylesheets>
    <stylesheets>
        <URL value="@ButtonLayout.css"/>
    </stylesheets>
    <children>
        <VBox alignment="TOP_CENTER" spacing="20">
            <ImageView>
                <image>
                    <Image url="@ImageFiles/MillionaireLogo1.png"/>
                </image>
            </ImageView>
            <Label text="Click to Change the Background Color" style="-fx-font-style: Italic;"  textFill="white">
                <font>
                    <javafx.scene.text.Font name="sans-serif" size="20" />  
                </font>
            </Label>
            <HBox alignment="CENTER" spacing="200">
                <children>
                    <Button fx:id="optionButton1" onAction="#changeBackgroundScreen" prefWidth="80" prefHeight="50" id="SmallBlueBackground1"/>
                    <Button fx:id="optionButton2" onAction="#changeBackgroundScreen" prefWidth="80" prefHeight="50" id="SmallBlueBackground2"/>
                    <Button fx:id="optionButton3" onAction="#changeBackgroundScreen" prefWidth="80" prefHeight="50" id="SmallBlueBackground3"/>
                </children>
            </HBox>
        </VBox>
        <HBox alignment="BOTTOM_RIGHT" spacing="10"  >
            <children>
                <Button fx:id="backToMain"  prefWidth="200" prefHeight="30" onAction="#goToTheMainMenu"  text="Back to the Main Menu" styleClass="ButtonLayout"> 
                    <shape>
                        <javafx.scene.shape.Rectangle  width="200" height="30" arcHeight="30" arcWidth="30" />  
                    </shape>
                </Button>
            </children>
        </HBox>
    </children>
</StackPane>

这是我的控制器Class

package millionairetriviagame;

import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;

public class OptionscreenController implements Initializable, ControllingScreens
{
    private ScreenNavigator controller;
    private MediaPlayer optionMenuPlayer;
    @FXML private Button backToMain;
    private BooleanProperty isDisabled;
    @FXML private StackPane Optionmenu;
    @FXML private Button optionButton1;
    @FXML private Button optionButton2;
    @FXML private Button optionButton3;
    @FXML private StackPane mainMenu;

    @Override
    public void initialize(URL url, ResourceBundle rb)
    {
        configureProperties();
        playSong();
    }

    private void configureProperties()
    {
        isDisabled = new SimpleBooleanProperty();
        backToMain.disableProperty().bind(isDisabled);
    }

    @Override
    public void setScreenParent(ScreenNavigator parentScreen)
    {
        controller = parentScreen;
    }

    private void playSong()
    {
        Media optionIntroTheme = new Media(getClass().getResource("/millionairetriviagame/AudioFiles/OptionMenuMusic.mp3").toExternalForm());
        optionMenuPlayer = new MediaPlayer(optionIntroTheme);
        optionMenuPlayer.setAutoPlay(true);
        optionMenuPlayer.setVolume(0.1);
        optionMenuPlayer.setCycleCount(MediaPlayer.INDEFINITE);
    }

    @FXML private void changeBackgroundScreen(ActionEvent event)
    {
        try
        {
            FXMLLoader myLoader = new FXMLLoader(getClass().getResource(MillionaireTriviaGame.MAIN));
            myLoader.load();
            mainMenu = myLoader.getRoot();
        }
        catch (IOException ex)
        {
            Logger.getLogger(OptionscreenController.class.getName()).log(Level.SEVERE, null, ex);
        } 

        if(optionButton2.isPressed())
        {
            mainMenu.setId("BlueBackground2");
            Optionmenu.setId("BlueBackground2");
        }
    }

    @FXML private void goToTheMainMenu(ActionEvent event)
    {
        isDisabled.setValue(true);
        optionMenuPlayer.stop();
        controller.loadScreen(MillionaireTriviaGame.MAINSCREENID, MillionaireTriviaGame.MAIN);
        controller.setScreen(MillionaireTriviaGame.MAINSCREENID);
    }
}

这是我的 CSS 文件,如果你也需要看的话。

#BlueBackground1
{
    -fx-background-image: url("/millionairetriviagame/ImageFiles/BlueBackgroundColor.jpg");
}

#BlueBackground2
{
    -fx-background-image: url("/millionairetriviagame/ImageFiles/BlueBackgroundColor2.jpg");
}

#SmallBlueBackground1
{
    -fx-background-image: url("/millionairetriviagame/ImageFiles/BlueBackgroundColor.jpg");
    -fx-background-repeat: stretch;   
    -fx-background-size: 80 50;
    -fx-background-position: center center;
    -fx-background-insets: 0, 0, 0, 0;
}

#SmallBlueBackground2
{
    -fx-background-image: url("/millionairetriviagame/ImageFiles/BlueBackgroundColor2.jpg");
    -fx-background-repeat: stretch;   
    -fx-background-size: 80 50;
    -fx-background-position: center center;
    -fx-background-insets: 0, 0, 0, 0;
}

#SmallBlueBackground3
{
    -fx-background-image: url("/millionairetriviagame/ImageFiles/BlueBackgroundColor3.jpg");
    -fx-background-repeat: stretch;   
    -fx-background-size: 80 50;
    -fx-background-position: center center;
    -fx-background-insets: 0, 0, 0, 0;
}

这是视觉效果

问题

问题出在您的布局上。你有一个带 VBox 的 StackPane(包含触发 changeBackgroundScreen 方法的按钮),最重要的是你有一个 HBox(有一个按钮,与右下角对齐)。

乍一看,一切都可能看起来很酷。但是,请记住 VBoxHBox 填充其父级 的布局。因此,即使您看不到,HBox 位于 VBox 中的按钮之上,会阻止所有交互。

解决方案

一个更复杂的解决方案是使用 StackPane 以外的东西,因为我真的没有看到它的需要。但是,由于您已经有了布局,让我们开始一些不需要对布局进行微调的东西。

一个非常简单的解决方案是将 HBox 移动到 VBox。这样,就没有阻挡层。但是,由于您希望按钮 固定在场景的右下角 ,我们将在 VBox 的子项之间使用 Region 并设置 VGrow as Always.这会将新添加的 HBox推送 到场景的底部,并使其固定在那里,无论您的场景大小是多少。

完整的 FXML

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

<?import java.lang.*?>
<?import java.net.*?>
<?import javafx.scene.shape.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.image.*?>
<?import java.net.URL?>

<StackPane id="BlueBackground1" fx:id="Optionmenu" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.40" fx:controller="millionairetriviagame.OptionscreenController">
    <stylesheets>
        <URL value="@BackgroundImages.css" />
    </stylesheets>
    <stylesheets>
        <URL value="@ButtonLayout.css" />
    </stylesheets>
    <children>
        <VBox alignment="TOP_CENTER" spacing="20">
            <ImageView>
                <image>
                    <Image url="@ImageFiles/MillionaireLogo1.png" />
                </image>
            </ImageView>
            <Label style="-fx-font-style: Italic;" text="Click to Change the Background Color" textFill="white">
                <font>
                    <javafx.scene.text.Font name="sans-serif" size="20" />  
                </font>
            </Label>
            <HBox alignment="CENTER" spacing="200">
                <children>
                    <Button id="SmallBlueBackground1" fx:id="optionButton1" onAction="#changeBackgroundScreen" prefHeight="50" prefWidth="80" />
                    <Button id="SmallBlueBackground2" fx:id="optionButton2" onAction="#changeBackgroundScreen" prefHeight="50" prefWidth="80" />
                    <Button id="SmallBlueBackground3" fx:id="optionButton3" onAction="#changeBackgroundScreen" prefHeight="50" prefWidth="80" />
                </children>
            </HBox>
         <Region prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS" />
         <HBox alignment="BOTTOM_RIGHT" spacing="10">
            <children>
                <Button fx:id="backToMain" onAction="#goToTheMainMenu" prefHeight="30" prefWidth="200" styleClass="ButtonLayout" text="Back to the Main Menu"> 
                    <shape>
                        <javafx.scene.shape.Rectangle arcHeight="30" arcWidth="30" height="30" width="200" />  
                    </shape>
                </Button>
            </children>
           </HBox>
        </VBox>
    </children>
</StackPane>