简体   繁体   中英

Java: Why doesn't my image show up?

I have created 2 classes that are working together to show pictures by clicking different buttons. In my EventEvent class I tried to make it so that when you press the "Picture 1" button, the variable ImageIcon xpic gets the value of ImageIcon vpic (which holds an image), after xpic has the same value as vpic my frame is supposed to somehow refresh so that xpic 's new value applies and gets then shows the picture.

Why doesn't my image show up even though the button press repaints the JPanel the image is in?

Main class:

import java.awt.*;
import javax.swing.*;

public class EventMain extends JFrame{
EventEvent obje = new EventEvent(this);


// Build Buttons

JButton picB1;
JButton picB2;
JButton picB3;
JButton picB4;
JButton picB5;

//Build Panels
JPanel row0;

//Build Pictures
ImageIcon xpic;
ImageIcon vpic;


public EventMain(){
    super("Buttons");
    setLookAndFeel();
    setSize(470, 300);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    GridLayout layout1 = new GridLayout(3,4);

    setLayout(layout1);

    picB1 = new JButton("Picture 1");
    picB2 = new JButton("Picture 2");
    picB3 = new JButton("Picture 3");
    picB4 = new JButton("Picture 4");
    picB5 = new JButton("Picture 5");


    vpic = new ImageIcon(getClass().getResource("Images/vanessa.png")); 

    // Set up Row 0
    row0 = new JPanel();
    JLabel statement = new JLabel("Choose a picture: ", JLabel.LEFT);
    JLabel picture = new JLabel(xpic);
    // Set up Row 1
    JPanel row1 = new JPanel();
    // Set up Row 2
    JPanel row2 = new JPanel();

    //Listeners

    picB1.addActionListener(obje);

    FlowLayout grid0 = new FlowLayout (FlowLayout.CENTER);
    row0.setLayout(grid0);
    row0.add(statement);
    row0.add(picture);
    add(row0);


    FlowLayout grid1 = new FlowLayout(FlowLayout.CENTER);
    row1.setLayout(grid1);
    row1.add(picB1);
    row1.add(picB2);
    add(row1);

    FlowLayout grid2 = new FlowLayout(FlowLayout.CENTER);
    row2.setLayout(grid2);
    row2.add(picB3);
    row2.add(picB4);
    row2.add(picB5);
    add(row2);

    setVisible(true);
}
private void setLookAndFeel() {
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.NimbusLookAndFeel");
    } catch (Exception exc) {           
    }

}
public static void main(String[] args) {
    EventMain con = new EventMain();

}
}

Class containing events:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class EventEvent implements ActionListener {

EventMain gui;

public EventEvent(EventMain in){
    gui = in;
}

public void actionPerformed(ActionEvent event) {
    String command = event.getActionCommand();
    if (command.equals("Picture 1")){
        gui.xpic = gui.vpic;
        gui.row0.repaint();
    }   
}
}

You're confusing variables with objects. Just because you change the object associated with the xpic variable, don't assume that this will change the object (the Icon) held by the JLabel. There is no magic in Java, and changing the object that a variable refers to will have no effect on the prior object.

In other words, this:

    gui.xpic = gui.vpic;
    gui.row0.repaint();

will have no effect on the icon that the picture JLabel is displaying

To swap icons, you must call setIcon(...) on the JLabel. Period. You will need to make the picture JLabel a field, not a local variable, and give your GUI class a public method that allows outside classes to change the state of the JLabel's icon.

Also, you should not manipulate object fields directly. Instead give your gui public methods that your event object can call.


