Как изменить изображение, отображаемое JLabel?

#java #swing #timer #jpanel #jlabel

#java #качать #таймер #jpanel #jlabel

Вопрос:

В настоящее время я программирую видеоигру. Я использую Util.Таймер для отслеживания нескольких функций игры, но одна из моих проблем заключается в попытке переключаться между фоновыми изображениями. Я пытаюсь обновлять JPanel до нового изображения каждую секунду, но пока безуспешно. Я использовал JLabel для отображения изображения внутри JPanel. Я также вызываю displayFrame () по прошествии секунды. Итак, теперь мой вопрос в том, как я смогу обновлять свою JPanel каждую секунду новым изображением? Вот мой код:

 public static void displayFrame(){
    panel_1.setBounds(10, 11, 519, 614);
    ImageIcon image = changeFrame();
    JLabel label = new JLabel("", image, JLabel.CENTER);
    panel_1.add(label, BorderLayout.CENTER);
    frame.getContentPane().add(panel_1);
}

public static ImageIcon changeFrame(){
    if(frameCounter == 9){
        frameCounter = 1;
    }
    if(frameCounter == 1){
        frameCounter = 2;
        return new ImageIcon("Capture.PNG");
    }
    if(frameCounter == 2){
        frameCounter = 3;
        return new ImageIcon("Capture2.PNG");
    }
    if(frameCounter == 3){
        frameCounter = 4;
        return new ImageIcon("Capture3.PNG");
    }
    if(frameCounter == 4){
        frameCounter = 5;
        return new ImageIcon("Capture4.PNG");
    }
    if(frameCounter == 5){
        frameCounter = 6;
        return new ImageIcon("Capture5.PNG");
    }
    if(frameCounter == 6){
        frameCounter = 7;
        return new ImageIcon("Capture6.PNG");
    }
    if(frameCounter == 7){
        frameCounter = 8;
        return new ImageIcon("Capture7.PNG");
    }
    if(frameCounter == 8){
        frameCounter = 9;
        return new ImageIcon("Capture8.PNG");
    }
    if(frameCounter == 9){
        frameCounter = 1;
        return new ImageIcon("Capture9.PNG");
    }
    return new ImageIcon("Capture.PNG");
    }
  

Ответ №1:

Я использую Util.Таймер

Не используйте Util.Таймер. Вы должны использовать Swing Timer, чтобы убедиться, что все обновления графического интерфейса выполняются в потоке отправки событий.

Затем, когда срабатывает таймер, вы вызываете setIcon(...) метод на вашей этикетке, чтобы изменить фактический значок.

Не используйте несколько операторов «if» для управления отображаемым изображением. Что, если вы хотите иметь 100 изображений, которые требовали бы ввода большого количества кода. Вместо этого я бы сохранил все ваши изображения в ArrayList. Затем вы просто используете get(...) метод ArrayList, чтобы получить изображение, которое вы хотите отобразить, используя вашу переменную «frameCounter». Затем вы обновляете счетчик при следующем срабатывании таймера.

Кроме того, не используйте статические методы в своем классе. Я предлагаю вам прочитать руководство по Swing. Размещенные там примеры показывают вам, как лучше структурировать код в ваших классах.

Комментарии:

1. Хорошо, спасибо за информацию о таймере Swing. И теперь я использую массив вместо операторов if. Хотя я пытался использовать setIcon, как вы предложили. Я думаю, что метка обновляется, но изменения не попадают в JFrame. Вот мой код с изменениями:

2. int delay = 1000; //миллисекунды ActionListener taskPerformer = новый ActionListener() { общедоступный недействительный actionPerformed(ActionEvent evt) { displayFrame(); } }; новый таймер (задержка, taskPerformer).start();

3. public void displayFrame(){ panel_1.setBounds(10, 11, 519, 614); ImageIcon изображение = changeFrame(); label.setIcon(изображение); panel_1.add (метка, BorderLayout. ПО ЦЕНТРУ); frame.getContentPane().add(panel_1); }

4. Я не уверен, как форматировать мой код в комментариях, чтобы он выглядел лучше. Но спасибо вам за всю вашу помощь до сих пор!

5. @user2748943, обновите свой вопрос надлежащим SSCCE , который демонстрирует вашу проблему.