001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.commons.scxml.env;
018:
019: import java.awt.BorderLayout;
020: import java.awt.Graphics;
021: import java.awt.Image;
022: import java.awt.Toolkit;
023: import java.awt.event.ActionEvent;
024: import java.awt.event.ActionListener;
025: import java.net.URL;
026: import java.util.Timer;
027: import java.util.TimerTask;
028:
029: import javax.swing.JButton;
030: import javax.swing.JFrame;
031: import javax.swing.JLabel;
032: import javax.swing.JPanel;
033:
034: /**
035: * Quick GUI to demonstrate the SCXML driven stopwatch.
036: *
037: * Separation of UI (this class) from behavior (StopWatch class).
038: * UI serves merely as a front to relay user initiated events to StopWatch
039: * object, which encapsulates all the behavior of a stopwatch.
040: * Using SCXML makes the StopWatch class simplistic, and provides a direct
041: * route from the UML model to the runtime.
042: *
043: * @see StopWatch
044: */
045: public class StopWatchDisplay extends JFrame implements ActionListener {
046:
047: private static final long serialVersionUID = 1L;
048: private StopWatch stopWatch;
049: private Image watchImage, watchIcon;
050:
051: public StopWatchDisplay() {
052: super ("SCXML stopwatch");
053: stopWatch = new StopWatch();
054: setupUI();
055: }
056:
057: public void actionPerformed(ActionEvent e) {
058: String command = e.getActionCommand();
059: if (command.equals("START")) {
060: if (start.getText().equals("Start")) {
061: stopWatch.fireEvent(StopWatch.EVENT_START);
062: start.setText("Stop");
063: split.setEnabled(true);
064: } else if (start.getText().equals("Stop")) {
065: stopWatch.fireEvent(StopWatch.EVENT_STOP);
066: start.setText("Reset");
067: split.setEnabled(false);
068: } else {
069: stopWatch.fireEvent(StopWatch.EVENT_RESET);
070: start.setText("Start");
071: split.setText("Split");
072: }
073: } else if (command.equals("SPLIT")) {
074: if (split.getText().equals("Split")) {
075: stopWatch.fireEvent(StopWatch.EVENT_SPLIT);
076: split.setText("Unsplit");
077: } else {
078: stopWatch.fireEvent(StopWatch.EVENT_UNSPLIT);
079: split.setText("Split");
080: }
081: }
082: }
083:
084: private void setupUI() {
085: URL imageURL = this .getClass().getClassLoader().getResource(
086: "org/apache/commons/scxml/env/stopwatch.gif");
087: URL iconURL = this .getClass().getClassLoader().getResource(
088: "org/apache/commons/scxml/env/stopwatchicon.gif");
089: Toolkit kit = Toolkit.getDefaultToolkit();
090: watchImage = kit.createImage(imageURL);
091: watchIcon = kit.createImage(iconURL);
092: WatchPanel panel = new WatchPanel();
093: panel.setLayout(new BorderLayout());
094: setContentPane(panel);
095: display = new JLabel(stopWatch.getDisplay());
096: panel.add(display, BorderLayout.PAGE_START);
097: start = makeButton("START", "start, stop, reset", "Start");
098: panel.add(start, BorderLayout.LINE_START);
099: 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
117: + stopWatch.getCurrentState() + 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: private static final long serialVersionUID = 1L;
134:
135: public void paintComponent(Graphics g) {
136: if (watchImage != null) {
137: g.drawImage(watchImage, 0, 0, this .getWidth(), this
138: .getHeight(), this );
139: }
140: }
141: }
142:
143: public static void main(String[] args) {
144: StopWatchDisplay stopWatchDisplay = new StopWatchDisplay();
145: }
146:
147: private JLabel display, state;
148: private JButton start, split;
149: // spaces :: GridBagConstraints ;-)
150: private static final String DISPLAY_PREFIX = "<html><font face=\"Courier\" color=\"maroon\""
151: + " size=\"10\"><b> ",
152: DISPLAY_SUFFIX = "</b></font></html>",
153: STATE_PREFIX = "<html><font color=\"blue\" size=\"4\""
154: + "> ",
155: STATE_SUFFIX = "</font></html>";
156:
157: }
|