如何调整JTable列以适应列单元格中最长的内容 [英] How to adjust JTable columns to fit the longest content in column cells

查看:124
本文介绍了如何调整JTable列以适应列单元格中最长的内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 https://stackoverflow.com/a/5820366 http://tips4java.wordpress.com/2008/11/10/table-column-adjuster/ 它可以工作,但是列的大小通常太宽或太窄。

I'm using answer https://stackoverflow.com/a/5820366 and http://tips4java.wordpress.com/2008/11/10/table-column-adjuster/ and it works, but frequently columns' sizes are too wide or too narrow.

无论用HTML还是文本填充表格。

No matter filling my table with HTML or text.

从oracle文档中使用标准 TableModel

Using standard TableModel from oracle documentation.

调整大小模式= JTable.AUTO_RESIZE_OFF

Resize mode = JTable.AUTO_RESIZE_OFF

我的表格的容器是jGoodies:

Container of my tabel is jGoodies:

FormLayout currentEventLayout = new FormLayout(
            "fill:p",
            "pref, pref");
PanelBuilder currentEventBuilder = new PanelBuilder(currentEventLayout);
currentEventBuilder.add(mainQuotesTable.getTableHeader(), constraints.xy(1, 1));
currentEventBuilder.add(mainQuotesTable, constraints.xy(1, 2));

HTML示例:

"<html><pre><font size=+1 face='Arial'>" + firstValue + "\n" + secondValue + "</font></pre></html>"

简单行:

firstValue + " - " + secondValue

以下是示例:

public class TableAdjustExample {
private static JTable mainTable;
private static Random random = new Random();

private static List<Data> data;

private static class Data {
    String name;
    String surname;

    private Data(String name, String surname) {
        this.name = name;
        this.surname = surname;
    }
}

public static void main(String[] args) {
    data = stubProvider();

    final JFrame frame = new JFrame("table adjust example");
    frame.add(createUI());
    frame.pack();
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    frame.setSize(350, 400);
    frame.setVisible(true);

    update();
    java.util.Timer timer = new java.util.Timer();
    timer.schedule(new TimerTask() {
        @Override
        public void run() {
            update();
        }
    }, 3000, 3000);
}

private static JPanel createUI() {
    JPanel jPanel = new JPanel();
    mainTable = new JTable(2, 3);
    mainTable.setModel(new AbstractTableModel() {
        @Override
        public int getRowCount() {
            return data.size();
        }

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

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            Data dataItem = data.get(rowIndex);
            if (columnIndex == 0) {
                return dataItem.name;
            }
            if (columnIndex == 1) {
                return dataItem.surname;
            }
            throw new IllegalStateException();
        }
    });
    mainTable.setGridColor(Color.black);
    mainTable.setShowHorizontalLines(false);
    mainTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

    final TableCellRenderer defaultRenderer = mainTable.getTableHeader().getDefaultRenderer();
    mainTable.getTableHeader().setDefaultRenderer(new TableCellRenderer() {
        @Override
        public Component getTableCellRendererComponent(JTable jTable, Object o, boolean b, boolean b1, int row, int column) {
            JLabel parent = (JLabel) defaultRenderer.getTableCellRendererComponent(jTable, o, b, b1, row, column);
            if (column == 0) {
                parent.setText("name");
            } else {
                parent.setText("surname");
            }
            return parent;
        }
    });

    jPanel.add(mainTable.getTableHeader());
    jPanel.add(mainTable);

    return jPanel;
}

private static void update() {
    System.out.println("updating");
    data = stubProvider();

    adjustJTableRowSizes(mainTable);
    for (int i = 0; i < mainTable.getColumnCount(); i++) {
        adjustColumnSizes(mainTable, i, 2);
    }
}

private static void adjustJTableRowSizes(JTable jTable) {
    for (int row = 0; row < jTable.getRowCount(); row++) {
        int maxHeight = 0;
        for (int column = 0; column < jTable.getColumnCount(); column++) {
            TableCellRenderer cellRenderer = jTable.getCellRenderer(row, column);
            Object valueAt = jTable.getValueAt(row, column);
            Component tableCellRendererComponent = cellRenderer.getTableCellRendererComponent(jTable, valueAt, false, false, row, column);
            int heightPreferable = tableCellRendererComponent.getPreferredSize().height;
            maxHeight = Math.max(heightPreferable, maxHeight);
        }
        jTable.setRowHeight(row, maxHeight);
    }

}

public static void adjustColumnSizes(JTable table, int column, int margin) {
    DefaultTableColumnModel colModel = (DefaultTableColumnModel) table.getColumnModel();
    TableColumn col = colModel.getColumn(column);
    int width;

    TableCellRenderer renderer = col.getHeaderRenderer();
    if (renderer == null) {
        renderer = table.getTableHeader().getDefaultRenderer();
    }
    JLabel comp = (JLabel) renderer.getTableCellRendererComponent(
            table, col.getHeaderValue(), false, false, 0, 0);
    width = comp.getPreferredSize().width;

    for (int r = 0; r < table.getRowCount(); r++) {
        renderer = table.getCellRenderer(r, column);
        comp = (JLabel) renderer.getTableCellRendererComponent(
                table, table.getValueAt(r, column), false, false, r, column);
        int currentWidth = comp.getPreferredSize().width;
        width = Math.max(width, currentWidth);
    }

    width += 2 * margin;

    col.setPreferredWidth(width);
}

