Когда я добавляю таймер, изображения больше не загружаются - PullRequest
0 голосов
/ 09 июля 2019

Я пытаюсь создать Asteroids-игру, но я уже борюсь с самого начала: я хочу создать обратный отсчет до запуска игры. Для этого я использую таймер, который запускается при нажатии кнопки «Пуск» и который (должен) загружать BufferedImage каждую секунду, а затем отображает его на JFrame.

Все это работало отлично, прежде чем я добавил таймер. Однако изображение все еще рисуется, и метод run() из TimerTask все еще используется полностью. Однако изображение не отображается на моем JFrame.

public class Main implements ActionListener {

    private static File load = null;
    private static BufferedImage image = null;
    private JFrame frame;
    private JButton start;
    private JLabel game_name;
    private JLabel screen;
    private ImageIcon icon;
    private Asteroids aster = new Asteroids();
    private static Main m = new Main();

    protected static int height = 550;
    protected static int width = 800;
    protected static int cd = 0;

    /*
     * Here the JFrame frame gets created and set up, and the main method 
     * does its job. I believe only the actionPerformed method to be 
     * important, so I removed this part from the post.
     *
     */


    private void addScreen() {
        frame.add(screen);
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        // Cleaning the screen
        start.setVisible(false);
        game_name.setVisible(false);

        // Creating the image
        aster.spawn(5);

        // creating the countdown timer
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {            
            public void run() {
                // creating countdown
                aster.initialScreen();

                // Reading the image
                load = new File(aster.filePath + aster.fileName + ".png");
                image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
                try {
                image = ImageIO.read(load); 
                } catch (IOException i) {
                    System.out.println("Reading has encountered an error: \n" + i); }

                // Implementing the Image
                screen = new JLabel();
                screen.setSize(width, height);
                icon = new ImageIcon(image);
                screen.setIcon(icon);
                m.addScreen();
                System.out.println("roger");
            }

        }, 0, 1000);

    } // end actionPerfomed()

} // end class

Может кто-то заметить ошибку? Я действительно не понимаю, в чем проблема, хотя я новичок в таймерах, поэтому, если что-то я делаю, действительно глупо, пожалуйста, скажите мне.

Ответы [ 2 ]

1 голос
/ 09 июля 2019

Скорее всего, ваша проблема связана с тем, что вы используете java.util.Timer, который запускает собственный фоновый поток и вызывает проблемы параллелизма при доступе к компонентам Swing.

В любом случае я бы порекомендовал использовать javax.swing.Timer, который планирует выполнение ваших задач в качестве прослушивателей действий в потоке диспетчеризации событий Swing:

new javax.swing.Timer(1000, new ActionListener() {
    public void actionPerformed(ActionEvent e) {
            // Your code here
        }
    }).start();
0 голосов
/ 22 июля 2019

Хорошо, поэтому я как-то решил проблему: во-первых, я изменил util.Timer на swing.Timer, который сам по себе не помог.Раньше я сохранял каждое изображение после того, как оно было нарисовано на моем рабочем столе, а затем я загружал его на экран, когда оно должно отображаться.Я немного поигрался с кодом и обнаружил, что мне не нужно его сохранять, но я могу ссылаться на него напрямую, сделав его static.Когда я это сделал, проблема исчезла.Вот пример кода того, что я имею в виду:

До:

// In the drawing class
save = new File(aster.filePath + aster.fileName + ".png");
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
try {
    ImageIO.write(image, "png", save); 
    } catch (IOException i) {
    System.out.println("Writing has encountered an error: \n" + i); }

// In the displaying class
load = new File(aster.filePath + aster.fileName + ".png");
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
try {
    image = ImageIO.read(load); 
    } catch (IOException i) {
    System.out.println("Reading has encountered an error: \n" + i); }
ImageIcon icon = new ImageIcon(image);
displayingJLabel.setIcon(icon);
frame.add(displayingJLabel);

После:

// One static declaration and initialization of an BufferedImage in the drawing class
public static BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
// Drawing Code

// Accessing the image
ImageIcon icon = new ImageIcon(DrawingClass.image);
displayingJLabel.setIcon(icon);
frame.add(displayingJLabel);

По сути, все то же самое, за исключением того, что все сохранение и чтениепроцесс был пропущен, и вместо нескольких локальных BufferedImage я использую только один static BufferedImage.

Я не знаю точно, почему это сработало, но я предполагаю, что весь процесс чтения и записипросто потребовалось слишком много времени, чтобы таймер срабатывал каждую секунду, и этот новый метод намного быстрее.Я еще не пытался сделать все это с помощью util.Timer, но я думаю, что колебание. Вероятно, Timer имеет свою долю в решении этой проблемы.

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