Javafx - 使用xml文件填充表

时间:2017-02-26 16:53:02

标签: javafx

我是javafx的新手,并且一直在关注我的所有代码都来自的教程(http://code.makery.ch/library/javafx-8-tutorial/)。

我在使用xml文件填充表格时遇到问题,我认为这是因为我想首先切换场景然后在这个新场景中显示表格。在指南中,他们只在加载的第一个场景上进行,如果我这样做,我可以正常工作,但是当我希望表格数据在不同的场景中可见时,它似乎无法工作。我所做的就是改变一些代码在课堂上的位置以试图反映这一点,因为我在第一个场景中并不想要它,但现在它不会显示。

为LibraryApp

package libraryapp;

import java.io.File;
import java.io.IOException;
import java.util.prefs.Preferences;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import libraryapp.model.Book;
import libraryapp.model.BookListWrapper;
import libraryapp.view.HomeOverviewController;
import libraryapp.view.RootLayoutController;

public class LibraryApp extends Application {

private Stage primaryStage;
private BorderPane rootLayout;

/**
 * The data as an observable list of Books.
 */
private ObservableList<Book> bookData = FXCollections.observableArrayList();

/**
 * Constructor
 */
public LibraryApp() {
    // Add some sample data
    bookData.add(new Book("Hans", "Muster"));
    bookData.add(new Book("Ruth", "Mueller"));
    bookData.add(new Book("Heinz", "Kurz"));
    bookData.add(new Book("Cornelia", "Meier"));
    bookData.add(new Book("Werner", "Meyer"));
    bookData.add(new Book("Lydia", "Kunz"));
    bookData.add(new Book("Anna", "Best"));
    bookData.add(new Book("Stefan", "Meier"));
    bookData.add(new Book("Martin", "Mueller"));
}

/**
 * Returns the data as an observable list of Books. 
 * @return
 */
public ObservableList<Book> getBookData() {
    return bookData;
}



@Override
public void start(Stage primaryStage) {
    this.primaryStage = primaryStage;
    this.primaryStage.setTitle("LibraryApp");

    initRootLayout();
    showHomeOverview();

 }


/**
* 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(LibraryApp.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.setLibraryApp(this);

    primaryStage.show();
} catch (IOException e) {
    e.printStackTrace();
}

// Try to load last opened person file.
File file = getBookFilePath();
if (file != null) {
    loadBookDataFromFile(file);
}
}





/**
 * Shows the book overview inside the root layout.
 */
public void showHomeOverview() {
    try {
        // Load home overview.
        FXMLLoader loader = new FXMLLoader();
          loader.setLocation(LibraryApp.class.getResource("view/HomeOverview.fxml"));
        AnchorPane homeOverview = (AnchorPane) loader.load();



        // Set home overview into the center of root layout.
        rootLayout.setCenter(homeOverview);

    // Give the controller access to the main app.
    HomeOverviewController controller = loader.getController();



    } catch (IOException e) {
        e.printStackTrace();
    }
}

/**
 * Returns the main stage.
 * @return
 */
public Stage getPrimaryStage() {
    return primaryStage;
}

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

/**
 * Returns the book 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 getBookFilePath() {
Preferences prefs = Preferences.userNodeForPackage(LibraryApp.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 setBookFilePath(File file) {
Preferences prefs = Preferences.userNodeForPackage(LibraryApp.class);
if (file != null) {
    prefs.put("filePath", file.getPath());

    // Update the stage title.
    primaryStage.setTitle("LibraryApp - " + file.getName());
} else {
    prefs.remove("filePath");

    // Update the stage title.
    primaryStage.setTitle("LibraryApp");
}
}

/**
* Loads book data from the specified file. The current book data will
* be replaced.
* 
* @param file
*/
public void loadBookDataFromFile(File file) {
try {
    JAXBContext context = JAXBContext
            .newInstance(BookListWrapper.class);
    Unmarshaller um = context.createUnmarshaller();

    // Reading XML from the file and unmarshalling.
    BookListWrapper wrapper = (BookListWrapper) um.unmarshal(file);

    bookData.clear();
    bookData.addAll(wrapper.getBooks());

    // Save the file path to the registry.
    setBookFilePath(file);

} catch (Exception e) { // catches ANY exception
    Alert alert = new Alert(AlertType.ERROR);
    alert.setTitle("Error");
    alert.setHeaderText("Could not load data");
    alert.setContentText("Could not load data from file:\n" +       file.getPath());

    alert.showAndWait();
}
}

/**
 * Saves the current book data to the specified file.
* 
* @param file
*/
public void saveBookDataToFile(File file) {
try {
    JAXBContext context = JAXBContext
            .newInstance(BookListWrapper.class);
    Marshaller m = context.createMarshaller();
    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

    // Wrapping our book data.
    BookListWrapper wrapper = new BookListWrapper();
    wrapper.setBooks(bookData);

    // Marshalling and saving XML to the file.
    m.marshal(wrapper, file);

    // Save the file path to the registry.
    setBookFilePath(file);
} catch (Exception e) { // catches ANY exception
    Alert alert = new Alert(AlertType.ERROR);
    alert.setTitle("Error");
    alert.setHeaderText("Could not save data");
    alert.setContentText("Could not save data to file:\n" + file.getPath());

    alert.showAndWait();
}
}



}

HomeOverViewController

package libraryapp.view;



import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.layout.AnchorPane;
import libraryapp.view.BrowseController;


public class HomeOverviewController implements Initializable {


@FXML
private AnchorPane homePane;



@FXML
private void goToBrowse(ActionEvent event) throws IOException {

    AnchorPane pane =   FXMLLoader.load(getClass().getResource("Browse.fxml"));
    homePane.getChildren().setAll(pane);

}

@FXML
private void goToManageAccount(ActionEvent event) throws IOException {

    AnchorPane pane =  FXMLLoader.load(getClass().getResource("ManageAccount.fxml"));
    homePane.getChildren().setAll(pane);
}

@FXML
public void logout(ActionEvent event) throws IOException {
    AnchorPane pane = FXMLLoader.load(getClass().getResource("Login.fxml"));
    homePane.getChildren().setAll(pane);
}


@Override
public void initialize(URL url, ResourceBundle rb) {
    // TODO
}    

}

BrowseController

package libraryapp.view;

import java.io.File;
import java.io.IOException;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.AnchorPane;
import libraryapp.LibraryApp;
import libraryapp.model.Book;

public class BrowseController {
@FXML
private TableView<Book> bookTable;
@FXML
private TableColumn<Book, String> titleColumn;

@FXML
private Label titleLabel;
@FXML
private Label authorLabel;
@FXML
private Label isbnLabel;
@FXML
private Label quantityLabel;

@FXML
private AnchorPane browsePane;


// Reference to the main application.
private LibraryApp libraryApp;

/**
 * The constructor.
 * The constructor is called before the initialize() method.
 */
public BrowseController() {
}

/**
 * Initializes the controller class. This method is automatically called
 * after the fxml file has been loaded.
 */
@FXML
private void initialize() {
// Initialize the book table
titleColumn.setCellValueFactory(
        cellData -> cellData.getValue().titleProperty());

// Clear person details.
showBookDetails(null);

// Listen for selection changes and show the person details when changed.
bookTable.getSelectionModel().selectedItemProperty().addListener(
        (observable, oldValue, newValue) -> showBookDetails(newValue));
}



 /**
 * Is called by the main application to give a reference back to itself.
 * 
 * @param libraryApp
 */
public void setLibraryApp(LibraryApp libraryApp) {
    this.libraryApp = libraryApp;

    // Add observable list data to the table
    bookTable.setItems(libraryApp.getBookData());
}




private void showBookDetails(Book book) {
if (book != null) {
    // Fill the labels with info from the book object.
    titleLabel.setText(book.getTitle());
    authorLabel.setText(book.getAuthor());
    isbnLabel.setText(book.getIsbn());
    quantityLabel.setText(Integer.toString(book.getQuantity()));


} else {
    // Book is null, remove all the text.
    titleLabel.setText("");
    authorLabel.setText("");
    isbnLabel.setText("");
    quantityLabel.setText("");

}


}


/**
 * Called when the user clicks on the borrow button.
*/
@FXML
private void handleDeleteBook() {
int selectedIndex = bookTable.getSelectionModel().getSelectedIndex();
if (selectedIndex >= 0) {
    bookTable.getItems().remove(selectedIndex);
} else {
    // Nothing selected.
    Alert alert = new Alert(AlertType.WARNING);
    alert.initOwner(libraryApp.getPrimaryStage());
    alert.setTitle("No Selection");
    alert.setHeaderText("No book Selected");
    alert.setContentText("Please select a book.");

    alert.showAndWait();
  }
}


@FXML
public void logout(ActionEvent event) throws IOException {

        File bookFile = libraryApp.getBookFilePath();
        libraryApp.saveBookDataToFile(bookFile);


    AnchorPane pane = FXMLLoader.load(getClass().getResource("Login.fxml"));
    browsePane.getChildren().setAll(pane);
}

}

我的想法是,我想按下一个调用goToBrowse的按钮,它将加载浏览场景,然后用xml文件中的数据填充表格。它可以很好地浏览场景,但不会填充表格。

请原谅任何凌乱的代码和任何错误的命名约定,因为我对这个javafx的东西很新,并且一直在尝试遵循之前提到的教程并将其调整为我认为正确的。

我相信我想在setLibraryApp中调用BrowseController,但我所尝试的似乎并不起作用。

0 个答案:

没有答案