代码之家  ›  专栏  ›  技术社区  ›  Austin Hyde

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

  •  2
  • Austin Hyde  · 技术社区  · 15 年前

    我想能画画 Image JFrame ,但只要我愿意(不是在 JFrame.paint 方法。

    对于我正在进行的项目,我有一个 class Bullseye extends BufferedImage ,我想把它放到 :

    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 回复  |  直到 15 年前
        1
  •  1
  •   DJClayworth    15 年前

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

    如果需要在特定时间打开牛眼的绘制,请在DrawingFrame对象上创建一个标志,并在需要时进行设置。设置标志时,需要调用repaint()。

        2
  •  4
  •   Vivien Barousse    15 年前

    我想你把问题倒过来了。在Swing中,所有绘图操作都应在 paint() 方法。

    您可以做的是将要绘制的图像作为属性存储在类中,然后在pain方法中,在任何需要的地方绘制图像。例如:

    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);
    
        3
  •  1
  •   Ashish Patil    15 年前

        4
  •  1
  •   camickr    15 年前

    很少应该使用paint()方法进行自定义绘制,尤其是JFrame的paint()方法。自定义绘制是通过重写Swing组件(通常是JComponent或JPanel)的paintComponent()方法完成的。阅读Swing教程中关于 Custom Painting 更多信息和工作示例。

    然而,在这种情况下,你不需要做任何定制绘画。您只需创建一个ImageIcon并将该图标添加到JLabel,然后将JLabel添加到面板。阅读Swing教程中关于 How to Use Icons 工作示例。

    如果找不到合适的布局管理器,也可以使用绝对定位。同样,您将在教程中找到一个关于使用布局管理器的部分,该部分将对此进行更详细的解释。

        5
  •  1
  •   Hynek -Pichi- Vychodil Paulo Suassuna    11 年前

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

    public class Graphics2D freefrompaint = null;  
    

    private boolean heypaintreturnnow = false;
    

    并重写subject Swing Component超类的update method(),如下所示:

    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组件的paint()中执行的三种方法:

    (1) 它调用它自己的paintComponent(),这里是该组件的实际绘制被委托给的地方;

    (2) 绘制其边界的方法;最后是绘制其子组件。最后一件非常重要且不可避免的事情:使用嵌套的、命名的或匿名的类来重写容器方法。并将该类传递给JFrame的setContentPane(Container actualgraphicsreference)方法;这是必须的。我希望我的解释性和信息性的方法是明确的。自我解释,您现在可以使用freefrompaint来绘制beyond,并且操作系统对帧的repaint()的调用不会调用“twin Graphics”默认光栅清除操作,现在您已经按照上面的指示和建议在代码中抑制了该操作。谢谢你给我一个表达的机会。