簡體   English   中英

JavaFX FXML控制器ClassNotFoundException

[英]JavaFX FXML controller ClassNotFoundException

我試圖在JavaFX中獲得TableView來動態顯示內容。

當我運行程序時,出現此錯誤:

java.lang.ClassNotFoundException: UserInterfaceController

我的控制器名為“ UserInterfaceController.java”,它與FXML文件位於同一軟件包下,我也已將該軟件包導入了FXML中。 為什么找不到控制器?

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>

控制器:

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的全限定名來引用您的控制器:

fx:controller="d1example2.UserInterfaceController"

后續問題的答案

對以下問題的回答解釋了為什么會這樣,但是您不必理解為什么不這樣做,以下純粹是參考信息。

為什么他有進口聲明時必須完全合格?

解決FXML控制器類時,不搜索FXML文件中的導入。 可以通過類加載器找到控制器的類類型(我通過閱讀JavaFX FXMLLoader源代碼確定了這一點)。 類加載器需要一個完全限定的名稱(根據Java語言規范,具體來說是一個二進制名稱 )。

一旦找到類型,如果沒有為fxml加載指定控制器工廠,則FXMLLoader將使用反射實例化控制器本身,否則它將將該作業委派給適當的控制器工廠(例如,與控制器實例關聯的控制器工廠)基於Spring依賴注入),但即使在這種情況下,也必須首先由FXMLLoader找到並確定適當的類型,然后才能為控制器要求完全限定的類名。

如果我仍然需要這樣做,導入語句有什么意義?

import語句用於解析與文檔中FXML元素相對應的Java類型 這樣,文檔可以包含以下行:

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

當您要在FXML中定義新的GridPane時,可以僅引用GridPane而不是javafx.scene.layout.GridPane。

<GridPane alignment="center" ...>

是的,可能,可以將FXMLLoader編碼為也以相同的方式解析控制器類,但是在編寫此答案時還沒有以這種方式編寫。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM