JTable Cells似乎没有挑衅就调整大小

时间:2014-07-06 02:28:40

标签: java swing jtable jscrollpane

我有一个从hibernate填充的Jtable。虽然表在jscrollpane中,但所有字段都填充得很好。我像这样设置表的dbData.setPreferredScrollableViewportSize:

dbData.setPreferredScrollableViewportSize(dbData.getPreferredSize());

    dbScrollPane = new JScrollPane(null, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    dbScrollPane.getViewport().add(dbData);
    Universalvars.setUpdatePane(dbScrollPane);
    dbScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    dbScrollPane.setSize(750, 725);

    dbScrollPane.setLocation(25, 0);

    this.add(dbScrollPane);

现在用hibernate和mysql中的数据填充表后,我调整了每个列的宽度,这反过来又使得text中的textAreas变得更长,因为文本的高度需要更少的空间。执行此操作后,行不会调整大小。

现在有问题的表有15列。只有前7个在视口中可见,并且是1个衬里文本块。当我在Jscrollpane中滚动以查看较大的文本块单元格时,表格自动生成单元格的高度,尽管它仍然留下空白空白区域。

我希望这有意义,因为发布所有项目代码可能会非常过分。无论如何,有没有办法得到它,以便我可以将单元格设置在一定的宽度和行高度,以匹配他们应该保持正确数量的文本?就好像所有列在行中都有一行文本我不需要它高200 px,但如果有一行有一列有500个字符的文本和单元格,那就相同是300 px宽,然后整行需要更高。虽然它不需要具有容纳所述文本所需的空间量的两倍或三倍。

有什么想法吗?提前致谢。

1 个答案:

答案 0 :(得分:1)

请勿使用getViewport().add(...),请使用getViewport().setView(...)

这是因为视口在概念上控制单个视图,并以特殊方式完成。

不要使用setSizesetLocation,这建议使用null布局,这会导致在不同系统上运行时遇到问题,使用不同的字体和渲染管道。坚持使用布局管理API,它会让生活更简单

<强>更新

首先,不要在单元格渲染器中修改表格或模型的状态,这将设置一个严重的永无止境的更新。

其次,使用TableModelListener监视表状态的更改,使用TableColumnModelListener监视列模型的更改

当您检测到其中任何一个的更改时,您需要探测适当的单元格渲染器以确定其首选大小并相应地调整列/行大小。

请确保,由于您的调整引发的事件,您不会进行调整;)

更新了示例

这是一个非常基本的例子,可以尝试大致了解如何实现这一目标......

enter image description here

import java.awt.Color;
import java.awt.Component;
import static java.awt.Component.TOP_ALIGNMENT;
import java.awt.EventQueue;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;

public class VariableTable {

    public static void main(String[] args) {
        new VariableTable();
    }

    private JTable table;
    private boolean ignoreUpdates;

    public VariableTable() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                table = new JTable(loadTableModel());
                table.getColumnModel().getColumn(2).setCellRenderer(new TextAreaRenderer());

                table.getModel().addTableModelListener(new TableModelListener() {
                    @Override
                    public void tableChanged(TableModelEvent e) {
                        updateTableProperties();
                    }
                });
                table.getColumnModel().addColumnModelListener(new TableColumnModelListener() {

                    @Override
                    public void columnAdded(TableColumnModelEvent e) {
                        updateTableProperties();
                    }

                    @Override
                    public void columnRemoved(TableColumnModelEvent e) {
                        updateTableProperties();
                    }

                    @Override
                    public void columnMoved(TableColumnModelEvent e) {
                        updateTableProperties();
                    }

                    @Override
                    public void columnMarginChanged(ChangeEvent e) {
                        updateTableProperties();
                    }

                    @Override
                    public void columnSelectionChanged(ListSelectionEvent e) {
                    }
                });