private static List<Data> stubProvider() {
    List<Data> data = new ArrayList<Data>();
    for (int i = 0; i < 4; i++) {
        data.add(new Data(
                "<html>" +
                        "<div style='font-size: 15px'>Jason</div>" +
                        "<div style='font-size: 15px'>" + random.nextInt() + "</div>" +
                        "</html>",
                "Statham " + random.nextInt()));
    }
    return data;
}
}






行高调整我有这个问题。使用< pre> \ n< / pre> 代替< br> 修复行调整。

推荐答案

似乎对我有用......

Seems to be working okay for me...

< img src =https://i.stack.imgur.com/BFu26.pngalt =在此处输入图像说明>

public class TestTable01 extends JPanel {

    private JTable mainTable;

    public TestTable01() {
        super(new GridLayout(1, 0));

        String[] columnNames = {"First Name",
                                "Last Name",
                                "Sport",
                                "# of Years",
                                "Vegetarian"};

        Object[][] data = {
            {"Kathy", "Smith",
             "Snowboarding", new Integer(5), new Boolean(false)},
            {"John", "Doe",
             "Rowing", new Integer(3), new Boolean(true)},
            {"Sue", "Black",
             "Knitting", new Integer(2), new Boolean(false)},
            {"Jane", "White",
             "Speed reading", new Integer(20), new Boolean(true)},
            {"Joe", "Brown",
             "Pool", new Integer(10), new Boolean(false)}
        };

        mainTable = new JTable(data, columnNames);
        mainTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        mainTable.setPreferredScrollableViewportSize(new Dimension(500, 70));
        mainTable.setFillsViewportHeight(true);

        update();

        //Create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(mainTable);

        //Add the scroll pane to this panel.
        add(scrollPane);
    }

