001package bradleyross.swing;
002import java.awt.Color;
003import java.awt.Dimension;
004import java.awt.FlowLayout;
005import java.awt.event.ActionListener;
006import java.awt.event.ActionEvent;
007import java.awt.event.KeyListener;
008import java.lang.reflect.InvocationTargetException;
009import java.awt.event.KeyEvent;
010import java.awt.Graphics;
011import javax.swing.BorderFactory;
012import javax.swing.JFrame;
013import javax.swing.JPanel;
014import javax.swing.JButton;
015import javax.swing.SwingUtilities;
016import javax.swing.Timer;
017import java.util.Random;
018/**
019 * This Swing demo creates a JPanel component and randomly 
020 * moves a red dot within the panel when triggered by a
021 * timer.
022 * 
023 * <p>Try changing the size of the window to see how it affects the relationship between
024 *    the button and the panel where the graphics are generated.</p>
025 * 
026 * <p>The {@link java.util.Timer} object was replaced with a {@link javax.swing.Timer} object.</p>
027 * 
028 * @author Bradley Ross
029 *
030 */
031public class SwingTimer implements Runnable {
032        protected JFrame mainFrame;
033        protected FlowLayout layout;
034        protected MyPanel panel;
035        /**
036         * x-coordinate of red dot in pixels.
037         */
038        protected int xPos = 0;
039        /**
040         * y-coordinate of red dot in pixels.
041         */
042        protected int yPos = 0;
043        protected Random random = new Random();
044        /**
045         * Timer object for this application.
046         */
047        protected Timer timer;
048        /**
049         * This method is triggered by the Swing utilities.
050         */
051        public void run() {
052                buildFrame();
053        }
054        /**
055         * Action listener for this application for the
056         * buttons in this application.
057         * 
058         * @author Bradley Ross
059         *
060         */
061        protected class Listener1 implements ActionListener {
062                public void actionPerformed(ActionEvent e) {
063                        System.out.println("Action " + e.getActionCommand());
064                }
065        }
066        /**
067         * Key listener for this application.
068         * 
069         * @author Bradley Ross
070         *
071         */
072        protected class Listener2 implements KeyListener {
073                /** 
074                 * Action when key event is detected.
075                 *  @param e key event
076                 */
077                public void keyTyped(KeyEvent e) {
078                        System.out.println("Keystroke received " + e.getKeyChar());
079                }
080                public void keyPressed(KeyEvent e) { ; }
081                public void keyReleased(KeyEvent e) { ; }
082                
083        }
084        /**
085         * This subclass of JPanel represents the
086         * panel where the graphics are displayed.
087         * 
088         * <p>It repaints the
089         *    the dot using {@link SwingTimer#xPos} and 
090         *    {@link SwingTimer#yPos}.</p>
091         * 
092         * @author Bradley Ross
093         *
094         */
095        @SuppressWarnings("serial")
096        protected class MyPanel extends JPanel {
097                public void paintComponent(Graphics g) {
098                        super.paintComponent(g);
099                        g.fillOval(xPos,  yPos, 5, 5);
100                }
101        }
102        /**
103         * Executed each time the timer triggers an event.
104         * 
105         * <p>It randomly repositions the dot within the
106         *    panel by changing {@link SwingTimer#xPos} and 
107         *    {@link SwingTimer#yPos}.  After this the
108         *    repaint method of the panel causes the
109         *    contents to be repainted using the
110         *    {@link MyPanel#paintComponent(Graphics)}
111         *    method.
112         *    </p>
113         * @author Bradley Ross
114         *
115         */
116        protected class Motion implements ActionListener {
117                public void actionPerformed(ActionEvent e) {
118                        xPos = random.nextInt(300);
119                        yPos = random.nextInt(300);
120                        panel.repaint();
121                }
122        }
123        /**
124         * Creates and sets up components in frame.
125         */
126        protected void buildFrame() {
127                xPos = random.nextInt(300);
128                yPos = random.nextInt(300);
129                KeyListener listener2 = new Listener2();
130                ActionListener listener1 = new Listener1();
131                mainFrame = new JFrame();
132                layout = new FlowLayout(FlowLayout.LEADING);
133                mainFrame.setLayout(layout);
134                mainFrame.addKeyListener(listener2);
135                JButton first = new JButton("First");
136                first.setActionCommand("first");
137                first.addActionListener(listener1);
138                first.addKeyListener(listener2);
139                first.setFocusable(false);
140                mainFrame.add(first);
141                mainFrame.setFocusable(true);
142                panel = new MyPanel();
143                panel.setBorder(BorderFactory.createLineBorder(Color.black));
144                panel.setPreferredSize(new Dimension(300,300));
145                panel.setForeground(Color.red);
146                panel.addKeyListener(listener2);
147                panel.repaint();
148                timer = new Timer(2000, new Motion());
149                timer.start();
150                mainFrame.add(panel);
151                mainFrame.setSize(500, 500);
152                mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
153                mainFrame.setVisible(true);
154        }
155        /**
156         * Main driver.
157         * @param args not used in this example
158         */
159        public static void main(String[] args) {
160                try {
161                        SwingUtilities.invokeAndWait(new SwingTimer());
162                } catch (InvocationTargetException e) {
163                        e.printStackTrace();
164                } catch (InterruptedException e) {
165                        e.printStackTrace();
166                }
167        }
168}