Javafx.fxml加载程序终止
我找不到如何修复以下消息的解决方案:Javafx.fxml加载程序终止,java,eclipse,javafx,scenebuilder,Java,Eclipse,Javafx,Scenebuilder,我找不到如何修复以下消息的解决方案: javafx.fxml.LoadException: /Users/stefanhegetschweiler/Downloads/AddressApp-Part-7-2/bin/ch/makery/address/view/PersonOverview.fxml:36 at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2617) at javafx.fxml.FXMLLo
javafx.fxml.LoadException:
/Users/stefanhegetschweiler/Downloads/AddressApp-Part-7-2/bin/ch/makery/address/view/PersonOverview.fxml:36
at javafx.fxml.FXMLLoader.constructLoadException(FXMLLoader.java:2617)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2595)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441)
at javafx.fxml.FXMLLoader.load(FXMLLoader.java:2409)
at ch.makery.address.MainApp.showPersonOverview(MainApp.java:123)
at ch.makery.address.MainApp.start(MainApp.java:81)
at com.sun.javafx.application.LauncherImpl$8.run(LauncherImpl.java:837)
at com.sun.javafx.application.PlatformImpl$7.run(PlatformImpl.java:335)
at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:301)
at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:298)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$6.run(PlatformImpl.java:298)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Caused by: java.lang.IllegalArgumentException: Can not set ch.makery.address.MainApp field ch.makery.address.view.PersonOverviewController.mainApp to javafx.scene.control.Button
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:171)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81)
at java.lang.reflect.Field.set(Field.java:758)
at javafx.fxml.FXMLLoader$ValueElement.processValue(FXMLLoader.java:857)
at javafx.fxml.FXMLLoader$ValueElement.processStartElement(FXMLLoader.java:745)
at javafx.fxml.FXMLLoader.processStartElement(FXMLLoader.java:2723)
at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2527)
... 11 more
下面您可以看到控制器的代码。目前,该应用程序没有显示
人员概述和所有其他主要功能,如编辑、删除和新建按钮
你需要向我们展示你的代码在上面你可以看到主应用还是我应该展示一些特定的东西?PersonOverview.fxml和控制器会很有帮助。同时删除不相关的部分肯定不会出错,请看。FXMLLoader似乎正在尝试为应该保存MainApp的字段分配一个按钮。显示FXML以及至少与mainApp属性相关的控制器部分会有所帮助。顺便说一句,一个控制器引用了使用它的应用程序代码,这通常是一个糟糕的设计。感谢您提示一个按钮试图分配给MainApp,表视图被错误地链接到它。所以现在它起作用了。非常感谢你的评论!
public class MainApp extends Application {
private Stage primaryStage;
private BorderPane rootLayout;
/**
* The data as an observable list of Persons.
*/
private ObservableList<Person> personData = FXCollections.observableArrayList();
/**
* Constructor
*/
public MainApp() {
// Add some sample data
personData.add(new Person("Hans", "Muster"));
personData.add(new Person("Ruth", "Mueller"));
personData.add(new Person("Heinz", "Kurz"));
personData.add(new Person("Cornelia", "Meier"));
personData.add(new Person("Werner", "Meyer"));
personData.add(new Person("Lydia", "Kunz"));
personData.add(new Person("Anna", "Best"));
personData.add(new Person("Stefan", "Meier"));
personData.add(new Person("Martin", "Mueller"));
}
@Override
public void start(Stage primaryStage) {
this.primaryStage = primaryStage;
this.primaryStage.setTitle("AddressApp");
// Set the application icon.
this.primaryStage.getIcons().add(
new Image("file:resources/images/address_book_32.png"));
initRootLayout();
showPersonOverview();
}
/**
* Initializes the root layout and tries to load the last opened
* person file.
*/
public void initRootLayout() {
try {
// Load root layout from fxml file.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("view/RootLayout.fxml"));
rootLayout = (BorderPane) loader.load();
// Show the scene containing the root layout.
Scene scene = new Scene(rootLayout);
primaryStage.setScene(scene);
// Give the controller access to the main app.
RootLayoutController controller = loader.getController();
controller.setMainApp(this);
primaryStage.show();
} catch (IOException e) {
e.printStackTrace();
}
// Try to load last opened person file.
File file = getPersonFilePath();
if (file != null) {
loadPersonDataFromFile(file);
}
}
/**
* Shows the person overview inside the root layout.
*/
public void showPersonOverview() {
try {
// Load person overview.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("view/PersonOverview.fxml"));
AnchorPane personOverview = (AnchorPane) loader.load();
// Set person overview into the center of root layout.
rootLayout.setCenter(personOverview);
// Give the controller access to the main app.
PersonOverviewController controller = loader.getController();
controller.setMainApp(this);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Opens a dialog to edit details for the specified person. If the user
* clicks OK, the changes are saved into the provided person object and true
* is returned.
*
* @param person
* the person object to be edited
* @return true if the user clicked OK, false otherwise.
*/
public boolean showPersonEditDialog(Person person) {
try {
// Load the fxml file and create a new stage for the popup dialog.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("view/PersonEditDialog.fxml"));
AnchorPane page = (AnchorPane) loader.load();
// Create the dialog Stage.
Stage dialogStage = new Stage();
dialogStage.setTitle("Edit Person");
dialogStage.initModality(Modality.WINDOW_MODAL);
dialogStage.initOwner(primaryStage);
dialogStage.getIcons().add(new Image("file:resources/images/edit.png"));
Scene scene = new Scene(page);
dialogStage.setScene(scene);
// Set the person into the controller.
PersonEditDialogController controller = loader.getController();
controller.setDialogStage(dialogStage);
controller.setPerson(person);
// Show the dialog and wait until the user closes it
dialogStage.showAndWait();
return controller.isOkClicked();
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
/**
* Opens a dialog to show birthday statistics.
*/
public void showBirthdayStatistics() {
try {
// Load the fxml file and create a new stage for the popup.
FXMLLoader loader = new FXMLLoader();
loader.setLocation(MainApp.class.getResource("view/BirthdayStatistics.fxml"));
AnchorPane page = (AnchorPane) loader.load();
Stage dialogStage = new Stage();
dialogStage.setTitle("Birthday Statistics");
dialogStage.initModality(Modality.WINDOW_MODAL);
dialogStage.initOwner(primaryStage);
dialogStage.getIcons().add(new Image("file:resources/images/calendar.png"));
Scene scene = new Scene(page);
dialogStage.setScene(scene);
// Set the persons into the controller.
BirthdayStatisticsController controller = loader.getController();
controller.setPersonData(personData);
dialogStage.show();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Returns the person file preference, i.e. the file that was last opened.
* The preference is read from the OS specific registry. If no such
* preference can be found, null is returned.
*
* @return
*/
public File getPersonFilePath() {
Preferences prefs = Preferences.userNodeForPackage(MainApp.class);
String filePath = prefs.get("filePath", null);
if (filePath != null) {
return new File(filePath);
} else {
return null;
}
}
/**
* Sets the file path of the currently loaded file. The path is persisted in
* the OS specific registry.
*
* @param file the file or null to remove the path
*/
public void setPersonFilePath(File file) {
Preferences prefs = Preferences.userNodeForPackage(MainApp.class);
if (file != null) {
prefs.put("filePath", file.getPath());
// Update the stage title.
primaryStage.setTitle("AddressApp - " + file.getName());
} else {
prefs.remove("filePath");
// Update the stage title.
primaryStage.setTitle("AddressApp");
}
}
/**
* Loads person data from the specified file. The current person data will
* be replaced.
*
* @param file
*/
public void loadPersonDataFromFile(File file) {
try {
JAXBContext context = JAXBContext
.newInstance(PersonListWrapper.class);
Unmarshaller um = context.createUnmarshaller();
// Reading XML from the file and unmarshalling.
PersonListWrapper wrapper = (PersonListWrapper) um.unmarshal(file);
personData.clear();
personData.addAll(wrapper.getPersons());
// Save the file path to the registry.
setPersonFilePath(file);
} catch (Exception e) { // catches ANY exception
Dialogs.create()
.title("Error")
.masthead("Could not load data from file:\n" + file.getPath())
.showException(e);
}
}
/**
* Saves the current person data to the specified file.
*
* @param file
*/
public void savePersonDataToFile(File file) {
try {
JAXBContext context = JAXBContext
.newInstance(PersonListWrapper.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
// Wrapping our person data.
PersonListWrapper wrapper = new PersonListWrapper();
wrapper.setPersons(personData);
// Marshalling and saving XML to the file.
m.marshal(wrapper, file);
// Save the file path to the registry.
setPersonFilePath(file);
} catch (Exception e) { // catches ANY exception
Dialogs.create().title("Error")
.masthead("Could not save data to file:\n" + file.getPath())
.showException(e);
}
}
/**
* Returns the main stage.
*
* @return
*/
public Stage getPrimaryStage() {
return primaryStage;
}
/**
* Returns the data as an observable list of Persons.
*
* @return
*/
public ObservableList<Person> getPersonData() {
return personData;
}
public static void main(String[] args) {
launch(args);
}
}
package ch.makery.address.view;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import org.controlsfx.dialog.Dialogs;
import ch.makery.address.MainApp;
import ch.makery.address.model.Person;
public class PersonOverviewController {
@FXML
private TableView<Person> personTable;
@FXML
private TableColumn<Person, String> firstNameColumn;
@FXML
private TableColumn<Person, String> lastNameColumn;
@FXML
private Label firstNameLabel;
@FXML
private Label lastNameLabel;
@FXML
// Reference to the main application.
private MainApp mainApp;
/**
* The constructor.
* The constructor is called before the initialize() method.
*/
public PersonOverviewController() {
}
/**
* Initializes the controller class. This method is automatically called
* after the fxml file has been loaded.
*/
@FXML
private void initialize() {
// Initialize the person table with the two columns.
firstNameColumn.setCellValueFactory(
cellData -> cellData.getValue().firstNameProperty());
lastNameColumn.setCellValueFactory(
cellData -> cellData.getValue().lastNameProperty());
// Clear person details.
showPersonDetails(null);
// Listen for selection changes and show the person details when changed.
personTable.getSelectionModel().selectedItemProperty().addListener(
(observable, oldValue, newValue) -> showPersonDetails(newValue));
}
/**
* Is called by the main application to give a reference back to itself.
*
* @param mainApp
*/
public void setMainApp(MainApp mainApp) {
this.mainApp = mainApp;
// Add observable list data to the table
personTable.setItems(mainApp.getPersonData());
}
/**
* Fills all text fields to show details about the person.
* If the specified person is null, all text fields are cleared.
*
* @param person the person or null
*/
private void showPersonDetails(Person person) {
if (person != null) {
// Fill the labels with info from the person object.
firstNameLabel.setText(person.getFirstName());
lastNameLabel.setText(person.getSecondEnglish());
} else {
// Person is null, remove all the text.
firstNameLabel.setText("");
lastNameLabel.setText("");
}
}
/**
* Called when the user clicks on the delete button.
*/
@FXML
private void handleDeletePerson() {
int selectedIndex = personTable.getSelectionModel().getSelectedIndex();
if (selectedIndex >= 0) {
personTable.getItems().remove(selectedIndex);
} else {
// Nothing selected.
Dialogs.create()
.title("No Selection")
.masthead("No Person Selected")
.message("Please select a person in the table.")
.showWarning();
}
}
/**
* Called when the user clicks the new button. Opens a dialog to edit
* details for a new person.
*/
@FXML
private void handleNewPerson() {
Person tempPerson = new Person();
boolean okClicked = mainApp.showPersonEditDialog(tempPerson);
if (okClicked) {
mainApp.getPersonData().add(tempPerson);
}
}
/**
* Called when the user clicks the edit button. Opens a dialog to edit
* details for the selected person.
*/
@FXML
private void handleEditPerson() {
Person selectedPerson = personTable.getSelectionModel().getSelectedItem();
if (selectedPerson != null) {
boolean okClicked = mainApp.showPersonEditDialog(selectedPerson);
if (okClicked) {
showPersonDetails(selectedPerson);
}
} else {
// Nothing selected.
Dialogs.create()
.title("No Selection")
.masthead("No Person Selected")
.message("Please select a person in the table.")
.showWarning();
}
}
}