如何将一个窗格连线到另一个窗格
如何将输出连接到paneWithList
?
PaneWithList
在其JList
上有一个监听器,这样所选择的行就输出到控制台。 如何将输出定向到输出上的JTextPane
?
PaneWithList
触发Main
拾取的事件吗? 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); } }
下面是一个使用观察者模式的例子, 在这里和这里也可以看到。 请注意,也可以听组合模型。
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; } } }
我将使用JMenu与JMenuItems内容使用CardLayout而不是非常复杂的JTabbedPane(s)
对于我自己的参考,对于任何使用Netbeans GUI构建器的人来说,
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); } }
和Frame.java作为驱动程序:
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 }
关键在于panelWithList1PropertyChange
是'panelWithList'本身的监听器。
因为PanelWithList.firePropertyChange("list", -1, 1);
不能发送对象和我看到的字符串,我不完全确定如何获取从JList一直选择到JFrame的值。
嗯, API说是的,它可以发送对象。 必须检查出来。
我认为有必要得到关于JList使用JFrame的模型的一些信息。 但是,这不是打破了MVC? 或者也许这是错误的方法。