我界面两个方法加载图像,label add()和g.drawimage
其中 gdrawimage中的图像需要按钮触发更换,label不需要....
问题:  是当我切换页面是,label和按钮变成白色无法复原.....空点按钮还能恢复...label里的图像只能最小化打开才能恢复,两部分代码如下 :label:       ImageIcon imgNorth=new ImageIcon("north.jpg");                 
     JLabel labelNorth=new JLabel(imgNorth,JLabel.CENTER); 
       jPanelNorth.add(labelNorth,null);
       
          jContentPanel.add(jPanelNorth, BorderLayout.NORTH);  drawimage 部分:
public void paint (Graphics g)
   {
         //    super.paintComponent(g);
// if (img[index] == null ) return;
  
   index=(index)%10;
g.drawImage(img[index], 0, 0,  this);
    repaint();
    } 
   
   public void playClick()
   {
   
     index++; }其中这个问题 是加入  repaint语句 导致的,之前没有!!

解决方案 »

  1.   


    paintComponent再提一下  给你看个蚂蚁的腿 你知道是公是母吗?
      

  2.   

    public void paint (Graphics g)
       {
             //   super.paintComponent(g);
    看到我注释了没有,paintComponet早就用过了,不行啊,我知道他的作用是重绘每个组件,可问题是我旁边labelNorth 是 把图像添加进去的,我就想知道激活label里面图片的方法,原代码太啰嗦 ,我怕你们会没兴趣,好吧,贴出来吧~~public void init()
    {this.setSize(166,230);
     this.setContentPane(getJContentPanel());
     
    }
    private javax.swing.JPanel getJContentPanel() 
    {

    Color playColor = new Color (100,100,100);
    Font playFont = new Font ("default",Font.BOLD,10);

    if(jContentPanel == null )
    {
          jContentPanel = new javax.swing.JPanel(); 
          
          jContentPanel.setLayout(new BorderLayout());
             jContentPanel.setBackground(java.awt.Color.WHITE);
          
          if(jPanelNorth == null )
          {  
           
           javax.swing.JPanel jPanelNorth = new javax.swing.JPanel(new GridLayout(1,0,0,0));
          
           ImageIcon imgNorth=new ImageIcon("north.jpg");
           
        
           
           
           if(labelNorth == null)
           { 
           JLabel labelNorth=new JLabel(imgNorth,JLabel.CENTER); 
           
           jPanelNorth.add(labelNorth,null);
           
          
           }
              jContentPanel.add(jPanelNorth, BorderLayout.NORTH);  
        
           
          }if(jPanelSouth == null )
          {  
           javax.swing.JPanel jPanelSouth = new javax.swing.JPanel(new GridLayout(2,0,0,0));
           Icon imgSouth=new ImageIcon("south.jpg"); 
           if (labelSouth == null)
              {
           JLabel labelSouth=new JLabel(imgSouth,JLabel.CENTER); 
           jPanelSouth.add(labelSouth,null);
          
          if(jPanelPlay == null)
           {
         javax.swing.JPanel jPanelPlay = new javax.swing.JPanel (new GridLayout(1,1,0,0)) ;
           
    //          jPanelPlay.setLayout(null);
           
             jPanelPlay.add(playButton = new MyJButton("PLAY",playColor,playFont ),null);
           jPanelPlay.add(playButton = new MyJButton("STOP",playColor,playFont ),null);
           
             jPanelSouth.add(jPanelPlay ,null);
           }    
               
        
        
    //       jPanelSouth.add(playButton = new MyJButton("play",playColor,playFont ),null);
        
              
                  
               } 
              jContentPanel.add(jPanelSouth, BorderLayout.SOUTH);  
                if(jPanelCenter == null )
           {
            JCenterPanel jPanelCenter  = new JCenterPanel();
            jContentPanel.add(jPanelCenter, BorderLayout.CENTER);
           }
      

     }
    return jContentPanel;

    }
    public class JCenterPanel extends JPanel
    {

         
     Image[] img = new Image [10];
     
     public JCenterPanel ()
     {
     
     try  
      {  
     for (int i=0; i<10; i++)
     {
     img [i] = getImage(getCodeBase(),(i+1)+".jpg" );
          }
     
       }
        catch (Exception e)
        {e.printStackTrace(); }
      } 
        public void paint (Graphics g)
       {
    //    super.paintComponent(g);
    // if (img[index] == null ) return;
      
       index=(index)%10;
    g.drawImage(img[index], 0, 0,  this);
        repaint();
        } 
       
       public void playClick()
       {
       
         index++;
       
      
       
        
        }   public void stopClick()
       {
           index=0;
          
        
        } 
      
      
     
    }public class MyJButton extends JButton
    {  

      
    Timer mouseTimer = null ;
    public MyJButton( String pTitle, Color pBk, java.awt.Font pFont)
    {

    this.setText(pTitle);
    this.setBackground(pBk);
    this.setFont(pFont);
    this.addMouseListener

    new MouseAdapter()
    {
    public void mouseClicked(MouseEvent e) 
       {   
      if (e.getClickCount()==1) 
          {
    mouseTimer = new javax.swing.Timer
    (350,  
      new ActionListener()
           {
          public void actionPerformed(ActionEvent evt)
          {   
           if (!Selected)
           return;
           if (getText().equals("PLAY"))
           {    
           JCenterPanel jCenterPanel = new  JCenterPanel();
           jCenterPanel.playClick();
                                                  setBackground(java.awt.Color.GREEN);
           
                  mouseTimer.stop();}
           else if (getText().equals("STOP")) 
           {
           JCenterPanel jCenterPanel = new  JCenterPanel();
           jCenterPanel.stopClick();
           setBackground(java.awt.Color.RED);
            
                  mouseTimer.stop();

    }
           
               }
           } 
    );
    mouseTimer.restart(); 
           }
      

  3.   

    我昨天刚好有解释过有关的帖子我想说一点
    super.paintComponent(g);可以不用注释掉然后后面你说的很对,就是repaint的问题
    这个方法很讨厌,他的名字非常的迷惑
    实际上这个方法是很危险的,因为他有一个没有参数的repaint这个方法官方文档有解释
    Components that render complex output should invoke repaint() with arguments defining only the region that requires updating. A common mistake is to always invoke the no-arg version, which causes a repaint of the entire component, often resulting in unnecessary paint processing. 
    翻译为
    如果部件要呈现复杂的图形,就应该使用带参数的repaint()方法,通过参数来指定需要更新的区域。一个比较常见的错误是总是调用无参数的repaint()来提出重画请求,这个方法会重画整个部件,经常导致一些不必要的画图处理。而我个人对最后一句有疑问
    看过源码之后,我认为是因为无参数的repaint仅仅是调用了parent容器的repaint
    但是这个repaint是没有对当前的组件进行绘画处理的
    所以导致最后什么都看不见希望有所帮助
    建议:这里用update(g),应该就可以了
      

  4.   

    zdjray(PubSoft),感谢你的留言,看得出来你对repaint方法有相当的了解,我因此也受益非浅,关于你对update(g)的使用建议,我也做了相应的尝试 
    如 public void paint (Graphics g)
       { super.paintComponent(g);   
       index=(index)%10;
    g.drawImage(img[index], 0, 0,  this);
    update(g);
        repaint(30,0,0,120,120);
    //  update(g);
        }  可是这样连初始化都失败了~~~~经查阅资料发现,update更新组件是在重量级组件时才会被调用,而我这边的JPanel类显然是轻量级,repaint会直接调用paint,况且repaint包含了update方法,如下:   
      repaint(Graphics   g)   {   
      g.clearRect(0,0,width,height);   
      update(g);   
      }
    所以加不加update都无法解决.....
    另外我想重申,我的问题集中在窗口被覆盖后激活的重绘,paint方法实现drawimage区域我想利用 repaint实现动画,但是这显然影响了
    ImageIcon imgNorth=new ImageIcon("north.jpg");
     JLabel labelNorth=new JLabel(imgNorth,JLabel.CENTER); 
    JLabel中的 图片在窗口被覆盖,然后激活时的重绘,这样导致周围是白色的结果,我的焦点在于有没有类似repaint的方法在 窗口激活时让 旁边的label中的图片再重新加载一遍???
      

  5.   

    insiku(FUCK Java Generics!!! || PM我时请附上帖子地址),感谢你对本问题的关注,如果你的强项在于调试程序而不是描述的话,请留下你的邮箱,我可将我的工程文件打包寄给你,谢谢~~~~
      

  6.   

    你的repaint为什么放在paint里面?
    还有repaint(30,0,0,120,120);不行吗?
      

  7.   

    你的repaint为什么放在paint里面?
    还有repaint(30,0,0,120,120);不行吗?我是做得按钮实时触发的repaint,drawimage里面的图片
    很奇怪,repaint放在此程序的paint{}以外任何地方都没有起到调用paint的作用(经过断点调试),唯独放在paint里面可行,代码如下:按钮触发:
    new MouseAdapter(){
    public void mouseClicked(MouseEvent e) {   
    if (e.getClickCount()==1) {
    mouseTimer = new javax.swing.Timer(350,  new ActionListener()
    {public void actionPerformed(ActionEvent evt) {   if (getText().equals("PLAY"))
           {    JCenterPanel jCenterPanel = new  JCenterPanel();
    jCenterPanel.playClick();//接口调用 paint  方法
    ............public class JCenterPanel extends JPanel
    {Image[] img = new Image [10];public JCenterPanel ()
     { try   {  for (int i=0; i<10; i++)
    {img [i] = getImage(getCodeBase(),(i+1)+".jpg" );}
      }
    catch (Exception e)
    {e.printStackTrace(); }} 
      public void paint (Graphics g)
       {
       super.paintComponent(g);
    // if (img[index] == null ) return;
      
       index=(index)%10;
    g.drawImage(img[index], 0, 0,  this);
        repaint(30,0,0,120,120); } 
      public void playClick()
       {index++;  //repaint(30,0,0,120,120); 放在这里无法响应按钮,放在paint函数里做到了,但带来如题的问题}
      

  8.   

    [email protected]
    发来吧邮件已经发送,请查收~~~~~~~
      

  9.   

    我觉得很奇怪的是你的playClick方法中有调用paint吗?
      

  10.   

    源码麻烦请发到[email protected]
      

  11.   

    我觉得很奇怪的是你的playClick方法中有调用paint吗?
    没有,开始把repaint();放在playClick里面也不能调用paint,但是放在paint里面中间的画布居然可以响应 按钮,我怀疑程序是不是在按button时自动调用了paint,同时repaint()也能实现(完全是猜测,望达人解疑),但效果 出来了~~~
      

  12.   

    源码麻烦请发到[email protected]
    已经发了,请查收~~~把libel发在另外一个panel里不太理解意图,不过单纯修改label不太可能,这个位置都是按照需求摆放的....
      

  13.   

    已经看了  我上午就在奇怪 在paint中调用repaint 会产生死循环  
    (repaint产生事件 会导致面板调用paintComponent 和 paint  而调用paint 又重新repaint)
    所以就想看看完整的代码
    果然如此
    button点击以后 将index++  在paint的时候就会达到切换图片的效果
    你所说的label 变白 不能刷新   
    估计是LZ的CPU太差了 死循环以后 所以就刷新不出来了
      

  14.   

    insiku(FUCK Java Generics!!! || PM我时请附上帖子地址)  谢谢你 帮忙看了程序~~~~中央处理器(CPU) Intel Core(TM)2 Duo Processor
    规格 Intel(R) Core(TM)2 CPU T5600 @ 1.83GHz
    显示卡 NVIDIA GeForce Go 7300
    内存 1047792 KB这配置也不算太差吧,那既然方法找到了能不能有更好的方法去repaint呢?
    能不能避免这个死循环,只让他调用一次达到换图效果就行了啊~你有没有发现repaint在别的地方调用不了呢,比如在playclick 里面~~~
      

  15.   

    我也看过源码了
    你那里写repaint肯定不行
    cpu都是满的
    之所以还能够显示图片是另外的线程还没有完全饿死不知道为什么你会显示出白色的东西,有可能是浏览器响应不了
    因为我的浏览器不能显示applet,所以我这里改成JFrame了我的建议是
    把这一句
    jCenterPanel.paint(WebPlayer.this.getGraphics());
    加到
    jCenterPanel.playClick(); //接口的调用
    这一句的后面,然后前面的repaint方法去掉还有
    JCenterPanel jCenterPanel = new JCenterPanel();
    变成
    final JCenterPanel jCenterPanel = new JCenterPanel();
    写在
    if (e.getClickCount() == 1) {
    的前面总之,我觉得代码看起来不是很舒服,还有很多可以改进的地方,楼主自己想吧
    加油~~
      

  16.   

    你这样改过之后cpu应该会降下来了
    不知道还会不会变白?
      

  17.   

    zdjray(PubSoft)  谢谢,经你提醒,确实程序存在很大的问题,但是你的解决方案
    jCenterPanel.paint(WebPlayer.this.getGraphics());
    加到
    jCenterPanel.playClick(); //接口的调用
    却没成功,我思考了一下,可能是因为 getGraphics()把下个图像的索引返回给了g,但同时index的数字也加1 ,就是说g和index值都变了....这样同样导致了下一次paint的Bug,况且好像paint函数仍然没有调用,因为没按Button的同时没有变化.....
    还有这个语句插在这个位置也不妥,因为gui的语句放在一起最好,click时只要调用就好了,
    另外,final JCenterPanel jCenterPanel = new JCenterPanel();我知道将变量变成不能被继承的最小单位,但我不清楚这样做的好处,请指明~还有你说到有很多可以改进的地方,简直是在吊我的胃口,迫切希望和你多交流~~~~
    qq 781212997  msn  [email protected]
      

  18.   

    现在问题很清楚了,只要提出可行的repaint方案代替现在的死循环就揭帖了,从这个过程我搞明白的很多东西,谢谢大家,还希望能有更有见地的想法~~~~~~~
      

  19.   

    playclick  里面为什么调用不了的问题 你还是回去好好想想
    你代码里面所谓的接口的东西 都是用错的   还有你的OO思想要培养一下  改一下你的代码 
    playclick  调用 WebPlayer的addIndex方法 来达到Index++的效果
    在addIndex方法中添加对 图片切换面板的repaint
      

  20.   


    public class WebPlayer extends JApplet
    {
        private static final long  serialVersionUID = 345678L;    private javax.swing.JPanel jContentPanel    = null;
        private javax.swing.JPanel jPanelNorth      = null;
        private javax.swing.JPanel jPanelSouth      = null;
        private javax.swing.JPanel jPanelEast       = null;
        private javax.swing.JPanel jPanelWest       = null;
        private javax.swing.JPanel jPanelCenter     = null;
        private javax.swing.JPanel jPanelPlay       = null;    private javax.swing.JLabel labelNorth       = null;
        private javax.swing.JLabel labelSouth       = null;
        private javax.swing.JLabel labelEast        = null;
        private javax.swing.JLabel labelWest        = null;
        // private javax.swing.JLabel labelCenter = null ;    private MyJButton          playButton       = null;
        private boolean            Selected         = true;
        // int i = 1;
        int                        index            = 0;    public void init()
        {
            this.setContentPane(getJContentPanel());
            this.setSize(166, 230);    }    public void start()
        {    }    private javax.swing.JPanel getJContentPanel()
        {        Color playColor = new Color(100, 100, 100);
            Font playFont = new Font("default", Font.BOLD, 10);        if (jContentPanel == null)
            {
                jContentPanel = new javax.swing.JPanel();            jContentPanel.setLayout(new BorderLayout());            jContentPanel.setBackground(java.awt.Color.WHITE);            // 将applet的总范围设置为broderlayout,构成播放器的大体结构            if (jPanelNorth == null)
                {                javax.swing.JPanel jPanelNorth = new javax.swing.JPanel(
                            new GridLayout(1, 0, 0, 0));                ImageIcon imgNorth = new ImageIcon("north.jpg");                if (labelNorth == null)
                    {
                        JLabel labelNorth = new JLabel(imgNorth, JLabel.CENTER); // 在label里面加入图片                    jPanelNorth.add(labelNorth, null);// 将有图片的label放进上部分的jpanel                }
                    jContentPanel.add(jPanelNorth, BorderLayout.NORTH); // 上部分的jpanel放入整个borderlayout布局中            }            if (jPanelSouth == null)
                {
                    javax.swing.JPanel jPanelSouth = new javax.swing.JPanel(
                            new GridLayout(2, 0, 0, 0));// 将加入borderlayout.south的jpanel分成两列
                    Icon imgSouth = new ImageIcon("south.jpg");
                    if (labelSouth == null)
                    {
                        JLabel labelSouth = new JLabel(imgSouth, JLabel.CENTER);
                        jPanelSouth.add(labelSouth, null);// 将带标签的图像放入第一列                    if (jPanelPlay == null)
                        {
                            javax.swing.JPanel jPanelPlay = new javax.swing.JPanel(
                                    new GridLayout(1, 1, 0, 0));
                            // 将放入jpanelsouth第二列的jpanelplay分成两格,这里用
                            // gridlayout也很重要,避免了第一列的图像与其它模块产生缝隙                        // jPanelPlay.setLayout(null);                        jPanelPlay.add(playButton = new MyJButton("PLAY",
                                    playColor, playFont), null);
                            jPanelPlay.add(playButton = new MyJButton("STOP",
                                    playColor, playFont), null);                        jPanelSouth.add(jPanelPlay, null);
                        }                    // jPanelSouth.add(playButton = new
                        // MyJButton("play",playColor,playFont ),null);                }
                    jContentPanel.add(jPanelSouth, BorderLayout.SOUTH);            }            if (jPanelWest == null)
                {
                    javax.swing.JPanel jPanelWest = new javax.swing.JPanel(
                            new GridLayout(1, 0, 0, 0));                Icon imgWest = new ImageIcon("west.jpg");
                    if (labelWest == null)
                    {
                        JLabel labelWest = new JLabel(imgWest, JLabel.LEFT);
                        jPanelWest.add(labelWest, null);
                    }
                    jContentPanel.add(jPanelWest, BorderLayout.WEST);            }            if (jPanelEast == null)
                {
                    javax.swing.JPanel jPanelEast = new javax.swing.JPanel(
                            new GridLayout(1, 0, 0, 0));
                    Icon imgEast = new ImageIcon("east.jpg");
                    if (labelEast == null)
                    {
                        JLabel labelEast = new JLabel(imgEast, JLabel.RIGHT);
                        jPanelEast.add(labelEast, BorderLayout.NORTH);                }
                    jContentPanel.add(jPanelEast, BorderLayout.EAST);            }            /*
                 * if(jPanelCenter == null ) {
                 * 
                 * String image =new String(); switch (i) { case 1: image = "1.jpg";
                 * break; case 2: image = "2.jpg"; break; case 3: image = "3.jpg";
                 * break; case 4: image = "4.jpg"; break; case 5: image = "5.jpg";
                 * break; default: break; }
                 * 
                 * 
                 * 
                 * javax.swing.JPanel jPanelCenter = new javax.swing.JPanel(); Icon
                 * imgCenter=new ImageIcon(image); if (labelCenter == null) { JLabel
                 * labelCenter=new JLabel(imgCenter,JLabel.CENTER);
                 * jPanelCenter.add(labelCenter,BorderLayout.CENTER);
                 * 
                 * 
                 * 
                 *  } jContentPanel.add(jPanelCenter, BorderLayout.CENTER);
                 * 
                 *  }
                 */            if (jPanelCenter == null)
                {
                    jPanelCenter = new JCenterPanel();// 这个体现了接口的作用,先实例化一个对应类的变量
                    jContentPanel.add(jPanelCenter, BorderLayout.CENTER);// 调用drawimage的主动画界面
                }        }
            return jContentPanel;    }    //addIndex methond
        public void addIndex()
        {
            index++;
            System.out.println(index);
            jPanelCenter.repaint();
        }
        
        
        //
        public void cleanIndex()
        {
            index = 0;
            jPanelCenter.repaint();
        }
        
        ===============================
    太长 分段回复
    ===================
      

  21.   

    ==================
    接上
    =====================    // 主要的面板布局实现
        public class JCenterPanel extends JPanel
        {        Image[] img = new Image[10];        public JCenterPanel()
            {            try
                {
                    for (int i = 0; i < 10; i++)
                    {
                        img[i] = getImage(getCodeBase(), (i + 1) + ".jpg");
                    }            }
                catch (Exception e)
                {
                    e.printStackTrace();
                }
            }        public void paintComponent(Graphics g)
            {
                super.paintComponent(g);
                // if (img[index] == null ) return;            index = (index) % 10;
                g.drawImage(img[index], 0, 0, this);        }        public void playClick()
            {            addIndex();        }        public void stopClick()
            {
                cleanIndex();        }    }    // 实现中间的动画转换    public class MyJButton extends JButton
        {        Timer mouseTimer = null;        public MyJButton(String pTitle, Color pBk, java.awt.Font pFont)
            {            this.setText(pTitle);
                this.setBackground(pBk);
                this.setFont(pFont);
                this.addMouseListener(new MouseAdapter()
                {
                    public void mouseClicked(MouseEvent e)
                    {
                        if (e.getClickCount() == 1)
                        {
                            mouseTimer = new javax.swing.Timer(350,
                                    new ActionListener()
                                    {
                                        public void actionPerformed(ActionEvent evt)
                                        {
                                            if (!Selected)
                                                return;
                                            if (getText().equals("PLAY"))
                                            {
                                                JCenterPanel jCenterPanel = new JCenterPanel();
                                                jCenterPanel.playClick();// 接口的调用
                                                setBackground(java.awt.Color.GREEN);                                            mouseTimer.stop();
                                            }
                                            else if (getText().equals("STOP"))
                                            {
                                                JCenterPanel jCenterPanel = new JCenterPanel();
                                                jCenterPanel.stopClick();
                                                setBackground(java.awt.Color.RED);                                            mouseTimer.stop();                                        }                                    }
                                    });
                            mouseTimer.start();
                        }
                        else if (e.getClickCount() == 2 && mouseTimer.isRunning())
                        {
                            mouseTimer.stop();
                            setBackground(java.awt.Color.blue);
                        }                }
                });        }    }
    }
      

  22.   

    其实说实话我并不知道你想要的结果是什么样?
    昨天在我这边是跑成功了才回复你的
    虽然可能存在很多bug但是应该是满足下面的要求:
    启动之后显示1.jpg
    按下play之后不停播放图片
    (但是stop之后没有停,因为你没有实现)
    最小化后无显示问题
    按下play之后,play变绿
    需要注意的是按下play之后需要等一下图片才会切换
      

  23.   

    问题都解决了,谢谢大家付出的努力~~~~zdjray(PubSoft),上午又看了你一下你的jCenterPanel.paint(WebPlayer.this.getGraphics());  这个语句,除了开始会显示混乱,图像不在画布中央外,过一会显示和功能还是比较正常,呵呵,程序这个东西还是蛮有性格的,最重要的是这句话提供另一种思路,我会最近两天研究一下正常实现这个语句的~~~~~insiku(FUCK Java Generics!!! || PM我时请附上帖子地址),非常非常感谢你晚上快12点还帮我提供了解决方案,我今后会向你多多学习~~揭帖了,再一次感谢两位,在论坛中我也会关注和 支持两位的~~~我要把这个帖子总结一下,问题回顾一下,争取尽快解决~~并尽早添加新的线程~~~
      

  24.   

    我看了一下,他把jPanelCenter作为全局变量
    这样是很方便的
    我开始也奇怪为什么你每次要新申明一个JCenterPanel 
    我只是把他改到了匿名内外,这样作用域小些
    不过没想到不满足你的要求~~
    说实话我并不知道你具体的布局是怎样的,所以就照上面的给你了:)