2012-05-09 15 views
6

¿Cómo cableo la salida a paneWithList?Cómo cablear un panel a otro

PaneWithList tiene un detector en su JList para que la fila seleccionada salga a la consola. ¿Cómo puedo dirigir esa salida al JTextPane en la salida?

¿Podría PaneWithList desencadenar un evento que Main recoge? ¿Sería suficiente con PropertyChangeSupport?

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

Simplemente haga que 'JTextPane' se registre como un oyente de la misma' JList'. – user1329572

+0

addListener (this)? ¿Puedes expandir eso un poco? – Thufir

Respuesta

13

Aquí hay un ejemplo usando el observer pattern, también se observa here, here y here. Tenga en cuenta que también sería posible escuchar el modelo del combo.

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

Entiendo mejor cómo se propociona firePropertyChange, gracias. No estoy muy seguro de cómo pasó los valores reales, necesito leer nuevamente, pero esta fue la pieza que faltaba para mí. – Thufir

+0

Aquí hay un [ejemplo] relacionado (http://stackoverflow.com/a/11832979/230513) que usa un cuadro de diálogo no modal. – trashgod

+0

¡guau! ¡magnífico! Me pregunto si Observer Pattern exige crear una instancia de _Observed Panel_ en _Observer Panel_ –

3

Estaría uso JMenu with JMenuItems con contenidos layed utilizando CardLayout en vez de muy complicada JTabbedPane(s)

+0

+1 buena alternativa, a menudo conectada mediante ['Action'] (http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html). – trashgod

+0

La acción no parece funcionar en todos los controles Swing, sin embargo ..? – Thufir

1

Por mi propia referencia, y para cualquiera que use el generador de NetBeans GUI, esto funciona tan lo que le pasa:

La clase PanelWithList:

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

y Frame.java como conductor:

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 
} 

El ser clave que es panelWithList1PropertyChange al oyente en 'panelWithList' en sí.

Debido PanelWithList.firePropertyChange("list", -1, 1); no puede enviar ni objeto String que veo, no estoy muy seguro de cómo obtener el valor seleccionada hasta el final de la JList hasta el JFrame.

Hmm, bueno el API dice que sí puede enviar Objetos. Tengo que verificarlo.

Creo que es necesario obtener información sobre el modelo que JList está usando hasta el JFrame. Sin embargo, ¿eso no rompe MVC? O tal vez ese es el enfoque equivocado.

+0

Como referencia, [tag: jcalendar] es un ejemplo bastante accesible de un 'JComponent' que implementa' PropertyChangeListener'.Ver también [* A Swing Architecture Overview *] (http://java.sun.com/products/jfc/tsc/articles/architecture/). – trashgod

Cuestiones relacionadas