Java 如何避免嵌套ActionListener?
在我的程序中,我希望用户:Java 如何避免嵌套ActionListener?,java,swing,user-interface,Java,Swing,User Interface,在我的程序中,我希望用户: 自行选择/打开数据库(如Access) 从数据库中选择一个表 从表中选择列 在我的代码中,我有一个类可以执行以下操作: mntmOpenDatabase.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { //open the database //display tables as buttons
mntmOpenDatabase.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//open the database
//display tables as buttons
tableButton.addActionListener(new ActionListener() { // select a table
public void actionPerformed(ActionEvent e) {
//display the columns of the table selected as buttons
colButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {// add to the list of columns to be exported }
public class OpenDataBaseListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e){
//your event handling here
}
}
public class TableButtonListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e){
//your logic
}
}
这会产生一大块代码。有更干净、更简单的方法吗?解决方案是重构:
- 为代码创建一个单独且可单独测试的类以打开数据库
- 以及用于显示此数据的单独且可单独测试的类
- 在ActionListener中,创建这些类的实例,或者与它们交互(如果它们已经存在)
- 学习M-V-C(模型视图控制)设计模式的基本原理,并使用它们。你不必屈从于它们,上帝知道它们有很多变体,但它们的总体指导原则至少应该得到尊重
- 努力使您的GUI或视图尽可能地变得愚蠢。它知道如何显示其数据,它有允许控件更新其显示的设施,并且它知道当用户与控件交互时如何通知控件,这就是它
- 侧面建议1:确保所有数据库交互都在后台线程中完成
- 附带建议2:确保几乎所有Swing交互都是在Swing EDT(事件调度线程)上完成的
mntmOpenDatabase.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
control.openDatabase();
}
}
在您的示例中,您将在每个ActionEvent上实例化并添加新的侦听器。实际上,您应该配置它一次。大概是这样的:
mntmOpenDatabase.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//open the database
//display tables as buttons
tableButton.addActionListener(new ActionListener() { // select a table
public void actionPerformed(ActionEvent e) {
//display the columns of the table selected as buttons
colButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {// add to the list of columns to be exported }
public class OpenDataBaseListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e){
//your event handling here
}
}
public class TableButtonListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e){
//your logic
}
}
等等
当您创建侦听器时,您应该注册一次:
mntmOpenDatabase.addActionListener(new OpenDataBaseListener());
tableButton.addActionListener(new TableButtonListener());
colButton.addActionListener(new ColButtonListener());
所以我最后做了一些关于MVC的研究。我想我已经有了基本的想法,但是我仍然在想,我应该把ActionListeners放在哪里?在控制器内部还是视图内部?关于这一点似乎有不同的看法。@ForeverLearning:那是因为两者都可以很好地工作。在我看来,如果ActionListener在视图中,那么它们非常简单,它们所做的只是调用一个等价的控制方法,如我上面所示。否则,您可以将控件注入到视图中。听起来不错。我想我会试试的。但是,创建一个包含所有动作侦听器的动作类是一个好主意,还是将它们与组件放在同一个类中就可以了?