Java Graphics重绘行为

时间:2012-01-02 05:42:00

标签: java swing graphics draw repaint

我一直在我的代码中搜索这种行为的原因已有一段时间了。我不想深入了解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);
}
}

3 个答案:

答案 0 :(得分:5)

除了camickr的建议..

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


E.G。

第一次看,我看到了。

enter image description here

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");
    }
}

答案 1 :(得分:1)

不要使用getGraphics()方法。当下一次Swing确定某个组件需要重新绘制时,该绘画将会丢失。

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

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

答案 2 :(得分:1)

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

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