JTable使用ctrl + click组合选择多个不连续的单元格 [英] JTable select multiple non-contiguous cells with ctrl+click combination

查看:100
本文介绍了JTable使用ctrl + click组合选择多个不连续的单元格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个JTable,它将能够使用 ctrl + click 组合选择多个非连续的单元格.到目前为止,当我从同一行中选择不连续的单元格时,效果很好.

I want to create a JTable that I'll be able to select multiple, non-contiguous cells with ctrl+click combination. So far, when I select not contiguous cells from the same row it works fine.

但是当我从不同的行中选择单元格时,我得到了

But when I select cells from different row, I get this

这可以帮我吗?

这是我的代码

Class TestTimeTable

public class TestTimeTable extends JFrame{
private final int rows = 10;
private final int cols = 8;
private final String daysOfTheWeek[] = {"ΔΕΥΤΕΡΑ", "ΤΡΙΤΗ", "ΤΕΤΑΡΤΗ", "ΠΕΜΠΤΗ", "ΠΑΡΑΣΚΕΥΗ"};
private final JPanel jTablePanel;
private final JScrollPane scrollPane;
private final JTable timeTable;
private final Object[][] rowData;

public TestTimeTable(){
    this.rowData = new Object[this.rows][this.cols];
    this.timeTable = new JTable(this.rowData,this.daysOfTheWeek){
                                                                    @Override
                                                                   public boolean isCellEditable(int row, int column) {
                                                                       return false;
                                                                   }
                                                                };        
    this.timeTable.setRowHeight(200, 200);
    this.timeTable.setFillsViewportHeight(true);
    this.timeTable.setOpaque(true);
    this.timeTable.setColumnSelectionAllowed(true);
    this.timeTable.setRowSelectionAllowed(true);
    this.timeTable.setCellSelectionEnabled(true);
    this.timeTable.setDefaultRenderer(Object.class, new BoardTableCellRenderer());
    this.scrollPane = new JScrollPane(this.timeTable, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

    this.jTablePanel = new JPanel();
    this.jTablePanel.add(this.scrollPane);
    getContentPane().add(new JScrollPane(this.timeTable), BorderLayout.CENTER);

}
 public void createAndShowUI(){
    setSize(600, 600);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
}

public static void main(String[] argas){
    TestTimeTable tt = new TestTimeTable();
    tt.createAndShowUI();
}

Class BoardTableCellRenderer

class BoardTableCellRenderer  extends DefaultTableCellRenderer{
    Component c;
    private static final long serialVersionUID = 1L;
    private final Color selectionBlue = new Color(131,166,198);
    private final MatteBorder border = new MatteBorder(1, 1, 0, 0, Color.BLACK);
     @Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

    if (table.isCellSelected(row, column)){
        c.setBackground(this.selectionBlue);
        setBorder(this.border);
    }
    else {
        c.setBackground(Color.WHITE);
    }
    return c;
    }
}

任何意见都会非常有帮助.预先谢谢你.

Any opinion would be very helpful. Thank you in advance.

推荐答案

这似乎是JTables的常见问题,您不能选择不连续的单元格,但是可以显示伪"不连续的单元格.

Well this seems to be a common problem with JTables, you can not select non-contiguous cells but you can show "fake" non-contiguous cells.

您可以检查我的解决方案,但并不完美.在那种解决方案中,班次"选择不起作用.

You can check my solution but is not perfect. In that solution the "shift" selections doesn't work.

这个想法是要覆盖 JTable的 isCellSelected (int行,int列)和 changeSelection (int rowIndex,int columnIndex,布尔切换,布尔扩展) .

The idea is to override isCellSelected(int row, int colum) and changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) of JTable.

因此,我存储了单独选择的单元格,并在isCellSelected中使用它们.

So I store the individually selected cells and use them in isCellSelected.

通过单元格存储创建这些类:

Create these classes fom cell storage :

class Cell {
    private int row;

    private int column;

    public Cell(int row, int column) {
        this.row = row;
        this.column = column;
    }

    public boolean is(int r, int c) {
        return row == r && column == c;
    }
}

class CellSelectionSet {
    private ArrayList<Cell> cells = new ArrayList<TestTimeTable.Cell>();

    public void add(int r, int c) {
        if (!contains(r, c)) {
            cells.add(new Cell(r, c));
        }
    }

    public boolean containsOneOrLess() {
        return cells.size() <= 1;
    }

    public boolean contains(int r, int c) {
        for (Cell cell : cells) {
            if (cell.is(r, c)) {
                return true;
            }
        }
        return false;
    }

    public void clear() {
        cells.clear();
    }


}

在JTable上您可以使用它:

and at JTable you can use that :

this.timeTable = new JTable(this.rowData, this.daysOfTheWeek) {
        CellSelectionSet cellSelectionSet = new CellSelectionSet();

        @Override
        public boolean isCellEditable(int row, int column) {
            return false;
        }

        @Override
        public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) {
            super.changeSelection(rowIndex, columnIndex, toggle, extend);

            if (toggle) {
                    cellSelectionSet.add(rowIndex, columnIndex);

            } else {
                if (extend) {
                    cellSelectionSet.add(rowIndex, columnIndex);

                } else {
                    // reset
                    cellSelectionSet.clear();
                    cellSelectionSet.add(rowIndex, columnIndex);
                }
            }

      }

        @Override
        public boolean isCellSelected(int row, int column) {
            if (cellSelectionSet.containsOneOrLess()) {
                // show the default
                return super.isCellSelected(row, column);
            }
            return cellSelectionSet.contains(row, column);
        }

    };

希望对您有帮助.

这篇关于JTable使用ctrl + click组合选择多个不连续的单元格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