Переключение между фото (JFrame, JButton) - PullRequest
0 голосов
/ 15 февраля 2020

Я пытаюсь сделать окно, которое переключается между картинками при нажатии кнопки «изменить». Когда я пытаюсь запустить программу, Java lo go выскакивает, как будто программа вот-вот запустится, но затем она просто исчезает. Я как бы застрял сейчас и надеюсь, что кто-нибудь подскажет, что может быть не так.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import javax.imageio.*;
import javax.swing.*;

public class ImageViewer extends JFrame{

private JPanel panel;
private JLabel imageLabel;
private JButton button;
private Icon[] icons = {};
private static final long serialVersionUID = 1L;

public ImageViewer() {

    try {
        panel = new JPanel();
        URL url1 = new URL("http://www.sm.luth.se/csee/courses/d0010e/l/prob/10tj5Ei9o/LTU-Teatern.jpg");
        URL url2 = new URL("http://www.sm.luth.se/csee/courses/d0010e/l/prob/10tj5Ei9o/LTU-Vetenskapens-hus.jpg");
        Icon image = new ImageIcon(ImageIO.read(url1));
        Icon image2 = new ImageIcon(ImageIO.read(url2));
        icons[0] = image;
        icons[1] = image2;
        imageLabel = new JLabel();
        panel.add(button);
        panel.add(imageLabel);
        button = new JButton("Change");
        button.addActionListener(new ActionListener() {     
            private boolean value = false;
            {
            }

            public void actionPerformed(ActionEvent arg0) {
                value = value == true ? false : true;
                if (value == false) {
                    imageLabel.setIcon(icons[0]);
                }else { 
                    imageLabel.setIcon(icons[1]);
                }
            }
        });
        this.setContentPane(panel);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.pack();
        this.setVisible(true);
    }catch (Exception e) {
    }
}

public static void main(String args[]) {
    new ImageViewer();
}
}

1 Ответ

0 голосов
/ 22 февраля 2020

Во-первых, вот что я создал, чтобы дать вам несколько советов.

First Image

Second Image

А вот и код. Подсказки будут следовать после кода.

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ImageViewer implements Runnable {

    private boolean isImage1;

    private BufferedImage image;

    private ImageData imageData;

    private JLabel label;

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new ImageViewer());
    }

    public ImageViewer() {
        this.imageData = new ImageData();
        this.image = imageData.getImage1();
        this.isImage1 = true;
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Image Viewer");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel();

        label = new JLabel(new ImageIcon(image));
        panel.add(label);

        JButton button = new JButton("Change");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                if (isImage1) {
                    image = imageData.getImage2();
                } else {
                    image = imageData.getImage1();
                }
                label.setIcon(new ImageIcon(image));
                isImage1 = !isImage1;
            }
        });
        panel.add(button);

        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }

    public class ImageData {

        private BufferedImage image1;
        private BufferedImage image2;

        public ImageData() {
            URL url1;
            URL url2;
            try {
                url1 = new URL("http://www.sm.luth.se/csee/courses/d0010e/l/prob/10tj5Ei9o/LTU-Teatern.jpg");
                url2 = new URL("http://www.sm.luth.se/csee/courses/d0010e/l/prob/10tj5Ei9o/LTU-Vetenskapens-hus.jpg");
                this.image1 = readImage(url1);
                this.image2 = readImage(url2);
            } catch (MalformedURLException e) {
                e.printStackTrace();
            }
        }

        private BufferedImage readImage(URL url) {
            try {
                return ImageIO.read(url);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        public BufferedImage getImage1() {
            return image1;
        }

        public BufferedImage getImage2() {
            return image2;
        }

    }
}

Итак, вот подсказки.

  1. Не расширяйте JFrame или любой компонент Swing, если вы не собираетесь переопределять один или несколько методов класса.

  2. Всегда запускайте проект Swing в потоке диспетчеризации событий (EDT). Для удобства я реализовал Runnable в основном классе ImageViewer. Ваш основной метод всегда должен содержать вызов SwingUtilities invokeLater.

  3. Я переместил чтение изображений в свой собственный класс данных. Всегда отделяйте данные от представления. Я обычно использую архитектуру модель / представление / контроллер для создания проекта Swing.

  4. Я проверил ошибки в URL-адресах или фактическом чтении изображения. Если бы произошла ошибка, она напечатала бы трассировку стека, которая помогла бы мне найти ошибку. Никогда не заключайте целые методы в блок try-catch.

  5. Единственным компонентом Swing, который должен был быть переменной класса, был компонент JLabel. Создайте только те переменные класса, которые вам нужны для всего класса. Моя привычка - делать все переменные класса приватными, а также методы класса. Разоблачайте только те методы, которые необходимо раскрыть.

Как только я все это сделал, написание слушателя действия было тривиально.

...