调用run方法后,主线程被另一个线程中断?

时间:2015-03-07 16:51:26

标签: java multithreading swing

我正在制作一个使用JLabel将种子更改为植物的小型农场游戏演示,点击bt1后初始化种子图像,然后我使用线程在几秒钟后将标签图像更改为成长的植物。但我有这个问题,种子图像永远不会出现。 那是因为我调用了run方法所以主线程被线程时间中断了吗?在wheat.jpg接手之前,我应该改变什么才能让see.jpg出现在JLabel上?这是我的代码。

public class UI {
    JButton bt1, bt2, bt3, bt4, bt5, bt6;
    JPanel gamePanel;

    public UI(){
        JFrame frame = new JFrame("Little Farm Game");
        JPanel mainPanel = new JPanel(new GridLayout(2,5));
        gamePanel = new JPanel(new GridLayout(3,4));
        JPanel controlPanel = new JPanel(new GridLayout(3,3));
        controlPanel.setBackground(Color.DARK_GRAY);

        bt1 = new JButton("Wheat Seed");
        bt2 = new JButton("Flower Seed");
        bt3 = new JButton("Land Purchase");
        bt4 = new JButton("Wheat Seed Purchase");
        bt5 = new JButton("Flower Seed Purchase");
        bt6 = new JButton("Wallet: "+ Wallet.getInstance().getCurrentMoney());

        Thread time = new Thread(){

            @Override
            public void run() {
                try {       
                    sleep(300);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                for(int i=0; i<gamePanel.getComponentCount(); i++)
                {
                    JLabel label = (JLabel) gamePanel.getComponent(i);
                    label.setIcon(new ImageIcon(getImage("src/wheat.jpg")));
                }
            }
        };

        bt1.addActionListener(new ActionListener(){

        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub

             gamePanel.add(new JLabel(new ImageIcon(getImage("src/flowerseed.jpg"))));
             gamePanel.validate();

               time.run();
            }
        });

        controlPanel.add(bt1);
        controlPanel.add(bt2);
        controlPanel.add(bt3);
        controlPanel.add(bt4);
        controlPanel.add(bt5);
        controlPanel.add(bt6);
        mainPanel.add(gamePanel);
        mainPanel.add(controlPanel);
        frame.add(mainPanel);
        frame.setSize(600, 400);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
    }

    public static Image getImage(final String pathAndFileName) {

        return Toolkit.getDefaultToolkit().getImage(pathAndFileName);
    }
}

1 个答案:

答案 0 :(得分:3)

  1. 不要直接使用Threads。没有必要,如果你在后台线程中调用代码而不小心改变Swing状态,这会带来风险,这正是你正在做的
  2. 使用Swing Timer进行动画循环。
  3. 在JLabel中将图像显示为ImageIcons。
  4. 如上所述,让你的GUI中有JLabel。
  5. 只需将您的图片图标读入一次,然后将其保存在变量或集合中。
  6. 只需调用stop()方法即可轻松暂停Swing Timer,并可以通过调用start()轻松重启。
  7. 为了您和我们的利益,请学习并使用良好的Java格式,尤其是在本网站上发布代码时。您当前的代码都是左对齐的,这使得代码难以阅读和理解。

  8. 例如,使用安德鲁的图像:

    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 ChangingImages extends JPanel {
       public static final String SPRITE_SHEET_PATH = "http://i.stack.imgur.com/SeZ5y.png";
       private static final int DELAY = 400;
       private List<Icon> imageIconList = new ArrayList<>();
       private JLabel label = new JLabel();
    
       public ChangingImages() throws IOException {
          URL imgUrl = new URL(SPRITE_SHEET_PATH);
          BufferedImage img = ImageIO.read(imgUrl); 
          for (int i = 0; i < 2; i++) {
             for (int j = 0; j < 6; j++) {
                int x = (img.getWidth() * j) / 6;
                int y = (img.getHeight() * i) / 2;
                int w = img.getWidth() / 6;
                int h = img.getHeight() / 2;
                BufferedImage subImg = img.getSubimage(x, y, w, h);
                imageIconList.add(new ImageIcon(subImg));            
             }
          }
    
          add(label);
          label.setIcon(imageIconList.get(0));
    
          new Timer(DELAY, new ActionListener() {
             int index = 0;
             @Override
             public void actionPerformed(ActionEvent e) {
                index++;
                index %= imageIconList.size();
                label.setIcon(imageIconList.get(index));
             }
          }).start();
       }
    
       private static void createAndShowGui() {
          ChangingImages mainPanel = null;
          try {
             mainPanel = new ChangingImages();
          } catch (IOException e) {
             e.printStackTrace();
             System.exit(-1);
          }
    
          JFrame frame = new JFrame("ChangingImages");
          frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
          frame.getContentPane().add(mainPanel);
          frame.pack();
          frame.setLocationByPlatform(true);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    }