在paintbrushtypes的GUI中,paintComponent()与paint()和JPanel vs Canvas

我从中得到了一些有趣的想法和批评, 这篇文章和这篇文章(见最后一篇关于GUI代码的文章)。 尽pipe如此,我仍然对一些事情感到困惑。 主要是显示用户引入graphics的最便宜方式是什么?

更具体地说,我通过在MouseDragged()方法中使用paintComponent(getGraphics())方法(相应的AuxClass2AuxClass1 )将该类的一个对象与JPanel类中的paintComponent(getGraphics()) MouseDragged()方法一起使用。

显然,使用getGraphics()paintComponent()而不是repaint()是不好的想法,我怀疑与内存使用有关。 每次用户拖动鼠标时也调用AuxClass2也是一个坏主意。

JPanel vs Canvas(比如swing vs awt)也有点混乱。 什么是什么时候用?

我一直在试图find解决方法,但没有find一个,特别是对于getGraphics()方法:如何将graphics添加到面板?

我一直在试图find解决方法,但没有find一个,特别是对于getGraphics()方法:如何将graphics添加到面板?

你记得需要作为一个variables绘制,并在paintComponent()中使用它。 例如,你似乎试图在你的另一个问题上做什么看起来像:

 import java.awt.*; import java.awt.event.*; import javax.swing.*; public class PaintRectangle extends JPanel { private Point mouseLocation; public PaintRectangle() { setPreferredSize(new Dimension(500, 500)); MouseAdapter listener = new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { updateMouseRectangle(e); } private void updateMouseRectangle(MouseEvent e) { mouseLocation = e.getPoint(); repaint(); } @Override public void mouseDragged(MouseEvent e) { updateMouseRectangle(e); } @Override public void mouseReleased(MouseEvent e) { mouseLocation = null; repaint(); } }; addMouseListener(listener); addMouseMotionListener(listener); } private Rectangle getRectangle() { if(mouseLocation != null) { return new Rectangle(mouseLocation.x - 5, mouseLocation.y - 5, 10, 10); } else { return null; } } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Rectangle rectangle = getRectangle(); if(rectangle != null) { Graphics2D gg = (Graphics2D) g; gg.setColor(Color.BLUE); gg.fill(rectangle); gg.setColor(Color.BLACK); gg.draw(rectangle); } } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { JFrame frame = new JFrame("Test"); frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frame.getContentPane().add(new PaintRectangle()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } } 

另见http://docs.oracle.com/javase/tutorial/uiswing/painting/

重量轻,重量轻

基本上来说,一个重量级的组件被链接到它自己的本地对等体,轻量级组件共享一个共同的本地对等体。

总的来说,把重量和重量轻的零部件混合在一起并不是一个好主意,因为z顺序和我的经验都存在问题(即使它现在应该会更好),也会出现可能会出现的绘画问题。

这就是为什么你不敢使用Canvas类的原因,可能是因为你试图把它放在一个轻量级的组件上…我猜

控制的幻觉

Swing API的新手最大的问题之一是你对绘画过程有某种控制的错觉,你不这样做。 接受它就容易了。

您可以做的最好的方式是请求重绘pipe理器尽早执行更新。

此外,调用getGraphics不保证返回一个非空值。

事物的正确顺序

paint vs paintComponent

这里的问题是paint做了一些重要的工作,调用paintComponent只是其中的一个。

在Swing中,当我们想要执行自定义绘画时,我们大大鼓励使用paintComponent ,这通常是组件的最低级别,并在绘制子组件之前被调用。

如果你重写paint然后在调用super.paint之后在Graphicssuper.paint你将最终绘制所有的东西,这并不总是所期望的结果

即使是这样,子组件也可以独立于其父容器进行绘制,使绘画“超过”您添加的任何绘画效果

有用的链接

  • 在Swing中绘画 (谈论绘画过程的工作原理)
  • 执行自定义疼痛(在Swing中)
  • 二维graphics轨迹

分开的想法

只有实际添加到组件的附加到本地对等组件的组件才会有调用的paint方法。 所以试图画一个没有被添加到容器中的组件却是没有意义的。

..paintbrushtypes的graphics用户界面

使用BufferedImage作为绘画表面。 在JLabel显示它。 将标签放置在JScrollPane面板的中心。

根据需要调用bufferedImage.getGraphics() ,但记住在完成时dispose()它,然后调用label.repaint()

在整个过程中使用Swing组件,不要覆盖任何东西。

这是一个使用图像作为绘画表面的例子 。

这是一个更好的 !

我没有说屏幕截图越好,代码越好。 ;)