• java中的组件重绘


    高手写的一篇文章:

    Who calls paintComponent

    When you subclass JComponent or JPanel to draw graphics, override the paintComponent() method. This method is called because the user did something with the user interface that required redrawing, or your code has explicitly requested that it be redrawn.

    Called automatically when it becomes visible

    When a window becomes visible (uncovered or deminimized) or is resized, the "system" automatically calls the paintComponent() method for all areas of the screen that have to be redrawn.

    Called indirectly from a user-defined listener via repaint()

    When a listener (mouse, button, keyboard, ...) of yours is called, the listener code often makes changes that should be displayed in your graphics area. Never call paintComponent() method directly.

    1. Change instance variables. The listener code should set instance variables that paintComponent()uses in drawing the panel. After changing the values, the next time paintComponent() is called, these new values will be used. But you won't want to wait for a call to paintComponent(), callrepaint().
    2. Call repaint(). The repaint() method consolidates all requests to change the component (there may be several repaint requests between screen refreshes). It adds an update request to the GUI event queue so that the update will be properly coordinated with other GUI actions (Swing and AWT are not thread-safe). This update request, when processed, calls update(), which callspaint(), which calls your paintComponent() method (as well as calling paintBorder() andpaintChildren()

    http://www.leepoint.net/notes-java/GUI-lowlevel/graphics/15who-calls-paintcomponent.html

    当java认为需要重新绘制组件的时候由java调用。
    
    例如你在程序中repaint();或者程序窗口最小化,然后恢复。或者程序窗口被遮挡,又显现的时候。
    
    你注意观察,这个方法是个受保护的方法,这就是说我们平常并不用管这个方法,这个方法只在你需要继承paintComponent(一般是JFrame)的时候,重写方法,(也可以不重新方法,如果你不需要改变绘制组件动作的话)。

    先看下面源码:
    import java.awt.*;
    import java.awt.event.*;
    public class DrawLine
    {
        Frame f= new Frame("IT资讯交流网");
        public static void main(String [] args)
        {
            new DrawLine().init();    
        }
        public void init()
        {
            f.setSize(300,300);
            f.setVisible(true);
            f.addMouseListener(new MouseAdapter()
            {
                int orgX;
                int orgY;
                public void mousePressed(MouseEvent e)
                {
                    orgX=e.getX();
                    orgY=e.getY();
                }
                public void mouseReleased(MouseEvent e)
                {
                    f.getGraphics().setColor(Color.red);
    //设置绘图颜色为红色
                f.getGraphics().drawLine(orgX,orgY,e.getX(),e.getY());
                }    
            });
        }
    }

    当窗口改变大小后原来画的内容全都不能显示了。

    awt线程在重新绘制组件后,会立即调用组件的paint方法,所以我们的图形重绘代码应在paint中编写
    public void paint(Graphics g)
    可见,awt线程已经获得了组件的Graphics对象,并将它传递给了paint方法,在paint方法中绘图时只能使用这个graphics对象。
    当我们想要执行paint方法中的程序代码时,应用程序不应该直接调用paint方法,如果我们想要执行paint中的代码,需调用
    component.repaint方法,repaint调用component.update方法,update再调用paint方法。

    由于我们不可能直接进入某个组件的paint方法中修改程序代码,我们需要定义一个继承了该组件的子类,在子类中覆盖paint方法,在新的paint方法中编写代码,并将原先创建的组件对象改为由这个子类创建,就可以达到我们的目的了,

    import java.awt.Color;
    import java.awt.Frame;
    import java.awt.Graphics;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    public class DrawLine extends Frame
    {
         int orgX;
         int orgY;
         int endX;
         int endY;
         
     
        public static void main(String [] args)
        {
            //new DrawLine().init();
            DrawLine dl=new DrawLine();
            dl.init();
        }
        public void paint(Graphics g)
        {
            g.drawLine(orgX, orgY,endX,endY);
            
        }
        public void init()
        {
             
            
            setSize(300,300);
            setVisible(true);
            addMouseListener(new MouseAdapter()
            {
               
                public void mousePressed(MouseEvent e)
                {
                    orgX=e.getX();
                    orgY=e.getY();
                    
                }
                public void mouseReleased(MouseEvent e)
                {
                    endX=e.getX();
                    endY=e.getY();
                Graphics g=getGraphics();
                g.setColor(Color.red);
                
                g.drawLine(orgX,orgY,e.getX(),e.getY());
                
                }    
            });
        }
    }

    上面的程序只能重绘最后一次划线。 要想完全重绘窗口上的内容,需要将每一条直线的坐标保存到一个集合类 中。

    另一篇文章:

      在Java游戏编程时,使用Swing组件绘图时,一般需要覆盖组件的paintComponent(Graphics)方法,在该方法中写绘图代码,需要注意的是,在绘图代码之前要调用super.paintComponent(g)来清除一个遮光部件的背景。(某些人为图简单省略掉,不要不写)。

       此外,如果需要重画,则使用repaint方法,repaint方法会自动调用paintComponent(Graphics)方法。
      Java游戏编程中,绘制圆的代码写在Jpanel类的paintComponent(Graphics)方法中,然后在多线程中不断调用repaint方法,从而不断调用paintComponent(Graphics)方法绘出移动的圆形。

      如果是在AWT组件内绘图,比Frame,则需要把绘图代码写在paint(Graphics)方法中。如果需要不断重画,则需要在多线程中调用repaint方法,repaint会自动调用update方法,update方法会自动调用paint方法完成重画。

      Java游戏编程中还有一点需要注意:在Swing中绘图,Java提供了双缓冲的功能,而AWT中绘图则没有双缓冲的功能,从而绘图会出现闪烁的问题。
     

  • 相关阅读:
    没穿过几次的衬衫,发黄了!郁闷ing!
    delta3d与ode物理引擎的结合。
    PIMPL 模式的实现及应用。
    互联网搜索广告介绍(一)
    Windows Phone 7的Launchers&Choosers简介及其行为浅析
    Windows Phone 7的屏幕方向及变更处理
    Windows Phone 7常用资源大集合
    Windows Phone 7 Developer Tools 更新指南
    html 5简易的影片播放器(高手绕行)
    App Inventor for Android Button单击事件
  • 原文地址:https://www.cnblogs.com/youxin/p/2471233.html
Copyright © 2020-2023  润新知