我使用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
答案 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();
}
}