Java 如何使用JGoodies库绑定筛选表?

Java 如何使用JGoodies库绑定筛选表?,java,swing,jgoodies,Java,Swing,Jgoodies,我在一个JavaEE项目中为我的客户工作,在该项目中,我们使用JGoodies将JTable行绑定到表下的文本字段。这很好,但是在一个对话框中,有过滤复选框。单击所有复选框(共三个)时,所有项目均可见。如果选中“非”,则表将保持为空。可以过滤掉一些行,但是使用表模型的JGoodies不知道这种过滤。单击筛选表中的第一行时,未筛选表的第一行元素将显示在下面的文本字段中。有没有办法绕过这个问题 在我看来,问题不是JGoodies问题,而是使用已过滤表的表模型将文本字段与JGoodies绑定 我附加了

我在一个JavaEE项目中为我的客户工作,在该项目中,我们使用JGoodies将JTable行绑定到表下的文本字段。这很好,但是在一个对话框中,有过滤复选框。单击所有复选框(共三个)时,所有项目均可见。如果选中“非”,则表将保持为空。可以过滤掉一些行,但是使用表模型的JGoodies不知道这种过滤。单击筛选表中的第一行时,未筛选表的第一行元素将显示在下面的文本字段中。有没有办法绕过这个问题

在我看来,问题不是JGoodies问题,而是使用已过滤表的表模型将文本字段与JGoodies绑定

我附加了一个示例,其中我无法使用Bindings.bind方法绑定文本字段,但它显示了问题所在。为了我的目的,我采纳了互联网上的发现

该表根据组合框内容进行过滤。如果选择了一般的饮食类型,下面文本字段的绑定就可以了。但是,如果组合框选择了部分表内容,下面的文本字段仍然从(未过滤的)表模型中获取信息。在这里,我需要的信息是如何以正确的方式做到这一点

提前感谢您的帮助

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

/**
 * A simplified mouse listener that reacts when the mouse has been clicked or pressed.
 *
 * @since 2013-08-12
 */
public abstract class ASimpleMouseListener implements MouseListener {

/**
 * Event method that is called when the mouse has been clicked or pressed.
 *
 * @param mouseEvent the mouse event
 */
public abstract void mouseClickedOrPressed(final MouseEvent mouseEvent);

/**
 * {@inheritDoc}
 */
@Override
public void mouseClicked(final MouseEvent mouseEvent) {
    mouseClickedOrPressed(mouseEvent);
}

/**
 * {@inheritDoc}
 */
@Override
public void mousePressed(final MouseEvent mouseEvent) {
    mouseClickedOrPressed(mouseEvent);
}

/**
 * {@inheritDoc}
 */
@Override
public void mouseReleased(final MouseEvent mouseEvent) { }

/**
 * {@inheritDoc}
 */
@Override
public void mouseEntered(final MouseEvent mouseEvent) { }

/**
 * {@inheritDoc}
 */
@Override
public void mouseExited(final MouseEvent mouseEvent) { }
}

/**
 * The enumeration for eating.
 *
 * @since 2014-04-21
 */
public enum EEating {

/** The constant for the general. */
GENERAL,

/** The constant for the lactovegetarian. */
LACTOVEGETARIAN,

/** The constant for the ovolactovegetarian. */
OVOLACTOVEGETARIAN,

/** The constant for the vegan. */
VEGAN,

/** The constant for the vegetarian. */
VEGETARIAN,
;
}

import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.regex.Pattern;

import javax.swing.DefaultRowSorter;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowFilter;
import javax.swing.RowSorter;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

import swing.table.filtering.EEating;
import swing.table.filtering.ImprovedTableModel;

import com.jgoodies.binding.adapter.Bindings;
import com.jgoodies.binding.list.ArrayListModel;
import com.jgoodies.binding.list.SelectionInList;
import common.view.ASimpleMouseListener;

/**
 * The table sort demo.
 */
public class ImprovedTableFilterBindingDemo extends JPanel {

/**
 * The Class WidgetToolkit.
 */
public class WidgetToolkit {

    /** The description. */
    private String description;

    /** The name. */
    private String name;

    /** The producer. */
    private String producer;

    /**
     * Instantiates a new widget toolkit.
     *
     * @param name the name
     * @param description the description
     * @param producer the producer
     */
    public WidgetToolkit(String name, String description, String producer) {
        this.description = description;
        this.name = name;
        this.producer = producer;
    }

    /**
     * Gets the description.
     *
     * @return the description
     */
    public String getDescription() {
        return description;
    }

