我在一个applet中加入了自己定制的DrawPanel类,并且设置了背景色,DrawPanel类是用于画图的,但是很奇怪,无论怎么设置JPanel总是显示不出背景色,除非把paintComponent注释掉,这是为什么呢?希望大家能帮我讲述一下JPanel的绘图原理,无比感激!
public class MainApplet extends Applet implements ActionListener
{
JPanel jpnFunction = new JPanel();
DrawPanel jpnDraw;


/**
 * 在applet上加swing组件。
 * @param jc 组件
 * @param x x坐标
 * @param y y坐标
 * @param width 组件长度
 * @param height 组件高度
 */
public void add(JComponent jc,int x,int y,int width,int height)
{
jc.setBounds(x, y, width, height);
add(jc);
}

public void init()
{
setBackground(Color.yellow);   
setLayout(null);
jpnDraw = new DrawPanel();
jpnDraw.setBackground(Color.green);
jpnFunction.setBackground(Color.blue);
 
add(jpnDraw,10,10,600,600);
add(jpnFunction,350,350,300,300);
} public void actionPerformed(ActionEvent e)
{ }
}public class DrawPanel extends JPanel 
{
public void paintComponent(Graphics g)
{
super.paintComponents(g);
g.setColor(Color.blue);
g.drawString("fuck", getX(),getY());
g.drawRect(getX(),getY(),getWidth()/10,getHeight()/10);   

}

解决方案 »

  1.   

    jpnDraw.setBackground(Color.green);这里设置的背景色何用?
    如果要给jpnDraw添加背景色,可以通过绘制实体矩形来实现
    public void paintComponent(Graphics g)
        {
            super.paintComponents(g);
            //设置颜色
            g.setColor(Color.green);
            g.fillRect(getX(),getY(),getWidth(),getHeight()); 
            //设置其他颜色
            g.setColor(Color.blue);
            g.drawString("fuck", getX(),getY());
            g.drawRect(getX(),getY(),getWidth()/10,getHeight()/10);   
        } 
      

  2.   

    2楼的方法我知道,不过我的问题就是为何会显示不出背景色,如果是一个没有绘图的JPanel就能显示,为什么呢?
      

  3.   

    如果要想知道原理,需要看下相关文件的源代码,具体如下,JPanel的父类java,swing.JComponent中的paintComponent的实现中,主要是调用了java.swing.plaf.CompontUI的update方法对其组件进行重绘,查看update的方法内容你会发现,其实他也是通过设置颜色,绘制了一个实体矩形,而其设置的颜色就是JComponent(JPanel)的背景色,如果你覆盖paintComponent方法,则绘制时不会再调用JComponent的paintComponent,也就不会调用update,你设置的背景色也失效了,可以看下相关class源码,JDK下src.zip解压后既可看到
      

  4.   

    谢谢楼上的解答,不过下面这个程序也是重写paintComponent方法,也是在重写前设置了背景色,但是这个程序就能显示背景色,这就是我所郁闷的为什么我的就不能显示?public class CustomPanel extends JPanel {
       public final static int CIRCLE = 1, SQUARE = 2;
       private int shape;   // use shape to draw an oval or rectangle
       public void paintComponent( Graphics g )
       {
          super.paintComponent( g );      if ( shape == CIRCLE )
             g.fillOval( 50, 10, 60, 60 );
          else if ( shape == SQUARE )
             g.fillRect( 50, 10, 60, 60 );
       }   // set shape value and repaint CustomPanel
       public void draw( int shapeToDraw )
       {
          shape = shapeToDraw;
          repaint();
       }}  // end class CustomPanelpublic class CustomPanelTest extends JFrame {
    private JPanel buttonPanel;
    private CustomPanel myPanel;
    private JButton circleButton, squareButton;// set up GUI
    public CustomPanelTest()
    {
       super( "CustomPanel Test" );   // create custom drawing area
       myPanel = new CustomPanel();   
       myPanel.setBackground( Color.green );   // set up squareButton
       squareButton = new JButton( "Square" );
       squareButton.addActionListener(      // anonymous inner class to handle squareButton events
          new ActionListener() {         // draw a square
             public void actionPerformed( ActionEvent event )
             {
                myPanel.draw( CustomPanel.SQUARE );
             }      }  // end anonymous inner class   ); // end call to addActionListener   circleButton = new JButton( "Circle" );
       circleButton.addActionListener(      // anonymous inner class to handle circleButton events
          new ActionListener() {         // draw a circle
             public void actionPerformed( ActionEvent event )
             {
                myPanel.draw( CustomPanel.CIRCLE );
             }      }  // end anonymous inner class   ); // end call to addActionListener   // set up panel containing buttons
       buttonPanel = new JPanel();
       buttonPanel.setLayout( new GridLayout( 1, 2 ) );
       buttonPanel.add( circleButton );
       buttonPanel.add( squareButton );   // attach button panel & custom drawing area to content pane
       Container container = getContentPane();
       container.add( myPanel, BorderLayout.CENTER );  
       container.add( buttonPanel, BorderLayout.SOUTH );   setSize( 300, 150 );
       setVisible( true );
    }// execute application
    public static void main( String args[] )
    {
       CustomPanelTest application = new CustomPanelTest();   application.setDefaultCloseOperation(
          JFrame.EXIT_ON_CLOSE );
    }}  // end class CustomPanelTest
      

  5.   


    class DrawPanel extends JPanel
    {

    public void paintComponent(Graphics g)
    { getUI().update(g, this);
    g.setColor(Color.blue);
    g.drawString("fuck", getX(), getY());
    g.drawRect(getX(), getY(), getWidth() / 10, getHeight() / 10);
    g.dispose();
    }
    }
      

  6.   

    呵呵,我建议楼主多看看API源码,有些东西不是说就能说明白的,就拿SWING的机制来说,如果查找代码发现很多地方就断掉了,实际上实现部分在com.sun这个包里面。
      

  7.   

    其实楼主你不行的主要原因是你将super.paintComponent(Graphics)写成了super.paintComponents,哈哈这是两个完全不同的方法。