Java JLayeredPane没有显示它的元素

时间:2014-05-03 21:00:53

标签: java swing jlayeredpane

我正在尝试使用JLayeredPane将一个JPanel叠加在另一个上面。出于某种原因,添加的面板不会显示出来。

这是创建JLayeredPane并向其添加元素的代码:

import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLayeredPane;
import javax.swing.SwingUtilities;

public class CarAnimator extends JFrame {

    public CarAnimator()
    {
        JLayeredPane racingOverlay = new JLayeredPane();

        CarAnimatorJPanel animation = new CarAnimatorJPanel();
        Racetrack racetrack = new Racetrack();

        racingOverlay.add(racetrack,JLayeredPane.DEFAULT_LAYER);
        racingOverlay.add(animation,new Integer(2));

        racingOverlay.setBorder(BorderFactory.createTitledBorder("Can't see a thing"));

        this.getContentPane().add(racingOverlay,BorderLayout.CENTER);

        this.setLocationByPlatform(true);
        this.setPreferredSize(new Dimension(850,650));
        this.setMaximumSize(new Dimension(850,650));
        this.setMinimumSize(new Dimension(850,650));
        this.setResizable(false);//prevents user from resizing the window

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.pack();
    }

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(() -> {
            (new CarAnimator()).setVisible(true);
        });
    }  
}

这是赛道JPanel的代码:

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;

public class Racetrack extends JPanel
{
    Graphics g = this.getGraphics();

    @Override
    public void paintComponent(Graphics g)
    {
        Color c1 = Color.green; 
        g.setColor( c1 ); 
        g.fillRect( 150, 200, 550, 300 ); //grass

        Color c2 = Color.black; 
        g.setColor( c2 ); 
        g.drawRect(50, 100, 750, 500); // outer edge 
        g.drawRect(150, 200, 550, 300); // inner edge 

        Color c3 = Color.yellow; 
        g.setColor( c3 ); 
        g.drawRect( 100, 150, 650, 400 ); // mid-lane marker 

        Color c4 = Color.white; 
        g.setColor( c4 ); 
        g.drawLine( 425, 500, 425, 600 ); // start line
    }
}

这是JPanel动画示例,取自Java:How to Program book(http://java.uom.gr/~chaikalis/javaLab/Java_HowTo_9th_Edition.pdf),适用于我的代码:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;

public class CarAnimatorJPanel extends JPanel
{

 protected ImageIcon images[];
 private int currentImage=0;
 private final int ANIMATION_DELAY=50;
 private int width;
 private int height;
 private Timer animationTimer;

   public CarAnimatorJPanel()
   {
      try
      {
         File directory = new File("C://Users/eltaro/Desktop/Car images");
         File[] files = directory.listFiles();
         images = new ImageIcon[files.length];
         for (int i=0;i<files.length;i++)
         {
            if (files[i].isFile())
            {
                images[i]=new ImageIcon(ImageIO.read(files[i]));
            }
         }

         width = images[0].getIconWidth();
         height = images[0].getIconHeight();
      }
      catch(java.io.IOException e)
      {
         e.printStackTrace();
      }
   }

   @Override
   public void paintComponent(Graphics g)
   {
      super.paintComponent(g);
      images[currentImage].paintIcon(this,g,0,0);

      if(animationTimer.isRunning())
      {
         currentImage=(currentImage+1)%images.length;
      }
   }

   public void startAnimation()
   {
      if(animationTimer==null)
      {
         currentImage=0;
         animationTimer=new Timer(ANIMATION_DELAY, new TimerHandler());
         animationTimer.start();
      }
      else
      {
         if(!animationTimer.isRunning())
         {
            animationTimer.restart();
         }
      }
   }

   public void stopAnimation()
   {
      animationTimer.stop();
   }

   @Override
   public Dimension getMinimumSize()
   {
      return getPreferredSize();
   }

   @Override
   public Dimension getPreferredSize()
   {
      return new Dimension(width,height);
   }

   private class TimerHandler implements ActionListener
   {
      @Override
      public void actionPerformed(ActionEvent actionEvent)
      {
      repaint();
      }
   }
}

当我将两个JPanel添加到CarAnimator构造函数中的JLayeredPane时,它们无法显示:

enter image description here

1 个答案:

答案 0 :(得分:2)

一些建议:

  • 由于我猜测你的CarAnimatorJPanel位于背景JPanel之上,你最好通过setOpaque(false)将CarAnimatorJPanel设置为非透明,以便可以看到它背后的JPanel。
  • 将组件添加到JLayeredPane时,实质上是将组件添加到空布局。这意味着您绝对需要设置这些组件的大小(或覆盖getSize()),而不是首选大小。
  • 与往常一样,在处理图像文件时,调试您可以在单独的小型测试程序中充分读取图像。像往常一样,考虑将图像作为资源而不是文件。
  • 您的paintComponent(Graphics g)方法中有一些程序逻辑代码 - 您可以更改currentImage字段的状态。永远不要这样做,因为你永远无法完全控制何时甚至如果调用 paintComponent。这段代码属于你的动画循环,你的Swing Timer的ActionListener。