所以我基本上不希望第二列出现在我的JTable排序中,反之亦然。一张图片胜过千言万语所以这里有一张图片向您展示我的意思。 http://i48.tinypic.com/2rzpfe9.jpg 因此,当我在JTable中搜索单词“apple”时,您可以看到第二列仍然存在,因为第一列中包含单词“apple”而不是第二列。那么如何才能使其他列不显示,反之亦然?
编辑:我编辑了下面的代码以匹配MadProgrammer所说的但它仍然无法正常工作。新图片http://i48.tinypic.com/2rzpfe9.jpg 这一次的文本已经消失,但专栏仍然存在。这次我做错了什么?
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.RowFilter;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
public class sorter extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
public sorter() {
initComponents();
panel.setLayout(null);
search.setBounds(30,10,400,25);
search_button.setBounds(430,10,30,25);
}
public class FilterEntry extends RowFilter.Entry<TableModel, Integer> {
private final TableModel model;
private final Object value;
private final int rowIndex;
public FilterEntry(TableModel model, Object value, int rowIndex) {
this.model = model;
this.value = value;
this.rowIndex = rowIndex;
}
@Override
public TableModel getModel() {
return model;
}
@Override
public int getValueCount() {
return getModel().getColumnCount();
}
@Override
public Object getValue(int index) {
return value;
}
@Override
public Integer getIdentifier() {
return rowIndex;
}
}
private void initComponents() {
panel = new JPanel();
logo = new JLabel();
pane = new JScrollPane();
search = new JTextField();
search_button = new JButton();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setBackground(new Color(255, 255, 204));
setResizable(false);
panel.setBackground(new Color(51, 51, 51));
panel.setPreferredSize(new Dimension(290, 40));
javax.swing.GroupLayout panelLayout = new javax.swing.GroupLayout(panel);
panel.setLayout(panelLayout);
panelLayout.setHorizontalGroup(
panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelLayout.createSequentialGroup()
.addGap(198, 198, 198)
.addComponent(logo)
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
panelLayout.setVerticalGroup(
panelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, panelLayout.createSequentialGroup()
.addContainerGap(0, Short.MAX_VALUE)
.addComponent(logo)
.addContainerGap())
);
search.setText("");
search.setToolTipText("");
search.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.LOWERED));
search.setPreferredSize(new java.awt.Dimension(30, 15));
search_button.setIcon(new javax.swing.ImageIcon(getClass().getResource("/search.JPG"))); // NOI18N
search_button.setAlignmentY(0.0F);
search_button.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
search_button.setContentAreaFilled(false);
search_button.setIconTextGap(1);
search_button.setMargin(new java.awt.Insets(1, 4, 1, 4));
search_button.setMaximumSize(new java.awt.Dimension(5, 30));
search_button.setMinimumSize(new java.awt.Dimension(5, 30));
search_button.setPreferredSize(new java.awt.Dimension(30, 20));
javax.swing.GroupLayout panelLayout1 = new javax.swing.GroupLayout(panel);
panel.setLayout(panelLayout1);
panelLayout1.setHorizontalGroup(
panelLayout1.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelLayout1.createSequentialGroup()
.addGroup(panelLayout1.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelLayout1.createSequentialGroup()
.addGap(25, 25, 25)
.addComponent(search, javax.swing.GroupLayout.PREFERRED_SIZE, 400, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, 0)
.addComponent(search_button, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(panelLayout1.createSequentialGroup()
.addGap(174, 174, 174)
.addComponent(logo)))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
panelLayout1.setVerticalGroup(
panelLayout1.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(panelLayout1.createSequentialGroup()
.addGap(5, 5, 5)
.addComponent(logo)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addGroup(panelLayout1.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(search, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addComponent(search_button, javax.swing.GroupLayout.PREFERRED_SIZE, 26, Short.MAX_VALUE))
.addContainerGap())
);
ImageIcon Icon1 = getImage("lemon.jpg");
ImageIcon Icon2 = getImage("az.jpg");
ImageIcon Icon3 = getImage("aaa.jpg");
ImageIcon Icon4 = getImage("ba.jpg");
ImageIcon Icon5 = getImage("bas.jpg");
ImageIcon Icon6 = getImage("cookies.jpg");
String[] columnNames = {"A", "Section 1","B", "Section 2"};
Object[][] data =
{
{Icon1, "Lemon", Icon2, "Grapes"},
{Icon3, "Apple", Icon4, "Banana"},
{Icon5, "Orange", Icon6, "Cookies"},
};
DefaultTableModel model = new DefaultTableModel(data, columnNames);
JTable table = new JTable(model)
{
/**
*
*/
private static final long serialVersionUID = 1L;
@SuppressWarnings({ "unchecked", "rawtypes" })
public Class getColumnClass(int column)
{
return getValueAt(0, column).getClass();
}
public boolean isCellEditable(int row, int col) {
return false;
}
};
class MultiLineCellRenderer extends JTextArea implements TableCellRenderer {
/**
*
*/
private static final long serialVersionUID = 1L;
public MultiLineCellRenderer() {
setLineWrap(true);
setWrapStyleWord(true);
setOpaque(true);
}
public Component getTableCellRendererComponent(JTable table, Object value,boolean isSelected, boolean hasFocus, int row, int column) {
RowFilter rowFilter = ((TableRowSorter) table.getRowSorter()).getRowFilter();
if (rowFilter != null) {
if (!rowFilter.include(new FilterEntry(table.getModel(), value, row))) {
value = null;
}
} else {
setForeground(table.getForeground());
setBackground(table.getBackground());
}
setFont(table.getFont());
if (hasFocus) {
setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
if (table.isCellEditable(row, column)) {
setForeground(UIManager.getColor("Table.focusCellForeground"));
setBackground(UIManager.getColor("Table.focusCellBackground"));
}
} else {
setBorder(new EmptyBorder(1, 2, 1, 2));
}
setText((value == null) ? "" : value.toString());
return this;
}
}
// Sorter Code.
table = new JTable(model);
final TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
table.setRowSorter(sorter);
search_button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String text = search.getText();
if (text.length() == 0) {
sorter.setRowFilter(null);
} else {
sorter.setRowFilter(RowFilter.regexFilter("(?i)"+ text));
}
}
});
// sorter code ends here.
table.setRowHeight(50);
pane.setViewportView(table);
table.setBackground(new Color(255, 255, 204));
table.setDefaultRenderer(String.class, new MultiLineCellRenderer());
table.getColumnModel().getColumn(1).setCellRenderer(new MultiLineCellRenderer());
table.getColumnModel().getColumn(3).setCellRenderer(new MultiLineCellRenderer());
table.getColumnModel().getColumn(0).setResizable(false);
table.getColumnModel().getColumn(1).setResizable(false);
table.getColumnModel().getColumn(2).setResizable(false);
table.getColumnModel().getColumn(3).setResizable(false);
table.setFocusable(false);
table.setRowSelectionAllowed(false);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
int vColIndex = 0;
TableColumn col = table.getColumnModel().getColumn(vColIndex);
int width = 33;
col.setPreferredWidth(width);
int vColIndex1 = 1;
TableColumn col1 = table.getColumnModel().getColumn(vColIndex1);
int width1 = 216;
col1.setPreferredWidth(width1);
int vColIndex11 = 2;
TableColumn col11 = table.getColumnModel().getColumn(vColIndex11);
int width11 = 33;
col11.setPreferredWidth(width11);
int vColIndex111 = 3;
TableColumn col111 = table.getColumnModel().getColumn(vColIndex111);
int width111 = 216;
col111.setPreferredWidth(width111);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(panel, javax.swing.GroupLayout.DEFAULT_SIZE, 500, Short.MAX_VALUE)
.addComponent(pane)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addComponent(panel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE)
.addComponent(pane, javax.swing.GroupLayout.PREFERRED_SIZE, 250, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 0, Short.MAX_VALUE)
.addGap(0, 0, Short.MAX_VALUE))
);
pack();
}
private ImageIcon getImage(String path)
{
java.net.URL url = getClass().getResource(path);
if (url != null)
return (new ImageIcon(url));
else
{
System.out.println(url);
return null;
}
}
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Windows".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(sorter.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(sorter.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(sorter.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(sorter.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new sorter().setVisible(true);
}
});
}
private JLabel logo;
private JScrollPane pane;
private JPanel panel;
private JTextField search;
private JButton search_button;
}
答案 0 :(得分:0)
您可以修改渲染器,使其只显示与滤镜匹配的值。
鉴于您使用TableRowSorter
这一事实使其变得更容易。
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
RowFilter rowFilter = ((TableRowSorter) table.getRowSorter()).getRowFilter();
if (rowFilter != null) {
if (!rowFilter.include(new FilterEntry(table.getModel(), value, row))) {
value = null;
}
}
// The rest of the code...
}
现在,您需要实现自己的FilterEntry
:P
public class FilterEntry extends RowFilter.Entry<TableModel, Integer> {
private final TableModel model;
private final Object value;
private final int rowIndex;
public FilterEntry(TableModel model, Object value, int rowIndex) {
this.model = model;
this.value = value;
this.rowIndex = rowIndex;
}
@Override
public TableModel getModel() {
return model;
}
@Override
public int getValueCount() {
return getModel().getColumnCount();
}
@Override
public Object getValue(int index) {
return value;
}
@Override
public Integer getIdentifier() {
return rowIndex;
}
}
为了让这个例子起作用,我不得不添加
table.getColumnModel().getColumn(1).setCellRenderer(new MultiLineCellRenderer());
table.getColumnModel().getColumn(3).setCellRenderer(new MultiLineCellRenderer());
在您设置默认单元格渲染器的位置
使用Mutable列模型更新
您遇到的更大问题是能够打开和关闭列。 Trashgod提供了example这个,我已经包含了一个样本模型。
您需要做的下一件事是,每次过滤器更改时,您需要遍历整个模型并确定应包含哪些内容以及不应包含哪些内容。
这就是我实现它的方式......
首先,您需要提供自己的ColumnModel
// Changing the column model effects the data model as well...
TableModel model = table.getModel();
table.setColumnModel(new MutableColumnModel());
table.setModel(model);
在您的动作侦听器中,应用过滤器后,您需要调用updateColumns
protected void updateColumns() {
RowFilter rowFilter = ((TableRowSorter) tblSearch.getRowSorter()).getRowFilter();
MutableTableColumnModel columnModel = (MutableTableColumnModel) tblSearch.getColumnModel();
// Want to reset the columns, otherwise we run into problems doing the value
// lookup, as the table doesn't think it exists.
// You might be able to get around it with this instead, but we need
// to rest the view any way...
// columnModel.getColumnByModelIndex(col);
columnModel.setColumnVisible(0, true);
columnModel.setColumnVisible(1, true);
columnModel.setColumnVisible(2, true);
columnModel.setColumnVisible(3, true);
if (rowFilter != null) {
Map<Integer, Boolean> mapColumns = new HashMap<Integer, Boolean>(tblSearch.getColumnCount());
for (int row = 0; row < tblSearch.getRowCount(); row++) {
boolean include = includeValue(row, 1, rowFilter);
mapColumns.put(0, include);
mapColumns.put(1, include);
include = includeValue(row, 3, rowFilter);
mapColumns.put(2, include);
mapColumns.put(3, include);
}
for (Integer col : mapColumns.keySet()) {
columnModel.setColumnVisible(col, mapColumns.get(col));
}
}
}
protected boolean includeValue(int row, int col, RowFilter filter) {
Object value = tblSearch.getValueAt(row, col);
boolean include = filter.include(new FilterEntry(tblSearch.getModel(), value, row));
System.out.println("include " + value + "; include = " + include);
return include;
}
MutableColumnModel
public class MutableTableColumnModel extends DefaultTableColumnModel {
private List<TableColumn> allTableColumns;
public MutableTableColumnModel() {
allTableColumns = new ArrayList<TableColumn>(10);
}
public void setColumnVisible(int index, boolean visible) {
setColumnVisible(getColumnByModelIndex(index), visible);
}
/**
* Sets the visibility of the specified TableColumn.
* The call is ignored if the TableColumn is not found in this column model
* or its visibility status did not change.
* <p>
*
* @param aColumn the column to show/hide
* @param visible its new visibility status
*/
// listeners will receive columnAdded()/columnRemoved() event
public void setColumnVisible(TableColumn column, boolean visible) {
if (column != null) {
if (!visible) {
if (isColumnVisible(column)) {
super.removeColumn(column);
}
} else {
// find the visible index of the column:
// iterate through both collections of visible and all columns, counting
// visible columns up to the one that's about to be shown again
int noVisibleColumns = tableColumns.size();
int noInvisibleColumns = allTableColumns.size();
int visibleIndex = 0;
for (int invisibleIndex = 0; invisibleIndex < noInvisibleColumns; ++invisibleIndex) {
TableColumn visibleColumn = (visibleIndex < noVisibleColumns ? (TableColumn) tableColumns.get(visibleIndex) : null);
TableColumn testColumn = (TableColumn) allTableColumns.get(invisibleIndex);
if (testColumn == column) {
if (visibleColumn != column) {
super.addColumn(column);
super.moveColumn(tableColumns.size() - 1, visibleIndex);
}
return; // ####################
}
if (testColumn == visibleColumn) {
++visibleIndex;
}
}
}
}
}
/**
* Makes all columns in this model visible
*/
public void showAllColumns() {
int noColumns = allTableColumns.size();
for (int columnIndex = 0; columnIndex < noColumns; ++columnIndex) {
TableColumn visibleColumn = (columnIndex < tableColumns.size() ? (TableColumn) tableColumns.get(columnIndex) : null);
TableColumn invisibleColumn = (TableColumn) allTableColumns.get(columnIndex);
if (visibleColumn != invisibleColumn) {
super.addColumn(invisibleColumn);
super.moveColumn(tableColumns.size() - 1, columnIndex);
}
}
}
/**
* Maps the index of the column in the table model at
* <code>modelColumnIndex</code> to the TableColumn object.
* There may me multiple TableColumn objects showing the same model column, though this is uncommon.
* This method will always return the first visible or else the first invisible column with the specified index.
* @param modelColumnIndex index of column in table model
* @return table column object or null if no such column in this column model
*/
public TableColumn getColumnByModelIndex(int modelColumnIndex) {
for (int columnIndex = 0; columnIndex < allTableColumns.size(); ++columnIndex) {
TableColumn column = (TableColumn) allTableColumns.get(columnIndex);
if (column.getModelIndex() == modelColumnIndex) {
return column;
}
}
return null;
}
/** Checks wether the specified column is currently visible.
* @param aColumn column to check
* @return visibility of specified column (false if there is no such column at all. [It's not visible, right?])
*/
public boolean isColumnVisible(TableColumn aColumn) {
return (tableColumns.indexOf(aColumn) >= 0);
}
/** Append <code>column</code> to the right of exisiting columns.
* Posts <code>columnAdded</code> event.
* @param column The column to be added
* @see #removeColumn
* @exception IllegalArgumentException if <code>column</code> is <code>null</code>
*/
public void addColumn(TableColumn column) {
allTableColumns.add(column);
super.addColumn(column);
}
/** Removes <code>column</code> from this column model.
* Posts <code>columnRemoved</code> event.
* Will do nothing if the column is not in this model.
* @param column the column to be added
* @see #addColumn
*/
public void removeColumn(TableColumn column) {
int allColumnsIndex = allTableColumns.indexOf(column);
if (allColumnsIndex != -1) {
allTableColumns.remove(allColumnsIndex);
}
super.removeColumn(column);
}
/** Moves the column from <code>oldIndex</code> to <code>newIndex</code>.
* Posts <code>columnMoved</code> event.
* Will not move any columns if <code>oldIndex</code> equals <code>newIndex</code>.
*
* @param oldIndex index of column to be moved
* @param newIndex new index of the column
* @exception IllegalArgumentException if either <code>oldIndex</code> or
* <code>newIndex</code>
* are not in [0, getColumnCount() - 1]
*/
public void moveColumn(int oldIndex, int newIndex) {
if ((oldIndex < 0) || (oldIndex >= getColumnCount())
|| (newIndex < 0) || (newIndex >= getColumnCount())) {
throw new IllegalArgumentException("moveColumn() - Index out of range");
}
TableColumn fromColumn = (TableColumn) tableColumns.get(oldIndex);
TableColumn toColumn = (TableColumn) tableColumns.get(newIndex);
int allColumnsOldIndex = allTableColumns.indexOf(fromColumn);
int allColumnsNewIndex = allTableColumns.indexOf(toColumn);
if (oldIndex != newIndex) {
allTableColumns.remove(allColumnsOldIndex);
allTableColumns.add(allColumnsNewIndex, fromColumn);
}
super.moveColumn(oldIndex, newIndex);
}
/**
* Returns the total number of columns in this model.
*
* @param onlyVisible if set only visible columns will be counted
* @return the number of columns in the <code>tableColumns</code> array
* @see #getColumns
*/
public int getColumnCount(boolean onlyVisible) {
List<TableColumn> columns = (onlyVisible ? tableColumns : allTableColumns);
return columns.size();
}
/**
* Returns an <code>Enumeration</code> of all the columns in the model.
*
* @param onlyVisible if set all invisible columns will be missing from the enumeration.
* @return an <code>Enumeration</code> of the columns in the model
*/
public Iterator<TableColumn> getColumns(boolean onlyVisible) {
List<TableColumn> columns = (onlyVisible ? tableColumns : allTableColumns);
return columns.iterator();
}
/**
* Returns the position of the first column whose identifier equals <code>identifier</code>.
* Position is the the index in all visible columns if <code>onlyVisible</code> is true or
* else the index in all columns.
*
* @param identifier the identifier object to search for
* @param onlyVisible if set searches only visible columns
*
* @return the index of the first column whose identifier
* equals <code>identifier</code>
*
* @exception IllegalArgumentException if <code>identifier</code>
* is <code>null</code>, or if no
* <code>TableColumn</code> has this
* <code>identifier</code>
* @see #getColumn
*/
public int getColumnIndex(Object identifier, boolean onlyVisible) {
if (identifier == null) {
throw new IllegalArgumentException("Identifier is null");
}
List columns = (onlyVisible ? tableColumns : allTableColumns);
int noColumns = columns.size();
TableColumn column;
for (int columnIndex = 0; columnIndex < noColumns; ++columnIndex) {
column = (TableColumn) columns.get(columnIndex);
if (identifier.equals(column.getIdentifier())) {
return columnIndex;
}
}
throw new IllegalArgumentException("Identifier not found");
}
/**
* Returns the <code>TableColumn</code> object for the column
* at <code>columnIndex</code>.
*
* @param columnIndex the index of the column desired
* @param onlyVisible if set columnIndex is meant to be relative to all visible columns only
* else it is the index in all columns
*
* @return the <code>TableColumn</code> object for the column
* at <code>columnIndex</code>
*/
public TableColumn getColumn(int columnIndex, boolean onlyVisible) {
return (TableColumn) tableColumns.elementAt(columnIndex);
}
/**
* Returns all the columns
* @return
*/
public TableColumn[] getAllColumns() {
return allTableColumns.toArray(new TableColumn[allTableColumns.size()]);
}
public TableColumn[] getHiddenColumns() {
ArrayList<TableColumn> lstColumns = new ArrayList<TableColumn>(10);
for (TableColumn column : getAllColumns()) {
if (!isColumnVisible(column)) {
lstColumns.add(column);
}
}
return lstColumns.toArray(new TableColumn[lstColumns.size()]);
}
}