edu.clemson.cs.nestbed.client.gui.MoteDetailFrame.java Source code

Java tutorial

Introduction

Here is the source code for edu.clemson.cs.nestbed.client.gui.MoteDetailFrame.java

Source

/* $Id$ */
/*
 * MoteDetailFrame.java
 *
 * Network Embedded Sensor Testbed (NESTbed)
 *
 * Copyright (C) 2006-2007
 * Dependable Systems Research Group
 * School of Computing
 * Clemson University
 * Andrew R. Dalton and Jason O. Hallstrom
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program 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 for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the
 *
 * Free Software Foundation, Inc.
 * 51 Franklin Street, Fifth Floor
 * Boston, MA  02110-1301, USA.
 */
package edu.clemson.cs.nestbed.client.gui;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTable;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.border.TitledBorder;
import javax.swing.table.AbstractTableModel;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import edu.clemson.cs.nestbed.common.management.configuration.ProgramMessageSymbolManager;
import edu.clemson.cs.nestbed.common.management.configuration.ProgramSymbolManager;
import edu.clemson.cs.nestbed.common.management.configuration.ProgramProfilingMessageSymbolManager;
import edu.clemson.cs.nestbed.common.management.configuration.ProgramProfilingSymbolManager;
import edu.clemson.cs.nestbed.common.management.profiling.NucleusManager;
import edu.clemson.cs.nestbed.common.model.Mote;
import edu.clemson.cs.nestbed.common.model.MoteTestbedAssignment;
import edu.clemson.cs.nestbed.common.model.MoteType;
import edu.clemson.cs.nestbed.common.model.Program;
import edu.clemson.cs.nestbed.common.model.ProgramProfilingSymbol;
import edu.clemson.cs.nestbed.common.model.ProgramProfilingMessageSymbol;
import edu.clemson.cs.nestbed.common.model.ProgramMessageSymbol;
import edu.clemson.cs.nestbed.common.model.ProgramSymbol;

public class MoteDetailFrame extends JFrame {
    private final static Log log = LogFactory.getLog(MoteDetailFrame.class);

    private final static String RMI_BASE_URL;
    private final static int WINDOW_WIDTH = 400;
    private final static int WINDOW_HEIGHT = 500;

    static {
        RMI_BASE_URL = System.getProperty("testbed.rmi.baseurl");
    }

    private int configID;
    private MoteTestbedAssignment mtba;
    private Mote mote;
    private MoteType moteType;
    private Program program;

    private ProgramSymbolManager programSymbolManager;
    private ProgramProfilingMessageSymbolManager progProfMsgSymManager;
    private ProgramProfilingSymbolManager profSymManager;
    private ProgramMessageSymbolManager progMsgSymManager;
    private NucleusManager nucleusManager;

    private List<ProgramProfilingSymbol> profilingSymbols;
    private List<ProgramProfilingMessageSymbol> progProfMsgSymbols;
    private Map<Integer, ProgramSymbol> programSymbols;
    private Map<Integer, ProgramMessageSymbol> programMessageSymbols;

    private JTextField addressField = new JTextField();
    private JTextField locationField = new JTextField();
    private JTextField serialIdField = new JTextField();
    private JTextField typeField = new JTextField();
    private JTextField totalRomField = new JTextField();
    private JTextField totalRamField = new JTextField();
    private JTextField totalEepromField = new JTextField();
    private JTextField programNameField = new JTextField();
    private JTextField programDescField = new JTextField();

    private JTable symbolTable = new JTable();
    private JTable messageTable = new JTable();

