简体   繁体   English

不能从静态上下文 JAVAFX 引用非静态方法

[英]Non-static method cannot be refered from a static context JAVAFX

So I'm trying to bind my Numpad keys so i can use them in my calculator app but when I try to send my keyEvent as a string from my MainWindow.java to my MainWindowController public void method it gives me the error "Non-static method cannot be refered from a static context" even though none of my classes are static?所以我试图绑定我的 Numpad 键,以便我可以在我的计算器应用程序中使用它们但是当我尝试将我的 keyEvent 作为字符串从 MainWindow.java 发送到我的 MainWindowController public void 方法时,它给了我错误“非静态方法不能从静态上下文中引用”,即使我的类都不是静态的? Here is the MainWindow code:这是主窗口代码:

package main`import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.paint.Color;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class MainWindow extends Application implements EventHandler<KeyEvent> {


private static Stage historyStage;

@Override
public void start(Stage stage) throws Exception {
    FXMLLoader loader = new FXMLLoader(getClass().getResource("MainWindowInterface.fxml"));
    Scene scene = new Scene(loader.load());
    scene.setFill(Color.TRANSPARENT);
    stage.setScene(scene);
    stage.initStyle(StageStyle.TRANSPARENT);
    stage.setResizable(false);
    stage.setTitle("Calculator");
    stage.getIcons().add(new Image(getClass().getResourceAsStream("../images/icon.png")));
    ((MainWindowController)loader.getController()).init(stage);
    stage.show();
    //scene.setOnKeyPressed(MainWindowController.handle());
    scene.setOnKeyPressed(this);
    scene.setOnKeyPressed(event -> {
        if (event.getCode() == KeyCode.ESCAPE){
            stage.close();
        }
    });
    createHistoryStage();
}

public void createHistoryStage() throws Exception{
    historyStage = new Stage();
    historyStage.initStyle(StageStyle.TRANSPARENT);
    historyStage.setTitle("Calculator History");
    historyStage.setAlwaysOnTop(true);
    historyStage.setResizable(false);
    historyStage.getIcons().add(new Image(getClass().getResourceAsStream("../images/icon.png")));
    historyStage.initModality(Modality.APPLICATION_MODAL);
}

public static Stage getHistoryStage(){
    return historyStage;
}

public void run() {
    launch();
}

@Override
public void handle(KeyEvent event) {
    String valueOfKey = String.valueOf(event.getCode());
    MainWindowController.keyPress(valueOfKey);
}

} }

and here is the MainWindowController file (look at keyPress method)这是 MainWindowController 文件(查看 keyPress 方法)

    package main`import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import java.io.IOException;
