在 JTable 中绘制 JLabel 作为列标题(并覆盖 PaintComponent)时出现问题

问题描述 投票:0回答:1

我正在尝试使用

JLabel
作为
JTable
中的列标题,并覆盖
paintComponent
为每列的非空值百分比着色,有点像填充率的背景可视化。这似乎非常简单,但由于某种原因,可视化始终仅应用于第一(左)列,如下图所示:

Example

示例中的“填充率”只是随机的,但仅适用于第一列,尽管循环遍历所有列。

编辑:使用 Java 8 和 MacOS

完整的源代码是:

import javax.swing.*;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;
import java.awt.*;
import java.util.Random;

public class CustomTable extends JFrame {

    private static class CustomLabel extends JLabel {

        public CustomLabel(String text) {
            super(text);
        }

        @Override
        protected void paintComponent(Graphics g) {
            Random random = new Random(System.currentTimeMillis());
            int w = random.nextInt(getWidth());
            int h = getHeight();
            int x = getX();
            int y = getY();
            Graphics2D g2 = (Graphics2D) g.create();
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2.setColor(Color.green);
            g2.fillRect(x, y, w, h);
            super.paintComponent(g2);
            g2.dispose();
        }

    }

    private static class CustomTableCellRenderer implements TableCellRenderer {

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

    }

    public CustomTable() {
        setTitle("CustomTable");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(320, 240);
        setLayout(new GridLayout(1, 1));
        String[] columns = {"id", "fname", "lname"};
        String[][] data = {{"1", "John", "Doe"}, {"2", "Jane", "Doe"}};
        JTable jt = new JTable(data, columns);
        TableColumnModel model = jt.getColumnModel();
        for (int i = 0; i < columns.length; i++) {
            CustomLabel cl = new CustomLabel(columns[i]);
            model.getColumn(i).setHeaderValue(cl);
            model.getColumn(i).setHeaderRenderer(new CustomTableCellRenderer());
        }
        add(new JScrollPane(jt));
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
                } catch (Exception e) {
                }
                new CustomTable();
            }
        });
    }

}
java swing jtable
1个回答
0
投票

Swing 组件的绘制应始终相对于组件进行,而不是相对于组件的位置进行。

因此,如果您想从组件的顶部/左侧进行绘制,则自定义绘制的 x/y 位置应始终为 (0, 0)。

        int x = getX();
        int y = getY();
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(Color.green);
        g2.fillRect(x, y, w, h);

应该是:

        //int x = getX();
        //int y = getY();
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(Color.green);
        //g2.fillRect(x, y, w, h);
        g2.fillRect(0, 0, w, h);
© www.soinside.com 2019 - 2024. All rights reserved.