【问题标题】:Java Graphics repaint behaviorJava 图形重绘行为
【发布时间】:2012-01-31 15:16:54
【问题描述】:

很长一段时间以来,我一直在我的代码中寻找这种行为的原因。我不想深入研究 Swing API 来弄清楚为什么会发生这种情况。我将不胜感激有关导致此问题的原因的任何信息。

这是我正在编写的应用程序的简化版本,问题似乎是当我第一次单击绘制时,图像不会绘制到面板上,但是当我第二次单击它时,它会绘制完美的形象。之后完成的任何绘图都可以正常工作,但最初的油漆问题让我非常恼火。谢谢你的帮助! :)

public class ImageTester {

public static void main(String[] args) {
    final JFrame window = new JFrame("Image Tester");
    final JPanel pane = new JPanel();
    JButton draw = new JButton("Draw");
    JButton paint = new JButton("Paint");

    Toolkit k = Toolkit.getDefaultToolkit();
    final Image i = k.createImage("tester.jpg");
    //pane.getGraphics().drawImage(i, 22, 15, null);

    draw.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent arg0) {
            System.out.println(pane.getGraphics());
            pane.getGraphics().drawRect(5, 5, 15, 15);
            pane.getGraphics().drawImage(i, 15, 15, null);
            System.out.println("Performance");
        }
    });

    paint.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {

        }
    });

    pane.add(draw);
    pane.add(paint);
    window.add(pane);
    window.setVisible(true);
    window.setSize(new Dimension(400, 400));
    window.setLocationRelativeTo(null);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

【问题讨论】:

    标签: java swing graphics draw repaint


    【解决方案1】:

    除了camickr的建议..

    图片使用Toolkit.createImage()异步加载。使用ImageIO.read(URL/File/InputStream) 或添加MediaTracker


    例如

    第一次运行时我看到了。

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.net.URL;
    import javax.imageio.ImageIO;
    
    public class ImageTester {
    
    public static void main(String[] args) throws Exception {
        final JFrame window = new JFrame("Image Tester");
        JButton draw = new JButton("Draw");
        JButton paint = new JButton("Paint");
    
        final Image i = ImageIO.read(new URL(
            "http://pscode.org/media/citymorn2.jpg"));
    
        ImagePanel gui = new ImagePanel();
        gui.setImage(i);
        draw.addActionListener(new ActionListener() {
    
            public void actionPerformed(ActionEvent arg0) {
            }
        });
    
        paint.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
            }
        });
    
        gui.add(draw);
        gui.add(paint);
        window.add(gui);
        window.setVisible(true);
        window.setSize(new Dimension(400, 400));
        window.setLocationRelativeTo(null);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    }
    
    class ImagePanel extends JPanel {
    
        Image i;
    
        public void setImage(Image image) {
            i = image;
        }
    
        public void paintComponent(Graphics g) {
            //System.out.println(pane.getGraphics());
            super.paintComponent(g);
            g.drawRect(5, 5, 15, 15);
            g.drawImage(i, 15, 15, null);
            System.out.println("Performance");
        }
    }
    

    【讨论】:

    • 我认为 ImageIO 在性能方面更慢且成本更高?我正在努力争取一些表现。
    • @user1125661,我不知道您的上述说法是否正确,但最好在担心性能之前学习正确的编程技术。使用您的旧方法,您是否尝试在单击按钮后调整框架大小以查看会发生什么?
    • 这个程序只是一个示例测试程序,用于缩小我在应用程序中遇到的问题。我了解这里实现的许多问题和可怕的编程技术。不过感谢您的提示!
    【解决方案2】:

    不要使用 getGraphics() 方法。下次 Swing 确定组件需要重新绘制自身时,该绘制将丢失。

    自定义绘画是通过覆盖 JPanel(或 JComponent)的 paintComponent() 方法完成的,然后将面板添加到框架中。

    有关更多信息和示例,请参阅Custom Painting

    【讨论】:

    • 这是真的,但与他遇到的问题无关。
    • 查看 Andrew 的建议,了解如何更好地读取图像,这样您就不会遇到问题。
    【解决方案3】:

    当您使用createImage() 时,图像数据被加载,但在它知道要在哪个组件上绘制之前,它不会转换为可渲染像素。 Toolkit.prepareImage() 方法可以做到这一点。将此行添加到程序的末尾,绘制问题就会消失:

    k.prepareImage(i, -1, -1, pane);
    

    【讨论】:

    • prepareImage()(返回)“如果图像已经完全准备好,则为 true;否则为 false。” 鉴于这意味着它不是阻塞方法,那么重点是什么在这段代码中?
    • 感谢您的快速回复。它确实解决了问题。解释是非常有用的工具。我也会对此进行更多研究。谢谢。
    • @user1125661 这可能会解决问题,但这只是一个问题,因为您的代码使用了错误的自定义绘画方法,而不是您追求的解决方案。结合 Andrew 和我自己的建议,找到合适的解决方案。如果您使用正确的绘画技巧,则无需使用此处建议的方法。
    • +1 用于解释实际问题,-1 用于不建议更好的自定义绘画解决方案。
    猜你喜欢
    • 2013-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-19
    • 2015-01-23
    • 1970-01-01
    相关资源
    最近更新 更多