Edit
For example:

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 javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class MyGui extends JPanel {
   public static final String IMAGE_PATH = "https://duke.kenai.com/cards/.Midsize/CardFaces.png.png";
   private static final int ROWS = 4;
   private static final int COLS = 13;
   private BufferedImage largeImg;
   private List<ImageIcon> iconList = new ArrayList<>();
   private JLabel pictureLabel = new JLabel();
   private JButton swapPictureBtn = new JButton(new SwapPictureAction(this, "Swap Picture"));
   private int iconIndex = 0;

   public MyGui() throws IOException {
      add(pictureLabel);
      add(swapPictureBtn);

      URL imgUrl = new URL(IMAGE_PATH);
      largeImg = ImageIO.read(imgUrl);
      for (int i = 0; i < ROWS; i++) {
         for (int j = 0; j < COLS; j++) {
            int x = (j * largeImg.getWidth()) / COLS;
            int y = (i * largeImg.getHeight()) / ROWS;
            int w = largeImg.getWidth() / COLS;
            int h = largeImg.getHeight() / ROWS;
            iconList.add(new ImageIcon(largeImg.getSubimage(x, y, w, h)));
         }
      }

      pictureLabel.setIcon(iconList.get(iconIndex));
   }

   public void swapPicture() {
      iconIndex++;
      iconIndex %= iconList.size();
      pictureLabel.setIcon(iconList.get(iconIndex));
   }

   private static void createAndShowGui() {
      MyGui mainPanel;
      try {
         mainPanel = new MyGui();
         JFrame frame = new JFrame("MyGui");
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.getContentPane().add(mainPanel);
         frame.pack();
         frame.setLocationByPlatform(true);
         frame.setVisible(true);

      } catch (IOException e) {
         e.printStackTrace();
      }

   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

@SuppressWarnings("serial")
class SwapPictureAction extends AbstractAction {

   private MyGui myGui;

   public SwapPictureAction(MyGui myGui, String name) {
      super(name);
      this.myGui = myGui;
   }

   @Override
   public void actionPerformed(ActionEvent e) {
      myGui.swapPicture();
   }
}

在此处输入图片说明

See the createAction() method below and how it creates an AbstractAction. See also the tutorial related to using actions with buttons. http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html

import javax.swing.*;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
import java.awt.*;
import java.awt.event.ActionEvent;

public class EventMain {
    private static final ImageIcon PICTURE_1 = new ImageIcon(EventMain.class.getResource("images/v1.png"));
    private static final ImageIcon PICTURE_2 = new ImageIcon(EventMain.class.getResource("images/v2.png"));

    private JFrame frame;

    EventMain create() {
        setLookAndFeel();

        frame = createFrame();
        frame.getContentPane().add(createContent());

        return this;
    }

    void show() {
        frame.setSize(470, 300);
        frame.setVisible(true);
    }

    private JFrame createFrame() {
        JFrame frame = new JFrame("Buttons");
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        return frame;
    }

    private Component createContent() {
        final JLabel picture = new JLabel();

        JButton picB1 = new JButton(createAction("Picture 1", picture, PICTURE_1));
        JButton picB2 = new JButton(createAction("Picture 2", picture, PICTURE_2));
        JButton picB3 = new JButton(createAction("Picture 3", picture, PICTURE_1));
        JButton picB4 = new JButton(createAction("Picture 4", picture, PICTURE_2));
        JButton picB5 = new JButton(createAction("Picture 5", picture, PICTURE_1));

        JLabel statement = new JLabel("Choose a picture: ", JLabel.LEFT);

        // Create rows 1, 2, 3
        JPanel panel = new JPanel(new GridLayout(3, 4));
        panel.add(createRow(statement, picture));
        panel.add(createRow(picB1, picB2));
        panel.add(createRow(picB3, picB4, picB5));

        return panel;
    }

    /**
     * Create an action for the button. http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html
     */
    private Action createAction(String label, final JLabel picture, final Icon icon) {
        AbstractAction action = new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                picture.setIcon(icon);
            }
        };
        action.putValue(Action.NAME, label);

        return action;
    }

    private Component createRow(Component... componentsToAdd) {
        JPanel row = new JPanel(new FlowLayout(FlowLayout.CENTER));
        for (Component component : componentsToAdd) {
            row.add(component);
        }

        return row;
    }

    private void setLookAndFeel() {
        try {
            UIManager.setLookAndFeel(new NimbusLookAndFeel());
        } catch (UnsupportedLookAndFeelException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new EventMain().create().show();
            }
        });
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM