你有没有重写setvisible,或者干预了绘制过程呢?
代码太长你就节选重要的部分啊,没代码怎么看

解决方案 »

  1.   

    偶没有改写setVisible
    偶可以把代码都帖出来,但真的会有人研究吗?(为了测试方便,偶还加了bug变量)package link;import java.util.*;
    import java.net.*;
    import java.awt.*;
    import java.awt.event.*;import table.Confirmee;
    import table.Table;
    import table.LightBox;
    import table.LightStatus;public class ConfirmDialog extends Dialog implements Observer
     {Confirmee cf;  Label lb,lights[];  int bug=0;
      public ConfirmDialog(Frame f,Confirmee m)
       {super(f,false); cf=m; 
        GridBagLayout gbl=new GridBagLayout(); setLayout(gbl);
        GridBagConstraints c=new GridBagConstraints();
       
        lights=new Label[Table.MAXPLAYERS];
        Panel p=new Panel(); byte a[]=new byte[1]; a[0]=64; String s;
        for(int i=0;i<Table.MAXPLAYERS;i++)
         {a[0]++; s=new String(a); 
          lights[i]=new Label(s,Label.CENTER); p.add(lights[i]);
         } 
        c.gridx=0;c.gridy=0; gbl.setConstraints(p,c); add(p);
        
        lb=new Label("Continue?",Label.CENTER);
        c.gridx=0;c.gridy=1; gbl.setConstraints(lb,c); add(lb);    p=new Panel(); Button b=new Button("Yes"); p.add(b);
        b.addActionListener(new ConfirmListener());
        b=new Button("No"); p.add(b);
        b.addActionListener(new ConfirmListener());
        b=new Button("Close"); p.add(b);   // b.addActionListener(new ConfirmListener());
        c.gridx=0;c.gridy=2; gbl.setConstraints(p,c); add(p);    pack(); setLocationRelativeTo(null);m.addObserver(this);
       }   class ConfirmListener implements ActionListener
       {public void actionPerformed(ActionEvent e)
         {String s=e.getActionCommand();
          if(s.equals("Yes")) cf.confirm(true); 
          if(s.equals("No")) cf.confirm(false); 
         }
       }    public void update(Observable o1,Object o2)
       {
        LightStatus s=cf.getLightStatus();
    //    if(Color.red.equals(b.getLight())) {setVisible(false); return;}  
    //    if(b.allGreen()) setVisible(false);   
            bug++;      System.out.println("Time="+cf.getTime()+" bug="+bug);
        if(cf.getTime()==-1) return;  setVisible(true);            
    //    if(cf.getTime()!=-1)      if(s==null) return; 
     byte c[]=new byte[1]; c[0]=64; String t;
        for(int i=0;i<Table.MAXPLAYERS;i++)
         {c[0]++; t=new String(c); if(i==cf.getSeat()) t="Me";
          lights[i].setText(t); lights[i].setBackground(s.getLight(i));
          if(i>s.getTotal()-1) lights[i].setEnabled(false);
          else lights[i].setEnabled(true);
         } 
        if(s.getSubID()>1) lb.setText("Continue? ("+cf.getTime()+")");
        else lb.setText("About to begin, pls click Yes ("+cf.getTime()+")");
        pack();         System.out.println("21 "+bug);
        if(s.getCounter()==s.getTotal())  {setVisible(false); System.out.println("22 "+bug);}
       }   
       
     }
      

  2.   

    为了能看得更清楚,重帖以上代码:
    package link;import java.util.*;
    import java.net.*;
    import java.awt.*;
    import java.awt.event.*;import table.Confirmee;
    import table.Table;
    import table.LightBox;
    import table.LightStatus;public class ConfirmDialog extends Dialog implements Observer
     {Confirmee cf;  Label lb,lights[];  int bug=0;
      public ConfirmDialog(Frame f,Confirmee m)
       {super(f,false); cf=m; 
        GridBagLayout gbl=new GridBagLayout(); setLayout(gbl);
        GridBagConstraints c=new GridBagConstraints();
       
        lights=new Label[Table.MAXPLAYERS];
        Panel p=new Panel(); byte a[]=new byte[1]; a[0]=64; String s;
        for(int i=0;i<Table.MAXPLAYERS;i++)
         {a[0]++; s=new String(a); 
          lights[i]=new Label(s,Label.CENTER); p.add(lights[i]);
         } 
        c.gridx=0;c.gridy=0; gbl.setConstraints(p,c); add(p);
        
        lb=new Label("Continue?",Label.CENTER);
        c.gridx=0;c.gridy=1; gbl.setConstraints(lb,c); add(lb);    p=new Panel(); Button b=new Button("Yes"); p.add(b);
        b.addActionListener(new ConfirmListener());
        b=new Button("No"); p.add(b);
        b.addActionListener(new ConfirmListener());
        b=new Button("Close"); p.add(b);   // b.addActionListener(new ConfirmListener());
        c.gridx=0;c.gridy=2; gbl.setConstraints(p,c); add(p);    pack(); setLocationRelativeTo(null);m.addObserver(this);
       }   class ConfirmListener implements ActionListener
       {public void actionPerformed(ActionEvent e)
         {String s=e.getActionCommand();
          if(s.equals("Yes")) cf.confirm(true); 
          if(s.equals("No")) cf.confirm(false); 
         }
       }    public void update(Observable o1,Object o2)
       {
        LightStatus s=cf.getLightStatus();
    //    if(Color.red.equals(b.getLight())) {setVisible(false); return;}  
    //    if(b.allGreen()) setVisible(false);   
            bug++;      System.out.println("Time="+cf.getTime()+" bug="+bug);
        if(cf.getTime()==-1) return;  setVisible(true);            
    //    if(cf.getTime()!=-1)      if(s==null) return; 
     byte c[]=new byte[1]; c[0]=64; String t;
        for(int i=0;i<Table.MAXPLAYERS;i++)
         {c[0]++; t=new String(c); if(i==cf.getSeat()) t="Me";
          lights[i].setText(t); lights[i].setBackground(s.getLight(i));
          if(i>s.getTotal()-1) lights[i].setEnabled(false);
          else lights[i].setEnabled(true);
         } 
        if(s.getSubID()>1) lb.setText("Continue? ("+cf.getTime()+")");
        else lb.setText("About to begin, pls click Yes ("+cf.getTime()+")");
        pack();         System.out.println("21 "+bug);
        if(s.getCounter()==s.getTotal())  {setVisible(false); System.out.println("22 "+bug);}
       }   
       
     }
      

  3.   

    为了便于测试,偶加了几个println语句,以下是运行时的输出
    偶觉得明显执行过setVisible(false),但对话窗口没被关掉No.0 Client
    r:len=423
    Time=-1 bug=1
    r:len=423
    Time=1 bug=2
    21 2
    r:len=423
    Time=2 bug=3
    21 3
    r:len=423
    Time=3 bug=4
    21 4
    r:len=435
    Time=3 bug=5
    21 5
    Time=4 bug=6
    21 6
    r:len=435
    Time=5 bug=7
    21 7
    r:len=435
    Time=6 bug=8
    21 8
    r:len=423
    Time=6 bug=9
    21 9
    22 9
    Time=7 bug=10
    21 10
    22 10
    Time=-1 bug=11
      

  4.   

    serViaible(false)后调用一下repaint()试试。如果还是不行,就从父级直接remove掉。
      

  5.   

    感谢各位回复!
    偶把setVisible(false)改成dispose(),效果好像还可以偶想搞清楚的是:这究竟是偶程序的错,还是JDK的错?
    如果不是偶的错,偶就有信心了再帖一个类的代码:
    (坛子规定最多只能连发三帖,好像不太方便)package table;import java.util.*;
    import java.io.Serializable; 
    import java.awt.Color;
    import java.awt.*;import link.*;
    import guai.GuaiType;
    //import guai.GuaiEngine;public class Confirmee extends Observable implements Runnable,Listener
     {public static final int MAXTIME=20;
      Receiver2 input; MyLight ml; LightStatus ls; int time; //boolean flag; 
      
      public static void main(String args[])
       {if(args.length!=1) {System.out.println("One Arg Pls!"); return;}
        int n;
        try
         {n=Integer.parseInt(args[0]); System.out.println("No."+n+" Client");
          Receiver2 r=new Receiver2(n); Confirmee cf=new Confirmee(r);
          cf.setSeat(n);
          Frame f=new Frame(); ConfirmDialog cd=new ConfirmDialog(f,cf);
         }      
        catch(Exception e) {System.out.println(e.toString());}
       }  public Confirmee(Receiver2 r) 
       {input=r; input.addListener(this); ml=new MyLight(); ls=null; time=-1;}  public MyLight getMyLight() {return ml;}
      public LightStatus getLightStatus() {return ls;}
      public Color [] getLights() {return ls.getLights();}
      public int getSeat() {return ml.getSeat();}
      public void setSeat(int s) {ml.setSeat(s);}
      public int getTime() {return time;}
    //  public int getTimeout() {return MAXTIME-time;}  private boolean update(LightStatus s)
       {
        if(ls==null) 
        {ls=s; ml.reset(s.getID(),s.getSubID()); return true;}    if(ls!=null) if(ls.getID()<s.getID()) 
         {ls=s; ml.reset(s.getID(),s.getSubID()); return true;}
        if(ls!=null) if(ls.getID()==s.getID() && ls.getSubID()<s.getSubID())
         {ls=s; ml.reset(s.getID(),s.getSubID()); return true;}
        if(ls!=null) if(ls.getID()==s.getID() && ls.getSubID()==s.getSubID())
         {if(ls.getStatus()<s.getStatus()) {ls=s; return true; }} 
        return false; 
       }  public void listen(Object o)
       {if(!(o instanceof Message)) return; Message m=(Message)o;
        if(!(m.getObject() instanceof LightStatus)) return;
        LightStatus s=(LightStatus)m.getObject();
        if(update(s)) 
         {echo(); if(time==-1) new Thread(this).start();
          setChanged(); notifyObservers();
         } 
       }  private void echo()
       {EchoLight el=new EchoLight(ml.getSeat(),ls.getStatus());
        Message m=input.createMessage(el);
        int p=ls.getTableID()+Receiver.TABPORT;
        Tools.sendThing(m,input.getServer(),p,input.getSocket());
       }
      public void confirm(boolean r)
       {if(ls==null) return;
        if(ls.getID()!=ml.getID() || ls.getSubID()!=ml.getSubID()) return;
        if(!Color.yellow.equals(ml.getLight())) return;
        if(r) ml.setLight(Color.green); else ml.setLight(Color.red);
        repeat(); //setChanged(); notifyObservers();
       }  private void repeat() 
       {if(ls==null) return;
        if(ml.getLight().equals(Color.yellow)) return;
        if(ml.getLight().equals(ls.getLight(ml.getSeat()))) return;
        Message m=input.createMessage(ml);
        int p=Receiver.TABPORT+ls.getTableID();
        Tools.sendThing(m,input.getServer(),p,input.getSocket());
       } 
      public void run()
       {time=0; while(true) //flag=true; true if running
         {try {Thread.sleep(1000);}
          catch(Exception e) {System.out.println(e.toString());}    
          time++; setChanged(); notifyObservers();
          if(time==MAXTIME || ls.getFlag()==false) break; repeat(); 
         } 
        time=-1; setChanged(); notifyObservers();
       }
       
     }
      

  6.   

    呵呵,偶是业余水平的程序员,一直习惯这样的格式
    还是您找个美化器……偶的程序的目的是让几个客户确认一下(点击“是”),服务器把结果随时反馈给客户
    假定相互知道IP和端口,使用UDP,需实现重发和确认
    就这么看似简单的功能,也折腾了好多时间以下帖一个服务器端的类package server;import java.net.*;
    import java.awt.Color;import link.*;
    import guai.GuaiType;
    import guai.GuaiState;
    import table.*;public class Confirmer 
     {public static final int MAXTIME=15,ENDED=-1;
      LightStatus lights; Client list[]; int time; 
     
      public Confirmer()
       {lights=new LightStatus(); time=-1;} //ge=new GuaiEngine(tab); tab=t; 
      public void reset(int n) {lights.reset(n); time=0;}
      public void setClients(Client c[]) {list=c;} 
      public void prepare(long id,int t1,int t2) {lights.prepare(id,t1,t2);} 
      public int getTime() {return time;}
      public LightStatus getLights() {return lights; }
      
      public void processLight(MyLight ml)
       {
        if(Color.green.equals(ml.getLight()))
         {lights.setGreen(ml.getSeat());
          if(lights.getCounter()==list.length)
           {time=ENDED;System.out.println("OKgreen");}//     {   new Thread(ge).start(); }
         }    if(Color.red.equals(ml.getLight()))
         {lights.setRed(ml.getSeat()); time=ENDED;}
       }
      
      public synchronized boolean finished()
       {if(time==ENDED || lights.getFlag()==false) return true; return false;}
      
      public synchronized void tick()
       {if(time==ENDED) return;
        time++; if(time==MAXTIME) time=ENDED;
    //     {for(int i=0;i<list.length;i++)
    //       {if(!Color.green.equals(lights.getLight(i))) {;} }//tab.removeUser(i);
    //     }
       } 
              
     }
      

  7.   

    再帖一个类:package table;import java.io.Serializable;
    import java.awt.Color;public class LightStatus implements Serializable
     {long id; int tabid,subid,status,total,counter; Color lights[]; boolean flag;
     
      public LightStatus() 
       {lights=new Color[Table.MAXPLAYERS]; }
      public long getID() {return id;} 
      public int getTableID() {return tabid;} 
      public int getSubID() {return subid;} 
      public int getCounter() {return counter;} 
      public int getStatus() {return status;} 
      public int getTotal() {return total;} 
      public synchronized void setGreen(int n) 
       {lights[n]=Color.green; counter++; status++; if(counter==total) flag=false;}
      public synchronized void setRed(int n)
       {lights[n]=Color.red; status++; flag=false;}
      public synchronized Color getLight(int n)
       {if(n<0 || n>lights.length-1) return null;  return lights[n]; } 
      public Color [] getLights() {return lights;} 
      public boolean getFlag() {return flag;}
      public void prepare(long i,int t1,int t2) {id=i; tabid=t1; total=t2;}   
      public void reset(int n) 
       {subid=n; status=0; counter=0; flag=true;
        for(int i=0;i<total;i++) lights[i]=Color.yellow;
       }  public void print() 
       {for(int i=0;i<total;i++) 
         {System.out.println(i+")"+lights[i].toString()); }
       }  
     }
      

  8.   

    通过修改一段偶觉得无关的代码,问题似乎解决了
    没必要把setVisible(false)改成dispose()
    看来还是偶的错?但偶还是没明白是怎么错的
      

  9.   

    setVisible貌似不会自动重绘窗体,所以setVisible以后虽然这个组件应该是不可见的,但是如果你不重绘,就会一直保持上一次绘制时的状态。
      

  10.   

    偶怀疑原来的问题可能是多线程引起的
    但是从4楼的运行输出看,setVisible(false)之后应该没有setVisible(true)
    多个线程的运行顺序超出偶的想象?
    其实偶还是没明白到底错在哪里
    偶只有使用最最严格的逻辑、编写最最正确的代码,方能取得想要的结果以下帖的是更正确的Confirmee类,感谢各位的关注和支持!
    package table;import java.util.*;
    import java.io.Serializable; 
    import java.awt.Color;
    import java.awt.*;import link.*;
    import guai.GuaiType;
    //import guai.GuaiEngine;public class Confirmee extends Observable implements Runnable,Listener
     {public static final int MAXTIME=20;
      Receiver2 input; MyLight ml; LightStatus ls; int time; //boolean flag; 
      
      public static void main(String args[])
       {if(args.length!=1) {System.out.println("One Arg Pls!"); return;}
        int n;
        try
         {n=Integer.parseInt(args[0]); System.out.println("No."+n+" Client");
          Receiver2 r=new Receiver2(n); Confirmee cf=new Confirmee(r);
          cf.setSeat(n);
          Frame f=new Frame(); ConfirmDialog cd=new ConfirmDialog(f,cf);
         }      
        catch(Exception e) {System.out.println(e.toString());}
       }  public Confirmee(Receiver2 r) 
       {input=r; input.addListener(this); ml=new MyLight(); ls=null; time=-1;}  public MyLight getMyLight() {return ml;}
      public LightStatus getLightStatus() {return ls;}
      public Color [] getLights() {return ls.getLights();}
      public int getSeat() {return ml.getSeat();}
      public void setSeat(int s) {ml.setSeat(s);}
      public int getTime() {return time;}
    //  public int getTimeout() {return MAXTIME-time;}  private boolean update(LightStatus s)
       {
        if(ls==null) 
         {ls=s; ml.reset(s.getID(),s.getSubID()); new Thread(this).start(); return true;}
        if(ls!=null) if(ls.getID()<s.getID()) 
         {ls=s; ml.reset(s.getID(),s.getSubID()); new Thread(this).start(); return true;}
        if(ls!=null) if(ls.getID()==s.getID() && ls.getSubID()<s.getSubID())
         {ls=s; ml.reset(s.getID(),s.getSubID()); new Thread(this).start(); return true;}
        if(ls!=null) if(ls.getID()==s.getID() && ls.getSubID()==s.getSubID())
         {if(ls.getStatus()<s.getStatus()) {ls=s; return true; }} 
        return false; 
       }  public void listen(Object o)
       {if(!(o instanceof Message)) return; Message m=(Message)o;
        if(!(m.getObject() instanceof LightStatus)) return;
        LightStatus s=(LightStatus)m.getObject();
        if(update(s)) {echo(); } 
       }  private void echo()
       {Echo el=new Echo(ml.getSeat(),ls.getStatus());
        Message m=input.createMessage(el);
        int p=ls.getTableID()+Receiver.TABPORT;
        Tools.sendThing(m,input.getServer(),p,input.getSocket());
       }
      public void confirm(boolean r)
       {if(ls==null) return;
        if(ls.getID()!=ml.getID() || ls.getSubID()!=ml.getSubID()) return;
        if(!Color.yellow.equals(ml.getLight())) return;
        if(r) ml.setLight(Color.green); else ml.setLight(Color.red);
        repeat(); //setChanged(); notifyObservers();
       }  private void repeat() 
       {if(ls==null) return;
        if(ml.getLight().equals(Color.yellow)) return;
        if(ml.getLight().equals(ls.getLight(ml.getSeat()))) return;
        Message m=input.createMessage(ml);
        int p=Receiver.TABPORT+ls.getTableID();
        Tools.sendThing(m,input.getServer(),p,input.getSocket());
       } 
      public void run()
       {time=0; setChanged(); notifyObservers();
        while(true) //flag=true; true if running
         {try {Thread.sleep(1000);}
          catch(Exception e) {System.out.println(e.toString());}    
          time++; setChanged(); notifyObservers();
          if(time==MAXTIME || ls.getFlag()==false) break; repeat(); 
         } 
        time=-1; setChanged(); notifyObservers();
       }
       
     }