【问题标题】:Using JLabel to flip through images使用 JLabel 翻阅图像
【发布时间】:2018-04-15 20:18:39
【问题描述】:

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

这是我的代码:

 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) 为了尽快获得更好的帮助,请发帖 minimal reproducible exampleShort, Self Contained, Correct Example。 2) 发布整个堆栈跟踪,并为其使用代码格式。
  • 正如@AndrewThompson 上面所说。还要在您发布的代码中指出哪一行引发了异常
  • 我猜这是Image image = icon.getImage().getScaledInstance(imageArea.getWidth(), imageArea.getHeight(), Image.SCALE_SMOOTH); 这一行,这是因为您的JLabel 当前的大小为[0, 0],因为它没有图像开始。为什么不给 JLabel 一个您自己创建的空白图像以使其大小不为 0,0?
  • @HovercraftFullOfEels "为什么不给 JLabel 一个你自己创建的空白图像开始" 好主意,然后代码可以pack() GUI 来纠正大小 &避免猜测,例如:currentframe.setSize(439, 548);
  • 非常感谢您的建议/建议!

标签: java swing jframe jpanel jlabel


【解决方案1】:

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

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 方法。

虽然有很多方法可以修复它,但最简单的方法是使用想要填充可用空间的布局管理器,例如 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,可以使用Java: maintaining aspect ratio of JPanel background imageQuality of Image after resize very low -- Java 之类的东西来缩放图像

这是一些私人的东西,但我不喜欢ImageIcon API,它不提供关于为什么图像可能没有加载的反馈并且不支持大范围的图像格式。

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

【讨论】:

  • 谢谢!你的解释太容易理解了!另外,也感谢您的提示 - 我一定会尝试将其应用到我的代码中
  • ? - 祝你好运
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-18
  • 2012-03-22
  • 1970-01-01
  • 2013-07-03
相关资源
最近更新 更多