2010-04-14 165 views
2

我很难过......我试图使用JGoodies绑定将单选按钮绑定到Enum属性。我似乎无法得到它的工作。下面是一个简单的例子,它是一个bean的表格,每个bean都有一个不可变的数字和一个可变的“形容词”属性。单选按钮绑定到“形容词”属性。单击单选按钮确实会更改形容词,并且在表格中选择一个新项目会更新单选按钮,但按下单选按钮不会清除其他单选按钮。为什么是这样的,我该如何解决?Java + Jgoodies绑定:单选按钮绑定

我是否需要使用PropertyChangeSupport? (它似乎没有任何区别)

package com.example.jgoodies; 

import java.beans.PropertyChangeSupport; 
import javax.swing.BoxLayout; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JRadioButton; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.ListSelectionModel; 
import javax.swing.event.ListSelectionEvent; 
import javax.swing.event.ListSelectionListener; 
import javax.swing.table.AbstractTableModel; 
import com.jgoodies.binding.adapter.Bindings; 
import com.jgoodies.binding.beans.BeanAdapter; 
import com.jgoodies.binding.value.ValueModel; 

public class RadioButtonBindingExample extends JFrame { 

    static public <T> T pick(T[] values, int i) 
    { 
     int j = i % values.length; 
     if (j < 0) 
      j += values.length; 
     return values[j]; 
    } 
    enum Adjective { SHORT, TALL, RED, GREEN; 
     @Override public String toString() { return name().toLowerCase(); } 
    } 

    static public class NumberBean 
    { 
     final private PropertyChangeSupport pcs = new PropertyChangeSupport(this); 
     final private int n; 
     private Adjective adjective; 

     public NumberBean(int n) { 
      this.n = n; 

      this.adjective = pick(Adjective.values(), n); 
     } 
     public int getNumber() { return this.n; } 
     public Adjective getAdjective() { return this.adjective; } 
     public void setAdjective(Adjective a) { 
      Adjective old = this.adjective; 
      this.adjective = a; 
      this.pcs.firePropertyChange("adjective", old, a); 
     } 
     public String getLabel() { return this.adjective + " " + n; } 
    } 

    final BeanAdapter<NumberBean> pNumber = 
     new BeanAdapter<NumberBean>((NumberBean)null); 

    final private NumberBeanTableModel numberBeanDataModel = new NumberBeanTableModel(100); 
    final private JPanel numberBeanDisplayPanel = new JPanel(); 

    public static class NumberBeanTableModel extends AbstractTableModel { 
     final private NumberBean[] v; 

     public NumberBeanTableModel(int nrows) 
     { 
      this.v = new NumberBean[nrows]; 
      for (int i = 0; i < nrows; ++i) 
      { 
       this.v[i] = new NumberBean(i); 
      } 
     } 

     public int getColumnCount() { return 2; } 
     public int getRowCount() { return this.v.length;} 
     public NumberBean getNumberBean(int row) 
     { 
      return this.v[row]; 
     } 
     public Object getValueAt(int row, int col) { 
      NumberBean nb = this.v[row]; 
      return (col==0 ? nb.getNumber() : nb.getAdjective()); 
     } 
    }; 

    NumberBeanTableModel getNumberBeanModel() { return this.numberBeanDataModel; } 

    public RadioButtonBindingExample(String title) 
    { 
     super(title); 

     JPanel panel = new JPanel();   
     panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS)); 

     JTable table = new JTable(getNumberBeanModel()); 
     table.getColumnModel().getColumn(0).setHeaderValue("row number"); 
     final ListSelectionModel lsm = table.getSelectionModel(); 
     lsm.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
     lsm.addListSelectionListener(new ListSelectionListener() { 
      @Override public void valueChanged(ListSelectionEvent event) { 
       int i = lsm.getLeadSelectionIndex(); 
       NumberBean nb = getNumberBeanModel().getNumberBean(i); 
       onTableSelection(nb); 
      }}); 
     JScrollPane scrollpane = new JScrollPane(table); 

     JLabel rowLabel = new JLabel(); 
     Bindings.bind(rowLabel, 
         this.pNumber.getValueModel("label")); 

     JPanel subpanel = this.numberBeanDisplayPanel; 
     subpanel.setLayout(new BoxLayout(subpanel, BoxLayout.PAGE_AXIS)); 
     subpanel.add(rowLabel); 

     ValueModel rmodel = this.pNumber.getValueModel("adjective"); 
     for (Adjective adjective : Adjective.values()) 
     { 
      JRadioButton r = new JRadioButton(adjective.toString()); 
      Bindings.bind(r, rmodel, adjective); 
      subpanel.add(r); 
     } 

     subpanel.setVisible(false); 
     panel.add(subpanel); 
     panel.add(scrollpane);  
     getContentPane().add(panel);   
    } 

    protected void onTableSelection(NumberBean nb) { 
     this.pNumber.setBean(nb); 
     this.numberBeanDisplayPanel.setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     RadioButtonBindingExample rbbe = 
      new RadioButtonBindingExample("radio button binding example"); 
     rbbe.pack(); 
     rbbe.setVisible(true); 
     rbbe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 
} 

回答

2

DOH!我想到了。我错过了两件事情:

  1. 属性更改的支持是必要的,我忘了这些线带属性更改支持添加到bean:

    public void addPropertyChangeListener(PropertyChangeListener pcl) 
    { 
        this.pcs.addPropertyChangeListener(pcl); 
    } 
    public void removePropertyChangeListener(PropertyChangeListener pcl) 
    { 
        this.pcs.removePropertyChangeListener(pcl); 
    } 
    
  2. 的BeanAdapter则构造函数接受第二个参数,以确保它正在从有问题的豆得到变化事件:

    final BeanAdapter<NumberBean> pNumber = 
        new BeanAdapter<NumberBean>((NumberBean)null, true);