如何在JFrame中的paint()函数之外绘制图形

时间:2010-09-15 17:53:50

标签: java swing graphics

我希望能够将Image绘制到JFrame上,但只要我想要(不在JFrame.paint方法中。

对于我正在处理的项目,我有class Bullseye extends BufferedImage,我正试图将其放到JFrame上:

class DrawingFrame extends JFrame {
    public void drawImage(Image img, int x, int y) {
        getGraphics().drawImage(img,x,y,null);
        repaint();
    }
}

class Main {
    public static void main(String[] args) {
        DrawingFrame frame = new DrawingFrame();
        Bullseye bullseye = new Bullseye(20,20); //width,height

        // later
        frame.setVisible(true);
        frame.drawImage(bullseye,10,20);
        frame.drawImage(bullseye,20,20);
        frame.drawImage(bullseye,30,20);
    }
}

然而,没有任何表现。经过一些研究后,显然这不起作用,因为graphics时对repaint()对象的更改已被清除。

我该怎么做?这甚至是正确的方法吗?

5 个答案:

答案 0 :(得分:4)

我认为你会倒退这个问题。在Swing中,所有绘图操作都应该在paint()方法中完成。

你可以做的是在你的课程中存储你想要作为属性绘制的图像,然后,在你的痛苦方法中,在任何你想要的地方绘制图像。例如:

class MyFrame extends JFrame {

    Image image;

    public void paint(Graphics g) {
        super.paint(g);
        if (image != null) {
            g.drawImage(image, /* ... */);
        }
    }

    public void setImage(Image image) {
        this.image = image;
        repaint();
    }

}

在你的其他课堂上:

myFrame.setImage(myImage);

答案 1 :(得分:1)

如果在实际绘画之外创建要在其上绘画的屏幕外图像,那么实际绘画只是将屏幕外图像绘制成实际图形?有点双缓冲?

答案 2 :(得分:1)

用Java绘制到屏幕(几乎)总是在paint()中完成。你班上需要的是:

class DrawingFrame extends JFrame {

    private Image bullseye = new Bullseye(20,20); //width,height


    public void paint(Graphics g) {
        g.drawImage(bullseye,10,20);
        g.drawImage(bullseye,20,20);
        g.drawImage(bullseye,30,20);
    }

}

class Main {
    public static void main(String[] args) {
        DrawingFrame frame = new DrawingFrame();

        // later
        frame.setVisible(true);
    }
}

如果您需要在特定时间打开bullseyes的绘图,请在DrawingFrame对象上创建一个标志,并在需要时设置它。

时,您需要调用repaint()。

答案 3 :(得分:1)

自定义绘画应该在paint()方法中完成,尤其是JFrame的paint()方法。自定义绘制是通过覆盖Swing组件的paintComponent()方法完成的,通常是JComponent或JPanel。阅读Custom Painting上Swing教程中的部分,了解更多信息和工作示例。

但是,在这种情况下你不需要做任何事件自定义绘画。您只需创建一个ImageIcon并将Icon添加到JLabel,然后将JLabel添加到面板。阅读How to Use Icons上的Swing教程中的部分以获取工作示例。

如果找不到合适的布局管理器,也可以使用绝对定位。您将再次在教程中找到有关使用布局管理器的部分,以便更详细地解释这一点。

答案 4 :(得分:1)

在类中创建一个图形对象,它必须具有全局,而不仅仅是方法本地存在。

public class Graphics2D freefrompaint = null;  

然后还有一个用于控制流的布尔值:

private boolean heypaintreturnnow = false;

并覆盖主题Swing Component超类'update method()asfollows:

public void update(Graphics g) { 
    if (heypaintreturnnow) return;  
    freefrompaint = (Graphics2D)g;  
    heypaintreturnnow = true; /*and if you want, do => super.update(?) once, or once after boolean hereof is set to false by your code. */

Update()将屏幕外图形数据缓冲区中的所有颜色清除为GraphicsObject的当前背景颜色。并且,您还必须知道在Swing Components的paint()中完成的三种方法:

(1)它调用它自己的paintComponent(),这里是委托给这种Component的实际绘画的地方;

(2)绘制边界的方法;然后是最后一个子组件的绘画。最后一个非常重要且不可避免的事情:使用这个覆盖容器方法的类,嵌套,命名或匿名。并将该类传递给JFrame的setContentPane(Container actualgraphicsreference)方法;这是必须的。我希望我的解释和信息方法毫不含糊。自我解释,您现在可以使用freefrompaint进行绘制,并且操作系统对Frame的重绘()的调用不会调用“双图形”默认光栅清除操作,现在您已经在上面的代码中被禁止了指导并向您推荐。感谢您提供富有表现力的机会。