【发布时间】:2021-12-08 21:22:54
【问题描述】:
你好,首先当我运行程序时会出现一个按钮,当我按下按钮时,图像会从上到下。 当图像从上到下时,我尝试了代码,效果很好 但是当我将所有代码放在一起时,( frame.add(new AnimationPane() ); )中出现错误
问题:如何将 AnimationPane() 添加到框架中? 因为这是我的问题。
我想制作两个场景的想法,第一个有一个按钮可以转到第二个场景,它将有一个图像(它必须从顶部推到向下)。
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package maincontentpaneswitching;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class MainContentPaneSwitching {
private static class ChangeContentPaneListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
// I want to put the image here
JPanel newFrameContents = new JPanel(); //Uses FlowLayout by default.
newFrameContents.add(new JLabel("You have successfully changed the content pane of the frame!", JLabel.CENTER));
/*We assume that the source is a JButton and that the Window is of type JFrame, hence
the following utility method call is possible without letting any errors appear:*/
JFrame frame = (JFrame) SwingUtilities.getWindowAncestor((JButton) e.getSource());
frame.setSize(600, 300);
frame.setContentPane(newFrameContents); //Change the content pane of the frame.
frame.revalidate(); //Notify the frame that the component hierarchy has changed.
frame.add(new AnimationPane() );
frame.pack(); //Resize the frame as necessary in order to fit as many contents as possible in the screen.
frame.setLocationRelativeTo(null); //Place the frame in the center of the screen. As you can tell, this needs its size to calculate the location, so we made sure in the previous line of code that it is set.
frame.repaint(); //Repaint frame with all its contents.
}
}
public class AnimationPane extends JPanel {
private BufferedImage boat;
private int yPos = 0;
private int direction = 1;
public AnimationPane() {
try {
boat = ImageIO.read(new URL("https://i.stack.imgur.com/memI0.png"));
Timer timer = new Timer(50, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
yPos += direction;
if (yPos + boat.getHeight() > getHeight()) {
yPos = getHeight() - boat.getHeight();
direction *= +1;
} else if (yPos < 0) {
yPos = 0;
direction *= +1;
}
repaint();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
} catch (IOException ex) {
ex.printStackTrace();
}
}
@Override
public Dimension getPreferredSize() {
return boat == null ? super.getPreferredSize() : new Dimension(boat.getHeight()*2 , boat.getWidth() *2);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int x = getWidth() - boat.getWidth();
g.drawImage(boat, x, yPos, this);
}
}
private static class MainRunnable implements Runnable {
@Override
public void run() {
JButton changeContentPaneButton = new JButton("Click to go to the next image!");
changeContentPaneButton.addActionListener(new ChangeContentPaneListener());
JPanel frameContents = new JPanel(); //Uses FlowLayout by default.
frameContents.add(changeContentPaneButton);
JFrame frame = new JFrame("My application");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Tells the frame that when the user closes it, it must terminate the application.
frame.setContentPane(frameContents); //Add contents to the frame.
frame.pack(); //Resize the frame as necessary in order to fit as many contents as possible in the screen.
frame.setLocationRelativeTo(null); //Place the frame in the center of the screen. As you can tell, this needs its size to calculate the location, so we made sure in the previous line of code that it is set.
frame.setVisible(true);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new MainRunnable()); //Swing code must always be used in the Event Dispatch Thread.
}
}
【问题讨论】:
-
我放了图片的链接,现在你可以运行了。
-
将animationPane添加到frame时出现错误
-
我尝试修复您的代码,但无法让图像动画正常工作。您过于依赖静态字段和方法。你的 getPreferredSize 是落后的。应该是宽度,高度。在显示任何内容之前创建完整的 GUI。使用 CardLayout 显示按钮 JPanel,然后显示图像 JPanel。分开你的顾虑。您的绘图 JPanel 应该绘制图像。时期。您可以在与绘图类分开的控制器类中修改 yPos。在开始构建 GUI 之前阅读所有图像。
-
感谢您的努力和建议。