2010-04-14 116 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);