Java JTable是否为图形返回null?
我试图使用我制作的Painter对象在我的JTable上画线,但出于某种原因Java JTable是否为图形返回null?,java,swing,jtable,line,paint,Java,Swing,Jtable,Line,Paint,我试图使用我制作的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(){ }
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
,它可能返回null
(正如您所发现的),这不是自定义绘制的方式。您不应该自己调用paintComponent
。如果在打印时,您不会直接调用它,最好是打破绘制链,引入无止境的附加问题和工件
要更好地了解绘画作品,请参见
现在,让我给你一个快速演示,为什么你不应该尝试在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像素的边框和/或减小边框宽度;)
另外,请查看更多详细信息简单规则。不要使用
getGraphics
,也不要自己调用paintComponent
。这不是SwingWhere定义了表
时的绘图方式?@GargAnkitgetGraphics
可以返回null
,如果组件未连接到可显示的本机对等方。基本规则是,永远不要尝试在Swing中进行自己的绘制,在Swing的绘制更新中进行相应的工作。抱歉,但是表格的定义与任何可能的答案都无关,因为他们基本上违反了绘画规则。坦白说,我对Swing漠不关心。我只是想帮助OP,作为一名开发人员,table
似乎没有定义@GargAnkit和我们感谢您的帮助,但在这方面,这是无关紧要的。非常感谢!我开始明白这一切是怎么回事了。我曾见过其他有类似答案的线程,但我试图避开它们,因为我不知道它们是如何工作的。我必须研究一下单元格渲染对象。由于MatteBorder
会将单元格内容推近一点,因此我对使用某种kingCompoundBorder
;)的评论仍有很多工作要做再次感谢你的帮助,麦迪。我的程序(几乎)完成了,但我想让你检查一下,告诉我你的想法!