如何创建实例

时间:2015-02-10 21:33:59

标签: java swing

我有两个类,一个扩展JPanel并实现Runnable的主类和类。我试图在actionListener中为同一个JPanel类实例创建两个线程,但我不知道在哪里创建JPanel1对象......

//编辑:Button1是应用程序的开始。之后,按钮2将显示标签的快速动画,单击它时(按钮2)也将启动相同的动画。如果单击其中一个按钮启动运行方法,我该怎么办?

public void run() {

            if(isTom){

            repaint();
            revalidate();
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {

            }
            panel.removeAll();
            panel.add(tomLabel1);
            repaint();
            revalidate();
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
            }
            panel.add(tomLabel2);
            repaint();
            revalidate();
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                }
            panel.add(tomLabel3);
            repaint();
            revalidate();
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {

            }
            panel.add(tomLabel4);
            repaint();
            revalidate();
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                }
            panel.add(tomLabel5);
            repaint();
            revalidate();
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                }


            panel.removeAll();
            repaint();
            revalidate();
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
            }

            }



public Game(){

        JFrame frame = new JFrame();
        Panel1 key = new Panel1();
        key.addKeyListener(key);
        frame.add(key);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setUndecorated(true);
        frame.setVisible(true);
    }
    public static void main(String[] args) {
        new Game();

    }

    public class Panel1 extends JPanel implements KeyListener,Runnable{
    JButton button1 = new JButton("BUTTON1");
    JButton button2 = new JButton("BUTTON2");
    add(button1);add(button2);

        Thread t = new Thread(this); // This works, but i need it inside the actionListener.

         button1.addActionListener(new ActionListener(){
                public void actionPerformed(ActionEvent e){
                    System.out.println("button1");
                    Thread x = new Thread(j);//'j' is an JPanel1 object. I need something like this i guess
                    x.setName("Thread x");});

         button2.addActionListener(new ActionListener(){
                public void actionPerformed(ActionEvent e){
                    System.out.println("button2");
                    Thread y = new Thread(j);
                    y.setName("Thread y");
                                           });

public void run(){
     System.out.println(Thread.currentThread().getName());
}

2 个答案:

答案 0 :(得分:1)

首先,Swing不是线程安全的!这意味着您永远不应该从Event Dispatching Thread的上下文之外创建或修改UI!

其次,Swing是一个单线程环境,这意味着你永远不应该在Event Dispatching Thread的上下文中阻塞或执行长时间运行的代码,这将导致UI冻结,直到删除该块。

你的概念是正确的,你的实现是错误的,你应该使用Swing Timer代替。

使用单个标签并更改其属性(文本/图标,无论如何),而不是删除和添加标签

有关详细信息,请参阅Concurrency in SwingHow to use Swing Timers

Splash

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

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

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                try {
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException exp) {
                    exp.printStackTrace();
                }
            }
        });
    }

    public class TestPane extends JPanel {

        private JButton button1;
        private JButton button2;

        private SplashScreen splashScreen;

        public TestPane() throws IOException {
            button1 = new JButton("Button One");
            button2 = new JButton("Button Two");

            JPanel buttons = new JPanel();
            buttons.add(button1);
            buttons.add(button2);

            button1.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    splashScreen.run();
                }
            });

            button2.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    splashScreen.run();
                }
            });

            splashScreen = new SplashScreen();

            setLayout(new BorderLayout());
            add(splashScreen);
            add(buttons, BorderLayout.SOUTH);
        }

    }

    public static  class SplashScreen extends JPanel {

        protected static final int IMAGE_COUNT = 4;

        private JLabel label;
        private Timer timer;

        private int delta;
        private int count;
        private Icon[] icons;

        private Dimension preferredSize;

        public SplashScreen() throws IOException {
            String path = "/images/splash";
            String ext = ".png";
            icons = new Icon[IMAGE_COUNT];
            int maxWidth = 0;
            int maxHeight = 0;
            for (int index = 0; index < IMAGE_COUNT; index++) {
                String name = path + (index + 1) + ext;
                System.out.println(name);
                icons[index] = new ImageIcon(ImageIO.read(getClass().getResource(name)));
                maxWidth = Math.max(maxWidth, icons[index].getIconWidth());
                maxHeight = Math.max(maxHeight, icons[index].getIconHeight());
            }
            preferredSize = new Dimension(maxWidth, maxHeight);

            timer = new Timer(250, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (count >= IMAGE_COUNT) {
                        count = IMAGE_COUNT - 2;
                        delta = -1;
                    } else if (count < 0) {
                        ((Timer)e.getSource()).stop();
                    } else {
                        label.setIcon(icons[count]);
                        count += delta;
                    }
                }
            });

            setLayout(new BorderLayout());
            label = new JLabel();
            add(label);
        }

        @Override
        public Dimension getPreferredSize() {
            return preferredSize;
        }

        public void run() {

            if (!timer.isRunning()) {

                delta = 1;
                count = 0;
                timer.start();

            }

        }

    }

}

答案 1 :(得分:0)

使用Panel1类实例创建一个新的Thread实例:

button1.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                System.out.println("button1");
                Thread x = new Thread(Panel1.this);
                x.start();
                x.setName("Thread x");});

使用新的Thread对象重复另一个按钮:

button2.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e){
                System.out.println("button2");
                Thread y = new Thread(Panel1.this);
                y.start();
                y.setName("Thread y"); });

Panel1.this指的是当前正在运行的Panel1类的实例,确保你的Threads正在执行该实例的run()。