Java - 为什么这个小程序的背景不显示浅蓝色(青色)?

时间:2015-03-30 01:45:53

标签: java swing applet japplet setbackground

此代码来自Lewis Loftus的Java教科书。它显示了教科书中的示例输出,背景为浅蓝色(青色)。我认为有一些问题:

setBackground(Color.cyan);

以下是整个计划:

import javax.swing.JApplet;
import java.awt.*;

public class Snowman extends JApplet
{
    //-----------------------------------------------------------------
    //  Draws a snowman.
    //-----------------------------------------------------------------
    public void paint(Graphics page)
    {
        final int MID = 150;
        final int TOP = 50;

        setBackground(Color.cyan);

        page.setColor(Color.blue);
        page.fillRect(0, 175, 300, 50);  // ground

        page.setColor(Color.yellow);
        page.fillOval(-40, -40, 80, 80);  // sun

        page.setColor(Color.white);
        page.fillOval(MID-20, TOP, 40, 40);      // head

        page.fillOval(MID-35, TOP+35, 70, 50);   // upper torso
        page.fillOval(MID-50, TOP+80, 100, 60);  // lower torso

        page.setColor(Color.black);
        page.fillOval(MID-10, TOP+10, 5, 5);   // left eye
        page.fillOval(MID+5, TOP+10, 5, 5);    // right eye

        page.drawArc(MID-10, TOP+20, 20, 10, 190, 160);   // smile

        page.drawLine(MID-25, TOP+60, MID-50, TOP+40);  // left arm
        page.drawLine(MID+25, TOP+60, MID+55, TOP+60);  // right arm

        page.drawLine(MID-20, TOP+5, MID+20, TOP+5);  // brim of hat
        page.fillRect(MID-15, TOP-20, 30, 25);        // top of hat

    }
}

1 个答案:

答案 0 :(得分:3)

永远不要尝试绘制顶级组件。相反,创建一个扩展JPanel的类,覆盖其paintComponent方法,确保在覆盖中调用超级paintComponent,然后将JPanel添加到JApplet的contentPane中。另外,在构造函数中设置JPanel的背景,而不是在paint或paintComponent方法中。

此外,在将来的问题中,请尝试将代码缩进合理且一致的数量。良好的代码格式化使代码更容易阅读,更重要的是,理解

如,

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.*;

@SuppressWarnings("serial")
public class SnowManPanel extends JPanel {
   private static final Color BACKGROUND = Color.CYAN;
   private static final int MID = 150;
   private static final int TOP = 50;
   private static final int PREF_W = 300;
   private static final int PREF_H = 225;

   public SnowManPanel() {
      setBackground(BACKGROUND);
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.setColor(Color.blue);
      g.fillRect(0, 175, PREF_W, PREF_H - 175);  // ground

      g.setColor(Color.yellow);
      g.fillOval(-40, -40, 80, 80);  // sun

      g.setColor(Color.white);
      g.fillOval(MID-20, TOP, 40, 40);      // head

      g.fillOval(MID-35, TOP+35, 70, 50);   // upper torso
      g.fillOval(MID-50, TOP+80, 100, 60);  // lower torso

      g.setColor(Color.black);
      g.fillOval(MID-10, TOP+10, 5, 5);   // left eye
      g.fillOval(MID+5, TOP+10, 5, 5);    // right eye

      g.drawArc(MID-10, TOP+20, 20, 10, 190, 160);   // smile

      g.drawLine(MID-25, TOP+60, MID-50, TOP+40);  // left arm
      g.drawLine(MID+25, TOP+60, MID+55, TOP+60);  // right arm

      g.drawLine(MID-20, TOP+5, MID+20, TOP+5);  // brim of hat
      g.fillRect(MID-15, TOP-20, 30, 25);        // top of hat
   }

   @Override
   public Dimension getPreferredSize() {
      if (isPreferredSizeSet()) {
         return super.getPreferredSize();
      }
      return new Dimension(PREF_W, PREF_H);
   }

   private static void createAndShowGui() {
      SnowManPanel mainPanel = new SnowManPanel();

      JFrame frame = new JFrame("SnowManPanel");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

请注意,顶级窗口(如JApplet和JFrame)有点复杂,并且具有多个角色以及多个层。一个问题是你的程序试图直接在JApplet的绘制方法中绘制,忽略了applet的背景是由另一个层绘制的,它的contentPane是一个JPanel,它包含所有的applet' s内容。通过不调用super.paint(...)方法,它也有可能破坏applet的绘画链 - 因为applet自己的绘画(通过super.paint(...)调用)最终负责绘制所有applet,包括其边框及其子组件。