JTable为Graphics返回null

JTable为Graphics返回null

本文介绍了JTable为Graphics返回null?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



画家类:

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

import javax.swing.JTable;

公共类Painter扩展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 ,它可以返回 null (正如你所发现的)并不是应该如何进行自定义绘画。你永远不需要自己调用 paintComponent 。如果在打印时,你不会直接调用它,最好,你打破了油漆链并且不会引入其他问题和工件。



更好地理解绘画的工作原理参见更多详情


I'm trying to draw lines over my JTable using a Painter object that I've made, but for some reason table.getGraphics() returns null.

Painter class:

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

I'm calling the method with:

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

I have no idea why this is the case, so I need some explanation.

解决方案

Never use getGraphics, it can return null (as you've found) and isn't how custom painting should be done. You should NEVER have a need to call paintComponent yourself. If when printing, you wouldn't call it directly, at the best, you'd break the paint chain and introduce no end of additional issues and artifacts.

For a better understanding of how painting works see Painting in AWT and Swing.

Now, let me give you a quick demonstration of why you shouldn't try and paint over the top of a JTable like you're trying to do...

Now, don't get me wrong, I'm sure with some very clever deduction work you could calculate the row/column positions so as to be able to paint the guides properly, but that's a lot of extra work.

A better solution might be to use a custom 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;
        }

    }

}

Now, this is just a proof of concept. You may need to use a compound border to offset the cell property (so all cells have at least a 2 pixel border around them and/or reduce the border width ;))

Also, take a look at How to Use Tables for more details

这篇关于JTable为Graphics返回null?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-20 11:42