【问题标题】:Handling events between classes处理类之间的事件
【发布时间】:2012-08-19 15:47:21
【问题描述】:

我有一个主类,其中有一个 Editor 类(带有 JTextPane)和一个 Toolbar 类(带有 JList 和 Jbutton,我不想使用 JToolBar)。这两个类由许多组件组成,我不想将它们混合到同一个类中。我希望编辑器和工具栏进行通信。 假设我在工具栏中写了“Hello”,然后单击提交。我希望文本窗格显示“你好”。 我以这种方式构建类:

public class Main{
    public MainGUI(){
        initComponents();
    }

    private void initComponents(){
        JFrame mainframe=new JFrame("Main Frame");
        Editor editor=new Editor();
        Toolbar toolbar=new Toolbar();
        mainframe.getContentPane().setLayout(new BorderLayout());
        mainframe.getContentPane().add(editor, BorderLayout.CENTER);
        mainframe.getContentPane().add(toolbar, BorderLayout.NORTH);
        mainframe.setVisible(true);
    }
}

public class Editor extends JPanel{
    public Editor(){
        super();
        initComponents();
    }

    private void initComponents(){
        JTextPane textpane=new JTextPane();

        this.setLayout(new BorderLayout());
        this.add(textpane, BorderLayout.CENTER);
    }
}

public class Toolbar extends JPanel{
    public Toolbar(){
        super();
        initComponents();
    }

    private void initComponents(){
        JTextField textfield=new JTextField();
        JButton submitbutton=new JButton("Submit");

        this.setLayout(newFlowLayout());
        this.add(textfield);
        this.add(submitbutton);
    }
}

我应该如何实现工具栏和编辑器之间的事件处理?

【问题讨论】:

  • 为事件处理创建一个单独的类并将这两个类的引用传递给该类,然后简单地做你的魔术开始:-)虽然你需要让你的字段实例字段,而不是将它们单独作为函数的本地。由于您要在外部访问的内容的范围仅限于 initComponents() 方法。

标签: java swing class events communication


【解决方案1】:

你可以创建一个接口ValueSubmittedListener

interface ValueSubmittedListener {
    public void onSubmitted(String value);
}

并让Editor 实现它。

class Editor implements ValueSubmittedListener{

    ...

    public void onSubmitted(String value) {
        // add text to JTextPane.
    }
}

然后让Toolbar提供方法

class Toolbar {

    private List<ValueSubmittedListener> listeners = new ArrayList<ValueSubmittedListener>();


    public void addListener(ValueSubmittedListener listener) {
        listeners.add(listener);
    }

    private void notifyListeners() {
        for (ValueSubmittedListener listener : listeners) {
            listener.onSubmitted(textfield.getText());
        }
    }

}

然后每次您需要向编辑器发送新值时(即:在submitButtonActionListener 中),只需调用方法notifyListeners

更新:

我忘了说在MaininitComponents中,你要注册EditorToolbar

private void initComponents() {
   JFrame mainframe = new JFrame("Main Frame");
   Editor editor = new Editor();
   Toolbar toolbar = new Toolbar();
   toolbar.addListener(editor); // register listener
   ...
}

【讨论】:

  • 知道了。我会尝试 :-) 使用 Java 的 ActionListener 而不是编写一个新的呢?我会遇到一些问题吗?
  • 我的回答的想法是使用Swing的事件处理。您也可以重复使用 ActionListener
  • 这对我很有用,也是一堂很好的编程课。谢谢:-)
  • 不客气!这只是Observer Pattern 的简单实现。你可以了解更多设计模式here
【解决方案2】:

关键原则是适当地传递引用,以便每个对象都可以访问它需要的对象。

例如,如果您的“提交”意味着将文本字段(您在工具栏中的)中的文本附加到编辑器的文本窗格中,那么您可以执行以下操作:

public class Main{
    public MainGUI(){
        initComponents();
    }

    private void initComponents(){
        JFrame mainframe=new JFrame("Main Frame");
        Editor editor=new Editor();
        Toolbar toolbar=new Toolbar(editor);
        mainframe.getContentPane().setLayout(new BorderLayout());
        mainframe.getContentPane().add(editor, BorderLayout.CENTER);
        mainframe.getContentPane().add(toolbar, BorderLayout.NORTH);
        mainframe.setVisible(true);
    }
}

private final JTextPane textpane=new JTextPane();
public class Editor extends JPanel{
    public Editor(){
        super();
        initComponents();
    }

    private void initComponents(){
        this.setLayout(new BorderLayout());
        this.add(textpane, BorderLayout.CENTER);
    }

    public void appendText(final String text) {
        this.textpane.setText( this.textpane.getText()+text );
    }
}

public class Toolbar extends JPanel{
    private final Editor editor;
    public Toolbar(final Editor editor){
        super();
        this.editor = editor;
        initComponents();
    }

    private void initComponents(){
        final JTextField textfield=new JTextField();
        JButton submitbutton=new JButton("Submit");
        submitbutton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(final ActionEvent event) {
                editor.appendText( textfield.getText() );
            }
            });

        this.setLayout(newFlowLayout());
        this.add(textfield);
        this.add(submitbutton);
    }
}

【讨论】:

  • 这应该可以,但在这种情况下,我的工具栏类应该由编辑器组成。我不打算将这些类如此牢固地绑定在一起。
  • 好的。有很多方法可以安排接口和两者之间的交互。这只是一种方法,从您发布的代码开始。我建议研究各种记录在案的Design Patterns,以获得关于软件组织的公认想法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多