有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

在paintbrushtype GUI中,java paintComponent()vs paint()和JPanel vs Canvas

我从thisthisthis帖子中得到了一些有趣的想法和批评(有关GUI的代码,请参见最后一篇帖子)。不过,有些事情我还是很困惑。主要是,什么是最便宜的用户图形显示方式

更具体地说,我使用了来自JPanel类的paintComponent()方法,通过在MouseDragged()方法中创建这个类的对象,以及paintComponent(getGraphics())方法(AuxClass2AuxClass1

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

此外,JPanel与Canvas(即swing与awt)的对比也有点混乱。使用什么以及何时使用

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


共 (3) 个答案

  1. # 1 楼答案

    重与轻

    基本上说,重量级组件链接到它自己的本地对等点,其中轻量级组件共享一个通用的本地对等点

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

    这就是为什么不鼓励您使用Canvas类的原因,可能是因为您试图将它放在一个轻量级组件上。。。我想

    控制的幻觉

    对于新加入Swing API的人来说,最大的问题之一是幻想你对绘画过程有某种控制,你没有。接受它更容易

    您所能做的最好的事情就是请求重绘管理器在方便的时候尽早执行更新

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

    事物的正确顺序

    paintvspaintComponent

    这里的问题是paint做了许多重要的工作,调用paintComponent只是其中之一

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

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

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

    有用的链接

    离别的思念

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

  2. # 2 楼答案

    ..paintbrush-type GUI..

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

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

    始终使用Swing组件,不要覆盖任何内容

    这是一个example of using an image as painting surface

    here is a better one

    我没有说屏幕截图更好,是代码更好

  3. # 3 楼答案

    I've been trying to find a workarounds, but have not found one, especially for the getGraphics() method: how else can the graphics be added to the panel?

    记住需要作为变量绘制的内容,并在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/