    /**
     * Gets the name.
     *
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * Gets the producer.
     *
     * @return the producer
     */
    public String getProducer() {
        return producer;
    }

    /**
     * Sets the description.
     *
     * @param description the new description
     */
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * Sets the name.
     *
     * @param name the new name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Sets the producer.
     *
     * @param producer the new producer
     */
    public void setProducer(String producer) {
        this.producer = producer;
    }

}

/** The constant serialVersionUID. */
private static final long serialVersionUID = 2843557005187163601L;

/** The surname column index. */
private final byte SURNAME_COLUMN_INDEX = 1;

/** The food type combo box. */
private final JComboBox<EEating> foodTypeComboBox;

/** The surname text field. */
private final JFormattedTextField surnameTextField;

/** The table row sorter. */
private final RowSorter<? extends TableModel> tableRowSorter;

/** The JTable. */
private JTable jTable;

/** The table model. */
private final TableModel tableModel = new ImprovedTableModel();

/** The array list model. */
private final ArrayListModel<WidgetToolkit> arrayListModel;

/**
 * Instantiates a new table sort demo.
 */
public ImprovedTableFilterBindingDemo() {
    super(new GridLayout(3, 1));

    getTable().setPreferredScrollableViewportSize(new Dimension(500, 70));
    getTable().setFillsViewportHeight(true);
    getTable().setAutoCreateRowSorter(true);

    System.out.println("Test EEating first…");
    final EEating[] eatings = EEating.values();

    for (byte y = 0; y < eatings.length; y++) {
        System.out.println("EEating: " + eatings[y].toString());
    }

    this.arrayListModel = new ArrayListModel<WidgetToolkit>();

    this.arrayListModel.add(new WidgetToolkit("Swing", "Is a Java API", "Sun"));
    this.arrayListModel.add(new WidgetToolkit("Flash", "Is NOT a Java API", "Macromedia"));
    this.arrayListModel.add(new WidgetToolkit("SWT", "Is a Java API", "Eclipse"));
    this.arrayListModel.add(new WidgetToolkit("QT", "Is NOT a Java API", "Trolltech"));
    this.arrayListModel.add(new WidgetToolkit("AWT", "Is a Java API", "Sun"));

    final SelectionInList<?> selectionInList =
            new SelectionInList<ArrayListModel<WidgetToolkit>>(this.arrayListModel);

    final JList<?> jList = new JList<Object>();

    Bindings.bind(jList, selectionInList);

    final ImprovedTableModel model = new ImprovedTableModel();

    tableRowSorter = new TableRowSorter<ImprovedTableModel>(model);

    // Create the scroll pane and add the table to it.
    final JScrollPane scrollPane = new JScrollPane(getTable());
    foodTypeComboBox = new JComboBox<EEating>();

    foodTypeComboBox.addItem(EEating.GENERAL);
    foodTypeComboBox.addItem(EEating.LACTOVEGETARIAN);
    foodTypeComboBox.addItem(EEating.OVOLACTOVEGETARIAN);
    foodTypeComboBox.addItem(EEating.VEGETARIAN);
    // Add the scroll pane to this panel.
    add(foodTypeComboBox);
    add(scrollPane);

    surnameTextField = new JFormattedTextField();

    add(surnameTextField);

    foodTypeComboBox.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(final ActionEvent ae) {
            newFilter();
        }
    });

    getTable().addMouseListener(new ASimpleMouseListener() {

        @Override
        public void mouseClickedOrPressed(MouseEvent mouseEvent) {
            surnameTextField.setText((String) getTable().getModel().getValueAt(
                    getTable().getSelectedRow(), SURNAME_COLUMN_INDEX));
        }
    });

}

/**
 * New filter.
 */
@SuppressWarnings("unchecked")
protected void newFilter() {
    getTable().setRowSorter(tableRowSorter);
    final String BEGIN = "(?i).*?\\b(", END = ")\\b.*";
    final StringBuilder regularExpression = new StringBuilder("(");

    final EEating selection = (EEating) foodTypeComboBox.getSelectedItem();

    switch (selection) {
        case LACTOVEGETARIAN:
            regularExpression.append(BEGIN + EEating.LACTOVEGETARIAN + END);
            break;
        case OVOLACTOVEGETARIAN:
            regularExpression.append(BEGIN + EEating.OVOLACTOVEGETARIAN + END);
            break;
        case VEGAN:
            regularExpression.append(BEGIN + EEating.VEGAN + END);
            break;
        case VEGETARIAN:
            regularExpression.append(BEGIN + EEating.VEGETARIAN + END);
            break;
        default:
            regularExpression.append(".*");
    }

    regularExpression.append(")");
    System.out.println("newFilter(): RegEx = \"" + regularExpression.toString() + "\"");
    final RowFilter<ImprovedTableModel, Object> rowFilter =
            RowFilter.regexFilter(Pattern.compile(
                    regularExpression.toString(), Pattern.CASE_INSENSITIVE).toString()
                    , 4);

    ((DefaultRowSorter<ImprovedTableModel, Integer>) tableRowSorter).setRowFilter(rowFilter);
    tableRowSorter.modelStructureChanged();
}