                updateTableProperties();

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new JScrollPane(table));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    protected void updateTableProperties() {
        if (!ignoreUpdates) {
            ignoreUpdates = true;
            try {
                for (int i = 0; i < table.getColumnCount() - 1; i++) {
                    adjustColumnSizes(i, 2);
                }
                adjustJTableRowSizes(2);
            } finally {
                ignoreUpdates = false;
            }
        }
    }

    private void adjustJTableRowSizes(int column) {
        for (int row = 0; row < table.getRowCount(); row++) {
            int maxHeight = 0;
            TableCellRenderer cellRenderer = table.getCellRenderer(row, column);
            Object valueAt = table.getValueAt(row, column);
            Component tableCellRendererComponent = cellRenderer.getTableCellRendererComponent(table, valueAt, false, false, row, column);

            DefaultTableColumnModel colModel = (DefaultTableColumnModel) table.getColumnModel();
            TableColumn tc = colModel.getColumn(column);

            int heightPreferable = tableCellRendererComponent.getPreferredSize().height;
            tableCellRendererComponent.setSize(tc.getWidth(), heightPreferable);
            heightPreferable = tableCellRendererComponent.getPreferredSize().height;

            maxHeight = Math.max(heightPreferable, maxHeight);
            table.setRowHeight(row, maxHeight);
        }

    }

    public void adjustColumnSizes(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);
//        col.setMinWidth(width);
        col.setMaxWidth(width);
    }

    public TableModel loadTableModel() {

        DefaultTableModel model = new DefaultTableModel(
                        new String[]{"Chapter", "Paragraph", "Text"}, 0);

        int chapter = 0;
        int paragraph = 0;
        try (BufferedReader br = new BufferedReader(new FileReader(new File("Book.txt")))) {

            String text = null;
            while ((text = br.readLine()) != null) {
                if (text.startsWith("Chapter:")) {
                    chapter++;
                    paragraph = 0;
                } else if (text.trim().length() > 0) {
                    paragraph++;
                    model.addRow(new Object[]{
                        chapter,
                        paragraph,
                        text
                    });
                }
            }

        } catch (IOException exp) {
            exp.printStackTrace();;
        }

        return model;

    }

    public static class TextAreaRenderer extends JTextArea implements TableCellRenderer {

        protected static Border NOT_SELECTED_BORDER = new EmptyBorder(1, 1, 1, 1);

        public TextAreaRenderer() {
            setLineWrap(true);
            setWrapStyleWord(true);
            this.setAlignmentY(TOP_ALIGNMENT);
            setBorder(NOT_SELECTED_BORDER);
            setColumns(20);
        }

        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                        boolean hasFocus, int row, int column) {
            setText(value.toString());

            if (table == null) {
                return this;
            }

            Color fg = null;
            Color bg = null;

            JTable.DropLocation dropLocation = table.getDropLocation();
            if (dropLocation != null
                            && !dropLocation.isInsertRow()
                            && !dropLocation.isInsertColumn()
                            && dropLocation.getRow() == row
                            && dropLocation.getColumn() == column) {

                fg = UIManager.getColor("Table.dropCellForeground");
                bg = UIManager.getColor("Table.dropCellBackground");

                isSelected = true;
            }

            if (isSelected) {
                setForeground(fg == null ? table.getSelectionForeground()
                                : fg);
                setBackground(bg == null ? table.getSelectionBackground()
                                : bg);
            } else {
                Color background = table.getBackground();
                if (background == null || background instanceof javax.swing.plaf.UIResource) {
                    Color alternateColor = UIManager.getColor("Table.alternateRowColor");
                    if (alternateColor != null && row % 2 != 0) {
                        background = alternateColor;
                    }
                }
                setForeground(table.getForeground());
                setBackground(background);
            }

            setFont(table.getFont());

            if (hasFocus) {
                Border border = null;
                if (isSelected) {
                    border = UIManager.getBorder("Table.focusSelectedCellHighlightBorder");
                }
                if (border == null) {
                    border = UIManager.getBorder("Table.focusCellHighlightBorder");
                }
                setBorder(border);

                if (!isSelected && table.isCellEditable(row, column)) {
                    Color col;
                    col = UIManager.getColor("Table.focusCellForeground");
                    if (col != null) {
                        super.setForeground(col);
                    }
                    col = UIManager.getColor("Table.focusCellBackground");
                    if (col != null) {
                        super.setBackground(col);
                    }
                }
            } else {
                setBorder(NOT_SELECTED_BORDER);
            }

            return this;
        }

    }
}