使用复选框隐藏一组形状(javafx)

mm9b1k5b  于 2021-08-20  发布在  Java
关注(0)|答案(1)|浏览(271)

我正在写一些代码,它有一个用户界面,并画出一道彩虹。有一个复选框,单击该复选框时将显示彩虹。如果不勾选,彩虹就会消失。有一个私有类负责复选框执行的操作。里面有一个if-else语句,说明如果选中该框,则彩虹的setvisible为true,否则为false。我的代码遇到的问题是,该框无法工作。似乎没有任何语法错误,所以我不确定错误在哪里。除了setvisible,我还没有学过其他方法。
下面是我的代码:

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.*;
import javafx.scene.shape.Arc;
import javafx.scene.shape.ArcType;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Ellipse;
import javafx.scene.shape.Rectangle;

public class Main extends Application {
    private Pane root;

    private CheckBox rainbowBox;

    private Rainbow r1;

    @Override
    public void start(Stage primaryStage) {

        root = new Pane();

        r1 = new Rainbow(450, 425);

        rainbowBox = new CheckBox("rainbow");
        rainbowBox.setLayoutX(10);
        rainbowBox.setLayoutY(10);

        root.getChildren().addAll(rainbowBox);

        rainbowEvent showRainbow = new rainbowEvent();
        rainbowBox.setOnAction(showRainbow);

        Scene scene = new Scene(root, 650, 500);
        primaryStage.setTitle("example");
        primaryStage.setScene(scene);
        primaryStage.show();

    }

    public static void main(String[] args) {

        Application.launch(args);
    }

    private class Rainbow {

        private Group rainbowGroup;

        public Rainbow(int x, int y) {
            Ellipse circle1 = new Ellipse(x, y, 300, 300);
            circle1.setFill(Color.RED);

            Ellipse circle2 = new Ellipse(x, y, 290, 290);
            circle2.setFill(Color.ORANGE);

            Ellipse circle3 = new Ellipse(x, y, 280, 280);
            circle3.setFill(Color.YELLOW);

            Ellipse circle4 = new Ellipse(x, y, 270, 270);
            circle4.setFill(Color.GREEN);

            Ellipse circle5 = new Ellipse(x, y, 260, 260);
            circle5.setFill(Color.BLUE);

            Ellipse circle6 = new Ellipse(x, y, 250, 250);
            circle6.setFill(Color.PURPLE);

            Ellipse circle7 = new Ellipse(x, y, 240, 240);
            circle7.setFill(Color.WHITE);

            root.getChildren().addAll(circle1, circle2, circle3, circle4, circle5, circle6, circle7);
        }

        public Group getNodes() {
            return rainbowGroup;
        }

    }

    private class rainbowEvent implements EventHandler<ActionEvent> {

        @Override
        public void handle(ActionEvent event) {
            if (event.getSource() == r1.rainbowGroup) {
                r1.rainbowGroup.setVisible(true);
            } else {
                r1.rainbowGroup.setVisible(false);
            }

        }
    }
}
x6h2sr28

x6h2sr281#

首先,正如vgr所指出的,确保初始化 rainbowGroup 将椭圆放入该组,然后将该组放入根父组。如果不初始化 rainbowGroup 然后你会得到一个npe。如果你没有把椭圆放在这个组中,那么你就不能通过这个组一次控制它们的可见性。
其次,您的事件处理程序实现:

private class rainbowEvent implements EventHandler<ActionEvent> {

    @Override
    public void handle(ActionEvent event) {
        if (event.getSource() == r1.rainbowGroup) {
            r1.rainbowGroup.setVisible(true);
        } else {
            r1.rainbowGroup.setVisible(false);
        }
    } 
}

注意:按照标准java命名约定,类以大写字母开头(即 RainbowEvent ). 尽管您可能也想更改名称,但当前名称并不能真正描述它的功能(类不是事件)。
确定基于的操作 event.getSource() == r1.rainbowGroup . 因为您在 CheckBox 这种情况永远不会成立,因此只有 else 块将被执行。它也从不查询复选框的选定状态。将实施更改为:

// using lambda expression instead of nested class
rainbowBox.setOnAction(e -> r1.getNodes().setVisible(rainbowBox.isSelected()));

应该对你有用。另一个选项是使用绑定:

r1.getNodes().visibleProperty().bind(rainbowBox.selectedProperty());

约束,或以其他方式观察他 selected 物业,可能是比较合适的选择。如果复选框的选定状态可以通过编程方式更改,则尤其如此。
注意,实际上并不经常需要查询事件的源。事件的源始终是当前处理处理程序注册到的事件的节点。因此,在您的代码中,因为您只将处理程序添加到 CheckBox 源始终是源 CheckBox .

相关问题