JTable不遵守单元格渲染器的必要高度

时间:2017-12-15 08:13:52

标签: java swing tablecellrenderer

这应该很简单,但我无法弄清楚出了什么问题。我需要我的表格以相当大的字体大小显示,但桌面画家不尊重单元格渲染器的高度。

我见过this post,当我的偏好设置窗口被改为字体大小时,它的工作非常出色。但是,虽然渲染器知道要使用的字体大小,但初始显示上的表正在使用标准行高(16)。桌面画家当然应该自动考虑渲染器的首选高度?或者我实际上必须手动告诉它使用什么高度?

我已尝试拨打doLayout(),如下所示,但它没有任何区别。

这是一个证明问题的SSCCE:

public class IncorrectRowHeight extends JPanel
{
    private class MyCellRenderer extends JTextField implements TableCellRenderer
    {
        private MyCellRenderer()
        {
            setFont(new Font("SansSerif", Font.PLAIN, 30));
            setBorder(BorderFactory.createEmptyBorder());
        }

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

    public IncorrectRowHeight()
    {
        super(new BorderLayout());

        add(new JTextField(25), BorderLayout.PAGE_START);

        String[][] data = {
                {"a", "b", "c", "d", "e"},
                {"f", "g", "h", "i", "j"},
                {"k", "l", "m", "n", "o"},
                {"p", "q", "r", "s", "t"}
        };
        String[] cols = {"h1", "h2", "h3", "h4", "h5"};
        JTable t = new JTable(data, cols);
        t.setGridColor(Color.GRAY);
        t.setPreferredScrollableViewportSize(new Dimension(300, 65));
        TableColumnModel model = t.getColumnModel();
        for (int i = 0; i < model.getColumnCount(); i++)
        {
            TableColumn column = model.getColumn(i);
            column.setCellRenderer(new MyCellRenderer());
        }
        JScrollPane scroller = new JScrollPane(t);
        add(scroller, BorderLayout.CENTER);

        //t.doLayout();  // doesn't help matters
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("IncorrectRowHeight");
        JComponent newContentPane = new IncorrectRowHeight();
        newContentPane.setOpaque(true);
        frame.setContentPane(newContentPane);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args)
    {
        javax.swing.SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
}

它产生以下内容:

这不是火箭科学!我做错了什么?

2 个答案:

答案 0 :(得分:0)

可能这种方法可以帮助你

public static void updateRowHeight(JTable table, int margin) {
    final int rowCount = table.getRowCount();
    final int colCount = table.getColumnCount();
    for (int i = 0; i < rowCount; i++) {
        int maxHeight = 0;
        for (int j = 0; j < colCount; j++) {
            final TableCellRenderer renderer = table.getCellRenderer(i, j);
            maxHeight = Math.max(maxHeight, table.prepareRenderer(renderer, i, j).getPreferredSize().height);
        }
        table.setRowHeight(i, maxHeight + margin);
    }
}

在使用数据填充表格后使用此方法。 margin参数用于行高的额外增量。如果不需要 - 使用0。

以下是具有正确单元格高度的示例。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

/**
 * <code>IncorrectRowHeight</code>.
 */
public class IncorrectRowHeight extends JPanel {
    private class MyCellRenderer extends JTextField implements TableCellRenderer {
        private MyCellRenderer() {
            setFont(new Font("SansSerif", Font.PLAIN, 30));
            setBorder(BorderFactory.createEmptyBorder());
        }

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

    public IncorrectRowHeight() {
        super(new BorderLayout());

        add(new JTextField(25), BorderLayout.PAGE_START);

        String[][] data = {{"a", "b", "c", "d", "e"}, {"f", "g", "h", "i", "j"}, {"k", "l", "m", "n", "o"}, {"p", "q", "r", "s", "t"}};
        String[] cols = {"h1", "h2", "h3", "h4", "h5"};
        JTable t = new JTable(data, cols);
        t.setGridColor(Color.GRAY);
        t.setPreferredScrollableViewportSize(new Dimension(300, 65));
        TableColumnModel model = t.getColumnModel();
        for (int i = 0; i < model.getColumnCount(); i++) {
            TableColumn column = model.getColumn(i);
            column.setCellRenderer(new MyCellRenderer());
        }
        updateRowHeight(t, 0);
        JScrollPane scroller = new JScrollPane(t);
        add(scroller, BorderLayout.CENTER);
    }

    public static void updateRowHeight(JTable table, int margin) {
        final int rowCount = table.getRowCount();
        final int colCount = table.getColumnCount();
        for (int i = 0; i < rowCount; i++) {
            int maxHeight = 0;
            for (int j = 0; j < colCount; j++) {
                final TableCellRenderer renderer = table.getCellRenderer(i, j);
                maxHeight = Math.max(maxHeight, table.prepareRenderer(renderer, i, j).getPreferredSize().height);
            }
            table.setRowHeight(i, maxHeight + margin);
        }
    }

    private static void createAndShowGUI() {
        JFrame frame = new JFrame("IncorrectRowHeight");
        JComponent newContentPane = new IncorrectRowHeight();
        newContentPane.setOpaque(true);
        frame.setContentPane(newContentPane);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

答案 1 :(得分:0)

使用table.setRowHeight(table.getFontMetrics(font).getHeight());

package com.logicbig.example;

import javax.swing.*;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import java.awt.*;

public class IncorrectRowHeight extends JPanel {
private static final Font font = new Font("SansSerif", Font.PLAIN, 30);
private class MyCellRenderer extends JTextField implements TableCellRenderer {
    private MyCellRenderer() {
        setFont(font);
        setBorder(BorderFactory.createEmptyBorder());
    }

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

public IncorrectRowHeight() {
    super(new BorderLayout());

    add(new JTextField(25), BorderLayout.PAGE_START);

    String[][] data = {
            {"a", "b", "c", "d", "e"},
            {"f", "g", "h", "i", "j"},
            {"k", "l", "m", "n", "o"},
            {"p", "q", "r", "s", "t"}
    };
    String[] cols = {"h1", "h2", "h3", "h4", "h5"};
    JTable t = new JTable(data, cols);
    t.setRowHeight(t.getFontMetrics(font).getHeight());
    t.setGridColor(Color.GRAY);
    t.setPreferredScrollableViewportSize(new Dimension(300, 65));
    TableColumnModel model = t.getColumnModel();
    for (int i = 0; i < model.getColumnCount(); i++) {
        TableColumn column = model.getColumn(i);
        column.setCellRenderer(new MyCellRenderer());
    }
    JScrollPane scroller = new JScrollPane(t);
    add(scroller, BorderLayout.CENTER);

    //t.doLayout();  // doesn't help matters
}

private static void createAndShowGUI() {
    JFrame frame = new JFrame("IncorrectRowHeight");
    JComponent newContentPane = new IncorrectRowHeight();
    newContentPane.setOpaque(true);
    frame.setContentPane(newContentPane);
    frame.pack();
    frame.setVisible(true);
}

public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
    });
  }
 }

enter image description here