2010-04-08 332 views
0

当我运行此代码paintComponent方法不被称为 它可能是非常简单的错误,但我不知道这是为什么,PLZ。JPanel paint方法没有被调用,为什么?

package test; 

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.image.BufferedImage; 
import javax.swing.BorderFactory; 
import javax.swing.JPanel; 

class Userboard extends JPanel 
{ 
    static BufferedImage image; 
    String shape; 
    Point start; 
    Point end; 
    Point mp; 
    String selected; 
    int ex,ey;//eraser 
    int w,h; 
    public Userboard() 
    {   

     setOpaque(false); 
     System.out.println("paper"); 
     setBackground(Color.white); 

     setBorder(BorderFactory.createLineBorder(Color.black));   
    } 
    public void paintComponent(Graphics g) 
    { 
      System.out.println("userboard-paint"); 
     try 
     { 

      //g.drawImage(image, 0, 0, this); 
      Graphics2D g2 = (Graphics2D)g; 
      g2.setPaint(Color.black); 
      if(start!=null && end!=null) 
      { 
       if(selected==("elipse")) 
       { 
        System.out.println("userboard-elipse"); 
        g2.drawOval(start.x, start.y,(end.x-start.x),(end.y-start.y)); 
        System.out.println("userboard-elipse drawn"); 
       } 
       else if(selected==("rect")) 
        g2.drawRect(start.x, start.y, (end.x-start.x),(end.y-start.y)); 
       else if(selected==("line")) 
        g2.drawLine(start.x,start.y,end.x,end.y); 
      }   
     } 
      catch(Exception e) 
      {} 
    } 
    //Function to draw the shape on image 
    public void draw() 
    { 
     System.out.println("Userboard-draw"); 
     System.out.println(selected); 
     System.out.println(start); 
     System.out.println(end); 
     Graphics2D g2 = image.createGraphics(); 
     g2.setPaint(Color.black); 
     if(start!=null && end!=null) 
     { 
      if(selected=="line") 
        g2.drawLine(start.x, start.y, end.x, end.y); 
      else if(selected=="elipse") 
      { 
       System.out.println("userboard-elipse"); 
       g2.drawOval(start.x, start.y, (end.x-start.x),(end.y-start.y)); 
       System.out.println("userboard-elipse drawn"); 
      } 
      else if(selected=="rect") 
        g2.drawRect(start.x, start.y, (end.x-start.x),(end.y-start.y)); 
     } 
     start=null; 
     repaint(); 
     g2.dispose(); 
    } 
    //To add the point to the board which is broadcasted by the server 
    public void addPoint(Point ps,String varname,String shape,String event) 
    {  
     try 
     { 
      if(end==null) 
       end = new Point(); 
      if(start==null) 
       start = new Point(); 

      if(shape.equals("elipse")) 
       this.selected="elipse"; 
      else if(shape.equals("line")) 
       this.selected="line"; 
      else if(shape.equals("rect")) 
       this.selected="rect"; 
      else if(shape.equals("erase")) 
       erase(); 

      if(end!=null && start!=null) 
      {   
       if(varname.equals("end")) 
         end=ps; 
       else if(varname.equals("mp")) 
         mp=ps;   
       else if(varname.equals("start")) 
         start=ps; 

       if(event.equals("drag")) 
         repaint(); 
       else if(event.equals("release")) 
         draw();  
      } 
       repaint(); 
     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 
     } 
} 
    //Function which provides the erase functionality 
    public void erase() 
    { 
     Graphics2D pic=(Graphics2D) image.getGraphics(); 
     pic.setPaint(Color.white); 
     if(start!=null) 
     pic.fillRect(start.x, start.y, 10, 10); 
    } 

    //To set the size of the image 

    public void setWidth(int x,int y) 
    { 
     System.out.println("("+x+","+y+")"); 
     w=x; 
     h=y; 
     image = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); 
    } 
    //Function to add buttons into the panel, calling this function returns a panel 

} 

代码实例化userboard类

public class Client extends Thread 
{ 
    Point point; 
    Paper paper; 
    Userboard userboard; 

    DatagramSocket datasocket=null; 
    public Client(DatagramSocket datasocket) 
    { 
      this.datasocket=datasocket; 
    } 

