Java 如何在jtable中显示部分文本

Java 如何在jtable中显示部分文本,java,swing,jtable,renderer,rowfilter,Java,Swing,Jtable,Renderer,Rowfilter,我有一个类似的应用程序,它生成一个db,其中的一些字段与此类似 {new File("/path/with/names/included/here.file"), "foo", "bar", new Integer(5), new Double(0.7)}, 路径可能很长,因此我实现了一个单元渲染器,它只显示文件名,但将完整路径设置为工具提示 table.getColumnModel().getColumn(0).setCellRenderer(new DefaultTableCellRend

我有一个类似的应用程序,它生成一个db,其中的一些字段与此类似

{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());
            }
        }

    });
现在的问题是,对文件列排序仍然是按完整路径排序,而不仅仅是文件名。我猜我需要实现某种比较器,但我不知道从哪里开始

编辑:说清楚点,我已经做了一个演讲来表达我的意思

我希望能够在单元格中只显示文件名(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();
            }
        });
    }
}
import javax.swing.*;
导入javax.swing.event.*;
导入javax.swing.table.AbstractTableModel;
导入javax.swing.table.TableRowSorter;
导入java.awt.BorderLayout;
导入java.awt.Dimension;
导入java.io.File;
导入javax.swing.table.DefaultTableCellRenderer;
公共类TableFilterDemo扩展了JPanel{
专用JTable表;
私有JTextField filterText;
私人桌面分拣机;
公共TableFilterDemo(){
setLayout(新的BorderLayout());
//文件列的比较器,按名称而不是按完整路径排序
Comparator fileComparator=新比较器(){
@凌驾
公共int比较(文件file1、文件file2){
返回file1.getName().compareTo(file2.getName());
}
};
//使用分拣机创建一个表格。
MyTableModel模型=新的MyTableModel();
分拣机=新的表格行分拣机(型号);
分类器。设置比较器(0,文件比较器);
表=新JTable(型号);
表.SetRow分拣机(分拣机);
表.setPreferredScrollableViewportSize(新维度(500,70));
表.setFillsViewPerthweight(真);
//在本例中,最好有一个
//选择。
表.setSelectionMode(ListSelectionModel.SINGLE_选择);
table.getColumnModel().getColumn(0).setCellRenderer(新的DefaultTableCellRenderer()){
@凌驾
受保护的无效设置值(对象值){
对象结果=值;
如果((值!=null)&&(文件的值实例)){
文件=(文件)值;
结果=file.getName();
super.setValue(结果);
super.setToolTipText(file.toString());
}
}
});
//将滚动窗格添加到此面板。
加(
新的JScrollPane(表),BorderLayout.CENTER);
//为filterText和statusText创建单独的表单
filterText=新的JTextField();
//每当filterText更改时,调用newFilter。
filterText.getDocument().addDocumentListener(新的DocumentListener()){
公共作废更改日期(记录事件e){
newFilter();
}
公共作废插入更新(文档事件e){
newFilter();
}
公共作废移除更新(文档事件e){
newFilter();
}
});
添加(filterText,BorderLayout.SOUTH);
}
/**
*从文本中的表达式更新行筛选器正则表达式
*盒子。
*/
私有void newFilter(){
RowFilter rf=null;
//如果当前表达式未解析,则不更新。
试一试{
rf=RowFilter.regexFilter(“(?i)”+filterText.getText());
}catch(java.util.regex.PatternSyntaxException e){
返回;
}
分拣机。设置行过滤器(rf);
}
类MyTableModel扩展了AbstractTableModel{
私有字符串[]columnNames={“文件”、“a”、“b”、“c”、“d”};
私有对象[][]数据={
{新文件(“/long/path/with/names/included/2012-10-11-001.File”),
“foo”,“bar”,新的整数(5),新的双精度(0.7)},
{新文件(“/path/full/of/text/2012-10-11-002.File”),
“baz”,“bah”,新整数(2),新双精度(1.7)},
{新文件(“/a/long/path/full/of/other/text/2012-10-11-003.File”),
“baz”,“bah”,新整数(2),新双精度(1.7)},};
public int getColumnCount(){
返回columnNames.length;
}
public int getRowCount(){
返回数据长度;
}
公共字符串getColumnName(int-col){
返回列名[col];
}
公共对象getValueAt(整数行,整数列){
返回数据[行][col];
}
公共类getColumnClass(int c){
返回getValueAt(0,c).getClass();
}
/*
*不需要实现此方法,除非表的数据可以
*改变。
*/
public void setValueAt(对象值、整行、整列){
数据[行][列]=值;
FireTableCell更新(行、列);
}
}
/**
*创建GUI并显示它。为了线程安全,应该
*从事件调度线程调用。
*/
私有静态void createAndShowGUI(){
//创建并设置窗口。
JFrame=新JFrame(“TableFilterDemo”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//创建并设置内容窗格。
TableFilterDemo newContentPane=新建TableFilterDemo();
newContentPane.setOkable(true);//内容窗格必须是不透明的
frame.setContentPane(newContentPane);
//显示窗口。
frame.pack();
frame.setVisible(true);
}
公共静态void main(字符串[]args){
//为事件显示计划作业
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.awt.Point;
import java.awt.event.MouseEvent;
import java.io.File;

/** @see https://stackoverflow.com/a/23450990/230513 */
public class TableFilterDemo extends JPanel {

    private JTable table;
    private JTextField filterText;
    private TableRowSorter<MyTableModel> sorter;

    public TableFilterDemo() {
        setLayout(new BorderLayout());

        // Create a table with a sorter.
        MyTableModel model = new MyTableModel();
        sorter = new TableRowSorter<MyTableModel>(model);
        table = new JTable(model) {

            @Override
            public String getToolTipText(MouseEvent e) {
                Point p = e.getPoint();
                int row = convertRowIndexToModel(rowAtPoint(p));
                MyTableModel model = (MyTableModel) table.getModel();
                return model.getPath(row);
            }
        };
        table.setRowSorter(sorter);
        table.setPreferredScrollableViewportSize(new Dimension(500, 200));
        table.setFillsViewportHeight(true);

        // For the purposes of this example, better to have a single
        // selection.
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        // 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 {

        String path = System.getProperty("user.dir");
        File[] data = new File(path).listFiles();

        private String getPath(int row) {
            return data[row].getPath();
        }

        @Override
        public int getColumnCount() {
            return 1;
        }

        @Override
        public int getRowCount() {
            return data.length;
        }

        @Override
        public String getColumnName(int col) {
            return "path";
        }

        @Override
        public Object getValueAt(int row, int col) {
            return data[row].getName();
        }

        @Override
        public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
        }
    }

    /**
     * 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();
            }
        });
    }
}