万一有人想要帮助我,我将不胜感激,因为我是Java的新手,试图学习简单的概念,同时又要保持代码的简洁和可读性。如果您认为这是一个愚蠢的问题,因为我的编码方法不正确,那么我会真的在乎您的意见,并且如果您向我解释为什么我会尝试获得您的经验。
现在的问题是:
我有一个mainApp包含人员的observableList和事件的observableList
public class MainApp extends Application {
private Stage primaryStage;
private BorderPane rootLayout;
private ObservableList<Evento> eventi = FXCollections.observableArrayList();
private ObservableList<Person> persons = FXCollections.observableArrayList();
public ObservableList<Evento> getEventi() {
return eventi;
}
public ObservableList<Person> getPersons() {
return persons;
}
public static void main(String[] args) {launch(args);}
public void start(Stage primaryStage){
this.primaryStage = primaryStage;
this.primaryStage.setTitle("Bettator Events");
Person test = new Person("Daniele", "Giaquinto");
test.getEventi().add(new Evento("danEvento", 1.0, "testConto"));
persons.add(test);
Person test2 = new Person("Roberto", "Sellitto");
test2.getEventi().add(new Evento("robEvento", 31.0, "testCo"));
persons.add(test2);
initRootLayout();
showEventiLayout();
}
Person对象也有一个事件列表,我之后创建了它,因为我试图创建一个响应式GUI,因此在这种情况下,每个人都有一个事件列表,而不是一个事件列表。
public class Person {
private StringProperty firstName;
private StringProperty lastName;
private StringProperty nickName;
private ObservableList<Evento> eventi = FXCollections.observableArrayList();
我在EventyLayout中创建了一个comboBox和tableView,当我使用侦听器更改组合框时,将使用该人员对象的事件列表填充tableView,我这样做是用Selected Person Events List填充mainApp事件列表
(EventiController)
public class EventiLayoutController {
private MainApp mainApp;
@FXML
private ComboBox<Person> utenteCmb;
@FXML
private TableView<Evento> eventiTbl;
@FXML
private TableColumn<Evento, String> eventoCol;
@FXML
private TableColumn<Evento, Double> importoCol;
@FXML
private TableColumn<Evento, String> contoCol;
@FXML
void initialize() {
eventoCol.setCellValueFactory(cellData -> cellData.getValue().nomeProperty());
importoCol.setCellValueFactory(cellData -> cellData.getValue().importoProperty().asObject());
contoCol.setCellValueFactory(cellData -> cellData.getValue().contoProperty());
utenteCmb.setCellFactory((comboBox) -> new ListCell<Person>() {
//cut for stackoverflow
});
utenteCmb.setConverter(new StringConverter<Person>() {
//cut for stackoverflow
});
utenteCmb.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
mainApp.getEventi().clear();
mainApp.getEventi().addAll(newValue.getEventi());
});
}
public void setMainApp(MainApp mainApp){
this.mainApp = mainApp;
eventiTbl.setItems(mainApp.getEventi());
utenteCmb.setItems(mainApp.getPersons());
}
}
在项目无法切换用户之前,我在rootLayoutController(向我显示menuBar和菜单项(其中添加按钮的位置))中创建了一个“ handleAddEvent”以将事件添加到mainApp列表中。
public class RootLayoutController {
private MainApp mainApp;
@FXML // ResourceBundle that was given to the FXMLLoader
private ResourceBundle resources;
@FXML // URL location of the FXML file that was given to the FXMLLoader
private URL location;
@FXML // This method is called by the FXMLLoader when initialization is complete
void initialize() {
}
/**
* Needed for pass the MainApp to this controller ad use the public variable
*/
public void setMainApp(MainApp mainApp){
this.mainApp = mainApp;
}
/**
* Open dialog for add a new event, then add it to the event collection
*/
@FXML
private void handleAdd() {
Evento evento = new Evento();
boolean okClicked = mainApp.showEventiEditEditDialog(evento);
if (okClicked)
mainApp.getEventi().add(evento);
}
}
但是后来我试图更深入地学习,我需要将该事件直接添加到person-> event中,如果我尝试使用相同的函数添加该事件,他会将其添加到mainApp事件列表中,而不是添加到人员事件列表,即使mainApp人员列表中填充了人员事件也是如此。
我想知道是否有一种方法可以将observableList作为指针传递给mainApp,还是有一种简单的方法可以达到我的目标。
RootLayoutController尝试添加事件时不知道有一个组合框,而mainApp也不需要知道有一个组合框,那么如何获取selectedPerson并将事件添加到他的事件列表中?
我应该在mainApp中创建一个“ activePerson”并在每次用户将项目更改到组合框中时切换它吗?但是在我看来,它是“硬编码”方法。
你会怎么做?
最佳答案
嗯,没有设计应用程序的正确方法。当然,您应该尝试遵循一些设计原则。有关该主题的信息很多,因此找到它不会有问题。
关于您的特定情况,我将组合框和Person
选择逻辑从EventiLayoutController
移到RootLayoutController
。这样,您将在根控制器中选择Person
实例,并且可以在发生更改时通知事件控制器,并向其提供选定的Person
。可以通过直接在EventiLayoutController
中具有RootLayoutController
实例或使用事件总线方法来进行通知。
另外,我会使用属性绑定(或双向绑定,具体取决于您的逻辑)来代替mainApp.getEventi().addAll(newValue.getEventi());
。但是,实际上,我不太理解为什么要在MainApp中需要单独的eventi
集合,如果您仍然用选定的人员事件来填充它的话。