我正在尝试使用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时,它们无法显示:
答案 0 :(得分:2)
一些建议:
setOpaque(false)
将CarAnimatorJPanel设置为非透明,以便可以看到它背后的JPanel。getSize()
),而不是首选大小。paintComponent(Graphics g)
方法中有一些程序逻辑代码 - 您可以更改currentImage字段的状态。永远不要这样做,因为你永远无法完全控制何时甚至如果调用 paintComponent。这段代码属于你的动画循环,你的Swing Timer的ActionListener。