多表单选

时间:2016-10-20 15:07:13

标签: java swing jtable

我正在开发一个应用程序,它利用一组JTable,每个JTable由不同的数据模型支持(例如,每个表中的不同对象)。用例需要一组表的多重排除范围(即,在任何给定点可以选择每组表最多1行)。

JDK ButtonGroup为一组AbstractButtons实现此功能。有没有人见过表的类似实现?如果没有,这是最好的追求方法吗?也许,有一个更好的设计模式/习语。

1 个答案:

答案 0 :(得分:2)

您必须自己动手,但这可以通过使用自定义ListSelectionListener来完成。这样的事情可以奏效:

@Override
public void valueChanged(ListSelectionEvent e) {
    ListSelectionModel selectedModel = (ListSelectionModel) e.getSource();
    for (ListSelectionModel model : models) {
        if (model != selectedModel) {
            model.removeListSelectionListener(this);
            model.clearSelection();
            model.addListSelectionListener(this);
        }
    }
}   

其中models是一个ArrayList,它包含所有JTable的ListSelectionModels。

例如:

import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;

@SuppressWarnings("serial")
public class ListSelectionListenerExample extends JPanel {
    private static final int TABLE_COUNT = 4;
    private static final Integer[][] DATA = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
    private static final String[] COL_NAMES = {"A", "B", "C"};

    public ListSelectionListenerExample() {
        ListSelectionGroup listSelectionGroup = new ListSelectionGroup();
        setLayout(new GridLayout(1, 0));
        for (int i = 0; i < TABLE_COUNT; i++) {
            DefaultTableModel model = new DefaultTableModel(DATA, COL_NAMES);
            JTable table = new JTable(model);
            ListSelectionModel selectionModel = table.getSelectionModel();
            listSelectionGroup.register(selectionModel);
            add(new JScrollPane(table));
        }
    }

    private static void createAndShowGui() {
        ListSelectionListenerExample mainPanel = new ListSelectionListenerExample();

        JFrame frame = new JFrame("ListSelectionListener Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

import java.util.ArrayList;
import java.util.List;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class ListSelectionGroup {

    private List<ListSelectionModel> models = new ArrayList<>();
    private MyListener myListener = new MyListener();

    public void register(ListSelectionModel model) {
        models.add(model);
        model.addListSelectionListener(myListener);
    }

    // overload method for convenience
    public void register(JTable table) {
        register(table.getSelectionModel());
    }

    // make a private inner class so that we don't accidentally add this to a 
    // ListSelectionModel without going through the register method
    private class MyListener implements ListSelectionListener {

        @Override
        public void valueChanged(ListSelectionEvent e) {
            ListSelectionModel selectedModel = (ListSelectionModel) e.getSource();
            for (ListSelectionModel model : models) {
                if (model != selectedModel) {
                    model.removeListSelectionListener(this);
                    model.clearSelection();
                    model.addListSelectionListener(this);
                }
            }
        }
    }
}