2012-05-09 11 views
6

Wie verdrahte ich die Ausgabe an paneWithList?So verdrahten Sie eine Scheibe mit einer anderen

PaneWithList hat einen Listener auf JList, so dass die ausgewählte Zeile an die Konsole ausgegeben wird. Wie kann ich diese Ausgabe an die Ausgabe JTextPane anleiten?

Konnte PaneWithList ein Ereignis auslösen, das Main aufhebt? Würde PropertyChangeSupport ausreichen?

Main.java:

package dur.bounceme.net; 

import javax.swing.JTabbedPane; 

public class Main { 

    private static JTabbedPane tabs; 
    private static PaneWithList paneWithList; 
    private static PaneWithTable paneWithTable; 
    private static Output output; 

    public static void main(String[] args) { 
     tabs = new javax.swing.JTabbedPane(); 
     paneWithList = new PaneWithList(); 
     paneWithTable = new PaneWithTable(); 
     tabs.addTab("list", paneWithList); 
     tabs.addTab("table", paneWithTable); 
     tabs.addTab("output", output); 
    } 
} 
+0

Nur die 'JTextPane' registrieren sich selbst als ein Listener zu der gleichen' JList'. – user1329572

+0

addListener (dies)? kannst du das etwas erweitern? – Thufir

Antwort

13

Hier ist ein Beispiel für die observer pattern Verwendung auch here gesehen, here und here. Beachten Sie, dass Sie auch das Modell der Combo hören können.

enter image description here

import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import javax.swing.*; 

/** 
* @see http://en.wikipedia.org/wiki/Observer_pattern 
* @see https://stackoverflow.com/a/10523401/230513 
*/ 
public class PropertyChangeDemo { 

    public PropertyChangeDemo() { 
     JFrame f = new JFrame(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setResizable(false); 
     f.add(new ObserverPanel()); 
     f.pack(); 
     f.setLocationByPlatform(true); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       PropertyChangeDemo example = new PropertyChangeDemo(); 
      } 
     }); 
    } 
} 

class ObserverPanel extends JPanel { 

    private JLabel title = new JLabel("Value received: "); 
    private JLabel label = new JLabel("null", JLabel.CENTER); 

    public ObserverPanel() { 
     this.setBorder(BorderFactory.createTitledBorder("ObserverPanel")); 
     JPanel panel = new JPanel(new GridLayout(0, 1)); 
     panel.add(title); 
     panel.add(label); 
     this.add(panel); 
     ObservedPanel observed = new ObservedPanel(); 
     observed.addPropertyChangeListener(new PropertyChangeListener() { 

      @Override 
      public void propertyChange(PropertyChangeEvent e) { 
       if (e.getPropertyName().equals(ObservedPanel.PHYSICIST)) { 
        String value = e.getNewValue().toString(); 
        label.setText(value); 
       } 
      } 
     }); 
     this.add(observed); 
    } 
} 

class ObservedPanel extends JPanel { 

    public static final String PHYSICIST = "Physicist"; 
    private static final String[] items = new String[]{ 
     "Alpher", "Bethe", "Gamow", "Dirac", "Einstein" 
    }; 
    private JComboBox combo = new JComboBox(items); 
    private String oldValue; 

    public ObservedPanel() { 
     this.setBorder(BorderFactory.createTitledBorder("ObservedPanel")); 
     combo.addActionListener(new ComboBoxListener()); 
     this.add(combo); 
    } 

    private class ComboBoxListener implements ActionListener { 

     @Override 
     public void actionPerformed(ActionEvent ae) { 
      String newValue = (String) combo.getSelectedItem(); 
      firePropertyChange(PHYSICIST, oldValue, newValue); 
      oldValue = newValue; 
     } 
    } 
} 
+0

Ich verstehe besser, wie firePropertyChange propogates, danke. Nicht ganz sicher, wie du die tatsächlichen Werte weitergegeben hast, musst du nochmal lesen, aber das war das fehlende Stück für mich. – Thufir

+0

