Java:为什么我的图像不显示?

时间:2014-07-05 03:41:52

标签: java swing embedded-resource repaint imageicon

我创建了2个类,它们通过单击不同的按钮一起显示图片。在我的EventEvent类中,我尝试将其设置为当您按下"Picture 1"按钮时,变量ImageIcon xpic在{{1}之后获取ImageIcon vpic(包含图像)的值具有与xpic相同的值,我的帧应以某种方式刷新,以便vpic的新值适用,然后获取显示图片。

为什么即使按下按钮重新绘制图像所在的JPanel,我的图像也不会显示?

主要课程:

xpic

包含事件的类:

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();

}
}

2 个答案:

答案 0 :(得分:3)

您将变量与对象混淆。仅仅因为您更改了与xpic变量关联的对象,不要假设这将更改JLabel持有的对象(Icon)。 Java中没有魔法,更改变量引用的对象将不会影响先前的对象。

换句话说,这个:

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

对JLabel图片显示的图标没有影响

要交换图标,您必须在JLabel上调用setIcon(...)。期。您需要将图片JLabel设为字段而不是局部变量,并为GUI类提供一个公共方法,允许外部类更改JLabel图标的状态。

此外,您不应直接操纵对象字段。而是提供你的gui公共方法,你的事件对象可以调用。


修改
例如:

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();
   }
}

enter image description here

答案 1 :(得分:2)

请参阅下面的createAction()方法以及它如何创建AbstractAction。另请参阅与使用按钮操作相关的教程。 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();
            }
        });
    }
}