1   /*
2    * Copyright 2006 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.apache.commons.scxml.env;
17  
18  import java.awt.BorderLayout;
19  import java.awt.Graphics;
20  import java.awt.Image;
21  import java.awt.Toolkit;
22  import java.awt.event.ActionEvent;
23  import java.awt.event.ActionListener;
24  import java.net.URL;
25  import java.util.Timer;
26  import java.util.TimerTask;
27  
28  import javax.swing.JButton;
29  import javax.swing.JFrame;
30  import javax.swing.JLabel;
31  import javax.swing.JPanel;
32  
33  
34  /***
35   * Quick GUI to demonstrate the SCXML driven stopwatch.
36   *
37   * Separation of UI (this class) from behavior (StopWatch class).
38   * UI serves merely as a front to relay user initiated events to StopWatch
39   * object, which encapsulates all the behavior of a stopwatch.
40   * Using SCXML makes the StopWatch class simplistic, and provides a direct
41   * route from the UML model to the runtime.
42   *
43   * @see StopWatch
44   */
45  public class StopWatchDisplay extends JFrame
46          implements ActionListener {
47  
48      private StopWatch stopWatch;
49      private Image watchImage, watchIcon;
50  
51      public StopWatchDisplay() {
52          super("SCXML stopwatch");
53          stopWatch = new StopWatch();
54          setupUI();
55      }
56  
57      public void actionPerformed(ActionEvent e) {
58          String command = e.getActionCommand();
59          if (command.equals("START")) {
60              if (start.getText().equals("Start")) {
61                  stopWatch.fireEvent(StopWatch.EVENT_START);
62                  start.setText("Stop");
63                  split.setEnabled(true);
64              } else if (start.getText().equals("Stop")) {
65                  stopWatch.fireEvent(StopWatch.EVENT_STOP);
66                  start.setText("Reset");
67                  split.setEnabled(false);
68              } else {
69                  stopWatch.fireEvent(StopWatch.EVENT_RESET);
70                  start.setText("Start");
71                  split.setText("Split");
72              }
73          } else if (command.equals("SPLIT")) {
74              if (split.getText().equals("Split")) {
75                  stopWatch.fireEvent(StopWatch.EVENT_SPLIT);
76                  split.setText("Unsplit");
77              } else {
78                  stopWatch.fireEvent(StopWatch.EVENT_UNSPLIT);
79                  split.setText("Split");
80              }
81          }
82      }
83  
84      private void setupUI() {
85          URL imageURL = this.getClass().getClassLoader().
86              getResource("org/apache/commons/scxml/env/stopwatch.gif");
87          URL iconURL = this.getClass().getClassLoader().
88              getResource("org/apache/commons/scxml/env/stopwatchicon.gif");
89          Toolkit kit = Toolkit.getDefaultToolkit();
90          watchImage = kit.createImage(imageURL);
91          watchIcon = kit.createImage(iconURL);
92          WatchPanel panel = new WatchPanel();
93          panel.setLayout(new BorderLayout());
94          setContentPane(panel);
95          display = new JLabel(stopWatch.getDisplay());
96          panel.add(display, BorderLayout.PAGE_START);
97          start = makeButton("START", "start, stop, reset", "Start");
98          panel.add(start, BorderLayout.LINE_START);
99          state = new JLabel();
100         panel.add(state, BorderLayout.CENTER);
101         split = makeButton("SPLIT", "split, unsplit", "Split");
102         split.setEnabled(false);
103         panel.add(split, BorderLayout.LINE_END);
104         pack();
105         setLocation(200,200);
106         setIconImage(watchIcon);
107         setResizable(false);
108         setSize(300,125);
109         show();
110         setDefaultCloseOperation(EXIT_ON_CLOSE);
111         Timer displayTimer = new Timer();
112         displayTimer.scheduleAtFixedRate(new TimerTask() {
113             public void run() {
114                 display.setText(DISPLAY_PREFIX + stopWatch.getDisplay()
115                     + DISPLAY_SUFFIX);
116                 state.setText(STATE_PREFIX + stopWatch.getCurrentState()
117                     + STATE_SUFFIX);
118             }
119         }, 100, 100);
120     }
121 
122     private JButton makeButton(final String actionCommand,
123             final String toolTipText, final String altText) {
124         JButton button = new JButton(altText);
125         button.setActionCommand(actionCommand);
126         button.setToolTipText(toolTipText);
127         button.addActionListener(this);
128         button.setOpaque(false);
129         return button;
130     }
131 
132     class WatchPanel extends JPanel {
133         public void paintComponent(Graphics g) {
134             if(watchImage != null) {
135                 g.drawImage(watchImage,0,0,this.getWidth(),this.getHeight(),this);
136             }
137         }
138     }
139 
140     public static void main(String[] args) {
141         StopWatchDisplay stopWatchDisplay = new StopWatchDisplay();
142     }
143 
144     private JLabel display, state;
145     private JButton start, split;
146     // spaces :: GridBagConstraints ;-)
147     private static final String
148         DISPLAY_PREFIX = "<html><font face=\"Courier\" color=\"maroon\"" +
149             " size=\"10\"><b>&nbsp;&nbsp;&nbsp;",
150         DISPLAY_SUFFIX = "</b></font></html>",
151         STATE_PREFIX = "<html><font color=\"blue\" size=\"4\"" +
152             ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;",
153         STATE_SUFFIX = "</font></html>";
154 
155 }
156