Почему слайд-шоу не работает в Java с использованием Swing и Awt? - PullRequest
2 голосов
/ 20 марта 2011

Я делаю слайд-шоу программы изображений в Java, используя таймер.В списке событий таймера я добавил код в изображение chnage, но изображение не меняется.Ниже код, который я написал

class ImagePanel extends JPanel {

    private Image backgroundImage;

    public ImagePanel(Image backgroundImage) {
        super();
        this.backgroundImage = backgroundImage;
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);        
        g.drawImage(this.backgroundImage, 0, 0, null);
    }
}

public class A extends JFrame{
    static int counter;
    List<String> imagePaths;
    int nimgpaths=0;
    static A frame = new A();
    public static void main(String[] args) {
        frame.setSize(1024, 768);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getPath();
        /* Getting required image */
        Image backgroundImage = null;
        String pathToTheImage = "C:\\Documents and Settings\\Administrator\\My Documents\\My Pictures\\civ1.JPG";
        try {
            backgroundImage = ImageIO.read(new File(pathToTheImage));
        } catch (IOException e) {
            e.printStackTrace();
        }

        /* Initializing panel with the our image */
        ImagePanel panel = new ImagePanel(backgroundImage);
        frame.getContentPane().add(panel);
        frame.setVisible(true);
        frame.timerEvent();
        //frame.show();
    }

    public void timerEvent(){
    Timer timer = new Timer(5000, new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("Time event occured");
            if(counter > nimgpaths)
                counter=0;
            String imgPath=imagePaths.get(counter);
            Image backgroundImage = null;
            try {
            backgroundImage = ImageIO.read(new File(imgPath));
        }catch (Exception e1) {
            e1.printStackTrace();
        }

        /* Initializing panel with the our image */
            frame.removeAll();
        ImagePanel panel = new ImagePanel(backgroundImage);
        panel.repaint();
        //panel.setBackground(backgroundImage);
        frame.getContentPane().add(panel);

        }
    });
    timer.start();
    }

   // To get path of images
    public void getPath(){
        DbOps db=new DbOps();
        imagePaths=db.getPath();
        nimgpaths=imagePaths.size();
        for(Iterator i=imagePaths.iterator();i.hasNext();){
            System.out.println((String)i.next());
        }

    }

}

Ответы [ 4 ]

2 голосов
/ 20 марта 2011

Почему вы используете нестандартную панель и рисование?

Ваш код просто рисует изображение в желаемом размере.Эта функциональность доступна при использовании JLabel.Затем, когда вы используете метку, все, что вам нужно сделать, это использовать:

label.setIcon(....);

, когда вы хотите изменить изображение.Прочитайте раздел из учебника по Swing на Как использовать значки для получения дополнительной информации.

Единственная причина для создания пользовательского компонента - это если вы планируете масштабировать изображение или делать что-то необычное, как это,Если это так, то вы можете использовать что-то вроде Background Panel , которая поддерживает масштабированные изображения, а также метод setImage (), чтобы вы могли динамически изменять изображение.

0 голосов
/ 24 марта 2011

Ваша концепция сама по себе неверна.

Вы можете обновить панель следующим образом:

public void refreshPanel(JPanel panel){
   panel.removeAll();
   panel.invalidate();
   panel.validate();
}

Проблема:

Я вижу в вашем коде, что вы пытаетесь создать более одного объекта на одной панели, который вам нужно обновить.

Было бы лучше создать один объект панели и обновить этот объект.

ImagePanel panel = new ImagePanel(backgroundImage);

Надеюсь, вы понимаете, что я хотел вам объяснить.

Если вы все еще в замешательстве, дайте мне знать.

0 голосов
/ 20 марта 2011

frame.removeAll () не делает то, что вы ожидаете - это удаление компонентов из самого фрейма, а не удаление компонентов из области содержимого фрейма.Измените код в конце слушателя действия таймера на что-то вроде этого, чтобы исправить это:

    ImagePanel panel = new ImagePanel(backgroundImage);
    frame.getContentPane().removeAll();
    frame.getContentPane().add(panel);
    frame.getContentPane().invalidate();
    frame.getContentPane().validate();
0 голосов
/ 20 марта 2011

Гораздо лучший дизайн для ImagePanel позволит вам просто заменить изображение, а не удалять компонент. Однако если вам нужно заменить видимый компонент, вы должны вызвать validate () для его контейнера, иначе новый не будет отображаться (в большинстве случаев, во всяком случае.) Я думаю, что это ваша проблема здесь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...