首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何访问超出类范围的变量?

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

Stack Overflow用户
提问于 2020-12-16 15:09:30
回答 1查看 295关注 0票数 0

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

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

代码的工作方式是,当单击按钮时,对应于该按钮的int被分配给selectedNum。当单击单元格时,单元格将其文本分配给selectedNum。但是,在实现setOnAction构造函数内的Cell函数时,问题就发生在这里。Cell无法访问selectedNum。当selectedNum是其类的作用域之外的变量时,如何传递它?

单元类:

代码语言:javascript
复制
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.
            }
        });
    }
}

主类

代码语言:javascript
复制
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类,因为它可以生成更有组织的代码。不管怎么说,这就是:

代码语言:javascript
复制
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);
    }
}

我还考虑过重写函数来添加一个参数,但是还没有成功地完成这个任务。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-12-16 16:37:24

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

代码语言:javascript
复制
public class Model {

    private int currentlySelectedValue ;

    // probably other properties here...

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

    public int getCurrentlySelectedValue() {
        return currentlySelectedValue ;
    }
}

然后你就可以:

代码语言:javascript
复制
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()); 
            }
        });
    }
}

代码语言:javascript
复制
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而不是自定义模型类。但结构和概念实际上是一样的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65325955

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档