【发布时间】:2014-08-02 20:27:59
【问题描述】:
还在学习 Java。
Swing 再次让我问这个问题,但这确实是一个一般的 OO 问题。如果我有一个主类(包含 main()),它会创建一个新对象“A”来做某事,主类现在有对该对象的引用,对象“B”如何访问该对象的属性?
我能想到的唯一方法是让主类创建一个新对象“B”,将对象“A”作为参数传递给构造函数,我想这是可以的。但这不会使事件处理变得困难。
例如,也许这是导致问题的糟糕设计。我有一个带有程序逻辑的大师班,它创建一个标准的 Swing 框架,带有一个菜单,菜单项具有动作侦听器。但是 actionlistener 需要与外部对象交互。
所以一些代码(忽略细节):
主类,包含程序逻辑和保存加载方法等:
public final class TheProgramme implements WindowListener }
private static final TheProgramme TP = new TheProgramme();
// Declare Class variables, instance variables etc.
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShewGUI();
}
});
}
private static void createAndShewGUI() {
TP.populateAndShew();
}
private void populateAndShew() {
final StandardFrame sF = new StandardFrame("TheProgramme");
theFrame = sF.getMainFrame();
theFrame.addWindowListener(this);
theFrame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
theFrame.pack(); theFrame.setVisible(true);
}
...
}
所以我们创建了一个标准框架对象,它创建了一个菜单、空面板和状态栏,但在菜单项上有事件监听器:
public class StandardFrame {
// Declare instance variables that must be visible to the ActionListener inner class
public StandardFrame(String theTitle) {
mainFrame = new JFrame(theTitle);
mainFrame.setJMenuBar(createMenuBar()); // ... the menu bar and ...
mainFrame.setContentPane(createBlankPanel()); // ... a blank panel
java.net.URL imageURL = TheProgramme.class.getResource("images/icon.png");
if (imageURL != null) {
ImageIcon icon = new ImageIcon(imageURL);
mainFrame.setIconImage(icon.getImage());
}
}
public JMenuBar createMenuBar() {
ActionListener menuEvents = new MenuListener();
JMenuBar aMenuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File"); fileMenu.setMnemonic(KeyEvent.VK_F);
...
aMenuBar.add(fileMenu);
...
JMenuItem newItem = new JMenuItem("New", KeyEvent.VK_N); newItem.addActionListener(menuEvents);
newItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK));
...
fileMenu.add(newItem);
...
return aMenuBar;
}
}
class MenuListener implements ActionListener {
public void actionPerformed(ActionEvent ae) {
String actionCommand = ae.getActionCommand();
switch (actionCommand) {
case "New":
// !!! here we need to call a method in an object to create a new document object !!!
break;
case "Reformat":
// !!! here we need to call a method in the object created above
}
}
}
第一个问题是菜单项上的 actionlistener 调用一个方法来创建一个对象,但它不是对静态方法的调用。 第二个问题是它需要能够在稍后作为另一个菜单选择的结果调用该新对象中的方法。
【问题讨论】:
-
一些示例代码会有所帮助。
-
需要更多关于问题的详细信息才能给出答案。目前有点难以理解问题所在。通常,对象从不知道任何其他对象开始;您可以在构造函数中传递详细信息,或者稍后使用 setXxx() 方法设置它们。尝试绘制不同对象的图表并使用它来决定哪个对象需要知道哪个其他对象。通常你应该把 UI 和数据类分开,所以如果你有一个模型对象指向一个 UI 对象,那么你就搞错了。
-
您似乎想要的是某种MVC 结构。您对当前的结构感到担忧是对的,但可能是出于错误的原因。在某些时候,您需要将某事的引用传递给某个人,以便在需要更改时得到通知,请参阅observer pattern 了解更多详细信息。您还应该研究“编程到接口而不是实现”的概念,这也是相关的
-
尝试提出MCVE。创建文档的方法在哪里定义,在哪个类中?此外,哪个类维护对需要重新格式化的(选定)文档的引用?这都是
StandardFrame的一部分吗?如果MenuListener是一个内部类,它可以访问StandardFrame中的所有内容。 -
@Aqua 我试图保留 StandardFrame 类只是为了制作空白程序屏幕并监听菜单事件,新的文档对象是一个不同的类。问题之一是如何将新对象引用返回到 StandardFrame 以便可以从那里调用方法,此时从动作侦听器调用主程序并创建新文档,但它是一个调用到静态方法。
标签: java swing oop design-patterns