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