【问题标题】:JTable returning null for Graphics?JTable为图形返回null?
【发布时间】:2015-05-07 14:43:03
【问题描述】:

我正在尝试使用我制作的 Painter 对象在我的 JTable 上画线,但由于某种原因 table.getGraphics() 返回 null。

画家类:

import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JTable;

public class Painter extends JTable {

    public Painter(){

    }

    public void paintSudokuLines(Graphics g){
        paintComponent(g);
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setStroke(new BasicStroke(3));
        g2.drawLine(0, 300, 400, 250);
    }
}

我正在调用该方法:

private Painter paint = new Painter();
paint.paintSudokuLines(table.getGraphics());

我不知道为什么会这样,所以我需要一些解释。

【问题讨论】:

  • 简单规则。不要使用getGraphics,也不要自己打电话给paintComponent。这不是 Swing 中绘画的工作方式
  • table 定义在哪里?
  • @GargAnkit getGraphics 可以返回 null 如果组件未附加到可显示的本机对等点。基本规则是,永远不要尝试在 Swing 中进行自己的绘画,在 Swing 的绘画更新中进行相应的工作。抱歉,表格的定义位置与任何可能的答案都无关,因为他们的 OP 从根本上违反了绘画规则
  • 坦率地说,我对 Swing 无动于衷。我只是想帮助 OP,作为开发人员,table 似乎未定义!
  • @GargAnkit 我们感谢您的帮助,但在这里,它只是无关紧要

标签: java swing jtable line paint


【解决方案1】:

永远不要使用getGraphics,它可以返回null(正如你所发现的那样),这不是自定义绘画的方式。你永远不需要自己打电话给paintComponent。如果在打印时,您不会直接调用它,那么充其量,您会破坏绘制链并引入无穷无尽的额外问题和工件。

要更好地了解绘画的工作原理,请参阅Painting in AWT and Swing

现在,让我快速演示一下为什么你不应该尝试在 JTable 的顶部进行绘画,就像你正在尝试做的那样......

现在,不要误会我的意思,我确信通过一些非常聪明的推导工作,您可以计算行/列位置,以便能够正确绘制指南,但这是很多额外的工作。

更好的解决方案可能是使用自定义TableCellRenderer...

import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
import javax.swing.border.MatteBorder;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;

public class SudokuTest {

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

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

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

    public class SudokuTable extends JTable {

        public SudokuTable() {
            super(new DefaultTableModel(9, 9));
            setDefaultRenderer(Object.class, new SudokuCellRender());
        }

    }

    public class SudokuCellRender extends DefaultTableCellRenderer {

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

            super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

            int left = 0;
            int top = 0;
            int right = 0;
            int bottom = 0;

            if ((column % 3) == 0) {
                left = 2;
            } else if ((column % 3) == 2) {
                right = 2;
            }

            if ((row % 3) == 0) {
                top = 2;
            }
            if ((row % 3) == 2) {
                bottom = 2;
            }

            setBorder(new MatteBorder(top, left, bottom, right, Color.RED));

            return this;
        }

    }

}

现在,这只是一个概念证明。您可能需要使用复合边框来偏移单元格属性(因此所有单元格周围至少有 2 个像素的边框和/或减小边框宽度;))

另外,请查看How to Use Tables 了解更多详情

【讨论】:

  • 非常感谢!我开始明白这一切是如何运作的。我见过其他类似答案的线程,但我试图避免它们,因为我不知道它们是如何工作的。我得看看单元格渲染对象。
  • 仍然需要做很多工作才能使输出正确,因为MatteBorder 会稍微推动单元格内容,因此我的 cmets 关于使用一些国王 @987654333 @ ;)
  • 再次感谢您的帮助,MadProgrammer。我的程序(几乎)完成了,但我想让你检查一下并告诉我你的想法! github.com/zulfe/sudoku
猜你喜欢
  • 1970-01-01
  • 2020-07-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-28
  • 2018-02-26
相关资源
最近更新 更多