    public MoteDetailFrame(int configID, MoteTestbedAssignment mtba, Mote mote, MoteType moteType, Program program)
            throws RemoteException, NotBoundException, MalformedURLException, ClassNotFoundException {
        super("Mote " + mtba.getMoteAddress() + " - (" + mote.getMoteSerialID() + ")");

        this.mtba = mtba;
        this.mote = mote;
        this.moteType = moteType;
        this.program = program;

        lookupRemoteManagers();
        profilingSymbols = profSymManager.getProgramProfilingSymbols(configID, program.getID());
        progProfMsgSymbols = progProfMsgSymManager.getProgramProfilingMessageSymbols(configID, program.getID());

        programSymbols = new HashMap<Integer, ProgramSymbol>();
        List<ProgramSymbol> ps = programSymbolManager.getProgramSymbols(program.getID());
        for (ProgramSymbol i : ps) {
            programSymbols.put(i.getID(), i);
        }

        programMessageSymbols = new HashMap<Integer, ProgramMessageSymbol>();
        List<ProgramMessageSymbol> pms = progMsgSymManager.getProgramMessageSymbols(program.getID());

        for (ProgramMessageSymbol i : pms) {
            programMessageSymbols.put(i.getID(), i);
        }

        symbolTable.addMouseListener(new ProfilingTableMouseListener());
        symbolTable.setModel(new ProfilingTableModel());
        symbolTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        messageTable.addMouseListener(new MessageTableMouseListener());
        messageTable.setModel(new MessageTableModel());
        messageTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
        setJMenuBar(buildMenuBar());

        Container c = this.getContentPane();
        c.setLayout(new BorderLayout());

        c.add(buildMotePanel(), BorderLayout.NORTH);
        c.add(buildBottomPane(), BorderLayout.CENTER);
    }

    private final void lookupRemoteManagers() throws RemoteException, NotBoundException, MalformedURLException {

        profSymManager = (ProgramProfilingSymbolManager) Naming
                .lookup(RMI_BASE_URL + "ProgramProfilingSymbolManager");

        programSymbolManager = (ProgramSymbolManager) Naming.lookup(RMI_BASE_URL + "ProgramSymbolManager");

        progMsgSymManager = (ProgramMessageSymbolManager) Naming
                .lookup(RMI_BASE_URL + "ProgramMessageSymbolManager");

        progProfMsgSymManager = (ProgramProfilingMessageSymbolManager) Naming
                .lookup(RMI_BASE_URL + "ProgramProfilingMessageSymbolManager");

        nucleusManager = (NucleusManager) Naming.lookup(RMI_BASE_URL + "NucleusManager");
    }

    private JMenuBar buildMenuBar() {
        JMenuBar menuBar = new JMenuBar();

        menuBar.add(buildFileMenu());

        return menuBar;
    }

