2011-08-13 17 views
8

Mam ramkę JF Java zawierającą JPanel. W ramach tego JPanel istnieją dwa oddzielne JPanele. Kiedy użytkownik kliknie przycisk w pierwszym JPanelu, wiadomość musi zostać wysłana do innego JPanel informującego, który przycisk został kliknięty. Jaki jest najłatwiejszy sposób wysyłania wiadomości między takimi obiektami?Wysyłanie wiadomości między dwoma obiektami JPanel

Odpowiedz

11

Dla mKorbel (i ich twórców):
Co ja polecając jest luźniejsza sprzęgło, że jeden JPanel nie ma wiedzy na temat innego JPanel i że wszystkie połączenia są wykonywane za pośrednictwem kontrola jakiegoś rodzaju. Na przykład, aby pożyczyć trochę swojego kodu:

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

dziękuję, bez baterii w zestawie, nadal mogę zobaczyć to samo w mojej strefie czasowej jest więcej niż 2 godziny po północy, czas spać +1 – mKorbel

+0

@mKorbel: dobranoc i dobry wypoczynek! –

+0

dzięki za lekcję, w przypadku, gdy jest więcej niż jedno połączenie, to lepiej ... – mKorbel

6

Można utworzyć zdarzenie niestandardowe i dołączyć do niego co najmniej jednego detektora.

Właściwy sposób implementacji polega na tym, że Button ActionListener wywołuje zdarzenie, a następnie dwa panele są odbiorcami tego zdarzenia.

+1

Zobacz także ['EventListenerList'] (http://download.oracle.com/javase/7/docs/api/javax/swing/event/EventListenerList.html). – trashgod

+0

Link (http://www.exampledepot.com/egs/java.util/custevent.html) wydaje się być przestarzały. – Lucio

3

na szczycie swojej klasy

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

Ale naprawdę, myślę, że nadszedł czas, aby zacząć myśleć o wzorcach projektowych. Co opisujesz jest idealnym kandydatem na wzór observer i ewentualnie command wzór

2

na przykład za pomocą pośredników Konstruktor klasy lub (dla debuging wystawienia) wyodrębnić wartość od pożądanego JComponent (ów) za pomocą 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(); 
      } 
     }); 
    } 
} 

+

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

Twarde kodowanie polega na uzyskaniu odwołania do jednego z paneli, który wydaje się być dość kruche rozwiązanie. O wiele lepiej jest sprawić, aby oba JPanels nie znały się nawzajem i używały słuchaczy zgodnie z innymi odpowiedziami. –

+0

@ Poduszkowiec pełen węgorzy w zależności od twoich komentarzy ciężko jest powiedzieć coś mądrego, Konstruktor i ostatecznie także Getter/Setter są zakodowane na sztywno, i myślę, że oba są nadal uważane za podstawowe rzeczy dla JComponents, dla mnie jest to ten sam wspaniały sposób tworzenia Klasy obiektu w przypadku, gdy coś złego dzieje się na każdym połączeniu – mKorbel

+0

, zobacz moją odpowiedź, aby zrozumieć, co mam na myśli. –

Powiązane problemy