【问题标题】:Java JLayeredPane doesn't show it's elementsJava JLayeredPane 不显示它的元素
【发布时间】:2014-06-20 09:58:21
【问题描述】:

我正在尝试使用 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 时,它​​们无法显示:

【问题讨论】:

    标签: java swing jlayeredpane


    【解决方案1】:

    一些建议:

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

    【讨论】:

    • 实际上,我已经查看了您提供的其他类似问题的答案,特别是这个:stackoverflow.com/questions/7938825/… 并未能使其正常工作。然而,我回到上面的例子并从那里提取了两行:myGraphic.setSize(layeredPane.getPreferredSize()); myGraphic.setLocation(0, 0);并将它们转换为我的:racetrack.setSize(750,500);赛马场.setLocation(0,0);它奏效了。您的答案现在被标记为正确。谢谢。
    猜你喜欢
    • 2013-12-08
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    • 2019-04-22
    • 1970-01-01
    • 1970-01-01
    • 2011-11-06
    • 1970-01-01
    相关资源
    最近更新 更多