[英]Background disappears when button is pressed
I have set up a game in Java using Swing UI.我已经使用 Swing UI 在 Java 中设置了一个游戏。
When firing a projectile across the screen and I want the background to be constantly there在屏幕上发射弹丸时,我希望背景一直存在
When I run the code the background appears to be fine.当我运行代码时,背景看起来很好。 But when the button to fire the projectile is pressed then the background disappears.
但是当按下发射弹丸的按钮时,背景就会消失。
public class ProjectileShooterTest {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JFrame f = new JFrame() {
};
ImageIcon background=new ImageIcon("Background.png");
Image img=background.getImage();
Image temp=img.getScaledInstance(800,440,Image.SCALE_SMOOTH);
background=new ImageIcon(temp);
JLabel back=new JLabel(background);
back.setBounds(0,0,800,500);
f.getContentPane().setLayout(new BorderLayout());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(800,500);
final ProjectileShooter projectileShooter = new ProjectileShooter();
ProjectileShooterPanel projectileShooterPanel = new ProjectileShooterPanel(projectileShooter);
projectileShooter.setPaintingComponent(projectileShooterPanel);
JPanel controlPanel = new JPanel(new GridLayout(1,0));
controlPanel.add(new JLabel(" Post-Launch Angle"));
final JSlider angleSlider = new JSlider(70, 89, 85);
angleSlider.setLayout( new FlowLayout() );
controlPanel.add(angleSlider);
f.add(back);
controlPanel.add(new JLabel(" Thrust"));
final JSlider powerSlider = new JSlider(50, 80, 60);
powerSlider.setLayout( new FlowLayout() );
controlPanel.add(powerSlider);
JButton shootButton = new JButton("Launch");
shootButton.setLayout( new FlowLayout() );
shootButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int angleDeg = angleSlider.getValue();
int power = powerSlider.getValue();
projectileShooter.setAngle(Math.toRadians(angleDeg));
projectileShooter.setPower(power);
projectileShooter.shoot();
}
});
f.add(back);
controlPanel.add(shootButton);
f.getContentPane().add(controlPanel, BorderLayout.NORTH);
f.getContentPane().add(projectileShooterPanel, BorderLayout.CENTER);
f.setVisible(true);
f.setLayout(new BorderLayout());
}
}
How can I solve this?我该如何解决这个问题?
f.add(back);
is equivalent to:相当于:
f.getContentPane().add(back, BorderLayout.CENTER);
Later in your code you do:稍后在您的代码中,您执行以下操作:
f.getContentPane().add(projectileShooterPanel, BorderLayout.CENTER);
Which will cause problems because you can't add two components to the CENTER.这会导致问题,因为您不能将两个组件添加到 CENTER。
A Swing GUI is parent/child design so you need something like: Swing GUI 是父/子设计,因此您需要类似的东西:
f.getContentPane().add(back, BorderLayout.CENTER);
back.setLayout(new BorderLayout());
back.add(projectileShooterPanel, BorderLayout.CENTER);
I'll let you figure out the logic order and placement of the above statements.我会让你弄清楚上述语句的逻辑顺序和位置。
Also why do you have:还有为什么你有:
f.setLayout(new BorderLayout());
at the end of the constructor?在构造函数的末尾? This replaces all the constraint information of your original layout.
这将替换原始布局的所有约束信息。
Finally, your projectile shooter panel needs to be transparent, otherwise it will paint over top of the background.最后,你的弹射器面板需要是透明的,否则它会覆盖在背景之上。 So you also need:
所以你还需要:
projectileShooterPanel.setOpaque( false );
Note: instead of using the JLabel as the background it would be easier to paint the background in your projectile shooter panel.注意:与其使用 JLabel 作为背景,不如在射弹发射器面板中绘制背景更容易。 Then you won't have issues with trying to add multiple panels to one another and the shooter panel won't need to be transparent.
这样你就不会在尝试将多个面板相互添加时遇到问题,而且射击面板也不需要是透明的。
While I cannot tell what projectileShooter.shoot() does, my gut feeling is that you are hogging the event dispatching thread.虽然我不知道 projectileShooter.shoot() 做了什么,但我的直觉是你正在占用事件调度线程。 As long as your button's ActionListener is busy your GUI is unresponsive.
只要按钮的 ActionListener 处于忙碌状态,您的 GUI 就没有响应。 Start a new Thread to perform the shooting itself.
启动一个新线程来执行拍摄本身。
So your ActionListener could look like this:所以你的 ActionListener 看起来像这样:
shootButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
new Thread(new Runnable()
{
public void run() {
int angleDeg = angleSlider.getValue();
int power = powerSlider.getValue();
projectileShooter.setAngle(Math.toRadians(angleDeg));
projectileShooter.setPower(power);
projectileShooter.shoot();
}
}).start();
}
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.