我有一个扩展Application的标准JavaFX App。我展示的第一页是一个仪表板,其中包含用于打开其他应用程序的按钮。这很好,第一个应用程序是一个名为AdminController的管理页面,允许用户对模型对象进行CRUD操作 - 用户,联系人,产品,每个实体都是管理视图上的选项卡 - 所以在我的主要Admin FXML中(使用SceneBuilder) )我使用fx包括其他fxml页面:包括用户选项卡,联系人选项卡和产品选项卡。这些包含都在Admin.fxml中,并带有自己的控制器。
<Tab fx:id="contactsTab" onSelectionChanged="#goToContacts" text="Contact">
<content>
<fx:include source="/fxml/manager_contacts_tab.fxml" fx:id="contact" />
</content
<Tab/>
我的想法是在AdminController中加载每个页面需要的资源,用户/联系人/产品,这样我使用的每个fx:include都可以使用那些相同的对象。由于某些选项卡需要所有这些资源(如用户)来管理关联以及其他选项卡(如产品),因此只需要产品列表。我的主控制器看起来像这样 我
public class AdminController {
@FXML
UserController userController;
@FXML
ProductController productController;
@FXML
ContactController contactController;
@FXML
public void initialize
// at this point userController already ran, and called DB so it calls it again here
if (users == null) {
this.users = FXCollections.observableArrayList(userDao.getAllWithProductsAndContacts());
}
if (products == null) {
this.products = FXCollections.observableArrayList(productDao.getAll());
}
if (contacts == null) {
this.contacts = FXCollections.observableArrayList(contactDao.getAll());
}
contactController.setContacts(contact);
// set other resources, like products
}
从逻辑上讲,我认为AdminController的初始化方法将首先运行,这将允许我在子控制器中设置我需要的任何对象,因为我可以访问它们,但是发生的事情是子控制器运行第一,前。使用ContactController
public class ContactController {
@FXML
public void initialize() {
if (contacts == null) {
this.contacts = FXCollections.observableArrayList(contactDao.getAll());
}
}
所以我的应用程序初始化方法按照它们包含在admin.fxml userController,contactController,finally productController中的顺序运行
我认为我的问题归结为我如何在子控制器之间共享对象,以便当单击一个新选项卡时,该选项卡具有与前一个选项卡相同的资源列表,则不会启动新的数据库调用 - 我的例子发生这种情况,当我加载用户页面时,它需要联系人列表和产品列表但是ContactController&amp; ProductController需要那些相同的列表,不需要进行另一个DB调用。
答案 0 :(得分:1)
在您的情况下,如果您一次性加载“全部”联系人,我可能会在初始化单个Controller之前调用数据库。
package main;
import javafx.application.Application;
import javafx.stage.Stage;
public class Main extends Application {
public void start(Stage window) throws Exception {
// Database call goes here!
DatabaseManager.initialize();
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
// Whatever window initialization stuff you need to do
window.show();
}
public static void main(String[] args) {
launch(args);
}
}
现在为您的DatabaseManager类
package sample;
public class DatabaseManager {
public static void initialize() {
// Query the database for your information.
// Little pseudo code here
Data.setUsers(Database.userQuery);
Data.setContacts(Database.contactQuery);
Data.setProducts(Database.productQuery);
}
}
现在是Data类
package sample;
public class Data {
public static ArrayList<User> getUsers() {
return users;
}
public static void setUsers(ArrayList<User> users) {
this.users = users;
}
public static ArrayList<Contact> getContacts() {
return contacts;
}
public static void setContacts(ArrayList<Contact> contacts) {
this.contacts = contacts;
}
public static ArrayList<Product> getProducts() {
return products;
}
public static void setProducts(ArrayList<Product> products) {
this.products = products;
}
private static ArrayList<User> users = new ArrayList<User>();
private static ArrayList<Contact> contacts = new ArrayList<Contact>();
private static ArrayList<Product> products = new ArrayList<Product>();
}
现在您的控制器只需要调用
this.contacts = FXCollections.observableArrayList(Data.getContacts());
这将使你的联系人的arraylist准备就绪。
另请注意,这就是所谓的“将其加载到内存中”。另一个词是你将所有信息存储在计算机的内存中并从那里访问它。这对于巨大的数据库不起作用,因为你的计算机不会有大脑空间。无论如何,希望这会有所帮助。