图像未出现在JFrame中

亚历克斯·特雷沃索

我正在尝试用Java制作幻灯片程序。可悲的是,图像没有出现在窗口中。不知道为什么...

我所知道的是,一切运行顺利,没有发生错误(堆栈跟踪)。出现窗口,那里没有图像。

public class Slideshow implements ActionListener, Runnable {
private ArrayList<String> haveUsed = new ArrayList<>();
private JFrame settingsFrame, imageFrame;
private JTextField rootFolder, timeFrame, hiddenRootFolder, hiddenTimeFrame;
private JButton startSlideShow, addRootFolder;
private JLabel jLabel = null;
private ImageIcon imageIcon = null;
public void openSettingsFrame() {
    settingsFrame = new JFrame("Settings - Slideshow v1.0");
    settingsFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    settingsFrame.setLayout(new GridBagLayout());
    GridBagConstraints gbc = new GridBagConstraints();
    settingsFrame.setSize(400, 400);
    gbc.gridx = 0;
    gbc.gridy = 0;
    gbc.insets = new Insets(0, 0, 5, 0);
    hiddenRootFolder = new JTextField("Root Folder:");
    hiddenRootFolder.setEditable(false);
    hiddenRootFolder.setBackground(settingsFrame.getBackground());
    hiddenRootFolder.setBorder(BorderFactory.createLineBorder(settingsFrame.getBackground()));
    settingsFrame.add(hiddenRootFolder, gbc);

    gbc.gridx = 1;
    rootFolder = new JTextField("", 15);
    gbc.insets = new Insets(0, 0, 0, 5);
    rootFolder.setBackground(new Color(255, 255, 255));
    rootFolder.setEditable(false);
    //TODO: add mouse listener
    settingsFrame.add(rootFolder, gbc);

    gbc.gridx = 2;
    addRootFolder = new JButton("Add");
    addRootFolder.addActionListener(this);
    addRootFolder.setSize(80, 20);
    addRootFolder.setPreferredSize(new Dimension(60, 20));
    addRootFolder.setMinimumSize(new Dimension(60, 20));
    settingsFrame.add(addRootFolder, gbc);

    gbc.gridx = 0;
    gbc.gridy = 1;
    hiddenTimeFrame = new JTextField("Speed sec.:");
    gbc.insets = new Insets(0, 0, 5, 0);
    hiddenTimeFrame.setBorder(BorderFactory.createLineBorder(settingsFrame.getBackground()));
    hiddenTimeFrame.setBackground(settingsFrame.getBackground());
    hiddenTimeFrame.setEditable(false);
    settingsFrame.add(hiddenTimeFrame, gbc);

    gbc.gridx = 1;
    timeFrame = new JTextField("", 15);
    settingsFrame.add(timeFrame, gbc);

    gbc.gridx = 0;
    gbc.gridy = 2;
    startSlideShow = new JButton("Start Slideshow");
    startSlideShow.addActionListener(this);
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.gridwidth = 3;
    settingsFrame.add(startSlideShow, gbc);
    settingsFrame.setVisible(true);
}

public static void main(String[] args) {
    new Slideshow().openSettingsFrame();
}


@Override
public void actionPerformed(ActionEvent e) {
    if(e.getSource() == addRootFolder) {
        JFileChooser jfc = new JFileChooser("");
        jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        int returnVal = jfc.showOpenDialog(addRootFolder);
        if(returnVal == JFileChooser.APPROVE_OPTION) {
            File f = jfc.getSelectedFile();
            rootFolder.setText(f.getPath());
        }
    } else if(e.getSource() == startSlideShow) {
        if(!rootFolder.getText().equals("")) {
            if(!timeFrame.getText().equals("")) {
                try {
                    int time = Integer.parseInt(timeFrame.getText());
                    openImageWindow(time);
                } catch (NumberFormatException ex) {
                    ex.printStackTrace();
                }

            }
        } else {
            //TODO: prompt
        }
    }
}

@Override
public void run() {
    File file = new File(rootFolder.getText());
    List list = Arrays.asList(file.list());
    Random random = new Random();
    int i = random.nextInt(list.size());
    while(haveUsed.contains(list.get(i).toString()) || !list.get(i).toString().endsWith(".jpg") ||
            !list.get(i).toString().endsWith(".bmp") || !list.get(i).toString().endsWith(".png")) {
        i = random.nextInt(list.size());
    }
    imageIcon = new ImageIcon(list.get(i).toString());
    imageFrame.repaint();
    imageFrame.revalidate();
    haveUsed.add(list.get(i).toString());
}

public void openImageWindow(int delay) {
    imageFrame = new JFrame("Slideshow v1.0");
    imageFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    imageFrame.setLayout(new BorderLayout());
    imageFrame.setSize(400, 400);
    File file = new File(rootFolder.getText());
    List list = Arrays.asList(file.list());
    Random random = new Random();
    int i = random.nextInt(list.size());
    imageIcon = new ImageIcon(list.get(i).toString());
    haveUsed.add(list.get(i).toString());
    jLabel = new JLabel(imageIcon);
    jLabel.setSize(399, 399);
    imageFrame.add(jLabel);
    ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
    scheduledExecutorService.scheduleWithFixedDelay(this, delay, delay, TimeUnit.SECONDS);
    imageFrame.setVisible(true);
}
疯狂程序员

所以,主要的问题是您while-loop要选择下一张图片...

while(haveUsed.contains(list.get(i).toString()) || !list.get(i).toString().endsWith(".jpg") ||
        !list.get(i).toString().endsWith(".bmp") || !list.get(i).toString().endsWith(".png")) {
    i = random.nextInt(list.size());
}

基本上,这似乎永远不会false因一个或另一个原因而产生结果(您可以花一些时间对其进行调试以找出原因)。

一个更简单的解决方案是List在开始之前先生成一个文件,然后简单地使用Collections.shuffle来对进行修饰List并删除第一个元素

就像是...

public void showNextImage() {
    try {
        Collections.shuffle(imageFiles);

        File imageFile = imageFiles.remove(0);

        jLabel.setIcon(new ImageIcon(ImageIO.read(imageFile)));
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

public void openImageWindow(int delay) {

    imageFiles = new ArrayList<>(Arrays.asList(new File(rootFolder.getText()).listFiles(new FileFilter() {
        @Override
        public boolean accept(File pathname) {
            return pathname.getName().toLowerCase().endsWith(".jpg")
                    || pathname.getName().toLowerCase().endsWith(".png")
                    || pathname.getName().toLowerCase().endsWith(".bmp")
                    || pathname.getName().toLowerCase().endsWith(".gif");
        }
    })));

    imageFrame = new JFrame("Slideshow v1.0");
    imageFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    imageFrame.setLayout(new BorderLayout());
    imageFrame.setSize(400, 400);
    File file = new File(rootFolder.getText());
    List list = Arrays.asList(file.list());
    Random random = new Random();
    int i = random.nextInt(list.size());
    imageIcon = new ImageIcon(list.get(i).toString());
    haveUsed.add(list.get(i).toString());
    jLabel = new JLabel(imageIcon);
    jLabel.setSize(399, 399);
    imageFrame.add(jLabel);
    Timer timer = new Timer(delay, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            showNextImage();
        }
    });
    imageFrame.setVisible(true);
    timer.setInitialDelay(0);
    timer.start();


}

我在添加了一个ArrayListimageFiles这是所有的图像在指定的目录列表,并使用一个SwingTimer更新UI。您应该确保将图像实际应用于JLabel加载后的jLabel.setIcon(new ImageIcon(ImageIO.read(imageFile)));

就个人而言,我发现ImageIO一种更好的读取/写入图像的方法,除了支持更多图像格式外,还会IOException在无法读取文件时抛出一个错误,这有助于诊断任何潜在的问题。

如果您想要目录的“实时”视图,那么我将使用您的目录haveUsed List并从File列表中删除元素

也许像...

List<File> imageFiles = new ArrayList<>(Arrays.asList(new File(rootFolder.getText()).listFiles(new FileFilter() {
    @Override
    public boolean accept(File pathname) {
        return pathname.getName().toLowerCase().endsWith(".jpg")
                || pathname.getName().toLowerCase().endsWith(".png")
                || pathname.getName().toLowerCase().endsWith(".bmp")
                || pathname.getName().toLowerCase().endsWith(".gif");
    }
})));
imageFiles.removeAll(haveUsed);
Collections.shuffle(imageFiles);

File imageFile = imageFiles.remove(0);
haveUsed(imageFile);

jLabel.setIcon(new ImageIcon(ImageIO.read(imageFile)));

你需要改变haveUsedArrayList<String>ArrayList<File>,虽然

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章