简体   繁体   English

如果我无法从内部 class 访问非最终变量,你如何在 Java 中进行“计数器”计数?

[英]How do you make a "counter" count in Java if I can't access a non-final variable from the inner class?

I'm working on a small coding exercise for my course but I can't seem to overcome an issue I'm having with it.我正在为我的课程做一个小的编码练习,但我似乎无法克服我遇到的问题。 I want to count everytime someone clicks a button, but I can't create a variable to store the information because I have to create the variable outside the event handler so it doesn't reset to 0 everytime the button is pressed.我想在每次有人单击按钮时进行计数,但我无法创建变量来存储信息,因为我必须在事件处理程序外部创建变量,这样每次按下按钮时它都不会重置为 0。

However, whenever I create a variable outside the event handler and try to add onto it by 1, it says it cannot be accessed from within the inner class.但是,每当我在事件处理程序外部创建一个变量并尝试将其加 1 时,它就会说无法从内部 class 访问它。

public class HelloApplication extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Counter Application");
        Label label = new Label("Counter");
        Button btn = new Button();
        btn.setText("Count");
         int count = 0;

        btn.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                count++;
            }
        });

        StackPane root = new StackPane();
        root.getChildren().add(btn);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }
}

You can make it an instance variable in the event handler:您可以在事件处理程序中将其设为实例变量:

public class HelloApplication extends Application {
    public static void main(String[] args) {
        launch(args);
    }
    
    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Counter Application");
        Label label = new Label("Counter");
        Button btn = new Button();
        btn.setText("Count");

        btn.setOnAction(new EventHandler<ActionEvent>() {

            private int count = 0 ;

            @Override
            public void handle(ActionEvent event) {
                count++;
            }
        });

        StackPane root = new StackPane();
        root.getChildren().add(btn);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }
}

Or you can make the counter an instance variable in the surrounding class:或者你可以让计数器成为 class 周围的一个实例变量:

public class HelloApplication extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    private int count = 0 ;
    
    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Counter Application");
        Label label = new Label("Counter");
        Button btn = new Button();
        btn.setText("Count");

        btn.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                count++;
            }
        });

        StackPane root = new StackPane();
        root.getChildren().add(btn);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }
}

Or you can define a wrapper class holding a mutable int:或者您可以定义一个包含可变 int 的包装器 class:

public class HelloApplication extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    
    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Counter Application");
        Label label = new Label("Counter");
        Button btn = new Button();
        btn.setText("Count");

        class IntWrapper {
            private int x = 0 ;
            public int getX() {
                return x;
            }
            public void increment() {
                x++;
            }
        }

        IntWrapper count = new IntWrapper();

        btn.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                count.increment();
            }
        });

        StackPane root = new StackPane();
        root.getChildren().add(btn);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }
}

The last two options let you implement the event handler as a lambda expression最后两个选项让您将事件处理程序实现为 lambda 表达式

btn.setOnAction(event -> count.increment());

while the first doesn't let you do this.而第一个不允许你这样做。

Make count a member of class HelloApplication and use a method reference . count class HelloApplication的成员并使用方法引用

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class HelloApplication extends Application {
    private int  count;

    public static void main(String[] args) {
        launch(args);
    }
    
    @Override public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("Counter Application");
        Label label = new Label("Counter");
        Button btn = new Button();
        btn.setText("Count");
        btn.setOnAction(this::buttonClickCounter);
        StackPane root = new StackPane();
        root.getChildren().add(btn);
        primaryStage.setScene(new Scene(root, 300, 250));
        primaryStage.show();
    }

    private void buttonClickCounter(ActionEvent event) {
        count++;
    }
}

As you can see, you can name the method anything you like and give it any access modifier you like.如您所见,您可以为该方法命名任何您喜欢的名称,并给它任何您喜欢的访问修饰符。 Just make sure it returns the same value and accepts the same parameters as method handle in interface EventHandler .只需确保它返回相同的值并接受与接口EventHandler中的方法handle相同的参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM