HuangJie
HuangJie

Reputation: 1530

event dispatch thread in Java SWING program

I am totally a newbie in Java. And I want to create an animation. But I did not succeed. mouseClicked() will be executed in the event dispatching thread. Why doesn't it work? Will the event dispatching be occupied by other threads, what other threads?

public class DemoThreadGUI {

    public static void main(String [] args) {
        DemoThreadGUI app = new DemoThreadGUI();
        app.go();
    }

    public void go() {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                generateGUI();
            }
        });     
    }
    public void generateGUI() {
        JFrame frame = new JFrame("Demo");
        frame.add(new MyPanel());
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    class MyPanel extends JPanel implements MouseListener {
        private int x,y;
        private int r;
        public MyPanel() {
            this.setPreferredSize(new Dimension(100,100));
            this.addMouseListener(this);
            x = 50;
            y = 50;
            r = 25;
        }
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.fillOval(x-r,y-r,r*2,r*2);
        }

        public void mouseClicked(MouseEvent event) {
            int targetX = event.getX();
            int targetY = event.getY();
            for(int i=0;i<10;++i) {
                x = (x+targetX)/2;
                y = (y+targetY)/2;
                repaint();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) { }
            }
        }

        public void mouseEntered(MouseEvent event) {}
        public void mouseExited(MouseEvent event) {}
        public void mousePressed(MouseEvent event) {}
        public void mouseReleased(MouseEvent event) {}

    }

}

Upvotes: 1

Views: 209

Answers (2)

dryairship
dryairship

Reputation: 6077

As Holger said, You can’t expect a thread to paint your UI when you told it to sleep.

Use this instead:

  • Make targetX and targetY global variables, and make a new java.util.Thread object t.

    private int x,y;
    private int r;
    Thread t;
    int targetX, targetY;
    
  • modify your mouseClicked method as:

    public void mouseClicked(final MouseEvent event) {
        targetX = event.getX();
        targetY = event.getY();
        t = new Thread(new Runnable(){public void run(){anim();}});
        t.start();
    }
    
  • Put your code of the mouseClicked method into the anim method as:

    public void anim()
    {
        for(int i=0;i<10;++i) {
            try{
                x = (x+targetX)/2;
                y = (y+targetY)/2;
                repaint();
                Thread.sleep(100);
            }catch(Exception e){}
        }
        t.stop();
    }
    

This works perfectly.

Upvotes: 0

StanislavL
StanislavL

Reputation: 57381

In your mouseClicked() start a new Thread and place the code in the thread

       for(int i=0;i<10;++i) {
            x = (x+targetX)/2;
            y = (y+targetY)/2;
            repaint();
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) { }
        }

The repaint() call should be wrapped into SwingUtilities.invokeAndWait() to pass control to EDT

Upvotes: 1

Related Questions