JavaFX FXML Controller ClassNotFoundException

标签 java uitableview dynamic javafx

我正在尝试在 JavaFX 中获取 TableView 以动态显示内容。

当我运行我的程序时出现这个错误:

java.lang.ClassNotFoundException: UserInterfaceController

我的 Controller 名为“UserInterfaceController.java”,它与 FXML 文件位于同一包下,我也已将包导入到 FXML 中。为什么找不到 Controller ?

FXML 文件:

<?import javafx.collections.*?> 
<?import javafx.geometry.Insets?>
<?import java.lang.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.cell.*?>
<?import javafx.scene.layout.*?>
<?import d1example2.*?>

<GridPane alignment="center" hgap="10.0" vgap="10.0" fx:controller="UserInterfaceController"
             xmlns:fx="http://javafx.com/fxml">
     <TableView fx:id="tableView" GridPane.columnIndex="0" GridPane.rowIndex="1">
          <columns>
          </columns>    
     </TableView>
</GridPane>

Controller :

package d1example2;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.text.Text;
import javafx.util.Callback;

public class UserInterfaceController implements Initializable {

    private Label label;
    @FXML
    private AnchorPane MainPane;
    @FXML
    private TextField FirstField;
    @FXML
    private Text TimesText;
    @FXML
    private Text EqualSign;
    @FXML
    private Text EquationResult;
    @FXML
    private TableColumn<?, ?> HalfColumn;
    @FXML
    private TableColumn<?, ?> DoubleColumn;
    @FXML
    private Button SubmitButton;

    @FXML private TableView tableView;

    @FXML
    public void initialize(URL url, ResourceBundle rb) {

    List<String> columns = new ArrayList<String>();
    columns.add("col1");
    columns.add("col2");
    TableColumn [] tableColumns = new TableColumn[columns.size()];     
    int columnIndex = 0;
    for(int i=0 ; i<columns.size(); i++) {
        final int j = i;
        TableColumn col = new TableColumn(columns.get(i));
        col.setCellValueFactory(new Callback<CellDataFeatures<ObservableList,String>,ObservableValue<String>>(){                   
           public ObservableValue<String> call(CellDataFeatures<ObservableList, String> param) {                                                                                             
                return new SimpleStringProperty(param.getValue().get(j).toString());                       
            }                   
        });
        tableView.getColumns().addAll(col);
    }       
    ObservableList<String> row = FXCollections.observableArrayList();
    ObservableList<String> row1 = FXCollections.observableArrayList();
    row.addAll("d1");
    row.addAll("d11");
    row1.addAll("d2");
    row1.addAll("d22");
    tableView.getItems().add(row);
    tableView.getItems().add(row1);
    }    

    @FXML
    private void handleButtonAction(MouseEvent event) {

    }

}

主类:

package d1example2;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class D1Example2 extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        primaryStage.setTitle("FXML TableView Example");
        Pane myPane = (Pane)FXMLLoader.load(getClass().getResource("UserInterface.fxml"));
        Scene myScene = new Scene(myPane);
        primaryStage.setScene(myScene);
        primaryStage.show();
    }

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

最佳答案

使用完全限定名称从 FXML 引用您的 Controller :

fx:controller="d1example2.UserInterfaceController"

后续问题的答案

以下问题的答案解释了为什么会这样,但如果您不想了解,则不一定需要了解原因,以下内容仅供引用。

Why must it be fully qualified when he has an import statement?

解析 FXML Controller 类时不搜索 FXML 文件中的导入。 Controller 类类型是通过类加载器找到的(我通过阅读 JavaFX FXMLLoader source code 确定了这一点)。类加载器需要一个完全限定的名称(具体来说,根据 Java 语言规范为 binary name)。

一旦找到类型,如果没有为 fxml 加载指定 Controller 工厂,则 FXMLLoader 将使用反射实例化 Controller 本身,否则它将将该工作委托(delegate)给适当的 Controller 工厂(例如,关联的 Controller 工厂)基于 Spring 依赖注入(inject)的 Controller 实例),但即使在该实例中,也必须首先由 FXMLLoader 找到并确定适当的类型,为此它需要 Controller 的完全限定类名。

What's the point of import statements if I need to do that anyway?

导入语句用于 resolving the Java types对应于文档中的 FXML 元素。这样,文档可以包含以下行:

<?import javafx.scene.layout.*?>

当您想在 FXML 中定义新的 GridPane 时,您可以只引用 GridPane 而不是 javafx.scene.layout.GridPane。

<GridPane alignment="center" ...>

是的,FXMLLoader 可能已经被编码为也以相同的方式解析 Controller 类,但在编写此答案时还没有那样写。

关于JavaFX FXML Controller ClassNotFoundException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20452035/

相关文章:

c# - 更新泛型类的泛型属性?

java - 为什么 javac 会为两个看似非常相似的结构生成不同的字节码?

java - JSF - 无法显示来自 ManagedBean 的对象列表

ios - 表未在另一个 TabBar ViewController 中重新加载

c# - Lambda - C# - 动态表达式,使用 string.IsNullOrEmpty

c# - DynamicObject 和 TrySetMember 性能与 ExpandoObject 性能

java - Spring Boot 2.0.0 循环 bean 依赖 EntityManger 和 SessionFactory

java - 带有 BigDecimal 的 JEP 库

ios - UITableViewCell 子类或原型(prototype)单元格

ios - TableView 重新加载数据后 TableView 单元格布局不正确