在两个JPanel对象之间发送消息

我有一个包含JPanel的Java JFrame。 在JPanel中,有两个单独的JPanel。 当用户点击第一个JPanel中的一个button时,需要发送一条消息给另​​一个JPanel,通知它哪个button被点击了。 在这样的对象之间发送消息最简单的方法是什么?

mKorbel(和原始海报):
我推荐的是松耦合,一个JPanel不知道另一个JPanel,所有的连接都是通过某种控件完成的。 例如,借用你的一些代码:

CopyTextNorthPanel2.java

import java.awt.*; import javax.swing.*; public class CopyTextNorthPanel2 extends JPanel { private static final long serialVersionUID = 1L; public JTextField northField; public CopyTextNorthPanel2() { northField = new JTextField("Welcome World"); northField.setFont(new Font("Serif", Font.BOLD, 20)); northField.setPreferredSize(new Dimension(300, 25)); add(northField); } public String getNorthFieldText() { return northField.getText(); } } 

CopyTextSouthPanel2.java

 import java.awt.event.*; import javax.swing.*; public class CopyTextSouthPanel2 extends JPanel { private static final long serialVersionUID = 1L; private JTextField firstText = new JTextField("Desired TextField"); private JButton copyButton = new JButton("Copy text from JTextFields"); private CopyTextControl2 control; public CopyTextSouthPanel2() { copyButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (control != null) { control.copyAction(); } } }); add(firstText); add(copyButton); } public void setControl(CopyTextControl2 control) { this.control = control; } public void setFirstText(String text) { firstText.setText(text); } } 

CopyTextControl2.java

 public class CopyTextControl2 { private CopyTextNorthPanel2 northPanel; private CopyTextSouthPanel2 southPanel; public void copyAction() { if (northPanel != null && southPanel != null) { southPanel.setFirstText(northPanel.getNorthFieldText()); } } public void setNorthPanel(CopyTextNorthPanel2 northPanel) { this.northPanel = northPanel; } public void setSouthPanel(CopyTextSouthPanel2 southPanel) { this.southPanel = southPanel; } } 

CopyText2.java

 import java.awt.*; import javax.swing.*; public class CopyText2 { private static void createAndShowUI() { CopyTextNorthPanel2 northPanel = new CopyTextNorthPanel2(); CopyTextSouthPanel2 southPanel = new CopyTextSouthPanel2(); CopyTextControl2 control = new CopyTextControl2(); southPanel.setControl(control); control.setNorthPanel(northPanel); control.setSouthPanel(southPanel); JPanel mainPanel = new JPanel(new BorderLayout()); mainPanel.add(northPanel, BorderLayout.NORTH); mainPanel.add(Box.createRigidArea(new Dimension(100, 100)), BorderLayout.CENTER); mainPanel.add(southPanel, BorderLayout.SOUTH); JFrame frame = new JFrame("Copy Text"); frame.getContentPane().add(mainPanel); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { createAndShowUI(); } }); } } 

您可以创build一个自定义事件,并附加一个或多个侦听器。

实现的正确方法是让Button ActionListener触发事件,然后让您的两个面板成为该事件的侦听器。

在你的class级的顶部

 public MyClass implements ActionListener { ... myButton.addActionListener(this); ... public void actionPerformed(ActionEvent e) { //for example if you have more than one events that you need to handle if(e.getSource().equals(myButton) { //update your do some work on you jpanels } } 

但是,我认为是时候开始思考devise模式了。 你所描述的是观察者模式和命令模式的完美候选人

例如使用Constructors betweens Classes或(用于debugging问题)通过使用getParent()从所需的JComponent提取值,

 import java.awt.*; import javax.swing.*; public class CopyTextFrame extends JFrame { private static final long serialVersionUID = 1L; private CopyTextNorthPanel northPanel; private CopyTextCenterPanel centerPanel; private CopyTextSouthPanel southPanel; public void makeUI() { northPanel = new CopyTextNorthPanel(); centerPanel = new CopyTextCenterPanel(); southPanel = new CopyTextSouthPanel(); northPanel.setName("northPanel"); centerPanel.setName("centerPanel"); southPanel.setName("southPanel"); centerPanel = new CopyTextCenterPanel(); centerPanel.setPreferredSize(new Dimension(300, 40)); southPanel = new CopyTextSouthPanel(); southPanel.setSourceTextField(northPanel.desText); northPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); centerPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); southPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); setLayout(new BorderLayout(5, 5)); setDefaultCloseOperation(EXIT_ON_CLOSE); add(northPanel, BorderLayout.NORTH); add(centerPanel, BorderLayout.CENTER); add(southPanel, BorderLayout.SOUTH); pack(); setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new CopyTextFrame().makeUI(); } }); } } 

+

 import javax.swing.*; public class CopyTextCenterPanel extends JPanel { private static final long serialVersionUID = 1L; public CopyTextCenterPanel() { } } 

+

 import java.awt.*; import javax.swing.*; public class CopyTextNorthPanel extends JPanel { private static final long serialVersionUID = 1L; public JTextField desText; public CopyTextNorthPanel() { desText = new JTextField("Welcome World"); desText.setFont(new Font("Serif", Font.BOLD, 20)); desText.setPreferredSize(new Dimension(300, 25)); desText.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1)); desText.addComponentListener(null); desText.setName("desText"); add(desText); } public JTextField getDesText() { return desText; } } 

+

 import java.awt.*; import java.awt.event.ActionEvent; import javax.swing.*; public class CopyTextSouthPanel extends JPanel { private static final long serialVersionUID = 1L; private JTextField firstText; private JButton copyButton; private JTextField sourceTextField; private String lds = ""; public CopyTextSouthPanel() { firstText = new JTextField("Desired TextField"); firstText.setMinimumSize(new Dimension(300, 25)); firstText.setPreferredSize(new Dimension(300, 25)); firstText.setMaximumSize(new Dimension(300, 25)); copyButton = new JButton("Copy text from JTextFields"); copyButton.setMinimumSize(new Dimension(200, 25)); copyButton.setPreferredSize(new Dimension(200, 25)); copyButton.setMaximumSize(new Dimension(200, 25)); copyButton.addActionListener(new java.awt.event.ActionListener() { @Override public void actionPerformed(java.awt.event.ActionEvent evt) { copyButtonActionPerformed(evt); } private void copyButtonActionPerformed(ActionEvent evt) { System.out.print("Button pressed" + "\n"); Component[] comp = CopyTextSouthPanel.this.getParent().getComponents(); int nO = comp.length; for (int i = 0; i < comp.length; ++i) { if (comp[i] instanceof JPanel) { String name = ((JPanel) comp[i]).getName(); if (name.equals("northPanel")) { JPanel panel = (JPanel) comp[i]; Component[] comp1 = panel.getComponents(); int nO1 = comp1.length; for (int ii = 0; ii < comp1.length; ++ii) { if (comp1[ii] instanceof JTextField) { String name1 = ((JTextField) comp1[ii]).getName(); if (!(name1 == null)) { if (name1.equals("desText")) { JTextField text = (JTextField) comp1[ii]; String str = text.getText(); firstText.setText(str); System.out.print("set value -> " + str + "\n"); break; } } } } break; } } } lds = sourceTextField.getText(); if (lds != null || (!(lds.isEmpty()))) { firstText.setText(" Msg -> " + lds); } } }); add(firstText, BorderLayout.EAST); add(copyButton, BorderLayout.WEST); } public void setSourceTextField(JTextField source) { this.sourceTextField = source; } }