java pick random images

别等时光非礼了梦想. 提交于 2019-12-11 06:25:56

问题


English is not my native language, sorry for any mistakes. I have to make a Bubble Shooter game in Java. I want to use images for the bubbles and I want the images to be picked randomly. I used Random and ImageIcon classes. My program doesn't show anything when I compile it and I don't know where the problem is. I'm a beginner in Java.

This is the code for my Game class:

import java.awt.Graphics;
import java.awt.Image;
import java.util.Vector;

import javax.swing.JPanel;

public class Game extends JPanel{
  private static final long serialVersionUID = 1L;

  //what the balls are like
  public final static int START_BALLS=40;
  public static Vector<Ball> balls = new Vector<Ball>();
  private Image img;
  private Graphics graphics;

  public Game() {
    for(int i=0; i<START_BALLS; i++) {
      balls.add(new Ball());
    }
  }

  public void paint(Graphics g) {
    img = createImage(null);
    graphics = img.getGraphics();
    paintComponent(graphics);
    g.drawImage(img, 0, 0, null);
    repaint();
  }

  public void paintComponet(Graphics g) {
    for(int i=0; i<balls.size(); i++) {
      Ball b=(Ball)balls.get(i);
      b.draw(g);
    }
  }

  public static void main(String [] args) {
    new Frame();
    Game game = new Game();
    new Game();
    Window.window.add(game);
  }
}

and the class for the bubbles:

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.util.Random;

import javax.swing.ImageIcon;

public class Ball {
  Random random = new Random();
  final String[] image_paths = new String[] {"balls/peg_0.png",
            "balls/peg_1.png","balls/peg_2.png","balls/peg_3.png",
            "balls/peg_4.png","balls/peg_5.png"};

  String randomBalls;
  public Image image;

  public Ball(){
    randomBalls = image_paths[random.nextInt(image_paths.length)];
    ImageIcon poza = new ImageIcon(randomBalls);
    image=poza.getImage();
  }

  public void draw(Graphics g){
    g.drawImage(image, 0, 0, null, null);
  }
}

What is wrong with my program?


回答1:


Look over my comments, look carefully at the comments in the code, see how I rearranged the organization of the classes.

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.Random;
import java.util.Vector;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.imageio.ImageIO;
import java.net.URL;

public class Game extends JPanel {

    Random random = new Random();
    final String[] image_path = new String[]{
        "http://i.stack.imgur.com/gJmeJ.png",
        "http://i.stack.imgur.com/IHARa.png",
        "http://i.stack.imgur.com/wCF8S.png",
        "http://i.stack.imgur.com/T5uTa.png"
    };
    private static final long serialVersionUID = 1L;
    //what the balls are like
    public final static int START_BALLS = 40;
    public static Vector<Ball> balls = new Vector<Ball>();
    private Image img;
    // A Graphics instance is typically transient.
    // There is rarely, if ever, a need to store them
    //private Graphics graphics;

    public Game() {
        for (int i = 0; i < image_path.length; i++) {
            balls.add(new Ball(image_path[i]));
        }
        //I have no idea what you were trying to achieve here, but it fails horribly
        // img = createImage(null);
        img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
        // graphics = img.getGraphics();
        ActionListener al = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                repaint();
            }
        };
        Timer timer = new Timer(400, al);
        timer.start();
    }

    @Override  // very handy!
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        // g.drawImage(img, 0, 0, null);  A JPanel IS A ImageObserver
        g.drawImage(img, 0, 0, this);
        Ball b = (Ball) balls.get(random.nextInt(4));
        b.draw(g);
    }

    public Dimension getPreferredSize() {
        return new Dimension(200, 200);
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                JFrame f = new JFrame("Game");
                f.add(new Game());
                // Ensures JVM closes after frame(s) closed and
                // all non-daemon threads are finished
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                // See https://stackoverflow.com/a/7143398/418556 for demo.
                f.setLocationByPlatform(true);

                // ensures the frame is the minimum size it needs to be
                // in order display the components within it
                f.pack();
                // should be done last, to avoid flickering, moving,
                // resizing artifacts.
                f.setVisible(true);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
        SwingUtilities.invokeLater(r);
    }
}

class Ball {

    String randomBalls;
    public Image image;

    public Ball(String url) {
        try {
            image = ImageIO.read(new URL(url));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void draw(Graphics g) {
        g.drawImage(image, 0, 0, null, null);
    }
}

Tips

  • Exception in thread "AWT-EventQueue-0" java.lang.UnsupportedOperationException: getGraphics() not valid for images created with createImage(producer) at img = createImage(null); I have no idea what you thought that code statement does, but ..nothing good.
  • When doing custom painting in a JPanel, we should override only paintComponent(Graphics) and leave the paint(Graphics) method as it is. When overriding the former, immediately call the super method.
  • Adding a call to repaint() inside paint(Graphics) will cause an infinite loop.. If the code needs to loop, establish a Swing Timer to call repaint()
  • paintComponet(Graphics g) should be paintComponent(Graphics g) Use @Override notation when appropriate. It would have warned you of the incorrectly spelled method name.

More general tips

  1. For better help sooner, post an MCVE.
  2. One way to get image(s) for an example is to hot-link to the images seen in this answer.
  3. By the time of deployment, those images will likely become an embedded-resource. That being the case, they must be accessed by URL instead of File. See the info page for the tag, for a way to form an URL.


来源:https://stackoverflow.com/questions/21025595/java-pick-random-images

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!