首页 > 代码库 > RowSelectableTableModel proxy for TableModel
RowSelectableTableModel proxy for TableModel
群里看到有的同学需要在某 JTable 内容的基础上,多出一列 checkbox,用于某种多选,不是第一次看到这种需求了,所以写了这个“通用”的代理实现。
大体写了一下,没有仔细处理原TableModel的事件,所以使用的时候要注意原TableModel不能fire基于cell的更新事件,不能添加删除列。
先扔这里,有时间再琢磨。
/* * Copyright 2014 raistlic@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableModel; import java.util.HashSet; import java.util.Iterator; import java.util.Set; /** * Currently not supporting column insertion or deletion, that is, if the wrapped (original) table * model inserted or deleted a column, not sure if the table will correctly pick up the event and * works fine afterwards, behaviour unknown. * * <p/> * Also not supporting cell based update event which column index is greater than the selectable * column. * * TODO: Builder and its methods not Java doc-ed yet. * TODO: properly delegate & translate events for the original table model. * * @author raistlic * @since 2014-08-26 */ public class RowSelectableTableModel extends AbstractTableModel implements TableModel { public static RowSelectableTableModel wrap(TableModel tableModel) { return builderFor(tableModel).build(); } public static Builder builderFor(TableModel tableModel) { if (tableModel == null) { throw new NullPointerException("'tableModel' is null."); } return new Builder(tableModel); } public static class Builder { private TableModel tableModel; private int limit; private int selectableColumnIndex; private String selectableColumnName; private Builder(TableModel tableModel) { this.tableModel = tableModel; this.limit = 0; selectableColumnIndex = 0; selectableColumnName = "Select"; } public Builder withSelectionLimit(int limit) { this.limit = limit; return this; } public Builder withSelectableColumnAt(int column) { if (column < 0) { throw new IndexOutOfBoundsException("Selectable column index out of bounds: " + column); } if (column > tableModel.getColumnCount()) { throw new IndexOutOfBoundsException( "Selectable column index out of bounds: " + column + " / " + tableModel.getColumnCount()); } this.selectableColumnIndex = column; return this; } public Builder withSelectableColumnName(String name) { this.selectableColumnName = (name == null) ? "" : name; return this; } public RowSelectableTableModel build() { RowSelectableTableModel result = new RowSelectableTableModel(this); tableModel.addTableModelListener(result.new OriginalModelAdapter()); return result; } } private final TableModel tableModel; private final int limit; private final int selectableColumnIndex; private final String selectableColumnName; private Set<Integer> selected; private int selectionBasedRowCount; private RowSelectableTableModel(Builder builder) { this.tableModel = builder.tableModel; this.limit = builder.limit; this.selectableColumnIndex = builder.selectableColumnIndex; this.selectableColumnName = builder.selectableColumnName; this.selectionBasedRowCount = tableModel.getRowCount(); this.selected = new HashSet<Integer>(); } public Set<Integer> getSelectedRows() { // defensive copy: return new HashSet<Integer>(selected); } @Override public int getRowCount() { return tableModel.getRowCount(); } @Override public int getColumnCount() { return 1 + tableModel.getColumnCount(); } @Override public String getColumnName(int columnIndex) { if (columnIndex < selectableColumnIndex) { return tableModel.getColumnName(columnIndex); } else if (columnIndex == selectableColumnIndex) { return selectableColumnName; } else { return tableModel.getColumnName(columnIndex - 1); } } @Override public Class<?> getColumnClass(int columnIndex) { if (columnIndex < selectableColumnIndex) { return tableModel.getColumnClass(columnIndex); } else if (columnIndex == selectableColumnIndex) { return boolean.class; } else { return tableModel.getColumnClass(columnIndex - 1); } } @Override public boolean isCellEditable(int rowIndex, int columnIndex) { if (columnIndex < selectableColumnIndex) { return tableModel.isCellEditable(rowIndex, columnIndex); } else if (columnIndex == selectableColumnIndex) { return limit <= 0 || selected.size() < limit; } else { return tableModel.isCellEditable(rowIndex, columnIndex - 1); } } @Override public Object getValueAt(int rowIndex, int columnIndex) { if (columnIndex < selectableColumnIndex) { return tableModel.getValueAt(rowIndex, columnIndex); } else if (columnIndex == selectableColumnIndex) { return selected.contains(rowIndex); } else { return tableModel.getValueAt(rowIndex, columnIndex - 1); } } @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { if (columnIndex < selectableColumnIndex) { tableModel.setValueAt(aValue, rowIndex, columnIndex); } else if (columnIndex == selectableColumnIndex) { @SuppressWarnings("unchecked") boolean value = http://www.mamicode.com/(Boolean) aValue;>RowSelectableTableModel proxy for TableModel
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。