2011-08-13 38 views
8

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

回答

11

对于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(); 
     } 
     }); 
    } 
} 
+0

谢谢,不包括电池,我仍然可以在我的时区看到相同的时间超过午夜2小时,睡觉时间+1 – mKorbel

+0

@mKorbel:晚安,好好休息! –

+0

感谢您的教训,agreen如果有多个连接的情况下,那么更好... – mKorbel

6

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

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

+1

请参阅['EventListenerList'](http://download.oracle.com/javase/7/docs/api/javax/swing/event/EventListenerList.html)。 – trashgod

+0

链接(http://www.exampledepot.com/egs/java.util/custevent.html)似乎已过时 – Lucio

3

在你的类

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 
     } 
} 

但顶部真的,我觉得是时候开始考虑设计模式。你所描述是为observer模式完美的候选人,并可能通过构造中间人类或(用于调试运行的问题)的command模式

2

例如,通过使用getParent()

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(); 
      } 
     }); 
    } 
} 
提取所需 JComponent(S)值

+

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; 
    } 
} 
+0

您正在编写一个引用到其中一个面板的引用的硬编码,这看起来很漂亮脆弱的解决方案。更好的做法是让两个JPanel对彼此无知,并根据其他答案使用监听器。 –

+0

@Hovercraft Full Of Eels by依赖你的评论很难说明智的东西,构造函数和最终的Getter/Setter都是硬编码的,我认为这两者仍然被认为是JComponents的基本东西,因为我同样是脆弱的创建方式如果在每个连接 – mKorbel

+0

上发生错误都会发生对象类,请参阅我的答案以了解我的意思。 –