我很难过......我正在尝试使用JGoodies绑定将radiobutton绑定到Enum属性。我似乎无法让它发挥作用。下面是一个简单的例子,它是一个bean表,每个bean都有一个不可变的数字和一个可变的“形容词”属性。无线电按钮被绑定到“形容词”属性。单击单选按钮确实会更改形容词,并且在表格中选择新项目会更新单选按钮,但按下单选按钮不会清除其他单选按钮。为什么会这样,我该如何解决?
我是否需要使用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);
}
}
答案 0 :(得分:2)
DOH!我想到了。我错过了两件事:
属性更改支持是必要的,我忘了将这些行添加到具有属性更改支持的bean中:
public void addPropertyChangeListener(PropertyChangeListener pcl)
{
this.pcs.addPropertyChangeListener(pcl);
}
public void removePropertyChangeListener(PropertyChangeListener pcl)
{
this.pcs.removePropertyChangeListener(pcl);
}
BeanAdapter构造函数接受第二个参数以确保它从相关bean获取更改事件:
final BeanAdapter<NumberBean> pNumber =
new BeanAdapter<NumberBean>((NumberBean)null, true);