问题
I wanted to create a JFrame and put a sequence of images for animation in there. But the images don't appear in the frame window. I just want basic troubleshooting tips to make it appear in the window. Just edit the code for an answer if you can.
My question: Why isn't the window displaying any pictures? It shows a window with a background color of blue, but that's it. Please tell me an efficient way to store images in variables and display it in a loop.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.io.*;
public class Game extends JLabel implements ActionListener{
/**
*
*/
private static final long serialVersionUID = 1L;
public static Game blah;
BufferedImage nekopics[] = new BufferedImage[7];
BufferedImage currentimg;
public String nekosrcs[];
int xpos;
Timer timer;
public Game() throws IOException
{
JFrame jframe = new JFrame();
nekosrcs = new String[] { "walk1.png", "walk2.png",
"walk3.png", "walk4.png", "walk5.png",
"walk6.png"};
jframe.setTitle("Game");
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setLayout(new FlowLayout());
jframe.setSize(400, 400);
jframe.setResizable(false);
jframe.setVisible(true);
jframe.getContentPane().setBackground(Color.BLUE);
for (int i=0; i < nekopics.length; i++) {
nekopics[i] = ImageIO.read(new FileInputStream("D:/Programs
/pics"+nekosrcs[i]));
}
for (int i=0; i < nekopics.length; i++) {
timer = new Timer(1000, this);
timer.setInitialDelay(0);
timer.start();
currentimg = nekopics[i];
repaint();
}
}
public void paintComponent(Graphics g)
{
super.paint(g);
g.drawImage(currentimg,100,100,this);
}
public static void main(String[] args) throws IOException {
blah = new Game();
}
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
}
回答1:
Alright, there are a lot of problems in your code, let's step into each of them:
You have a lot of spaces between lines, that makes your code a lot larger and harder to read
You haven't indented your code correctly (see the last
}on your code, it's at the same level than the others; yourforloops, etc), it makes the code so much harder to read and understand as wellYou're creating a
JFramebut extendingJLabel, I'm not sure why you're doing this, if you're doing it so you can use thepaintComponent()method, it's not necessary, on my code you can see how you can do it w/o extending anyComponentIf you haven't read the Swing
Timerdocs you should click that link and read what theActionListenerparameter does. In this case, we're going to use this listener to call therepaint()method and update ourcurrentImage(ornextImagein the code below) and change the image accordingly. You failed to do this.You were creating more than 1
Timertoo, you created 6 here! All of them new but they had no action to do when the time finishedfor (int i=0; i < nekopics.length; i++) { timer = new Timer(1000, this); timer.setInitialDelay(0); timer.start(); currentimg = nekopics[i]; repaint(); }You're changing unnecessarily the visibility of the
paintComponent()method topublicfromprotected
However I want to congratulate you for not using a null layout and following the recommendations I made on the comments above.
And finally the code that changes one image for another inside a Timer is the following, you can copy-paste it and change the image's names so you can see how it works.
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class ImageSequence {
private JFrame frame;
private JPanel pane;
private Timer timer;
private int nextImage = 0;
private String[] images = {"tokyo", "tokyo2", "starwars"};
private Image img = null;
public static void main (String args[]) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new ImageSequence().createAndShowGui();
}
});
}
public void createAndShowGui() {
frame = new JFrame("Image Sequence");
timer = new Timer(1000, listener);
pane = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
try {
img = ImageIO.read(new FileInputStream("/home/jesus/Pictures/" + images[nextImage] + ".jpg"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
g.drawImage(img , 0, 0, 200, 200, this);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
};
timer.start();
frame.getContentPane().add(pane);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
System.out.println(nextImage);
nextImage = nextImage < images.length - 1 ? nextImage + 1 : 0;
System.out.println(nextImage);
pane.repaint();
}
};
}
来源:https://stackoverflow.com/questions/38966000/animation-sequence-in-jframe