import java.util.ArrayList;`;



public class MainWindowController {
    @FXML private Pane titlePane;
    @FXML private ImageView btnMinimize, btnClose;
    @FXML private Label lblResult;

    private double x, y;
    private double num1 = 0;
    private String operator = "+";

    private ArrayList<String> calculation_history = new ArrayList<>();

    public void init(Stage stage) {
        titlePane.setOnMousePressed(mouseEvent -> {
            x = mouseEvent.getSceneX();
            y = mouseEvent.getSceneY();
        });
        titlePane.setOnMouseDragged(mouseEvent -> {
            stage.setX(mouseEvent.getScreenX()-x);
            stage.setY(mouseEvent.getScreenY()-y);
        });

        btnClose.setOnMouseClicked(mouseEvent -> stage.close());
        btnMinimize.setOnMouseClicked(mouseEvent -> stage.setIconified(true));
    }

    public void openHistoryWindow(){
        try{
            FXMLLoader loader2 = new FXMLLoader(getClass().getResource("history.fxml"));
            Parent root = loader2.load();
            Scene historyScene = new Scene(root);
            historyScene.setFill(Color.TRANSPARENT);
            MainWindow.getHistoryStage().setScene(historyScene);

            HistoryController historyController = loader2.getController();
            historyController.initializeCalculations(calculation_history);
            ((HistoryController)loader2.getController()).init(MainWindow.getHistoryStage());

            MainWindow.getHistoryStage().show();
            historyScene.setOnKeyPressed(event -> {
                if (event.getCode() == KeyCode.ESCAPE){
                    MainWindow.getHistoryStage().close();
                }
            });
        }catch (IOException ex){
            System.out.println(ex);
        }
    }

    public void addCalculation(String num1, String operator, String num2, String result){
        String expression = num1 + " " + operator + " " + num2;
        this.calculation_history.add(expression + " = " + result);
    }

    @FXML
    void onNumberClicked(MouseEvent event) {
        int value = Integer.parseInt(((Pane)event.getSource()).getId().replace("btn",""));
        lblResult.setText(Double.parseDouble(lblResult.getText())==0?String.valueOf((double)value):String.valueOf(Double.parseDouble(lblResult.getText())*10+value));
    }



    public void keyPress(String keyPressed){

        int value = 0;
        switch (keyPressed){
            case "NUMPAD1": value = 1;
                lblResult.setText(Double.parseDouble(lblResult.getText())==0?String.valueOf((double)value):String.valueOf(Double.parseDouble(lblResult.getText())*10+value));
                break;
            case "NUMPAD2": value = 2;
                lblResult.setText(Double.parseDouble(lblResult.getText())==0?String.valueOf((double)value):String.valueOf(Double.parseDouble(lblResult.getText())*10+value));
                break;
            case "NUMPAD3": value = 3;
                lblResult.setText(Double.parseDouble(lblResult.getText())==0?String.valueOf((double)value):String.valueOf(Double.parseDouble(lblResult.getText())*10+value));
                break;
            case "NUMPAD4": value = 4;
                lblResult.setText(Double.parseDouble(lblResult.getText())==0?String.valueOf((double)value):String.valueOf(Double.parseDouble(lblResult.getText())*10+value));
                break;
            case "NUMPAD5": value = 5;
                lblResult.setText(Double.parseDouble(lblResult.getText())==0?String.valueOf((double)value):String.valueOf(Double.parseDouble(lblResult.getText())*10+value));
                break;
            case "NUMPAD6": value = 6;
                lblResult.setText(Double.parseDouble(lblResult.getText())==0?String.valueOf((double)value):String.valueOf(Double.parseDouble(lblResult.getText())*10+value));
                break;
            case "NUMPAD7": value = 7;
                lblResult.setText(Double.parseDouble(lblResult.getText())==0?String.valueOf((double)value):String.valueOf(Double.parseDouble(lblResult.getText())*10+value));
                break;
            case "NUMPAD8": value = 8;
                lblResult.setText(Double.parseDouble(lblResult.getText())==0?String.valueOf((double)value):String.valueOf(Double.parseDouble(lblResult.getText())*10+value));
                break;
            case "NUMPAD9": value = 9;
                lblResult.setText(Double.parseDouble(lblResult.getText())==0?String.valueOf((double)value):String.valueOf(Double.parseDouble(lblResult.getText())*10+value));
                break;
            case "NUMPAD0": value = 0;
                lblResult.setText(Double.parseDouble(lblResult.getText())==0?String.valueOf((double)value):String.valueOf(Double.parseDouble(lblResult.getText())*10+value));
                break;
            default: break;
        }
    }

    @FXML
    void onSymbolClicked(MouseEvent event) {
        String symbol = ((Pane)event.getSource()).getId().replace("btn","");
        if(symbol.equals("Equals")) {
            double num2 = Double.parseDouble(lblResult.getText());
            switch (operator) {
                case "+" -> lblResult.setText((num1+num2) + "");
                case "-" -> lblResult.setText((num1-num2) + "");
                case "*" -> lblResult.setText((num1*num2) + "");
                case "/" -> lblResult.setText((num1/num2) + "");
            }
            addCalculation(String.valueOf(num1), operator, String.valueOf(num2), lblResult.getText());
            operator = ".";
        }
        else if(symbol.equals("Clear")) {
            lblResult.setText(String.valueOf(0.0));
            operator = ".";
        }
        else if(symbol.equals("HIST")){
            openHistoryWindow();
        }
        else {
            switch (symbol) {
                case "Plus" -> operator = "+";
                case "Minus" -> operator = "-";
                case "Multiply" -> operator = "*";
                case "Divide" -> operator = "/";
            }
            num1 = Double.parseDouble(lblResult.getText());
            lblResult.setText(String.valueOf(0.0));
        }
    }
}

This addresses the immediate question;这解决了直接的问题; there are other issues with your code which are too numerous to deal with.您的代码还有其他问题太多而无法处理。

The error message tells you the problem: keyPress(...) is an instance ("non-static") method, and you are trying to access it as though it is a static method (ie via the class name).错误消息告诉您问题: keyPress(...)是一个实例(“非静态”)方法,而您正试图访问它,就好像它是一个静态方法一样(即通过类名)。

Note that keyPress(...) accesses instance variables, so you cannot make it static.请注意, keyPress(...)访问实例变量,因此您不能将其设为静态。 Your only option is to access the method through the controller instance.您唯一的选择是通过控制器实例访问该方法。 Since you already retrieve that instance via loader.getController() , this is straightforward;由于您已经通过loader.getController()检索了该实例,因此这很简单; just save it to an instance variable:只需将其保存到实例变量中:

public class MainWindow extends Application implements EventHandler<KeyEvent> {


    private static Stage historyStage;

    private MainWindowController controller ;
    
    @Override
    public void start(Stage stage) throws Exception {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("MainWindowInterface.fxml"));
        Scene scene = new Scene(loader.load());
        scene.setFill(Color.TRANSPARENT);
        stage.setScene(scene);
        stage.initStyle(StageStyle.TRANSPARENT);
        stage.setResizable(false);
        stage.setTitle("Calculator");
        stage.getIcons().add(new Image(getClass().getResourceAsStream("../images/icon.png")));

        controller = loader.getController();
        controller.init(stage);

        stage.show();
        //scene.setOnKeyPressed(MainWindowController.handle());
        scene.setOnKeyPressed(this);

        // this will replace the handler from the previous line,
        // so is probably not what you want to do
        scene.setOnKeyPressed(event -> {
            if (event.getCode() == KeyCode.ESCAPE){
                stage.close();
            }
        });
        createHistoryStage();
    }

    // ...

    @Override
    public void handle(KeyEvent event) {
        String valueOfKey = String.valueOf(event.getCode());
        controller.keyPress(valueOfKey);
    }

}

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

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