    //This function is to create the JFrame 
    public void createFrame() 
    { 
     JLayeredPane layerpane=new JLayeredPane(); 
     JFrame frame=new JFrame("Whiteboard"); 
     paper= new Paper(datasocket); 
     userboard=new Userboard(); 
     frame.setLayout(new BorderLayout()); 
     layerpane.setLayout(new BorderLayout()); 


     layerpane.add(paper,BorderLayout.CENTER); 
     layerpane.add(userboard,BorderLayout.CENTER);//Panel where remote user draws 

     frame.add(paper.addButtons(),BorderLayout.WEST); 
     frame.add(layerpane,BorderLayout.CENTER); 


     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     frame.setSize(640, 480); 
     frame.addWindowListener(new WindowAdapter() 
     { 
      public void windowOpened(WindowEvent e) {} 
      public void windowClosing(WindowEvent e) 
      { 
       Draw draw=new Draw(); 
       draw. close(); 
      }   
     }); 
     paper.setWidth(frame.getWidth(),frame.getHeight()); 
     userboard.setWidth(frame.getWidth(),frame.getHeight()); 
     frame.setVisible(true); 
    } 

    /* 
    * This function is overridden from the thread class 
    * This function listens for incoming packets from the server 
    * which contains the points drawn by the other client 
    */ 
    public void run() 
    {  
      while (true) 
      { 
       try 
       { 
        byte[] buffer = new byte[512]; 
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length); 
        datasocket.receive(packet); 
        InputStream in=new ByteArrayInputStream(packet.getData(), packet.getOffset(),packet.getLength()); 
        DataInputStream din=new DataInputStream(in);    
        int x=din.readInt(); 
        int y=din.readInt(); 
        String varname=din.readLine(); 
        String var[]=varname.split("-",3); 
        point=new Point(x,y); 
        userboard.addPoint(point, var[0], var[1],var[2]);     
       } 
       catch (IOException ex) 
       { 
        ex.printStackTrace(); 
       } 
     }  
    } 

    //This function is to broadcast the newly drawn point to the server 
    public void broadcast (Point p,String varname,String shape,String event) 
    { 
     try 
     { 
      ByteArrayOutputStream baos=new ByteArrayOutputStream(); 
      DataOutputStream dos=new DataOutputStream(baos); 
      dos.writeInt(p.x); 
      dos.writeInt(p.y); 
      dos.writeBytes(varname); 
      dos.writeBytes("-"); 
      dos.writeBytes(shape); 
      dos.writeBytes("-"); 
      dos.writeBytes(event); 
      dos.close(); 
      byte[]data=baos.toByteArray(); 
      InetAddress ip=InetAddress.getByName("10.123.97.125"); 
      DatagramPacket packet=new DatagramPacket(data, data.length,ip , 8002); 
      datasocket.send(packet); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 
    } 

} 
+1

方法签名看起来是正确的。你可以发布你实例化UserBoard并将其添加到顶级窗口的代码吗? – Adamski 2010-04-08 11:05:30

+1

我刚刚运行了你的代码(注释掉了一些没有提供的类),并调用了Userboard的paint方法。我认为你需要系统地简化你的代码,直到它适合你,然后一次添加一个东西,直到你看到它出错的地方。 – Ash 2010-04-08 12:05:50

回答

2

我认为你将你的两个面板的分层窗格走错了路。我建议您阅读tutorial for JLayeredPane

添加到JLayeredPane时,不应提供布局提示(在本例中不相关),而是要添加组件的图层的ID。

从教程:

for (int i = 0; i < ...number of labels...; i++) { 
    JLabel label = createColoredLabel(...); 
    layeredPane.add(label, new Integer(i)); 
    ... 
} 

在你的情况,你可能希望这样的事情:

layerpane.add(paper,  new Integer(0)); 
layerpane.add(userboard, new Integer(1));//Panel where remote user draws 

我不保证这是唯一的问题,但如果的确图层出现问题,它可以解释为什么你的UserBoard.paintComponent()方法永远不会被调用。

0

如果您只是将面板用于您自己的绘图,那么只需重写paint(Grapics)即可。我发现它更容易。如果您想让JPanel显示边框,请在绘制后在paint(Graphics)中调用paintBorder。

相关问题