    /**
     * 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("SimpleTableDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        TestTable01 newContentPane = new TestTable01();
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    private void update() {
        System.out.println("updating");

        adjustJTableRowSizes(mainTable);
        for (int i = 0; i < mainTable.getColumnCount(); i++) {
            adjustColumnSizes(mainTable, i, 2);
        }
    }

    private void adjustJTableRowSizes(JTable jTable) {
        for (int row = 0; row < jTable.getRowCount(); row++) {
            int maxHeight = 0;
            for (int column = 0; column < jTable.getColumnCount(); column++) {
                TableCellRenderer cellRenderer = jTable.getCellRenderer(row, column);
                Object valueAt = jTable.getValueAt(row, column);
                Component tableCellRendererComponent = cellRenderer.getTableCellRendererComponent(jTable, valueAt, false, false, row, column);
                int heightPreferable = tableCellRendererComponent.getPreferredSize().height;
                maxHeight = Math.max(heightPreferable, maxHeight);
            }
            jTable.setRowHeight(row, maxHeight);
        }

    }

    public void adjustColumnSizes(JTable table, int column, int margin) {
        DefaultTableColumnModel colModel = (DefaultTableColumnModel) table.getColumnModel();
        TableColumn col = colModel.getColumn(column);
        int width;

        TableCellRenderer renderer = col.getHeaderRenderer();
        if (renderer == null) {
            renderer = table.getTableHeader().getDefaultRenderer();
        }
        Component comp = renderer.getTableCellRendererComponent(table, col.getHeaderValue(), false, false, 0, 0);
        width = comp.getPreferredSize().width;

        for (int r = 0; r < table.getRowCount(); r++) {
            renderer = table.getCellRenderer(r, column);
            comp = renderer.getTableCellRendererComponent(table, table.getValueAt(r, column), false, false, r, column);
            int currentWidth = comp.getPreferredSize().width;
            width = Math.max(width, currentWidth);
        }

        width += 2 * margin;

        col.setPreferredWidth(width);
        col.setWidth(width);
    }

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

        });
    }

}

更新

您的示例存在许多问题。

There are a number of issues with your example.


  • 表真的应该添加到 JScrollPane ,这将负责添加标题...

  • <$ c $ li>默认布局管理器c $ c> JPanel 是 FlowLayout ,在这种情况下,它可能不是你想要的,你可能想要使用 BorderLayout

  • Swing不是线程安全的。 java.util.Timer 的用户将违反此策略,这可能导致模型和视图失去同步。请改用 javax.swing.Timer

  • 渲染两个< div> 每个旁边都会导致html布局引擎在元素之间放置一个弱点。也就是说,如果引擎决定没有足够的可用空间将两个元素一起渲染,它将分割它们。最好使用一个< div> ,而不是两个< span> 标签......

  • Tables really should be added to a JScrollPane, this will take care of adding the header...
  • The default layout manager for a JPanel is FlowLayout, in this case, it's probably not what you want, you probably want to use a BorderLayout
  • Swing is not thread safe. The user of java.util.Timer will violate this policy, this could cause the model and view to fall out sync. Use a javax.swing.Timer instead.
  • Rendering two <div> next to each will cause the html layout engine to place a weak break between the elements. That is, if the engine decides there's not enough available space to render the two elements together, it will split them. Better to use a single <div> with two <span> tags instead...

我会读一读

  • Concurrency in Swing
  • How to Use Tables

public class TestColumnWidths {

    private static JTable mainTable;
    private static Random random = new Random();
    private static List<Data> data;

    private static class Data {

        String name;
        String surname;

        private Data(String name, String surname) {
            this.name = name;
            this.surname = surname;
        }
    }

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {

                data = stubProvider();

                final JFrame frame = new JFrame("table adjust example");
                frame.add(createUI());
                frame.pack();
                frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                update();
//                    java.util.Timer timer = new java.util.Timer();
//                    timer.schedule(new TimerTask() {
//                        @Override
//                        public void run() {
//                            update();
//                        }
//                    }, 3000, 3000);

                javax.swing.Timer timer = new javax.swing.Timer(3000, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        update();
                    }
                });
                timer.setRepeats(true);
                timer.setCoalesce(true);
                timer.start();

            }
        });
    }

    private static JPanel createUI() {
        JPanel jPanel = new JPanel();
        mainTable = new JTable(2, 3);
        mainTable.setModel(new AbstractTableModel() {
            @Override
            public int getRowCount() {
                return data.size();
            }

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

            @Override
            public Object getValueAt(int rowIndex, int columnIndex) {
                Data dataItem = data.get(rowIndex);
                if (columnIndex == 0) {
                    return dataItem.name;
                }
                if (columnIndex == 1) {
                    return dataItem.surname;
                }
                throw new IllegalStateException();
            }
        });
        mainTable.setGridColor(Color.black);
        mainTable.setShowHorizontalLines(false);
        mainTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

        final TableCellRenderer defaultRenderer = mainTable.getTableHeader().getDefaultRenderer();
        mainTable.getTableHeader().setDefaultRenderer(new TableCellRenderer() {
            @Override
            public Component getTableCellRendererComponent(JTable jTable, Object o, boolean b, boolean b1, int row, int column) {
                JLabel parent = (JLabel) defaultRenderer.getTableCellRendererComponent(jTable, o, b, b1, row, column);
                if (column == 0) {
                    parent.setText("name");
                } else {
                    parent.setText("surname");
                }
                return parent;
            }
        });

//            jPanel.add(mainTable.getTableHeader());
//            jPanel.add(mainTable);

        jPanel.setLayout(new BorderLayout());
        jPanel.add(new JScrollPane(mainTable));

        return jPanel;
    }

    private static void update() {
        System.out.println("updating");
        data = stubProvider();

        adjustJTableRowSizes(mainTable);
        for (int i = 0; i < mainTable.getColumnCount(); i++) {
            adjustColumnSizes(mainTable, i, 2);
        }
    }

    private static void adjustJTableRowSizes(JTable jTable) {
        for (int row = 0; row < jTable.getRowCount(); row++) {
            int maxHeight = 0;
            for (int column = 0; column < jTable.getColumnCount(); column++) {
                TableCellRenderer cellRenderer = jTable.getCellRenderer(row, column);
                Object valueAt = jTable.getValueAt(row, column);
                Component tableCellRendererComponent = cellRenderer.getTableCellRendererComponent(jTable, valueAt, false, false, row, column);
                int heightPreferable = tableCellRendererComponent.getPreferredSize().height;
                maxHeight = Math.max(heightPreferable, maxHeight);
            }
            jTable.setRowHeight(row, maxHeight);
        }

    }

    public static void adjustColumnSizes(JTable table, int column, int margin) {
        DefaultTableColumnModel colModel = (DefaultTableColumnModel) table.getColumnModel();
        TableColumn col = colModel.getColumn(column);
        int width;

        TableCellRenderer renderer = col.getHeaderRenderer();
        if (renderer == null) {
            renderer = table.getTableHeader().getDefaultRenderer();
        }
        Component comp = renderer.getTableCellRendererComponent(
                table, col.getHeaderValue(), false, false, 0, 0);
        width = comp.getPreferredSize().width;

        for (int r = 0; r < table.getRowCount(); r++) {
            renderer = table.getCellRenderer(r, column);
            comp = renderer.getTableCellRendererComponent(
                    table, table.getValueAt(r, column), false, false, r, column);
            int currentWidth = comp.getPreferredSize().width;
            width = Math.max(width, currentWidth);
        }

        width += 2 * margin;

        col.setPreferredWidth(width);
    }

    private static List<Data> stubProvider() {
        List<Data> data = new ArrayList<Data>();
        for (int i = 0; i < 4; i++) {
            data.add(new Data(
                    "<html>"
                    + "<div>"
                    + "<span style='font-size: 15px'>Jason</span>"
                    + "<span style='font-size: 15px'>" + random.nextInt() + "</span>"
                    + "</div>"
                    + "</html>",
                    "Statham " + random.nextInt()));
        }
        return data;
    }
}

这篇关于如何调整JTable列以适应列单元格中最长的内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