切换图像的可见性

时间:2018-05-13 22:47:21

标签: java swing jframe jlabel bufferedimage

我试图使一组图像显示5秒然后消失,基本上是幻灯片。这是我正在使用的图像类。我在同一个文件夹中有所需的图像,并在创建类的实例时将文件名作为字符串传递。当我调用toggleVisible方法时,框架显示没有图像。我对图形非常不熟悉,非常感谢任何反馈,谢谢。

import java.awt.FlowLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;



public class Picture {

        private JFrame frame;
        private BufferedImage img;
        private ImageIcon icon;
        private JLabel lbl;
        private Boolean isVisible = false;

    public Picture(String s) throws IOException {
        img = ImageIO.read(new File(s));
        icon = new ImageIcon(img);
        frame = new JFrame();
        frame.setLayout(new FlowLayout());
        frame.setSize(300,200);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        lbl = new JLabel();
        lbl.setIcon(icon);
        frame.add(lbl);
        frame.setVisible(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    public void toggleVisible(){
        isVisible = !isVisible;
        frame.setVisible(isVisible);
    }
}

2 个答案:

答案 0 :(得分:0)

图像没有显示?您可能想要指定JLabelImageIcon

ImageIcon i = new ImageIcon("src/resources/resource.png");
JLabel l = new JLabel(i);

您只需将JLabel设置为可见或不可见。此外,将边界设置为大致ImageIcon的大小。如果希望ImageIcon以JLabel为中心,请设置文本对齐方式:

JLabel.setHorizontalAlignment(JLabel.CENTER);
JLabel.setVerticalAlignment(JLabel.CENTER);

如果您使用JLabel.setBounds(x, y, width, height);设置界限,则需要使用JPanel.setLayout(null);

您还需要一个JPanel。你只需添加一个新的JPanel:

JPanel back = new JPanel();
JFrame.add(back);

然后添加所有JLabel / Images(在您的情况下)。它现在应该出现,然后在此评论并告诉我问题。最终代码:

JPanel back = new JPanel();
frame.add(back);
back.setLayout(null);
ImageIcon i = new ImageIcon("src/(whatever your resource file is called)/resource.png");
JLabel l = new JLabel(i);
l.setBounds(x, y, width, height);
back.add(l);
//this is optional, sets the image in the center of the JLabel:
l.setHorizontalAlignment(JLabel.CENTER);
l.setVerticalAlignment(JLabel.CENTER);

希望这有帮助。

答案 1 :(得分:0)

我认为这对你的问题来说有点不同,

但您可以通过覆盖java中JPanel类的 paintComponent 方法来实现此目的。

首先,您可以将画布作为jpanel类。

此类采用一个参数,其中路径是图像目录。

class ImageCanvas extends JPanel {
    private static final long serialVersionUID = 1L;
    private BufferedImage imageCandids[];
    private int imageLimitCount, imageCount;

    public ImageCanvas(String path) {
        File f = new File(path);
        String fileNames[] = f.list();
        imageCandids = new BufferedImage[fileNames.length];
        imageCount = imageLimitCount = fileNames.length;

        for (int i = 0; i < fileNames.length; i++) {
            try {
                imageCandids[i] = ImageIO.read(new File(f.getPath() + File.separator + fileNames[i]));

            } catch (IOException ex) {
                ex.printStackTrace();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    @Override
    protected void paintComponent(final Graphics g) {
        super.paintComponent(g);

        g.drawImage(imageCandids[--imageCount], 0, 0, null);

        if(imageCount == 0) imageCount = imageLimitCount;
    }

}

需要一个 BufferedImage 类的数组取决于文件列表。

File f = new File(path);
String fileNames[] = f.list();
imageCandids = new BufferedImage[fileNames.length];

然后,使用ImageIO类的read方法读取每个图像,以便生成一个真正的BufferedImage对象。

imageCandids[i] = ImageIO.read(new File(f.getPath() + File.separator + fileNames[i]));

您可以刷新这些图像,调用canvas对象的重绘方法,然后执行paintComponent方法。

第二,为了制作一个silde节目,我使用了一个由TimerTask类继承的ToggleImageJob类。

class ToggleImageJob extends TimerTask {

    public void run() {
        if (imageCanvas != null)
            imageCanvas.repaint();
    }
}

在ToggleImageAction类中,我将向您展示如何通过Timer类中的scheduleAtFixedRate方法运行此作业,如下所示;

private final class ToggleImageAction extends AbstractAction {
    private static final long serialVersionUID = 1L;
    private ToggleImageJob toggleImageJob;
    private Timer  toggleImageScheduler = new Timer();
    private boolean isStart;


    private ToggleImageAction(final String name) {
        super(name);
        isStart = false;
    }

    @Override
    public void actionPerformed(final ActionEvent e) {

        if(!isStart)
        {
            toggleImageJob = new ToggleImageJob();
            //every 5 seconds, 1 second delay
            toggleImageScheduler.scheduleAtFixedRate(toggleImageJob, 1000, 5000);
            isStart = true;
        }
        else
        {
            isStart = false;
            toggleImageJob.cancel();
        }
    }
}

使用JButton的此操作用于通过轮流单击来启动和停止此幻灯片放映。 除非用户再次单击该按钮,否则将每5秒显示一个不同的图像缓冲区数组图像。

您可以在此处查看完整的来源。

package com.tobee.tests.swing;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

import javax.imageio.ImageIO;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ToggleImageWin extends JFrame {
    private static final long serialVersionUID = 1L;

    private final JPanel imageCanvas;

    class ToggleImageJob extends TimerTask {

        public void run() {
            if (imageCanvas != null)
                imageCanvas.repaint();
        }
    }

    class ImageCanvas extends JPanel {
        private static final long serialVersionUID = 1L;
        private BufferedImage imageCandids[];
        private int imageLimitCount, imageCount;

        public ImageCanvas(String path) {
            File f = new File(path);
            String fileNames[] = f.list();
            imageCandids = new BufferedImage[fileNames.length];
            imageCount = imageLimitCount = fileNames.length;

            for (int i = 0; i < fileNames.length; i++) {
                try {
                    imageCandids[i] = ImageIO.read(new File(f.getPath() + File.separator + fileNames[i]));

                } catch (IOException ex) {
                    ex.printStackTrace();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }

        @Override
        protected void paintComponent(final Graphics g) {
            super.paintComponent(g);

            g.drawImage(imageCandids[--imageCount], 0, 0, null);

            if(imageCount == 0) imageCount = imageLimitCount;
        }

    }

    private final class ToggleImageAction extends AbstractAction {
        private static final long serialVersionUID = 1L;
        private ToggleImageJob toggleImageJob;
        private Timer  toggleImageScheduler = new Timer();
        private boolean isStart;


        private ToggleImageAction(final String name) {
            super(name);
            isStart = false;
        }

        @Override
        public void actionPerformed(final ActionEvent e) {

            if(!isStart)
            {
                toggleImageJob = new ToggleImageJob();
                toggleImageScheduler.scheduleAtFixedRate(toggleImageJob, 1000, 5000);
                isStart = true;
            }
            else
            {
                isStart = false;
                toggleImageJob.cancel();
            }
        }
    }

    private static final String DIR_PATH = "resource/images/";

    public ToggleImageWin() {
        imageCanvas = new ImageCanvas(DIR_PATH);

        add(imageCanvas, BorderLayout.CENTER);
        add(new JButton(new ToggleImageAction("Toggle Images")), BorderLayout.SOUTH);
    }

    public static void main(final String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new ToggleImageWin();
                frame.setTitle("Toggle Images");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                frame.setBounds(16, 16, 640, 480);
                frame.setVisible(true);
            }

        });
    }
}

enter image description here

我希望这会对你有所帮助。