Переключение видимости изображения - PullRequest
0 голосов
/ 14 мая 2018

Я пытаюсь заставить набор изображений появляться в течение 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 голосов
/ 16 мая 2018

Я думаю, что это немного другой подход к вашему вопросу,

, но вы можете сделать это с помощью переопределения paintComponent метода класса JPanel в Java.

Во-первых, у вас может быть холст в качестве класса 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];

Затем прочитайте каждое изображение методом read класса ImageIO, чтобы создать реальный объект BufferedImage.

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

Вы можете обновить эти изображения, вызывая метод перекраски объекта canvas, после чего выполняется метод paintComponent.

Во-вторых, для создания silde-шоу я использовал класс ToggleImageJob, унаследованный классом TimerTask.

class ToggleImageJob extends TimerTask {

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

В классе ToggleImageAction я покажу вам, как запустить это задание с помощью метода scheduleAtFixedRate в классе Timer следующим образом;

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

Надеюсь, это поможет вам.

0 голосов
/ 16 мая 2018

Изображение не отображается? Вы можете назначить JLabel ImageIcon:

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

и затем добавьте все JLabels / 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);

Надеюсь, это поможет.

...