我有一个JPanel
在JFrame
内部有一个简单的动画雪粒子效果,它可以单独使用。但是当我尝试添加另一个面板时,它会使雪的效果停止。谁能帮我这个?这是分层的问题,还是什么?或者我的布局管理员是个问题吗?
我的代码:
package christmasfinal;
import java.awt.*;
import javax.swing.*;
public class ChristmasFinal extends JApplet {
public static void main(String[] args) {
JFrame frame = new JFrame();
TreePanel treePanel = new TreePanel();
frame.setSize(550, 420);
SnowBackgroundPanel snowPanel = new SnowBackgroundPanel(frame.getWidth(), frame.getHeight());
treePanel.setSize(200, 320);
snowPanel.setSize(frame.getWidth(), frame.getHeight());
snowPanel.setLayout(new BorderLayout());
frame.setLayout(new BorderLayout());
frame.add(snowPanel, BorderLayout.CENTER);
snowPanel.add(treePanel, BorderLayout.CENTER);
System.out.println(treePanel.getWidth() + " " + treePanel.getHeight());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setTitle("Christmas Final");
}
}
package christmasfinal;
import javax.swing.*;
import java.awt.*;
public class TreePanel extends JPanel{
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int[] treeX = {getWidth()/2, getWidth()/2-20, getWidth()/2-60, getWidth()/2-20,
getWidth()/2-40, getWidth()/2-80, getWidth()/2-20, getWidth()/2-60, getWidth()/2-100,
getWidth()/2+100,getWidth()/2+60, getWidth()/2+20, getWidth()/2+80,
getWidth()/2+40, getWidth()/2+20, getWidth()/2+60, getWidth()/2+20, getWidth()/2};
int[] treeY = {getHeight()/2-120, getHeight()/2-80, getHeight()/2-40, getHeight()/2-40,
getHeight()/2-20, getHeight()/2, getHeight()/2, getHeight()/2+40, getHeight()/2+60,
getHeight()/2+60, getHeight()/2+40, getHeight()/2, getHeight()/2, getHeight()/2-20,
getHeight()/2-40, getHeight()/2-40, getHeight()/2-80, getHeight()/2-120};
g.setColor(Color.GREEN);
g.fillPolygon(treeX, treeY, treeX.length);
g.setColor(new Color(102, 51, 0));
g.fillRect(getWidth()/2-20, getHeight()/2+60, 40, 40);
}
}
package christmasfinal;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;
import java.math.*;
public class SnowBackgroundPanel extends JPanel{
Random rand = new Random();
//Create ArrayList for SnowParticles
ArrayList<SnowParticle> snow = new ArrayList();
//Create animation timer
Timer timer = new Timer(7, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
repaint();
}
});
public SnowBackgroundPanel(int width, int height){
setSize(width, height);
System.out.println(getHeight() + " " + getWidth());
for(int i=0; i<50; i++){
snow.add(new SnowParticle());
snow.get(i).x = rand.nextInt(getWidth()+1);
snow.get(i).y = 0-rand.nextInt(getHeight()+1);
}
timer.start();
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.WHITE);
//Set, paint, and move snow particles
for(int i=0; i<50; i++){
g.fillOval(snow.get(i).x, snow.get(i).y, 10, 10);
snow.get(i).y += 1;
if(snow.get(i).y > getHeight()){
snow.get(i).x = rand.nextInt(getWidth()+1);
snow.get(i).y = 0-rand.nextInt(getHeight()+1);
}
}
}
}
答案 0 :(得分:1)
您正在将TreePanel添加到SnowPanel的BorderLayout.CENTER位置,这将有效地覆盖SnowPanel,因此应该可以覆盖SnowPanel的图形和动画。通过调用它上面的setOpaque(false)
可能将TreePanel设置为非透明,这样您就可以看到它:
TreePanel treePanel = new TreePanel();
treePanel.setOpaque(false);
您的代码存在其他问题:
setSize(...)
,因为这是危险的事情。getPreferredSize()
paintComponent(...)
方法中使用程序逻辑,因为你永远无法完全控制何时甚至调用paintComponent(...)
。答案 1 :(得分:1)
我建议采用完全不同的方法:
SnowBackgroundPanel
&amp;扩展TreePanel
的{{1}}应该实现JPanel
Drawable
界面将使用单个方法Drawable
draw(Graphics2D g, Dimension sizeOfParent)
方法中,放置draw()
paintComponent()
),将列出的元素集合保存在符合其顺序的列表中。例如如果第一个元素是BG,则首先渲染它。RenderingSurface extends JPanel
的{{1}}中,迭代可绘制元素的集合并绘制每个元素。