如何访问超出类范围的变量?

罗伊·K

我正在尝试编写JavaFX Sudoku程序,用户可以通过以下方法填充单元格:

  1. 单击九个按钮之一(对应于1-9)
  2. 单击其中一个单元格

代码的工作方式是:单击按钮时,将与该按钮对应的int分配给selectedNum当单击单元格时,单元格将其文本分配给selectedNum但是,这就是问题所在–在构造函数内部实现setOnAction函数CellCell无法访问selectedNum如果它是超出类范围的变量,如何传递selectedNum?

单元格类别:

import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;

/**
 * The Cell class inherits StackPane, representing one of the cells in Sudoku.
 * @author rkuni
 *
 */
public class Cell extends StackPane{
    
    private Text text; //displays the number inside the cell
    private Rectangle rect; //visual element for the cell
    
    /**
     * Default Constructor for Cell
     */
    public Cell() {
        text = new Text("");
        text.setFont(Font.font(30));
        rect = new Rectangle(50, 50);
        rect.setStyle("-fx-fill: white; -fx-stroke: black; -fx-stroke-width: 1;");
        this.getChildren().add(rect);
        this.getChildren().add(text);
        
        this.setOnMouseClicked(new EventHandler<MouseEvent>() { 
            @Override
            public void handle(MouseEvent t) {
                text.setText("" + 1); //when clicked, I want to set text to the number that is selected.
            }
        });
    }
}

主班

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.text.Font;

public class Main extends Application {
    
    private int selectedNum = 0;
    
    @Override
    public void start(Stage primaryStage) {
        try {
            
            Group root = new Group();
            Cell cell1 = new Cell();
            cell1.setLayoutX(100);
            cell1.setLayoutY(100);
            root.getChildren().add(cell1);
            
            Button numSelection[] = new Button[9];
            for (int i = 0; i < 9; i++) {
                final int j = i; 
                numSelection[i] = new Button("" + (i + 1));
                numSelection[i].setLayoutY((i / 3) * 55 + 200);
                numSelection[i].setLayoutX((i % 3) * 55 + 630);
                numSelection[i].setMinHeight(50);
                numSelection[i].setMinWidth(50);
                numSelection[i].setFont(Font.font(20));
                root.getChildren().add(numSelection[i]);

                numSelection[i].setOnAction(new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(ActionEvent arg0) {
                        selectedNum = j + 1;
                    }
                });
            }
            
            Scene scene = new Scene(root,900,500);
            primaryStage.setScene(scene);
            primaryStage.show();
            
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}

潜在解决方案

潜在的解决方案是根本没有Cell类,并且代码将起作用。问题不再存在,因为所有变量都在同一范围内。但是,我想保留Cell类,因为它使代码更有条理。无论如何,这里:

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.stage.Stage;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;


public class Main extends Application {
    
    private int selectedNum; //will take the value of the last pressed button (1-9)
    
    @Override
    public void start(Stage primaryStage) {
        try {
            Group root = new Group();
            
            //setting up a stackpane that will contain a rect and text, making for a "cell"
            StackPane stack1 = new StackPane();
            Text text1 = new Text("");
            Rectangle rect1 = new Rectangle(50,50);
            rect1.setStyle("-fx-fill: white; -fx-stroke: black; -fx-stroke-width: 1;");
            stack1.getChildren().add(text1);
            stack1.getChildren().add(rect1);
            stack1.setLayoutX(100);
            stack1.setLayoutY(100);
            stack1.setOnMouseClicked(new EventHandler<MouseEvent>() { 
                @Override
                public void handle(MouseEvent t) {
                    text1.setText("" + selectedNum); //when clicked, set text to the number that is selected.
                }
            });
            
            //setting up the buttons that will designate which number will go into the cell.
            Button numButtons[] = new Button[9];
            for (int i = 0; i < 9; i++) {
                final int j = i;
                numButtons[i] = new Button("" + (i + 1));
                numButtons[i].setLayoutY((i / 3) * 55 + 200);
                numButtons[i].setLayoutX((i % 3) * 55 + 630);
                numButtons[i].setMinHeight(50);
                numButtons[i].setMinWidth(50);
                numButtons[i].setFont(Font.font(20));
                root.getChildren().add(numButtons[i]);

                numButtons[i].setOnAction(new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(ActionEvent arg0) {
                        selectedNum = j + 1;
                    }
                });
            }
            
            text1.toFront();
            root.getChildren().add(stack1);
            Scene scene = new Scene(root,900,500);
            primaryStage.setScene(scene);
            primaryStage.show();
            
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}

我还考虑过重写该函数以添加参数,但尚未使它成功工作。

詹姆斯·D

这种事情的(或多或少)标准方法是使用某种MVC设计模式的变体。这里的关键是要有一个单独的类(“模型”)来保存数据。然后,您可以将该类的单个实例传递给需要访问该类的任何参与者。

public class Model {

