java - 如何在jtable中显示部分文本

标签 java swing jtable renderer rowfilter

我有一个类似于 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订单FilegetName() 提供。添加到您已有的内容中,我认为这将为您提供您正在寻找的内容。

关于java - 如何在jtable中显示部分文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23449367/

相关文章:

java - 存储一项 Activity 的 Intent 但启动另一项 Activity

java - 如何使我的 BookPDF.class 与 `Fragment` 兼容 `Navigation Drawer` 。

java - Swing:垂直堆叠组件,无需 MigLayout

java - 如何访问 Java 中导入类的源代码?

java - 一个匿名类可以有多少个实例?

java - 简单的java计算器

java - 自定义 Swing 控件中的可访问性模仿了 native 控件?

Java - 如何在每页上打印行号?

java - JTable 呈现已删除的 JButton 而不是新的 JButton

java - 如何设置 JTableBinding 中的列大小?