Logo Search packages:      
Sourcecode: cacao-oj6 version File versions

AgentPanel.java

/*
 * $Id$
 *
 * Copyright 1996-2008 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
package com.sun.javatest.agent;

import java.awt.Button;
import java.awt.Choice;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Event;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Label;
import java.awt.List;
import java.awt.Panel;
import java.awt.ScrollPane;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.IOException;
import java.net.URL;
import java.util.Vector;

import com.sun.javatest.ProductInfo;
import com.sun.javatest.Status;

/**
 * A component to monitor the status of a Agent. This is normally displayed
 * in either an {@link AgentFrame} or an {@link AgentApplet}.
 */
00060 class AgentPanel extends ScrollPane 
{
    public interface MapReader {
      public abstract Map read(String name) throws IOException;
    };
      
    /**
     * Create a standard AgentPanel to control and monitor a Agent.
     *
     * @see Agent
     */
00071     public AgentPanel(ModeOptions[] modeOptions, MapReader mr) {
      mapReader = mr;
      initGUI(modeOptions);
    }

    /**
     * Set the mode of the agent.
     *
     * @arg mode  "active" or "passive"
     * @see Agent
     */
00082     public synchronized void setMode(String mode) {
      if (currAgent != null)
          throw new IllegalStateException();

      paramPanel.setMode(mode);
    }

    /**
     * Set the maximum number of requests that will be serviced at any
     * one time.
     *
     * @arg conc  the maximum number of requests
     *
     * @see Agent
     */
00097     public void setConcurrency(int conc) {
      if (currAgent != null)
          throw new IllegalStateException();

      paramPanel.setConcurrency(conc);
    }

    /**
     * Set the map file used to translate the arguments of incoming requests.
     *
     * @arg mapFile     the map file
     *
     * @see Agent#setMap
     */
00111     public void setMapFile(String mapFile) {
      if (currAgent != null)
          throw new IllegalStateException();

      paramPanel.setMapFile(mapFile);
    }

    /**
     * Set the retry delay for active agents.
     *
     * @arg delay the interval (in seconds) to wait after
     *                  a connection has been refused
     *
     * @see Agent
     */
00126     public void setRetryDelay(int delay) {
      if (currAgent != null)
          throw new IllegalStateException();

      paramPanel.setRetryDelay(delay);
    }

    /**
     * Set the number of requests remembered in the history.
     *
     * @arg limit the maximum number of requests to be remembered
     *
     * @see Agent
     */
00140     public void setHistoryLimit(int limit) {
      if (currAgent != null)
          throw new IllegalStateException();

      historyList.setMaxTasks(limit);
    }

    /**
     * Add a user observer to the agent when it is created.
     * @param userObs an observer to monitor the agent
     */
00151     public void addObserver(Agent.Observer userObs) {
      if (userObs == null)
          throw new NullPointerException();
      if (this.userObs != null)
          throw new IllegalStateException("just one observer can be registered");
      this.userObs = userObs;
    }

    /**
     * Start a agent running, based on the parameters in the panel.
     */
00162     public synchronized void start() {
      try {
          currAgent = paramPanel.createAgent();
          currAgent.addObserver(agentObs);
          if (userObs != null)
            currAgent.addObserver(userObs);

          Thread t = new Thread(currAgent, "AgentPanel worker thread");
          t.start();

          paramPanel.setEnabled(false);
          buttonPanel.setStartEnabled(false);
          buttonPanel.setStopEnabled(true);
      }
      catch (BadValue e) {
          error(e.getMessages());
      }
      catch (SecurityException e) {
          String[] msgs = {"Security Exception", e.getMessage()};
          error(msgs);
      }
      catch (ConnectionFactory.Fault e) {
          String[] msgs = {"cannot create connection", e.getMessage()};
          error(msgs);
      }
      catch (IOException e) {
          String[] msgs = {"problem reading map file", e.getMessage()};
          error(msgs);
      }
    }

    /**
     * Stop a agent running. Initially, the thread running the agent is
     * interrupted. If that doesn't work, after a short timeout, the thread
     * is stopped.  If that doesn't work, after another short timeout,
     * the thread is abandoned.
     */
00199     public synchronized void stop() {
      buttonPanel.setStopEnabled(false);
      if (currAgent != null)
          currAgent.interrupt();
      // the panel will be set idle when the agent reports (via the AgentObserver)
      // that it is finished
    }



    //-------------------------------------------------------------------

    public Dimension getPreferredSize() {
      Insets i = getInsets();
      Dimension d = deck.getPreferredSize();
      return new Dimension(i.left + d.width + i.right, i.top + d.height + i.bottom);
    }

    //-------------------------------------------------------------------

    void showTask(TaskState task) {
      mainFolder.show(taskPanel);
      taskPanel.setTask(task);
    }

    //-------------------------------------------------------------------
    //
    // The following are private methods for the GUI

    private void initGUI(ModeOptions[] modeOptions) {
      agentObs = new AgentObserver();
      deck = new Deck();
      initMainPanel(modeOptions);
      deck.add(mainPanel);
      errorPanel = new ErrorPanel();
      deck.add(errorPanel);
      helpPanel = new HelpPanel();
      deck.add(helpPanel);
      add(deck);
    }

    Component initMainPanel(ModeOptions[] modeOptions) {
      mainPanel = new Panel(new GridBagLayout());

      GridBagConstraints c = new GridBagConstraints();
      c.fill = GridBagConstraints.BOTH;
      c.gridwidth = GridBagConstraints.REMAINDER;
      c.weightx = 1;
      c.weighty = 1;

      mainFolder = new Folder();

      paramPanel = new ParamPanel(modeOptions);
      mainFolder.add("parameters", paramPanel);

      statsPanel = new StatsPanel();
      mainFolder.add("statistics", statsPanel);

      historyList = new HistoryList();
      mainFolder.add("history", historyList);

      taskPanel = new TaskPanel();
      mainFolder.add("selected task", taskPanel);

      c.insets.top = c.insets.left = c.insets.right = 10;
      mainPanel.add(mainFolder, c);

      buttonPanel = new ButtonPanel();
      c.weighty= 0;
      c.insets.bottom = 20;
      mainPanel.add(buttonPanel, c);

      return mainPanel;
    }

    private void setIdle() {
      paramPanel.setEnabled(true);
      buttonPanel.setStartEnabled(true);
      buttonPanel.setStopEnabled(false);
      currAgent = null;
      notifyAll();
    }

    private void showHelp() {
      deck.show(helpPanel);
    }

    private void error(String[] msgs) {
      for (int i = 0; i < msgs.length; i++)
          System.out.println(msgs[i]);
      errorPanel.show(msgs);
      deck.show(errorPanel);
    }

    private void ackError() {
      deck.show(mainPanel);
    }

    private static int getInt(String label, TextField field) throws BadValue {
      try {
          return Integer.parseInt(field.getText(), 10);
      }
      catch (NumberFormatException e) {
          throw new BadValue("bad value in `" + label + "' field");
      }
    }


    private MapReader mapReader;

    private Deck deck;
    private ErrorPanel errorPanel;
    private HelpPanel helpPanel;
    private Panel mainPanel;
    private Folder mainFolder;
    private ButtonPanel buttonPanel;
    private ParamPanel paramPanel;
    private StatsPanel statsPanel;
    private TaskPanel taskPanel;
    private HistoryList historyList;
    private AgentObserver agentObs;
    private Agent.Observer userObs;

    private Agent currAgent;

    private static final String[] statusCodes =
      {"PASS", "FAIL", "CHCK", "ERR ", "!RUN"};



    //-------------------------------------------------------------------



    //-------------------------------------------------------------------

    private static class TaskState
    {
      TaskState(Connection c) {
          connection = c;
      }

      Connection connection;
      int mode;
      String tag;
      String className;
      String[] args;
      Status status;

      static final int TEST = 0, COMMAND = 1, MAIN=2;
    }


    //-------------------------------------------------------------------

    private class AgentObserver implements Agent.Observer {
      public void started(Agent sl) {
          synchronized (AgentPanel.this) {
            if (sl != currAgent)
                return;
            
            historyList.removeAll();
            taskPanel.setTask(null);
            statsPanel.reset();
          }
      }
      
      public void errorOpeningConnection(Agent sl, Exception e) {
          synchronized (AgentPanel.this) {
            if (sl != currAgent)
                return;
            
            String[] msgs = {"error opening connection", e.getMessage()};
            error(msgs);
          }
      }
      
      public void finished(Agent sl) {
          synchronized (AgentPanel.this) {
            if (sl != currAgent)
                return;
            
            setIdle();
          }
      }
      
      public void openedConnection(Agent sl, Connection c) {
          synchronized (AgentPanel.this) {
            if (sl != currAgent)
                return;
            
            TaskState ts = new TaskState(c);
            historyList.addTask(ts);
            if (taskPanel.getTask() == null) 
                taskPanel.setTask(ts);
            statsPanel.startedTask(ts);
          }
      }
      
      public void execTest(Agent sl, Connection c, String tag, String className, String[] args) {
          synchronized (AgentPanel.this) {
            if (sl != currAgent)
                return;
            
            TaskState ts = historyList.getTask(c);
            ts.mode = TaskState.TEST;
            ts.tag = tag;
            ts.className = className;
            ts.args = args;
            historyList.update(ts, "EXEC", tag);
            if (ts == taskPanel.getTask())
                taskPanel.update();
          }
      }
      
      public void execCommand(Agent sl, Connection c, String tag, String className, String[] args) {
          synchronized (AgentPanel.this) {
            if (sl != currAgent)
                return;
            
            TaskState ts = historyList.getTask(c);
            ts.mode = TaskState.COMMAND;
            ts.tag = tag;
            ts.className = className;
            ts.args = args;
            historyList.update(ts, "EXEC", tag);
            if (ts == taskPanel.getTask())
                taskPanel.update();
          }
      }
      
      public void execMain(Agent sl, Connection c, String tag, String className, String[] args) {
          synchronized (AgentPanel.this) {
            if (sl != currAgent)
                return;
            
            TaskState ts = historyList.getTask(c);
            ts.mode = TaskState.MAIN;
            ts.tag = tag;
            ts.className = className;
            ts.args = args;
            historyList.update(ts, "EXEC", tag);
            if (ts == taskPanel.getTask())
                taskPanel.update();
          }
      }
      
      public void result(Agent sl, Connection c, Status r) {
          synchronized (AgentPanel.this) {
            if (sl != currAgent)
                return;
            
            TaskState ts = historyList.getTask(c);
            // don't update history list until data passed back to AgentClient OK
            // (i.e. in completed(...)
            ts.status = r;
            if (ts == taskPanel.getTask())
                taskPanel.update();
          }
      }
      
      public void exception(Agent sl, Connection c, Throwable t) {
          synchronized (AgentPanel.this) {
            if (sl != currAgent)
                return;
            
            TaskState ts = historyList.getTask(c);
            if (ts.tag == null) 
                historyList.removeTask(ts);
            else
                historyList.update(ts, "*IO*", ts.tag);
            statsPanel.finishedTask(ts, false);
          }
      }
      
      public void completed(Agent sl, Connection c) {
          synchronized (AgentPanel.this) {
            if (sl != currAgent)
                return;
            
            TaskState ts = historyList.getTask(c);
            historyList.update(ts, statusCodes[ts.status.getType()], ts.tag);
            statsPanel.finishedTask(ts, true);
          }
      }
    }

    //-------------------------------------------------------------------

    private class ButtonPanel extends Panel implements ActionListener { 
      ButtonPanel() {
          setLayout(new GridBagLayout());
          GridBagConstraints c = new GridBagConstraints();
          c.weightx = 1.0;
          
          startButton = new Button("Start");
          startButton.addActionListener(this);
          add(startButton, c);
          
          stopButton = new Button("Stop");
          stopButton.addActionListener(this);
          stopButton.setEnabled(false);
          add(stopButton, c);
          
          helpButton = new Button("Help");
          helpButton.addActionListener(this);
          add(helpButton, c);
      }

      public void actionPerformed(ActionEvent e) {
          Object src = e.getSource();
          if (src == startButton) {
            start();
          }
          else if (src == stopButton) {
            stop();
          }
          else if (src == helpButton) {
            showHelp();
          }
      }

      void setStartEnabled(boolean b) {
          startButton.setEnabled(b);
      }

      void setStopEnabled(boolean b) {
          stopButton.setEnabled(b);
      }

      private Button startButton;
      private Button stopButton;
      private Button helpButton;
    }

    //-------------------------------------------------------------------

    private class ErrorPanel extends Panel implements ActionListener {
      /**
       * Display a multi-line message in the error panel.
       *
       * @param msgs    The lines of the message to display
       */
      public synchronized void show(String[] msgs) {
          removeAll();
          
          setLayout(new GridBagLayout());
          
          GridBagConstraints c = new GridBagConstraints();
          c.gridwidth = GridBagConstraints.REMAINDER;
          c.insets = new Insets(30, 30, 0, 30); // top, left, bottom, right
          
          for (int i = 0; i < msgs.length; i++) {
            Label msg = new Label(msgs[i]);
            add(msg, c);
            c.insets.top = 0;
          }
          
          c.insets.top = 30;
          c.insets.bottom = 30;
          Button okBtn = new Button("OK");
          okBtn.addActionListener(this);
          add(okBtn, c);
          validate();
      }

      public void actionPerformed(ActionEvent e) {
          ackError();
      }
    }

    //-------------------------------------------------------------------

    private class HelpPanel extends Panel implements ActionListener {
      HelpPanel() {
          setLayout(new GridBagLayout());
          setBackground(Color.white);
          
          Panel logoPanel = new Panel(new GridBagLayout());
          GridBagConstraints lpc = new GridBagConstraints();
          lpc.gridwidth = GridBagConstraints.REMAINDER;
          lpc.weighty = 1;
          lpc.insets = new Insets(20, 20, 20, 20);
          
          Icon logoJava = createIcon("jticon.gif");
          if (logoJava != null) {
            lpc.anchor = GridBagConstraints.NORTH;
            logoPanel.add(logoJava, lpc);
          }
          
          /*
          Icon logo100pc = createIcon("100percent.gif");
          if (logo100pc != null) {
            lpc.anchor = GridBagConstraints.SOUTH;
            logoPanel.add(logo100pc, lpc);
          }
          */

          GridBagConstraints lrc = new GridBagConstraints();
          lrc.weighty = 1;
          lrc.fill = GridBagConstraints.BOTH;
          add(logoPanel, lrc);

          GridBagConstraints c = new GridBagConstraints();
          c.gridwidth = GridBagConstraints.REMAINDER;
          Panel infoPanel = new Panel(new GridBagLayout());
          Label nameLabel = new Label("JT Harness Agent");
          nameLabel.setFont(new Font("SansSerif", Font.BOLD, 32));
          infoPanel.add(nameLabel, c);

          Label versionLabel = new Label(ProductInfo.getVersion());
          versionLabel.setFont(new Font("SansSerif", Font.BOLD, 24));
          infoPanel.add(versionLabel, c);
          
          Label copyLabel1 = new Label("Copyright (c) 1996-2008 Sun Microsystems, Inc.  Use is subject to license terms.");
          infoPanel.add(copyLabel1, c);
        
          Label copyLabel2 = new Label("Use is subject to license terms.");
          infoPanel.add(copyLabel2, c);
          
          String helpText = 
            "  For full information on using the\n" +
            "  JT Harness Agent, please refer to the\n" +
            "     JT Harness User's Guide\n" +
            "  and to the documentation for the\n" +
            "  test suite you are using.\n";
            
          TextArea helpArea = new TextArea(helpText, 5, 35, TextArea.SCROLLBARS_NONE);
          helpArea.setEditable(false);
          c.weightx = 1;
          c.weighty = 1;
          infoPanel.add(helpArea, c);

          Button okBtn = new Button("OK");
          okBtn.addActionListener(this);
          c.weightx = 0;
          c.weighty = 0;
          c.insets.bottom = 10;
          infoPanel.add(okBtn, c);

          lrc.weightx = 1;
          add(infoPanel, lrc);
      }

      private Icon createIcon(String name)  {
          try {
            URL url = getClass().getResource(name);
            if (url == null) 
                return null;
            Icon icon = new Icon(url);
            return icon;
          }
          catch (RuntimeException e) {
            return null;
          }
          catch (Error e) {
            return null;
          }
            

      }

      public void actionPerformed(ActionEvent e) {
          ackError(); // hmm, not the most obvious name, but it will work
      }
    }

    //-------------------------------------------------------------------

    private class HistoryList extends List implements ItemListener {
      HistoryList() {
          super(5, false);
          super.addItemListener(this);
      }

      public synchronized void addTask(TaskState task) {
          if (tasks.size() >= maxTasks) {
            for (int i = 0; i < tasks.size(); i++) {
                String s = (String) getItem(i);
                // skip over active tasks that will be updated later
                if (s.startsWith("CONN") || s.startsWith("EXEC"))
                  continue;

                tasks.removeElementAt(i);
                super.remove(i);
            }
          }
          
          tasks.addElement(task);
          super.add("CONN " + task.connection.getName());
      }

      public synchronized TaskState getTask(Connection c) {
          for (int i = 0; i < tasks.size(); i++) {
            TaskState ts = (TaskState)(tasks.elementAt(i));
            if (ts.connection == c) 
                return ts;
          }
          throw new Error("AgentPanel.HistoryList.getTask: can't find socket");
      }

      public synchronized TaskState getSelectedTask() {
          return (TaskState)(tasks.elementAt(super.getSelectedIndex()));
      }

      public synchronized void removeAll() {
          tasks.setSize(0);
          if (getItemCount() > 0)
            // calling List.removeAll on empty list generates motif
                // warning message
            super.removeAll();
      }

      public synchronized void removeTask(TaskState task) {
          int index = tasks.indexOf(task);
          tasks.removeElementAt(index);
          super.remove(index);
      }

      public synchronized void setMaxTasks(int n) {
          maxTasks = n;
      }

      public synchronized void update(TaskState task, String state, String detail) {
          super.replaceItem(getKey(state, detail), tasks.indexOf(task));
      }

      public void itemStateChanged(ItemEvent e) {
          Object src = e.getItemSelectable();
          if (src == this) {
            switch (e.getStateChange()) {
            case ItemEvent.SELECTED:
                showTask(getSelectedTask());
                break;
            case Event.LIST_DESELECT:
                showTask(null);
                break;
            }
          }
      }

      private String getKey(String state, String detail) {
          return (state + " " + detail);
      }

      private int maxTasks = 10;
      private Vector tasks = new Vector();
    }


    //-------------------------------------------------------------------

    private class ParamPanel extends Panel  implements ItemListener {
      ParamPanel(ModeOptions[] modeOptions) {
          setLayout(new GridBagLayout());

          GridBagConstraints lc = new GridBagConstraints();
          lc.anchor = GridBagConstraints.EAST;
          
          GridBagConstraints fc = new GridBagConstraints();
          fc.fill = GridBagConstraints.HORIZONTAL;
          fc.gridwidth = GridBagConstraints.REMAINDER;
          fc.weightx = 1;
          fc.weighty = 0;
          
          
          // First row: mode choice, and the mode options deck
          add(new Label("mode:"), lc);
          
          modeChoice = new Choice();
          modeDeck = new Deck();

          for (int i = 0; i < modeOptions.length; i++) {
            ModeOptions m = modeOptions[i];
            modeChoice.addItem(m.getModeName());
            modeDeck.add(m);
          }

          // choices added later by modeOption objects
          modeChoice.addItemListener(this);
          fc.weightx = 0;
          fc.gridwidth = 1;
          add(modeChoice, fc);

          fc.insets.left = 20;
          fc.fill = GridBagConstraints.HORIZONTAL;
          fc.gridwidth = GridBagConstraints.REMAINDER;
          fc.weightx = 1;
          add(modeDeck, fc);
          fc.insets.left = 0;
          
          // Second row: the optional map file field
          add(new Label("map:"), lc);
          
          mapFileField = new TextField();
          add(mapFileField, fc);
          
          // Third row: the concurrency field
          Label concurrencyLabel = new Label("concurrency:");
          add(concurrencyLabel, lc);
          
          concurrencyField = new TextField("1", 3);
          fc.gridwidth = 1;
          fc.weightx = 0;
          add(concurrencyField, fc);
          
          fc.gridwidth = GridBagConstraints.REMAINDER;
          fc.weightx = 1;
          add(new Label(), fc); // dummy filler
          
      }
      
      public void setEnabled(boolean b) {
          modeChoice.setEnabled(b);
          for (int i = 0; i < modeDeck.getComponentCount(); i++) {
            ModeOptions o = (ModeOptions)(modeDeck.getComponent(i));
            o.setEnabled(b);
          }
          mapFileField.setEnabled(b);
          concurrencyField.setEnabled(b);
      }

      public void setMode(String modeName) {
          modeChoice.select(modeName);
          for (int i = 0; i < modeDeck.getComponentCount(); i++) {
            ModeOptions m = (ModeOptions)(modeDeck.getComponent(i));
            if (modeName.equals(m.getModeName())) {
                modeDeck.show(m);
                return;
            }
          }
      }

      public void setConcurrency(int conc) {
          concurrencyField.setText(Integer.toString(conc));
      }

      public void setMapFile(String mapFile) {
          mapFileField.setText(mapFile);
      }

      public void setRetryDelay(int delay) {
          retryDelay = delay; // not available in GUI
      }

      public Agent createAgent() throws BadValue, ConnectionFactory.Fault, IOException {
          // should consider catching IllegalArgumentException in here
          // and IllegalState?
          Map map = mapReader.read(mapFileField.getText());
          int concurrency = getInt("concurrency", concurrencyField);
          if (concurrency < 0)
            throw new BadValue("bad value for `concurrency field': " + concurrency);

          ModeOptions mo = (ModeOptions)(modeDeck.getCurrentCard());
          ConnectionFactory cf = mo.createConnectionFactory(concurrency);
          Agent agent = new Agent(cf, concurrency);

          if (retryDelay > 0)
            agent.setRetryDelay(retryDelay);

          agent.setMap(map);

          return agent;
      }

      private Deck createModeDeck(Choice modeChoice) {
          return deck;
      }

      public void itemStateChanged(ItemEvent e) {
          Object src = e.getItemSelectable();
          if (src == modeChoice) {
            String modeName = ((Choice)src).getSelectedItem();
            for (int i = 0; i < modeDeck.getComponentCount(); i++) {
                ModeOptions m = (ModeOptions)(modeDeck.getComponent(i));
                if (modeName.equals(m.getModeName())) {
                  modeDeck.show(m);
                  return;
                }
            }
          }
      }

      private Choice modeChoice;
      private Deck modeDeck;
      private TextField mapFileField;
      private Label concurrencyLabel;
      private TextField concurrencyField;
      private int retryDelay; // not currently in GUI
    }


    //-------------------------------------------------------------------

    private class StatsPanel extends Panel {
      StatsPanel() {
          setLayout(new GridBagLayout());

          GridBagConstraints lc = new GridBagConstraints();
          lc.anchor = GridBagConstraints.EAST;
          GridBagConstraints fc = new GridBagConstraints();
          fc.weightx = 1;
          fc.anchor = GridBagConstraints.WEST;
          fc.gridwidth = GridBagConstraints.REMAINDER;

          activeField = addField("currently active:", lc, fc);
          statusFields[Status.PASSED] = addField("passed:", lc, fc);
          statusFields[Status.FAILED] = addField("failed:", lc, fc);
          statusFields[Status.ERROR] = addField("error:", lc, fc);
          statusFields[Status.NOT_RUN] = addField("not run:", lc, fc);
          exceptionsField = addField("exceptions:", lc, fc);
      }
      
      void reset() {
          tasks.setSize(0);
          for (int i = 0; i < statusCounts.length; i++)
            statusCounts[i] = 0;
          exceptionsCount = 0;
          activeField.setText("0");
          for (int i = 0; i < statusCounts.length; i++)
            statusFields[i].setText("0");
          exceptionsField.setText("0");
      }

      void startedTask(TaskState task) {
          tasks.addElement(task);
          activeField.setText(String.valueOf(tasks.size()));
      }
      
      void finishedTask(TaskState task, boolean completedNormally) {
          int index = tasks.indexOf(task);
          if (index == -1)
            return;
          tasks.removeElementAt(index);
          activeField.setText(String.valueOf(tasks.size()));
          if (!completedNormally)
            exceptionsField.setText(String.valueOf(++exceptionsCount));
          if (task.status != null) {
            int t = task.status.getType();
            statusFields[t].setText(String.valueOf(++statusCounts[t]));
          }
      }

      private TextField addField(String name, GridBagConstraints lc, GridBagConstraints fc) {
          add(new Label(name), lc);
          TextField f = new TextField("0", 10);
          f.setEditable(false);
          add(f, fc);
          return f;
      }


      private Vector tasks = new Vector();

      private int[] statusCounts = new int[Status.NUM_STATES];
      private int exceptionsCount;
      
      private TextField activeField;
      private TextField[] statusFields = new TextField[Status.NUM_STATES];
      private TextField exceptionsField;
    }

    //-------------------------------------------------------------------

    private class TaskPanel extends Panel {
      TaskPanel() {
          setLayout(new GridBagLayout());

          GridBagConstraints lc = new GridBagConstraints();
          lc.anchor = GridBagConstraints.EAST;
          GridBagConstraints fc = new GridBagConstraints();
          fc.weightx = 1;
          fc.fill = GridBagConstraints.HORIZONTAL;
          fc.gridwidth = GridBagConstraints.REMAINDER;
          
          Label clientLabel = new Label("client:");
          add(clientLabel, lc);
          
          clientField = new Label("");
          add(clientField, fc);
          
          Label tagLabel = new Label("request:");
          add(tagLabel, lc);
          
          tagField = new Label("");
          add(tagField, fc);
          
          Label classLabel = new Label("class:");
          add(classLabel, lc);
          
          classField = new Label("");
          add(classField, fc);
          
          Label argsLabel = new Label("args:");
          add(argsLabel, lc);
          
          argsField = new TextField("");
          // make it a text field to support scrolling of very long fields
          argsField.setEditable(false);
          add(argsField, fc);
          
          Label resultLabel = new Label("result:");
          add(resultLabel, lc);
          
          resultField = new Label("");
          add(resultField, fc);
      }

      TaskState getTask() {
          return task;
      }

      void setTask(TaskState ts) {
          task = ts;
          update();
      }

      void update() {
          if (task == null) {
            clientField.setText("");
            tagField.setText("");
            classField.setText("");
            argsField.setText("");
            resultField.setText("");
          } else {
            clientField.setText(task.connection.getName());
            tagField.setText(task.tag);
            classField.setText(task.className);
            String a = "";
            if (task.args != null) {
                for (int i = 0; i < task.args.length; i++)
                  a += task.args[i] + " ";
            }
            argsField.setText(a);
            if (task.status == null)
                resultField.setText("");
            else
                resultField.setText(task.status.toString());
          }
      }

      private TaskState task;

      private Label clientField;
      private Label tagField;
      private Label classField;
      private TextField argsField;
      private Label resultField;
    }
}

Generated by  Doxygen 1.6.0   Back to index