    private int currentlySelectedValue ;

    // probably other properties here...

    public void setCurrentlySelectedValue(int value) {
        currentlySelectedValue = value ;
    }

    public int getCurrentlySelectedValue() {
        return currentlySelectedValue ;
    }
}

然后,您可以执行以下操作:

public class Cell extends StackPane{

    private final Model model ;
    
    private Text text; //displays the number inside the cell
    private Rectangle rect; //visual element for the cell
    
    /**
     * Default Constructor for Cell
     */
    public Cell(Model model) {
        this.model = model ;
        text = new Text("");
        text.setFont(Font.font(30));
        rect = new Rectangle(50, 50);
        rect.setStyle("-fx-fill: white; -fx-stroke: black; -fx-stroke-width: 1;");
        this.getChildren().add(rect);
        this.getChildren().add(text);
        
        this.setOnMouseClicked(new EventHandler<MouseEvent>() { 
            @Override
            public void handle(MouseEvent t) {
                text.setText("" + model.getCurrentlySelectedValue()); 
            }
        });
    }
}

public class Main extends Application {
    
    private int selectedNum = 0;
    
    @Override
    public void start(Stage primaryStage) {

        Model model = new Model();

        try {
            
            Group root = new Group();
            Cell cell1 = new Cell(model);
            cell1.setLayoutX(100);
            cell1.setLayoutY(100);
            root.getChildren().add(cell1);
            
            Button numSelection[] = new Button[9];
            for (int i = 0; i < 9; i++) {
                final int j = i + 1; 
                numSelection[i] = new Button("" + j);
                numSelection[i].setLayoutY((i / 3) * 55 + 200);
                numSelection[i].setLayoutX((i % 3) * 55 + 630);
                numSelection[i].setMinHeight(50);
                numSelection[i].setMinWidth(50);
                numSelection[i].setFont(Font.font(20));
                root.getChildren().add(numSelection[i]);

                numSelection[i].setOnAction(new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(ActionEvent arg0) {
                        model.setCurrentlySelectedValue(j);
                    }
                });
            }
            
            Scene scene = new Scene(root,900,500);
            primaryStage.setScene(scene);
            primaryStage.show();
            
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}

请注意,如果您只需要一个值,则可以使用一些“捷径”方法。例如,您可以使用IntegerProperty而不是自定义模型类。结构和概念实际上是相同的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何获取对超出范围的变量在php中的访问权限?

来自分类Dev

变量如何超出范围?

来自分类Dev

访问变量时,“索引超出数组的范围”

来自分类Dev

访问超出范围的变量Swift

来自分类Dev

访问变量超出范围?节点js

来自分类Dev

如何解决超出范围的变量?

来自分类Dev

如何访问范围外的类?

来自分类Dev

如何在类范围之外访问变量定义的浏览按钮类

来自分类Dev

超出范围的变量

来自分类Dev

如何检查std :: vector超出范围访问

来自分类Dev

如何从父类访问变量

来自分类Dev

如何访问父类变量?

来自分类Dev

如何访问异常类变量?

来自分类Dev

如何引用超出范围的Spark广播变量

来自分类Dev

如何在Kotlin中修改超出其范围的变量?

来自分类Dev

如何使用超出其异步功能范围的变量

来自分类Dev

如何访问模型类中的类变量

来自分类Dev

如何访问范围之外的rust变量?

来自分类Dev

在调用类析构函数之前,Delphi类变量超出范围

来自分类Dev

函数范围超出类php

来自分类Dev

变量(可能)超出范围

来自分类Dev

从R6类访问包范围的变量

来自分类Dev

Lambda表达式可以访问超出其范围的类的私有方法吗?

来自分类Dev

将变量超出脚本范围,以便在控制台会话中访问

来自分类Dev

如何从父类访问子类变量

来自分类Dev

如何从父类访问子变量?

来自分类Dev

如何在Smalltalk中访问类变量

来自分类Dev

Python如何访问类函数变量

来自分类Dev

如何访问其他类中的变量