Hier ist ein ähnliches [Beispiel] (http://stackoverflow.com/a/11832979/230513), das einen nicht modalen Dialog verwendet. – trashgod

+0

wow! großartig! Ich frage mich ob Observer Pattern eine Instanz von _Observed Panel_ in _Observer Panel_ –

3

würde ich Verwendung JMenu with JMenuItems mit Inhalten unter Verwendung CardLayout eher verlegt werden als sehr kompliziert JTabbedPane(s)

+0

+1 gute Alternative, oft verkabelt mit [Action] (http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html). – trashgod

+0

Aktion scheint jedoch nicht über alle Swing-Steuerelemente zu funktionieren ..? – Thufir

1

Für meine eigene Referenz, und für alle, die Netbeans GUI-Builder verwenden, das funktioniert so weit wie es geht:

Die PanelWithList Klasse:

package dur.bounceme.net; 

public class PanelWithList extends javax.swing.JPanel { 

    public PanelWithList() { 
     initComponents(); 
    } 

    /** 
    * This method is called from within the constructor to initialize the form. 
    * WARNING: Do NOT modify this code. The content of this method is always 
    * regenerated by the Form Editor. 
    */ 
    @SuppressWarnings("unchecked") 
    // <editor-fold defaultstate="collapsed" desc="Generated Code">       
    private void initComponents() { 

     jScrollPane1 = new javax.swing.JScrollPane(); 
     jList1 = new javax.swing.JList(); 
     jScrollPane2 = new javax.swing.JScrollPane(); 
     jTextArea1 = new javax.swing.JTextArea(); 

     jList1.setModel(new javax.swing.AbstractListModel() { 
      String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" }; 
      public int getSize() { return strings.length; } 
      public Object getElementAt(int i) { return strings[i]; } 
     }); 
     jList1.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); 
     jList1.addMouseListener(new java.awt.event.MouseAdapter() { 
      public void mouseClicked(java.awt.event.MouseEvent evt) { 
       jList1MouseClicked(evt); 
      } 
     }); 
     jList1.addKeyListener(new java.awt.event.KeyAdapter() { 
      public void keyReleased(java.awt.event.KeyEvent evt) { 
       jList1KeyReleased(evt); 
      } 
     }); 
     jScrollPane1.setViewportView(jList1); 

     jTextArea1.setColumns(20); 
     jTextArea1.setRows(5); 
     jScrollPane2.setViewportView(jTextArea1); 

     javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); 
     this.setLayout(layout); 
     layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup() 
       .addGap(54, 54, 54) 
       .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 247, javax.swing.GroupLayout.PREFERRED_SIZE) 
       .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) 
       .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 308, javax.swing.GroupLayout.PREFERRED_SIZE) 
       .addContainerGap(167, Short.MAX_VALUE)) 
     ); 
     layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGroup(layout.createSequentialGroup() 
       .addGap(35, 35, 35) 
       .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) 
        .addComponent(jScrollPane2) 
        .addComponent(jScrollPane1)) 
       .addContainerGap(166, Short.MAX_VALUE)) 
     ); 
    }// </editor-fold>       

    private void jList1MouseClicked(java.awt.event.MouseEvent evt) {          
     row(); 
    }         

    private void jList1KeyReleased(java.awt.event.KeyEvent evt) {         
     row(); 
    }         
    // Variables declaration - do not modify      
    private javax.swing.JList jList1; 
    private javax.swing.JScrollPane jScrollPane1; 
    private javax.swing.JScrollPane jScrollPane2; 
    private javax.swing.JTextArea jTextArea1; 
    // End of variables declaration     

    private void row() { 
     Object o = jList1.getSelectedValue(); 
     String s = (String)o; 
     jTextArea1.setText(s); 
     this.firePropertyChange("list", -1, 1); 
    } 
} 

und Frame.java als Treiber:

package dur.bounceme.net; 

public class Frame extends javax.swing.JFrame { 

    public Frame() { 
     initComponents(); 
    } 

