我有一个类似于 TableFilterDemo 的应用程序它会生成一个包含一些与此类似的字段的数据库
{new File("/path/with/names/included/here.file"), "foo", "bar", new Integer(5), new Double(0.7)},
路径可能很长,因此我实现了一个单元格渲染器,它仅显示文件名,但将完整路径设置为工具提示。
table.getColumnModel().getColumn(0).setCellRenderer(new DefaultTableCellRenderer(){
@Override
protected void setValue(Object value) {
Object result = value;
if ((value != null) && (value instanceof File)) {
File file = (File) value;
result = file.getName();
super.setValue(result);
super.setToolTipText(file.toString());
}
}
});
现在的问题是,对文件列进行排序仍然按完整路径排序,而不仅仅是文件名。我猜我需要实现某种比较器,但我不知道从哪里开始。
编辑:要明确的是,我做了一个 gist来表达我的意思。
我希望能够在单元格中仅显示文件名(here.file、there.file),而不是完整路径。对文件列进行排序时,也按文件名而不是完整路径进行排序。当鼠标指针位于相应的文件单元格上方时,完整路径应该是工具提示。过滤表格时,我希望搜索中也包含完整路径。
EDIT3:SSCCE 与解决方案
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableRowSorter;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.io.File;
import javax.swing.table.DefaultTableCellRenderer;
public class TableFilterDemo extends JPanel {
private JTable table;
private JTextField filterText;
private TableRowSorter<MyTableModel> sorter;
public TableFilterDemo() {
setLayout(new BorderLayout());
// Comparator for the file column, sorts by name instead of full path
Comparator<File> fileComparator = new Comparator<File>() {
@Override
public int compare(File file1, File file2) {
return file1.getName().compareTo(file2.getName());
}
};
// Create a table with a sorter.
MyTableModel model = new MyTableModel();
sorter = new TableRowSorter<MyTableModel>(model);
sorter.setComparator(0, fileComparator);
table = new JTable(model);
table.setRowSorter(sorter);
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
table.setFillsViewportHeight(true);
// For the purposes of this example, better to have a single
// selection.
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.getColumnModel().getColumn(0).setCellRenderer(new DefaultTableCellRenderer() {
@Override
protected void setValue(Object value) {
Object result = value;
if ((value != null) && (value instanceof File)) {
File file = (File) value;
result = file.getName();
super.setValue(result);
super.setToolTipText(file.toString());
}
}
});
// Add the scroll pane to this panel.
add(
new JScrollPane(table), BorderLayout.CENTER);
// Create a separate form for filterText and statusText
filterText = new JTextField();
// Whenever filterText changes, invoke newFilter.
filterText.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
newFilter();
}
public void insertUpdate(DocumentEvent e) {
newFilter();
}
public void removeUpdate(DocumentEvent e) {
newFilter();
}
});
add(filterText, BorderLayout.SOUTH);
}
/**
* Update the row filter regular expression from the expression in the text
* box.
*/
private void newFilter() {
RowFilter<MyTableModel, Object> rf = null;
// If current expression doesn't parse, don't update.
try {
rf = RowFilter.regexFilter("(?i)" + filterText.getText());
} catch (java.util.regex.PatternSyntaxException e) {
return;
}
sorter.setRowFilter(rf);
}
class MyTableModel extends AbstractTableModel {
private String[] columnNames = {"File", "a", "b", "c", "d"};
private Object[][] data = {
{new File("/long/path/with/names/included/2012-10-11-001.file"),
"foo", "bar", new Integer(5), new Double(0.7)},
{new File("/path/full/of/text/2012-10-11-002.file"),
"baz", "bah", new Integer(2), new Double(1.7)},
{new File("/a/long/path/full/of/other/text/2012-10-11-003.file"),
"baz", "bah", new Integer(2), new Double(1.7)},};
public int getColumnCount() {
return columnNames.length;
}
public int getRowCount() {
return data.length;
}
public String getColumnName(int col) {
return columnNames[col];
}
public Object getValueAt(int row, int col) {
return data[row][col];
}
public Class getColumnClass(int c) {
return getValueAt(0, c).getClass();
}
/*
* Don't need to implement this method unless your table's data can
* change.
*/
public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
fireTableCellUpdated(row, col);
}
}
/**
* 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("TableFilterDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create and set up the content pane.
TableFilterDemo newContentPane = new TableFilterDemo();
newContentPane.setOpaque(true); // content panes must be opaque
frame.setContentPane(newContentPane);
// Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
// Schedule a job for the event-dispatching thread:
// creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
最佳答案
TableRowSorter
类提供 setComparator(int column, Comparator<?> comparator)
方法。这应该正是你所需要的。提供Comparator
订单File
由 getName()
提供。添加到您已有的内容中,我认为这将为您提供您正在寻找的内容。
关于java - 如何在jtable中显示部分文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23449367/