使用JLabel翻阅图像

时间:2018-04-15 20:18:40

标签: java swing jframe jpanel jlabel

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

enter image description here

这是我的代码:

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

我不确定我做错了什么。通过在不同的StackOverflow帖子上尝试不同的东西,我觉得我一直在四处走动。

我目前得到的错误是:

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

非常感谢任何帮助。谢谢!!

1 个答案:

答案 0 :(得分:0)

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

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

imageArea = new JLabel();
imagePanel.add(imageArea);
默认情况下,

imagePanel使用的是FlowLayout,它会尝试兑现添加到其中的preferredSize个组件。

默认情况下,

JLabel的{​​{1}}为preferredSize

所以,当你做某事......

0x0

您实际上已将Image image = icon.getImage().getScaledInstance(imageArea.getWidth(), imageArea.getHeight(), Image.SCALE_SMOOTH); 传递给0x0方法。

虽然有很多方法可以修复它,但最简单的方法是使用想要填充可用空间的布局管理器,例如getScaledInstance ......

BorderLayout

反馈...

好的,一些小问题......

JPanel imagePanel = new JPanel(new BorderLayout()); imagePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); imageArea = new JLabel(); imagePanel.add(imageArea); 不会产生最佳效果,也不是缩放图像的最快方法。现在,如果您不想使用library, like imgscalr,可以使用Java: maintaining aspect ratio of JPanel background imageQuality of Image after resize very low -- Java之类的内容来缩放图片

这是一些个人的事情,但我不喜欢getScaledInstance API,它没有提供关于为什么图片可能没有被加载的反馈而且没有#39; t支持多种图像格式。

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