使用 JLabel 翻阅图片

Using JLabel to flip through images

我正在尝试使用上一张和下一张按钮翻阅多张图片。 目前,布局是:

这是我的代码:

 public void createWalkthrough() {
  if(currentframe != null) {
        currentframe.setVisible(true);
        return;
    }

  currentframe = new JFrame("Getting Started");

  JPanel imagePanel = new JPanel();
  imagePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

  imageArea = new JLabel();
  imagePanel.add(imageArea);

  JButton previousButton = new JButton("Previous");
  previousButton.addActionListener(this);
  previousButton.setActionCommand("Previous");

  JButton nextButton = new JButton("Next");
  nextButton.addActionListener(this);
  nextButton.setActionCommand("Next");

  JPanel panelButtons = new JPanel();
  panelButtons.setLayout(new BoxLayout(panelButtons, BoxLayout.LINE_AXIS));
  panelButtons.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
  panelButtons.add(Box.createRigidArea(new Dimension(10, 0)));
  panelButtons.add(Box.createHorizontalGlue());
  panelButtons.add(previousButton);
  panelButtons.add(nextButton);

  currentframe.setSize(439, 548);
  currentframe.setResizable(false);

  Container pane = currentframe.getContentPane();
  pane.add(imagePanel, BorderLayout.CENTER);
  currentframe.add(panelButtons, BorderLayout.PAGE_END);

  currentframe.setVisible(true);

  currentframe.requestFocusInWindow();
}       

public void displayImage(int index) {
  File[] imagesList = getImages();
  File imageName = imagesList[index];
  ImageIcon icon = new ImageIcon(imageName.getAbsolutePath());
  Image image = icon.getImage().getScaledInstance(imageArea.getWidth(), imageArea.getHeight(), Image.SCALE_SMOOTH);
  imageArea.setIcon(new ImageIcon(image));
}

public File[] getImages() {
  File folder = new File("/Users/jwh/Desktop/img");
  File[] listofImages = folder.listFiles();
  return listofImages;
}

@Override 
public void actionPerformed(ActionEvent e) {
    if(base == null) {
        return;
    }

    String selected = e.getActionCommand();

    if(selected.equals("Previous")) {
        pos = pos - 1;
        if(pos < 0) {
            pos = 0;
        }

        displayImage(pos);
    } else if(selected.equals("Next")) {
        pos = pos + 1;
        if(pos >= getImages().length) {
            pos = getImages().length;
        }

        displayImage(pos);
    }
}

我不确定我做错了什么。我觉得我一直在兜圈子,在不同的 Whosebug 帖子上尝试不同的东西。

我目前遇到的错误是:

"Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: 
    Width (0) and height (0) must be non-zero"

如有任何帮助,我们将不胜感激。谢谢!!

您的主要问题归结为布局的复合性质和对默认布局的误解...

JPanel imagePanel = new JPanel();
imagePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

imageArea = new JLabel();
imagePanel.add(imageArea);

imagePanel,默认情况下使用 FlowLayout,这将尝试兑现添加到其中的组件的 preferredSize

JLabel,默认情况下,preferredSize0x0

所以,当你做类似...

Image image = icon.getImage().getScaledInstance(imageArea.getWidth(), imageArea.getHeight(), Image.SCALE_SMOOTH);

您实际上是将 0x0 传递给 getScaledInstance 方法。

虽然有很多方法可以修复它,但最简单的方法是使用布局管理器来填充可用的 space,例如 BorderLayout...

JPanel imagePanel = new JPanel(new BorderLayout());
imagePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

imageArea = new JLabel();
imagePanel.add(imageArea);

反馈...

好了,一些小问题...

getScaledInstance 不会产生最佳结果,也不是缩放图像的最快方法。现在,如果您不想使用 library, like imgscalr, you could use something like Java: maintaining aspect ratio of JPanel background image and Quality of Image after resize very low -- Java 来缩放图像

这是个人的事情,但我不喜欢 ImageIcon API,它没有提供关于为什么图像可能没有加载并且没有加载的反馈支持多种图像格式。

就我个人而言,我更喜欢使用 ImageIO API。参见 Reading/Loading an Image