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

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

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

  1. import javafx.application.Application;
  2. import javafx.event.ActionEvent;
  3. import javafx.event.EventHandler;
  4. import javafx.scene.Group;
  5. import javafx.scene.Node;
  6. import javafx.scene.control.*;
  7. import javafx.scene.input.KeyCode;
  8. import javafx.scene.input.KeyEvent;
  9. import javafx.scene.layout.*;
  10. import javafx.scene.shape.Arc;
  11. import javafx.scene.shape.ArcType;
  12. import javafx.scene.text.Font;
  13. import javafx.scene.text.FontWeight;
  14. import javafx.scene.text.Text;
  15. import javafx.stage.Stage;
  16. import javafx.scene.Scene;
  17. import javafx.scene.paint.Color;
  18. import javafx.scene.shape.Ellipse;
  19. import javafx.scene.shape.Rectangle;
  20. public class Main extends Application {
  21. private Pane root;
  22. private CheckBox rainbowBox;
  23. private Rainbow r1;
  24. @Override
  25. public void start(Stage primaryStage) {
  26. root = new Pane();
  27. r1 = new Rainbow(450, 425);
  28. rainbowBox = new CheckBox("rainbow");
  29. rainbowBox.setLayoutX(10);
  30. rainbowBox.setLayoutY(10);
  31. root.getChildren().addAll(rainbowBox);
  32. rainbowEvent showRainbow = new rainbowEvent();
  33. rainbowBox.setOnAction(showRainbow);
  34. Scene scene = new Scene(root, 650, 500);
  35. primaryStage.setTitle("example");
  36. primaryStage.setScene(scene);
  37. primaryStage.show();
  38. }
  39. public static void main(String[] args) {
  40. Application.launch(args);
  41. }
  42. private class Rainbow {
  43. private Group rainbowGroup;
  44. public Rainbow(int x, int y) {
  45. Ellipse circle1 = new Ellipse(x, y, 300, 300);
  46. circle1.setFill(Color.RED);
  47. Ellipse circle2 = new Ellipse(x, y, 290, 290);
  48. circle2.setFill(Color.ORANGE);
  49. Ellipse circle3 = new Ellipse(x, y, 280, 280);
  50. circle3.setFill(Color.YELLOW);
  51. Ellipse circle4 = new Ellipse(x, y, 270, 270);
  52. circle4.setFill(Color.GREEN);
  53. Ellipse circle5 = new Ellipse(x, y, 260, 260);
  54. circle5.setFill(Color.BLUE);
  55. Ellipse circle6 = new Ellipse(x, y, 250, 250);
  56. circle6.setFill(Color.PURPLE);
  57. Ellipse circle7 = new Ellipse(x, y, 240, 240);
  58. circle7.setFill(Color.WHITE);
  59. root.getChildren().addAll(circle1, circle2, circle3, circle4, circle5, circle6, circle7);
  60. }
  61. public Group getNodes() {
  62. return rainbowGroup;
  63. }
  64. }
  65. private class rainbowEvent implements EventHandler<ActionEvent> {
  66. @Override
  67. public void handle(ActionEvent event) {
  68. if (event.getSource() == r1.rainbowGroup) {
  69. r1.rainbowGroup.setVisible(true);
  70. } else {
  71. r1.rainbowGroup.setVisible(false);
  72. }
  73. }
  74. }
  75. }
x6h2sr28

x6h2sr281#

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

  1. private class rainbowEvent implements EventHandler<ActionEvent> {
  2. @Override
  3. public void handle(ActionEvent event) {
  4. if (event.getSource() == r1.rainbowGroup) {
  5. r1.rainbowGroup.setVisible(true);
  6. } else {
  7. r1.rainbowGroup.setVisible(false);
  8. }
  9. }
  10. }

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

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

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

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

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

展开查看全部

相关问题