6

I am working on a slot machine in Java and so far I created a button that will randomly generate two pictures. My code compiles but when I run it, all the stuff I put in the paint method does not show up. Is there anything I am missing? Thanks for your help and here is some of my code.

    public void paint(Graphics g) {
        super.paintComponents(g);
        g.drawString("Int 1 is" + int1,30,30);
        g.drawString("Int 2 is" + int2,30,80);
        switch (int1) {
            case 0:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img, 300, 500, this);
                break;
            case 1:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img2,300,500,this);
                break;
            case 2:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img3,300,500,this);
                break;
            case 3:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img4,300,500,this);
                break;
            case 4:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img5,300,500,this);
                break;
            case 5:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img6,300,500,this);
                break;
            case 6:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img7,300,500,this);
                break;
            case 7:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img8,300,500,this);
                break;
            case 8:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img9,300,500,this);
                break;
            case 9:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img10,300,500,this);
                break;
        }
        switch (int2) {
            case 0:
                g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img, 800, 500, this);
                break;
            case 1:
                g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img2,800,500,this);
                break;
            case 2:
                g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img3,800,500,this);
                break;
            case 3:
                g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img4,800,500,this);
                break;
            case 4:
                g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img5,800,500,this);
                break;
            case 5:
\               g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img6,800,500,this);
                break;
            case 6:
                g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img7,800,500,this);
                break;
            case 7:
                g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img8,800,500,this);
                break;
            case 8:
                g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img9,800,500,this);
                break;
            case 9:
                g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img10,800,500,this);
                break;
        }
        this.setVisible(true);
    }
gooly bug
  • 135
  • 1
  • 6
  • 1
    When dealing with `Swing`, one shouldn't play with `paint` method for such a task. Instead override `paintComponent(...)` method of some `JComponent/JPanel` to do the painting related stuff. More info at [Performing Custom Painting](https://docs.oracle.com/javase/tutorial/uiswing/painting/). Do read the solving common problems, the first problem will answer what you doing wrong. Hope it helps :-) – nIcE cOw May 15 '15 at 17:44
  • 1
    Yikes, your `paint` method calls `super.paintComponents(...)` a very dangerous thing to do. Please read the painting tutorials on this as its all very well explained and agrees exactly with what @nIcEcOw states above. Myself, I'd simply swap ImageIcons displayed in a JLabel. – Hovercraft Full Of Eels May 15 '15 at 17:45
  • Please see edit to answer. – Hovercraft Full Of Eels May 15 '15 at 18:23

1 Answers1

5

Problems:

  • You're drawing directly in a JFrame -- don't do this as you can mess up the JFrame graphics.
  • Your overriding the paint method and calling the super.paintComponents(...) method, again a dangerous thing to do, and something that should never be done.

Instead you could do your drawing in the paintComponent(...) method of a JPanel and call the correct super.paintComponent(...) method inside of it, as described in the Swing painting tutorials, but why bother. Much easier would be to create an array of ImageIcons and simply call setIcon(...) on 3 (or however many you need) JLabels, after randomly selecting an Icon from the array or ArrayList.

Also, never do this:

try {

  // .... some code here

} catch (IOException e) {

}

At least print out the stack trace within the catch block so you can identify any IO exceptions if they occur:

try {

  // .... some code here

} catch (IOException e) {
  e.printStackTrace(); // ****** added ********    
}

For example, the following code will produce this GUI:

enter image description here

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
// extend JPanel, not JFrame as it gives the class more flexibility as to where to use
public class ShowRandomImages extends JPanel {
   // images from Andrew Thompson's example image page,
   // http://stackoverflow.com/questions/19209650/example-images-for-code-and-mark-up-qas
   private static final String IMAGE_SHEET_PATH = "https://i.stack.imgur.com/memI0.png";
   // how many JLabels to show in a row
   private static final int LABEL_COUNT = 3;
   // need to get subimages from image sheet. There are 6 columns in the sheet
   private static final int IMAGE_COLUMNS = 6;
   // array of JLabel
   private JLabel[] labels = new JLabel[LABEL_COUNT];
   // hold all the images as ImageIcons read in
   private List<Icon> imageIconList = new ArrayList<>();
   // to randomize the images
   private Random random = new Random();

   // pass the ImageIcon List into this class
   public ShowRandomImages(List<Icon> iconList) {
      this.imageIconList = iconList;
      // jpanel hold row of image-displaying JLabels
      JPanel labelHolderPanel = new JPanel(new GridLayout(1, 0, 5, 0));
      for (int i = 0; i < labels.length; i++) { // create all JLabels in array
         labels[i] = new JLabel();
         labels[i].setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
         labels[i].setHorizontalAlignment(SwingConstants.CENTER); // center the icon
         labels[i].setIcon(getRandomIcon()); // initialize with a random image
         labelHolderPanel.add(labels[i]); // add to holder JPanel
      }

      // panel to hold button at bottom
      JPanel bottomPanel = new JPanel();
      // button uses an AbstractAction rather than an ActionListener
      bottomPanel.add(new JButton(new ShowRandomIconAction("Show Random Image")));

      setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
      setLayout(new BorderLayout());
      add(labelHolderPanel, BorderLayout.CENTER);
      add(bottomPanel, BorderLayout.PAGE_END);
   }

   private Icon getRandomIcon() {
      int randomIndex = random.nextInt(imageIconList.size());
      return imageIconList.get(randomIndex);
   }

   private class ShowRandomIconAction extends AbstractAction {
      public ShowRandomIconAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         for (JLabel jLabel : labels) {
            jLabel.setIcon(getRandomIcon());
         }
      }
   }

   private static void createAndShowGui(List<Icon> imageIconList) {
      ShowRandomImages mainPanel = new ShowRandomImages(imageIconList);

      JFrame frame = new JFrame("ShowRandomImages");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      try {
         final List<Icon> iconList = getImages();
         SwingUtilities.invokeLater(new Runnable() {
            public void run() {
               createAndShowGui(iconList);
            }
         });
      } catch (IOException e) {
         e.printStackTrace();
         System.exit(-1);
      }
   }

   // read in image sheet and extract sub-images from it
   private static List<Icon> getImages() throws IOException {
      List<Icon> iconList = new ArrayList<>();
      URL imageUrl = new URL(IMAGE_SHEET_PATH);
      BufferedImage imageSheet = ImageIO.read(imageUrl);
      for (int i = 0; i < IMAGE_COLUMNS; i++) {
         int x = (int) ((double) i * imageSheet.getWidth() / IMAGE_COLUMNS);
         int y = 0;
         int w = imageSheet.getWidth() / IMAGE_COLUMNS;
         int h = imageSheet.getHeight() / 2;

         BufferedImage subImage = imageSheet.getSubimage(x, y, w, h);
         iconList.add(new ImageIcon(subImage));
      }
      return iconList;
   }
}

Otherwise if you absolutely must display images in a painting method, I'd recommend:

  • Create a JPanel extending class that displays just one image, say called ImageDisplayPanel. You'll give your class 2 of these if you need to display 2 images.
  • Pass into it a List<BufferedImage>
  • Give it a displayRandomImage() method
  • In this method, select a random image from the list and set a BufferedImage field to this image, and call repaint().
  • The paintComponent method of the DrawImagePanel will draw the image held by the field if it is not null.
  • In the main GUI, call this method on your 2 or 3 image JPanels as needed.
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373