无法运行我的JavaFX程序 - 引起:java.lang.RuntimeException

时间:2016-06-04 20:26:44

标签: java javafx

我使用eclipse编写了一个简单的JavaFX程序。但我不会跑。

我尝试运行时收到此"Caused by: java.lang.RuntimeException: Unable to construct Application instance: class Account"

我检查了所有在线提供的类似问题。但我还是无法解决它。我认为我的代码应该是正确的。

这是我的代码:

account.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import java.net.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>

<GridPane xmlns:fx="http://javafx.com/fxml" 
    fx:controller="AccountController"    
    alignment="center" hgap="10" vgap="10" 
    styleClass="root">

<Text styleClass="heading" text="${'Account: ' + controller.account.name}" GridPane.columnIndex="0" GridPane.rowIndex="0" GridPane.columnSpan="2"/>
<Label text="Name:" GridPane.columnIndex="0" GridPane.rowIndex="1"/>
<TextField fx:id="nameTf" styleClass="field" GridPane.columnIndex="1" GridPane.rowIndex="1"/>
<Label text="Balance:" GridPane.columnIndex="0" GridPane.rowIndex="2"/>
<TextField fx:id="balanceTf" text="${controller.account.balance}" styleClass="field" GridPane.columnIndex="1" GridPane.rowIndex="2"/>
<HBox alignment="center" spacing="10" GridPane.columnIndex="0" GridPane.rowIndex="3" GridPane.columnSpan="2">
    <Label text="\$"/>
    <TextField text="0.00" fx:id="amountTf"/>
    <Button text="Deposit" onAction="#handleDeposit"/>
    <Button text="Withdraw" onAction="#handleWithdraw"/>
</HBox>

<stylesheets><URL value="@style.css"/></stylesheets>

</GridPane>

Account.java

import javafx.beans.property.*;
import javafx.application.*;
import javafx.fxml.*;
import javafx.stage.*;
import javafx.scene.*;

public class Account extends Application{
public static void main(String[] args) 
{ 
    launch(args);
}
private StringProperty name = new SimpleStringProperty();
private DoubleProperty balance = new SimpleDoubleProperty();

public Account(String name) {
    this.name.set(name);
    this.balance.set(0.0);
}

public void deposit(double amount) {
    setBalance(getBalance() + amount);
}

public void withdraw(double amount) {
    setBalance(getBalance() - amount);
}

public final double getBalance() {
    return balance.get();
}

private final void setBalance(double value) {
    this.balance.set(value);
}

public ReadOnlyDoubleProperty balanceProperty() {
    return balance;
}

public final String getName() {
    return name.get();
}

public final void setName(String name) {
    this.name.set(name);
}

public StringProperty nameProperty() {
    return name;
}

@Override
public void start(Stage stage) throws Exception {
    // TODO Auto-generated method stub
    FXMLLoader loader = new FXMLLoader(getClass().getResource("account.fxml"));
    Parent root = loader.load();
    stage.setTitle("Account");
    stage.setScene(new Scene(root));
    stage.sizeToScene();
    stage.show();
}
}

AccountController.java

import javafx.collections.*;
import javafx.event.*;
import javafx.fxml.*;
import javafx.scene.text.*;
import javafx.scene.control.*;
import javafx.stage.*;
import javafx.beans.binding.*;
import javafx.beans.property.*;
import java.io.*;
import java.text.*;

public class AccountController {
private Account account = new Account("Mr Smith");
@FXML private TextField nameTf;
@FXML private TextField amountTf;
// @FXML private TextField balanceTf;

public final Account getAccount() { return account; }

@FXML private void initialize() {
    nameTf.textProperty().bindBidirectional(getAccount().nameProperty());
    // balanceTf.textProperty().bind(getAccount().balanceProperty());
}

@FXML private void handleDeposit(ActionEvent event) {
    getAccount().deposit(getAmount());
    setAmount(0);
}

@FXML private void handleWithdraw(ActionEvent event) {
    getAccount().withdraw(getAmount());
    setAmount(0);
}

private String getName()
{
    return nameTf.getText();
}

/*
private double getBalance()
{
    return Double.parseDouble(balanceTf.getText());
} */

private double getAmount() {
    return Double.parseDouble(amountTf.getText());
}

private void setAmount(double value) {
    amountTf.setText(new DecimalFormat("###,##0.00").format(value));
}
}

错误:

Exception in Application constructor

java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
    at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Unable to construct Application instance: class Account
    at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:907)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$152(LauncherImpl.java:182)
    at com.sun.javafx.application.LauncherImpl$$Lambda$51/164599   5473.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NoSuchMethodException: Account.<init>()
    at java.lang.Class.getConstructor0(Class.java:3082)
    at java.lang.Class.getConstructor(Class.java:1825)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$158(LauncherImpl.java:818)
    at com.sun.javafx.application.LauncherImpl$$Lambda$52/973703074.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$172(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl$$Lambda$47/186276003.run(Unknown Source)
    at com.sun.javafx.application.PlatformImpl.lambda$null$170(PlatformImpl.java:295)
    at com.sun.javafx.application.PlatformImpl$$Lambda$49/1714838540.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$171(PlatformImpl.java:294)
    at com.sun.javafx.application.PlatformImpl$$Lambda$48/237061348.run(Unknown Source)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Exception running application Account

1 个答案:

答案 0 :(得分:2)

调用Application.launch(...)会导致创建Application子类的实例,启动FX Application工具包,并在创建的实例上调用start()

这个Application实例是通过调用无参数构造函数创建的,因此你的Application子类Account需要定义一个:

public Account() {
    this("");
}

您的Account类实际上做了两件完全不同的事情:它充当Application实例,也充当帐户的数据模型(封装名称和余额)。你应该把它分成两个类,每个类都有自己的责任:

import javafx.beans.property.*;

public class Account {


    private StringProperty name = new SimpleStringProperty();
    private DoubleProperty balance = new SimpleDoubleProperty();

    public Account(String name) {
        this.name.set(name);
        this.balance.set(0.0);
    }

    public void deposit(double amount) {
        setBalance(getBalance() + amount);
    }

    public void withdraw(double amount) {
        setBalance(getBalance() - amount);
    }

    public final double getBalance() {
        return balance.get();
    }

    private final void setBalance(double value) {
        this.balance.set(value);
    }

    public ReadOnlyDoubleProperty balanceProperty() {
        return balance;
    }

    public final String getName() {
        return name.get();
    }

    public final void setName(String name) {
        this.name.set(name);
    }

    public StringProperty nameProperty() {
        return name;
    }

}

然后

import javafx.application.*;
import javafx.fxml.*;
import javafx.stage.*;
import javafx.scene.*;


public class AccountApp extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        // TODO Auto-generated method stub
        FXMLLoader loader = new FXMLLoader(getClass().getResource("account.fxml"));
        Parent root = loader.load();
        stage.setTitle("Account");
        stage.setScene(new Scene(root));
        stage.sizeToScene();
        stage.show();
    }

}