    private JMenu buildFileMenu() {
        JMenu menu = new JMenu("File");
        JMenuItem close = new JMenuItem("Close");

        close.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                MoteDetailFrame.this.setVisible(false);
            }
        });
        menu.add(close);

        return menu;
    }

    private JPanel buildMotePanel() {
        JPanel panel = new JPanel();
        panel.setBorder(new TitledBorder("Mote Information"));
        panel.setLayout(new BorderLayout());

        panel.add(buildMoteLabelPanel(), BorderLayout.WEST);
        panel.add(buildMoteFieldPanel(), BorderLayout.CENTER);

        return panel;
    }

    private JPanel buildMoteLabelPanel() {
        JPanel panel = new JPanel();
        int rows = 10;
        int cols = 1;

        panel.setLayout(new GridLayout(rows, cols));
        panel.add(new JLabel("Address:  "));
        panel.add(new JLabel("Location:  "));
        panel.add(new JLabel("Serial ID: "));
        panel.add(new JLabel("Type: "));
        panel.add(new JLabel("Total ROM: "));
        panel.add(new JLabel("Total RAM: "));
        panel.add(new JLabel("Total EEPROM: "));
        panel.add(new JLabel(""));
        panel.add(new JLabel("Program Name: "));
        panel.add(new JLabel("Program Description:  "));

        return panel;
    }

    private JPanel buildMoteFieldPanel() {
        JPanel panel = new JPanel();
        int rows = 10;
        int cols = 1;

        panel.setLayout(new GridLayout(rows, cols));

        addressField.setEditable(false);
        locationField.setEditable(false);
        serialIdField.setEditable(false);
        typeField.setEditable(false);
        totalRomField.setEditable(false);
        totalRamField.setEditable(false);
        totalEepromField.setEditable(false);
        programNameField.setEditable(false);
        programDescField.setEditable(false);

        panel.add(addressField);
        panel.add(locationField);
        panel.add(serialIdField);
        panel.add(typeField);
        panel.add(totalRomField);
        panel.add(totalRamField);
        panel.add(totalEepromField);
        panel.add(new JLabel(""));
        panel.add(programNameField);
        panel.add(programDescField);

        addressField.setText(Integer.toString(mtba.getMoteAddress()));
        locationField.setText("(" + mtba.getMoteLocationY() + ", " + mtba.getMoteLocationX() + ")");
        serialIdField.setText(mote.getMoteSerialID());
        typeField.setText(moteType.getName());
        totalRomField.setText(Integer.toString(moteType.getTotalROM()));
        totalRamField.setText(Integer.toString(moteType.getTotalRAM()));
        totalEepromField.setText(Integer.toString(moteType.getTotalEEPROM()));
        programNameField.setText(program.getName());
        programDescField.setText(program.getDescription());

        return panel;
    }

    private JPanel buildBottomPane() {
        JPanel panel = new JPanel();
        JTabbedPane tabbedPane = new JTabbedPane();

        panel.setLayout(new BorderLayout());
        panel.add(tabbedPane, BorderLayout.CENTER);

        tabbedPane.add("Symbol Profiling", new JScrollPane(symbolTable));
        tabbedPane.add("Message Profiling", new JScrollPane(messageTable));

        return panel;
    }

    protected class ProfilingTableModel extends AbstractTableModel {
        private final static int MODULE_CELL = 0;
        private final static int SYMBOL_CELL = MODULE_CELL + 1;
        private final static int VALUE_CELL = SYMBOL_CELL + 1;
        private final static int NUM_COLS = VALUE_CELL + 1;

        private ProgramProfilingSymbol[] symbols;
        private Integer[] values;

        public ProfilingTableModel() {
            symbols = profilingSymbols.toArray(new ProgramProfilingSymbol[profilingSymbols.size()]);
            values = new Integer[symbols.length];
        }

        public int getColumnCount() {
            return NUM_COLS;
        }

        public int getRowCount() {
            return symbols.length;
        }

        public String getColumnName(int col) {
            String name = null;

            switch (col) {
            case MODULE_CELL:
                name = "Module";
                break;
            case SYMBOL_CELL:
                name = "Symbol";
                break;
            case VALUE_CELL:
                name = "Last Known Value";
                break;
            }

            return name;
        }

        public Object getValueAt(int row, int col) {
            Object value = null;

            switch (col) {
            case MODULE_CELL:
                value = programSymbols.get(symbols[row].getProgramSymbolID()).getModule();
                break;
            case SYMBOL_CELL:
                value = programSymbols.get(symbols[row].getProgramSymbolID()).getSymbol();
                break;
            case VALUE_CELL:
                value = (values[row] == null) ? "" : values[row];
                break;
            }

            return value;
        }

        public Class getColumnClass(int col) {
            Class columnClass = Object.class;

            switch (col) {
            case MODULE_CELL:
                columnClass = String.class;
                break;
            case SYMBOL_CELL:
                columnClass = String.class;
                break;
            case VALUE_CELL:
                columnClass = Integer.class;
                break;
            }
            return columnClass;
        }

        public boolean isCellEditable(int row, int col) {
            return (col == VALUE_CELL);
        }

        public void setValueAt(Object aValue, int row, int col) {
            log.debug("User-invoked setValueAt, row: " + row + ", value: " + aValue);
            try {
                ProgramProfilingSymbol profilingSymbol = symbols[row];

                if (profilingSymbol != null) {
                    int value = ((Integer) aValue).intValue();
                    if (nucleusManager.setSymbol(value, profilingSymbol.getID(), program.getSourcePath(),
                            moteType.getTosPlatform(), mote.getMoteSerialID())) {
                        values[row] = (Integer) aValue;
                    }
                    symbolTable.repaint();
                }
            } catch (Exception ex) {
                log.error("Exception", ex);
                ClientUtils.displayErrorMessage(MoteDetailFrame.this, ex);
            }
        }

        public void setValue(Integer value, int row) {
            log.debug("Setting value at row " + row + " to " + value);
            values[row] = value;
            symbolTable.repaint();
        }

        public ProgramProfilingSymbol getProfilingSymbol(int row) {
            return (row != symbols.length) ? symbols[row] : null;
        }
    }

    protected class MessageTableModel extends AbstractTableModel {
        private int NUM_COLS = 1;

        private ProgramProfilingMessageSymbol[] symbols;

        public MessageTableModel() {
            symbols = progProfMsgSymbols.toArray(new ProgramProfilingMessageSymbol[progProfMsgSymbols.size()]);
        }

        public int getColumnCount() {
            return NUM_COLS;
        }

        public int getRowCount() {
            return symbols.length;
        }

        public String getColumnName(int col) {
            String name = null;

            if (col == 0) {
                name = "Message";
            }

            return name;
        }

        public Object getValueAt(int row, int col) {
            Object value = null;

            if (col == 0) {
                value = programMessageSymbols.get(symbols[row].getProgramMessageSymbolID()).getName();
            }

            return value;
        }

        public ProgramProfilingMessageSymbol getProfilingMessageSymbol(int row) {
            return (row != symbols.length) ? symbols[row] : null;
        }
    }

    protected class ProfilingTableMouseListener extends MouseAdapter {
        private JPopupMenu menu;
        private JMenuItem title;
        private JMenuItem queryValue;

        public ProfilingTableMouseListener() {
            menu = new JPopupMenu();
            title = new JMenuItem();

            title.setEnabled(false);
            menu.add(title);
            menu.add(new JSeparator());

            queryValue = new JMenuItem("Query Symbol Value");
            queryValue.addActionListener(new QuerySymbolActionListener());

            menu.add(queryValue);
        }

        public void mouseClicked(MouseEvent e) {
            int row = symbolTable.getSelectedRow();

            if (SwingUtilities.isRightMouseButton(e) && (row != -1)) {
                ProfilingTableModel model;
                ProgramProfilingSymbol profilingSymbol;

                model = (ProfilingTableModel) symbolTable.getModel();
                profilingSymbol = model.getProfilingSymbol(row);

                title.setText(model.getValueAt(row, 0).toString());
                menu.show(symbolTable, e.getX(), e.getY());
            }
        }
    }

    protected class MessageTableMouseListener extends MouseAdapter {
        private JPopupMenu menu;
        private JMenuItem title;
        private JMenuItem viewMsgMonitor;

        public MessageTableMouseListener() {
            menu = new JPopupMenu();
            title = new JMenuItem();
            viewMsgMonitor = new JMenuItem("View Message Monitor");
            viewMsgMonitor.addActionListener(new MessageMonitorActionListener());

            title.setEnabled(false);
            menu.add(title);
            menu.add(new JSeparator());
            menu.add(viewMsgMonitor);
        }

        public void mouseClicked(MouseEvent e) {
            int row = messageTable.getSelectedRow();

            if (SwingUtilities.isRightMouseButton(e) && (row != -1)) {
                MessageTableModel model;
                ProgramProfilingMessageSymbol profMsgSymbol;

                model = (MessageTableModel) messageTable.getModel();
                profMsgSymbol = model.getProfilingMessageSymbol(row);

                title.setText(model.getValueAt(row, 0).toString());
                menu.show(messageTable, e.getX(), e.getY());
            }
        }
    }

    protected class QuerySymbolActionListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            try {
                ProfilingTableModel model;
                ProgramProfilingSymbol profilingSymbol;

                model = (ProfilingTableModel) symbolTable.getModel();
                profilingSymbol = model.getProfilingSymbol(symbolTable.getSelectedRow());
                if (profilingSymbol != null) {
                    long value = nucleusManager.querySymbol(profilingSymbol.getID(), program.getSourcePath(),
                            moteType.getTosPlatform(), mote.getMoteSerialID());

                    model.setValue((int) value, symbolTable.getSelectedRow());
                    symbolTable.repaint();
                }
            } catch (Exception ex) {
                log.error("Exception", ex);
                ClientUtils.displayErrorMessage(MoteDetailFrame.this, ex);
            }
        }
    }

    protected class MessageMonitorActionListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            try {
                MessageTableModel model;
                ProgramProfilingMessageSymbol symbol;

                model = (MessageTableModel) messageTable.getModel();
                symbol = model.getProfilingMessageSymbol(messageTable.getSelectedRow());

                MessageMonitorFrame monitor = new MessageMonitorFrame(mote, symbol);
                monitor.setVisible(true);
            } catch (Exception ex) {
                log.error("Exception: ", ex);
                ClientUtils.displayErrorMessage(MoteDetailFrame.this, ex);
            }
        }
    }
}