【问题标题】:for loop JFrame image replacementfor循环JFrame图像替换
【发布时间】:2023-12-25 08:55:01
【问题描述】:
public void run() {

            frame = new JFrame("JFrame 1");
            Container contentPane = frame.getContentPane();

            JLabel label = new JLabel("labelling.....");
            frame.setPreferredSize(new Dimension(400,600));
            frame.pack();
            frame.setVisible(true);

            // TODO Auto-generated method stub
            try
            {
                for(int i = 0; i < 4; i++)
                {
                    frame.add(new JLabel(new ImageIcon("image1.jpg")));
                    Thread.sleep(000);

                    frame.add(new JLabel(new ImageIcon("image1.jpg")));
                    Thread.sleep(2000);

                    frame.add(new JLabel(new ImageIcon("image1.jpg")));
                    Thread.sleep(2000);
                }
            }
            catch(InterruptedException e)
            {

            }
}

但是它没有更新 JFrame。我在这个类之外设置了 Jframe...

这个愚蠢的事情要求我提供更多细节,所以这只是华夫饼...................................... ......

【问题讨论】:

  • 你重新验证了吗?什么是布局?你是否直接在框架中添加标签
  • 是的。我将向您展示全部内容。一会儿……
  • 不,重新验证无济于事。
  • @HovercraftFullOfEels 好的,虽然它会冻结 gui,但它不会在线程睡眠完成后添加标签吗?
  • @FastSnail:它会添加 JLabels,但会添加一大堆,并且知道如何放置。

标签: java multithreading swing for-loop jframe


【解决方案1】:

您不应该将 Thread.sleep 与 Swing GUI 一起使用,因为您会让 GUI 进入睡眠状态。使用Swing Timer 来帮助您交换图像,而不会占用 Swing 事件线程。另外,不要一直添加 JLabel,而是交换单个稳定 JLabel 的 ImageIcon。

类似

  int timerDelay = 500;
  new Timer(timerDelay, new ActionListener() {
     private boolean firstIcon = true;
     private int count = 0;

     @Override
     public void actionPerformed(ActionEvent e) {
        if (count >= MAX_COUNT) {
           ((Timer) e.getSource()).stop(); // stop the timer
           return;
        }

        // swap icons
        Icon icon = firstIcon ? icon1 : icon2;
        label.setIcon(icon);
        firstIcon = !firstIcon;
        count++;
     }
  }).start();

例如,

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.*;

public class SwapImages extends JPanel {
   public static final String PATH1 = "https://duke.kenai.com/iconSized/duke.gif"; 
   public static final String PATH2 = "https://duke.kenai.com/iconSized/penduke-transparent.gif";
   public static final String[] PATHS = {PATH1, PATH2};
   protected static final int MAX_COUNT = 8;
   private JLabel label = new JLabel();
   private List<Icon> icons = new ArrayList<>();
   private int index = 0;

   public SwapImages() throws IOException {
      for (String path : PATHS) {
         URL url = new URL(path);
         BufferedImage img = ImageIO.read(url);
         ImageIcon icon = new ImageIcon(img);
         icons.add(icon);
      }
      label.setIcon(icons.get(index));
      add(label);
      int timerDelay = 500;
      new Timer(timerDelay, new ActionListener() {
         private int count = 0;

         @Override
         public void actionPerformed(ActionEvent e) {
            if (count >= MAX_COUNT) {
               ((Timer) e.getSource()).stop();
               return;
            }
            index++;
            index %= icons.size();
            Icon icon = icons.get(index);
            label.setIcon(icon);
            count++;
         }
      }).start();
   }

   private static void createAndShowGUI() {
      SwapImages paintEg = null;
      try {
         paintEg = new SwapImages();
      } catch (IOException e) {
         e.printStackTrace();
      }

      JFrame frame = new JFrame("SwapImages");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(paintEg);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

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

【讨论】:

  • 你如何将图像计时器应用到 f​​or 循环中?
  • @NiallLonergan:查看提供的教程链接和上面的计时器用法概述。
  • 是否可以使用图形方法以某种方式重绘图像?
  • @NiallLonergan:是的,但为此您需要覆盖 JPanel 的 paintComponent 方法并在其中绘制。您仍然需要一个 Swing Timer,并且交换 ImageIcons 要容易得多并且更不容易出错。
  • 好的。你能告诉我如何将我的图像放入图标中吗?