    /** 
    * This method is called from within the constructor to initialize the form. 
    * WARNING: Do NOT modify this code. The content of this method is always 
    * regenerated by the Form Editor. 
    */ 
    @SuppressWarnings("unchecked") 
    // <editor-fold defaultstate="collapsed" desc="Generated Code"> 
    private void initComponents() { 

     jTabbedPane1 = new javax.swing.JTabbedPane(); 
     panelWithList1 = new dur.bounceme.net.PanelWithList(); 
     panelWithTable1 = new dur.bounceme.net.PanelWithTable(); 
     newJPanel1 = new dur.bounceme.net.PanelWithCombo(); 

     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

     panelWithList1.addPropertyChangeListener(new java.beans.PropertyChangeListener() { 
      public void propertyChange(java.beans.PropertyChangeEvent evt) { 
       panelWithList1PropertyChange(evt); 
      } 
     }); 
     jTabbedPane1.addTab("tab1", panelWithList1); 
     jTabbedPane1.addTab("tab2", panelWithTable1); 
     jTabbedPane1.addTab("tab3", newJPanel1); 

     javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); 
     getContentPane().setLayout(layout); 
     layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGap(0, 937, Short.MAX_VALUE) 
      .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
       .addGroup(layout.createSequentialGroup() 
        .addContainerGap() 
        .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 913, Short.MAX_VALUE) 
        .addContainerGap())) 
     ); 
     layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
      .addGap(0, 555, Short.MAX_VALUE) 
      .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) 
       .addGroup(layout.createSequentialGroup() 
        .addContainerGap() 
        .addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 521, javax.swing.GroupLayout.PREFERRED_SIZE) 
        .addContainerGap(22, Short.MAX_VALUE))) 
     ); 

     pack(); 
    }// </editor-fold> 

    private void panelWithList1PropertyChange(java.beans.PropertyChangeEvent evt) { 
     System.out.println("panelWithList1PropertyChange "); 

    } 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String args[]) { 
     /* 
     * Set the Nimbus look and feel 
     */ 
     //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> 
     /* 
     * If Nimbus (introduced in Java SE 6) is not available, stay with the 
     * default look and feel. For details see 
     * http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */ 
     try { 
      for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { 
       if ("Nimbus".equals(info.getName())) { 
        javax.swing.UIManager.setLookAndFeel(info.getClassName()); 
        break; 
       } 
      } 
     } catch (ClassNotFoundException ex) { 
      java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (InstantiationException ex) { 
      java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (IllegalAccessException ex) { 
      java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } catch (javax.swing.UnsupportedLookAndFeelException ex) { 
      java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } 
     //</editor-fold> 

     /* 
     * Create and display the form 
     */ 
     java.awt.EventQueue.invokeLater(new Runnable() { 

      public void run() { 
       new Frame().setVisible(true); 
      } 
     }); 
    } 
    // Variables declaration - do not modify 
    private javax.swing.JTabbedPane jTabbedPane1; 
    private dur.bounceme.net.PanelWithCombo newJPanel1; 
    private dur.bounceme.net.PanelWithList panelWithList1; 
    private dur.bounceme.net.PanelWithTable panelWithTable1; 
    // End of variables declaration 
} 

Der Schlüssel ist, daß panelWithList1PropertyChange ist der Hörer auf 'panelWithList' selbst.

Da PanelWithList.firePropertyChange("list", -1, 1); kann nicht Objekt noch String senden, die ich sehe, ich bin nicht ganz sicher, wie die Wert den ganzen Weg von der JList ausgewählt bekommen bis zum JFrame.

Hmm, also die API sagt ja es kann Objekte senden. Ich muss das überprüfen.

Ich denke, es ist notwendig, einige Informationen über das Modell, das die JList verwendet, bis zum JFrame zu bekommen. Aber bricht MVC das nicht? Oder vielleicht ist das die falsche Herangehensweise.

+0

Als Referenz ist [tag: jcalendar] ein ziemlich zugängliches Beispiel für eine 'JComponent', die' PropertyChangeListener' implementiert.Siehe auch [* A Swing Architecture Overview *] (http://java.sun.com/products/jfc/tsc/articles/architecture/). – trashgod

Verwandte Themen