2011-08-13 41 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

上發生錯誤都會發生對象類,請參閱我的答案以瞭解我的意思。 –