没有调用JPanel绘制方法,为什么?

时间:2010-04-08 10:44:55

标签: java swing paint

当我运行此代码时,不会调用paintComponent方法 这可能是非常简单的错误,但我不知道为什么这样,PLZ。

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  

}

实例化用户板类的代码

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

}

2 个答案:

答案 0 :(得分: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()方法。

答案 1 :(得分:0)

如果您只是将面板用于自己的绘图,那么只需覆盖绘图(Grapics)。我发现它更容易。如果您希望JPanel显示边框,请在绘图后调用paint(Graphics)中的paintBorder。