    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