    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.scxml.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
    35  /***
    36   * Quick GUI to demonstrate the SCXML driven stopwatch.
    37   *
    38   * Separation of UI (this class) from behavior (StopWatch class).
    39   * UI serves merely as a front to relay user initiated events to StopWatch
    40   * object, which encapsulates all the behavior of a stopwatch.
    41   * Using SCXML makes the StopWatch class simplistic, and provides a direct
    42   * route from the UML model to the runtime.
    43   *
    44   * @see StopWatch
    45   */
    46  public class StopWatchDisplay extends JFrame
    47          implements ActionListener {
    48
    49      private static final long serialVersionUID = 1L;
    50      private StopWatch stopWatch;
    51      private Image watchImage, watchIcon;
    52
    53      public StopWatchDisplay() {
    54          super("SCXML stopwatch");
    55          stopWatch = new StopWatch();
    56          setupUI();
    57      }
    58
    59      public void actionPerformed(ActionEvent e) {
    60          String command = e.getActionCommand();
    61          if (command.equals("START")) {
    62              if (start.getText().equals("Start")) {
    63                  stopWatch.fireEvent(StopWatch.EVENT_START);
    64                  start.setText("Stop");
    65                  split.setEnabled(true);
    66              } else if (start.getText().equals("Stop")) {
    67                  stopWatch.fireEvent(StopWatch.EVENT_STOP);
    68                  start.setText("Reset");
    69                  split.setEnabled(false);
    70              } else {
    71                  stopWatch.fireEvent(StopWatch.EVENT_RESET);
    72                  start.setText("Start");
    73                  split.setText("Split");
    74              }
    75          } else if (command.equals("SPLIT")) {
    76              if (split.getText().equals("Split")) {
    77                  stopWatch.fireEvent(StopWatch.EVENT_SPLIT);
    78                  split.setText("Unsplit");
    79              } else {
    80                  stopWatch.fireEvent(StopWatch.EVENT_UNSPLIT);
    81                  split.setText("Split");
    82              }
    83          }
    84      }
    85
    86      private void setupUI() {
    87          URL imageURL = this.getClass().getClassLoader().
    88              getResource("org/apache/commons/scxml/env/stopwatch.gif");
    89          URL iconURL = this.getClass().getClassLoader().
    90              getResource("org/apache/commons/scxml/env/stopwatchicon.gif");
    91          Toolkit kit = Toolkit.getDefaultToolkit();
    92          watchImage = kit.createImage(imageURL);
    93          watchIcon = kit.createImage(iconURL);
    94          WatchPanel panel = new WatchPanel();
    95          panel.setLayout(new BorderLayout());
    96          setContentPane(panel);
    97          display = new JLabel(stopWatch.getDisplay());
    98          panel.add(display, BorderLayout.PAGE_START);
    99          start = makeButton("START", "start, stop, reset", "Start");
    100         panel.add(start, BorderLayout.LINE_START);
    101         state = new JLabel();
    102         panel.add(state, BorderLayout.CENTER);
    103         split = makeButton("SPLIT", "split, unsplit", "Split");
    104         split.setEnabled(false);
    105         panel.add(split, BorderLayout.LINE_END);
    106         pack();
    107         setLocation(200,200);
    108         setIconImage(watchIcon);
    109         setResizable(false);
    110         setSize(300,125);
    111         show();
    112         setDefaultCloseOperation(EXIT_ON_CLOSE);
    113         Timer displayTimer = new Timer();
    114         displayTimer.scheduleAtFixedRate(new TimerTask() {
    115             public void run() {
    116                 display.setText(DISPLAY_PREFIX + stopWatch.getDisplay()
    117                     + DISPLAY_SUFFIX);
    118                 state.setText(STATE_PREFIX + stopWatch.getCurrentState()
    119                     + STATE_SUFFIX);
    120             }
    121         }, 100, 100);
    122     }
    123
    124     private JButton makeButton(final String actionCommand,
    125             final String toolTipText, final String altText) {
    126         JButton button = new JButton(altText);
    127         button.setActionCommand(actionCommand);
    128         button.setToolTipText(toolTipText);
    129         button.addActionListener(this);
    130         button.setOpaque(false);
    131         return button;
    132     }
    133
    134     class WatchPanel extends JPanel {
    135         private static final long serialVersionUID = 1L;
    136
    137         public void paintComponent(Graphics g) {
    138             if(watchImage != null) {
    139                 g.drawImage(watchImage,0,0,this.getWidth(),this.getHeight(),this);
    140             }
    141         }
    142     }
    143
    144     public static void main(String[] args) {
    145         StopWatchDisplay stopWatchDisplay = new StopWatchDisplay();
    146     }
    147
    148     private JLabel display, state;
    149     private JButton start, split;
    150     // spaces :: GridBagConstraints ;-)
    151     private static final String
    152         DISPLAY_PREFIX = "<html><font face=\"Courier\" color=\"maroon\"" +
    153             " size=\"10\"><b>&nbsp;&nbsp;&nbsp;",
    154         DISPLAY_SUFFIX = "</b></font></html>",
    155         STATE_PREFIX = "<html><font color=\"blue\" size=\"4\"" +
    156             ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;",
    157         STATE_SUFFIX = "</font></html>";
    158
    159 }
    160