16

我从这个这个这个帖子中得到了一些有趣的想法和批评(有关相关 GUI 的代码,请参阅最后一篇帖子)。尽管如此,我仍然对一些事情感到很困惑。主要是,显示用户介绍图形的最便宜的方式是什么?

更具体地说,我通过在paintComponent()方法JPanel中创建此类的对象以及方法(并相应地)来使用类中的MouseDragged()方法。paintComponent(getGraphics())AuxClass2AuxClass1

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

JPanel vs Canvas(即 swing vs awt)也有点令人困惑。什么时候用什么?

我一直在寻找一种解决方法,但没有找到,尤其是对于getGraphics()方法:图形如何添加到面板中?

4

3 回答 3

23

重与轻

基本上来说,重量级组件与它自己的本地节点相关联,而轻量级组件共享一个共同的本地节点。

一般来说,混合重量和重量轻的组件并不是一个好主意,因为 z 顺序存在问题,并且根据我的经验(即使现在应该更好),可能会出现绘画问题。

这就是不鼓励您使用Canvas该类的原因,可能是因为您试图将其放置在轻量级组件上……我猜

控制的错觉

对于Swing API的新手来说,最大的问题之一是您错觉您对绘画过程有某种控制,而您却没有。接受它更容易。

您能做的最好的事情是请求重绘管理器尽早执行更新。

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

事情的正确顺序

paint对比paintComponent

这里的问题是paint做许多重要的工作,打电话paintComponent只是其中之一。

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

如果您在调用之后覆盖paint然后在上绘制,最终会在所有内容之上绘制,这并不总是理想的结果Graphicssuper.paint

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

有用的链接

离别的思念

只有实际添加到组件(附加到本机对等方)的组件才会paint调用该方法。因此,尝试绘制到尚未添加到容器中的组件是毫无意义的......

于 2012-08-29T10:24:44.403 回答
11

..画笔式图形用户界面..

使用 aBufferedImage作为绘画表面。将其显示在JLabel. 将标签放在JScrollPane.

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

始终使用 Swing 组件,不要覆盖任何东西。

这是使用图像作为绘画表面的示例

是一个更好的

我并不是说屏幕截图更好,而是代码更好。;)

于 2012-08-29T11:15:50.423 回答
6

我一直在尝试寻找一种解决方法,但没有找到一种解决方法,尤其是对于 getGraphics() 方法:如何将图形添加到面板中?

您记得需要将什么绘制为变量并在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/

于 2012-08-29T10:36:59.883 回答