/**
 * Gets the table.
 *
 * @return the table
 */
private JTable getTable() {
    if (jTable == null) {
        jTable = new JTable(tableModel );
    }
    return jTable;
}

/**
 * Create the GUI and show it. For thread safety,
 * this method should be invoked from the
 * event-dispatching thread.
 */
private static void createAndShowGUI() {
    // Create and set up the window.
    JFrame frame = new JFrame("TableSortDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    // Create and set up the content pane.
    ImprovedTableFilterBindingDemo newContentPane = new ImprovedTableFilterBindingDemo();
    newContentPane.setOpaque(true); //content panes must be opaque
    frame.setContentPane(newContentPane);

    // Display the window.
    frame.pack();
    frame.setVisible(true);
}

/**
 * The main method.
 *
 * @param arguments the arguments
 */
public static void main(final String[] arguments) {
    // Schedule a job for the event-dispatching thread:
    // creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            createAndShowGUI();
        }
    });
}
}

import javax.swing.table.AbstractTableModel;

/**
 * The improved table sort model
 *
 * @since 2014-04-21
 */
public class ImprovedTableModel extends AbstractTableModel {

/** Automatically generated serial version UID */
private static final long serialVersionUID = 8348216048683404697L;

/** The column names. */
private final String[] columnNames = { "First Name",
                                        "Last Name",
                                        "Sport",
                                        "# of Years",
                                        "Vegetarian",
                                    };

/** The data. */
private final Object[][] data = {
    { "Kathy", "Smith", "Snowboarding", 5.5, EEating.GENERAL },
    { "John", "Doe", "Rowing", 3.03, EEating.VEGETARIAN },
    { "Sue", "Black", "Knitting", 2.78, EEating.GENERAL },
    { "Jane", "White", "Speed reading", 20.7, EEating.LACTOVEGETARIAN },
    { "Jonathan", "Browny", "Pool", 10.01, EEating.OVOLACTOVEGETARIAN },
    { "Joe", "Brown", "Pool", 10.98, EEating.GENERAL },
};

/* (non-Javadoc)
 * @see javax.swing.table.TableModel#getColumnCount()
 */
@Override
public int getColumnCount() {
    return columnNames.length;
}

/* (non-Javadoc)
 * @see javax.swing.table.TableModel#getRowCount()
 */
@Override
public int getRowCount() {
    return data.length;
}

/* (non-Javadoc)
 * @see javax.swing.table.AbstractTableModel#getColumnName(final int)
 */
@Override
public String getColumnName(final int columnIndex) {
    return columnNames[columnIndex];
}

/* (non-Javadoc)
 * @see javax.swing.table.TableModel#getValueAt(final int, int)
 */
@Override
public Object getValueAt(final int rowIndex, final int columnIndex) {
    return data[rowIndex][columnIndex];
}

/*
 * JTable uses this method to determine the default renderer/
 * editor for each cell. If we didn't implement this method,
 * then the last column would contain text ("true"/"false"),
 * rather than a check box.
 */
/* (non-Javadoc)
 * @see javax.swing.table.AbstractTableModel#getColumnClass(int)
 */
@Override
@SuppressWarnings("unchecked")
public Class getColumnClass(final int columnIndex) {
    return getValueAt(0, columnIndex).getClass();
}

/*
 * Don't need to implement this method unless your table's editable.
 */
/* (non-Javadoc)
 * @see javax.swing.table.AbstractTableModel#isCellEditable(int, int)
 */
@Override
public boolean isCellEditable(final int rowIndex, final int columnIndex) {
    // Note that the data/cell address is constant,
    // no matter where the cell appears on screen.
    return (columnIndex < 2) ? false : true;
}

/*
 * Don't need to implement this method unless your table's
 * data can change.
 */
/* (non-Javadoc)
 * @see javax.swing.table.AbstractTableModel#setValueAt(java.lang.Object, int, int)
 */
@Override
public void setValueAt(final Object value, final int rowIndex, final int columnIndex) {
    data[rowIndex][columnIndex] = value;
}
  }
