Подтвердить что ты не робот

Как настроить столбцы JTable для размещения самого длинного содержимого в ячейках столбца

Я использую answer qaru.site/info/157894/... и http://tips4java.wordpress.com/2008/11/10/table-column-adjuster/ и он работает, но часто размеры столбцов слишком широкие или слишком узкие.

Независимо от заполнения моей таблицы HTML или текстом.

Использование стандартной TableModel из документации оракула. ​​

Режим изменения размера = JTable.AUTO_RESIZE_OFF

Контейнер моей таблицы - 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> фиксированной регулировки строки.

4b9b3361

Ответ 1

Кажется, все будет хорошо для меня...

enter image description here

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 GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }

        });
    }

}

ОБНОВЛЕНО

В вашем примере имеется ряд проблем.

  • Таблицы действительно должны быть добавлены к JScrollPane, это позаботится о добавлении заголовка...
  • Диспетчер компоновки по умолчанию для JPanel - FlowLayout, в этом случае он, вероятно, не тот, который вы хотите, вы, вероятно, захотите использовать BorderLayout
  • Swing не является потокобезопасным. Пользователь java.util.Timer нарушит эту политику, это может привести к сбою синхронизации модели и представления. Вместо этого используйте javax.swing.Timer.
  • Рендеринг двух <div> рядом с каждым из них заставит механизм компоновки html помещать слабые разрывы между элементами. То есть, если двигатель решит, что недостаточно свободного места для визуализации двух элементов вместе, он будет разделять их. Лучше использовать один <div> с двумя тегами <span>...

Я бы прочитал

enter image description here

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

Ответ 2

Установите разумную минимальную ширину для слишком узких столбцов. Затем вычислите ширину в соответствии с содержимым столбцов и установите их.