import java.awt.event.MouseEvent;
导入java.awt.event.MouseListener;
/**
*一个简化的鼠标侦听器,当鼠标被单击或按下时会做出反应。
*
*@自2013年8月12日起
*/
公共抽象类ASimpleMouseListener实现了MouseListener{
/**
*单击或按下鼠标时调用的事件方法。
*
*@param mouseEvent鼠标事件
*/
公开摘要无效mouseClickedOrPressed(最终MouseEvent MouseEvent);
/**
*{@inheritardoc}
*/
@凌驾
公共无效鼠标单击(最终鼠标事件鼠标事件){
mouseClickedOrPressed(mouseEvent);
}
/**
*{@inheritardoc}
*/
@凌驾
公共无效鼠标按下(最终鼠标事件鼠标事件){
mouseClickedOrPressed(mouseEvent);
}
/**
*{@inheritardoc}
*/
@凌驾
公共无效MouseEvent(最终MouseEvent MouseEvent){}
/**
*{@inheritardoc}
*/
@凌驾
公共无效MouseEvent(最终MouseEvent MouseEvent){}
/**
*{@inheritardoc}
*/
@凌驾
public void mouseExited(最终MouseEvent MouseEvent){}
}
/**
*食物的计数。
*
*@自2014年4月21日起
*/
公共枚举{
/**一般情况下的常数*/
将军,
/**素食主义者的常数*/
素食主义者,
/**素食者的常数*/
卵生素食者,
/**素食主义者的常数*/
素食主义者,
/**对素食者来说这是不变的*/
素食主义者
;
}
导入java.awt.Dimension;
导入java.awt.GridLayout;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.MouseEvent;
导入java.util.regex.Pattern;
导入javax.swing.DefaultRowSorter;
导入javax.swing.JComboBox;
导入javax.swing.JFormattedTextField;
导入javax.swing.JFrame;
导入javax.swing.JList;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.JTable;
导入javax.swing.RowFilter;
导入javax.swing.RowSorter;
导入javax.swing.table.TableModel;
导入javax.swing.table.TableRowSorter;
导入swing.table.filtering.EEating;
导入swing.table.filtering.ImprovedTableModel;
导入com.jgoodies.binding.adapter.Bindings;
导入com.jgoodies.binding.list.ArrayListModel;
导入com.jgoodies.binding.list.selectionList;
导入common.view.ASimpleMouseListener;
/**
*表格排序演示。
*/
公共类改进的TableFilterBindingDemo扩展了JPanel{
/**
*WidgetToolkit类。
*/
公共类WidgetToolkit{
/**描述*/
私有字符串描述;
/**名字*/
私有字符串名称;
/**制片人*/
私人琴弦制作人;
/**
*实例化一个新的小部件工具包。
*
*@param name指定名称
*@param description描述
*@param producer生产者
*/
公共WidgetToolkit(字符串名称、字符串描述、字符串生成器){
this.description=描述;
this.name=名称;
this.producer=生产者;
}
/**
*获取描述。
*
*@返回描述
*/
公共字符串getDescription(){
返回说明;
}
/**
*获取名称。
*
*@返回名称
*/
公共字符串getName(){
返回名称;
}
/**
*找到制片人。
*
*@返回制作人
*/
公共字符串getProducer(){
回报生产者;
}
/**
*设置描述。
*
*@param description新的描述
*/
公共void集合描述(字符串描述){
this.description=描述;
}
/**
*设置名称。
*
*@param name新名称
*/
公共void集合名(字符串名){
this.name=名称;
}
/**
*设置制作人。
*
*@param producer新制作人
*/
公共无效集生成器(字符串生成器){
this.producer=生产者;
}
}
/**常量serialVersionId*/
私有静态最终长serialVersionUID=28435570505187163601L;
/**姓氏列索引*/
私有最终字节姓氏列索引=1;
/**食物型组合盒*/
私有最终JComboBox foodTypeComboBox;
/**姓氏文本字段*/
私有最终JFormattedTextField姓氏TextField;
/**桌子行分拣机*/
专用最终行分拣机选择列表=
新的SelectionList(this.arrayListModel);
最终JList JList=新JList();
Bindings.bind(jList,selectionList);
最终改进的表格模型=新的改进的表格模型();
tableRowSorter=新的tableRowSorter(型号);
//创建滚动窗格并将表添加到其中。
最终JScrollPane