Package jmt.gui.jaba.panels

Source Code of jmt.gui.jaba.panels.ClassesPanel$ClassTableModel

/**   
  * Copyright (C) 2012, Laboratorio di Valutazione delle Prestazioni - Politecnico di Milano

  * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
  */

package jmt.gui.jaba.panels;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.KeyStroke;
import javax.swing.ScrollPaneConstants;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;

import jmt.framework.data.ArrayUtils;
import jmt.framework.gui.help.HoverHelp;
import jmt.framework.gui.table.editors.ButtonCellEditor;
import jmt.framework.gui.wizard.WizardPanel;
import jmt.gui.common.resources.JMTImageLoader;
import jmt.gui.exact.panels.ForceUpdatablePanel;
import jmt.gui.exact.table.ComboBoxCell;
import jmt.gui.exact.table.DisabledCellRenderer;
import jmt.gui.exact.table.ExactTable;
import jmt.gui.exact.table.ExactTableModel;
import jmt.gui.exact.table.ListOp;
import jmt.gui.jaba.JabaConstants;
import jmt.gui.jaba.JabaModel;
import jmt.gui.jaba.JabaWizard;

/**

* @author alyf (Andrea Conti)
* Date: 11-set-2003
* Time: 23.48.19

* Adapted to JABA by Zanzottera

* Heavily bugfixed by Bertoli Marco (31-jan-2006)

*/

/**
* 1st panel: classes number, names, types and data
*/
public class ClassesPanel extends WizardPanel implements JabaConstants, ForceUpdatablePanel {
  /**
   *
   */
  private static final long serialVersionUID = 1L;
  // Added by Bertoli Marco
  private static final int MINCLASSES = 2;
  private static final int MAXCLASSES = 3;
  // end

  private HoverHelp help;
  private static final String helpText = "<html>In this panel you can define the number of stations in the system and their properties.<br><br>"
      + " To edit values, single-click on the desired cell"
      + " and start typing.<br> To select classes click or drag on the row headers.<br> <b>For a list of the available operations right-click"
      + " on the table</b>.<br>" + " Pressing DELETE removes all selected classes from the system.</html>";

  private JabaWizard ew;
  private boolean isLd;
  private int classes;
  private String[] classNames;
  private int[] classTypes;
  private double[] classData;
  private int nameCounter = 1;

  private List<ListOp> classOps;
  private boolean hasDeletes;
  private boolean deleting = false;

  private JSpinner classSpinner = new JSpinner(new SpinnerNumberModel(2, 2, MAX_CLASSES, 1));

  private ClassTable classTable;

  private ChangeListener spinnerListener = new ChangeListener() {
    public void stateChanged(ChangeEvent ce) {
      if (!deleting) {
        updateSizes();
      }
    }
  };

  private AbstractAction deleteClass = new AbstractAction("Delete selected classes") {
    /**
     *
     */
    private static final long serialVersionUID = 1L;

    {
      putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0, false));
      putValue(Action.SHORT_DESCRIPTION, "Deletes selected classes from the system");
    }

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

  private AbstractAction deleteOneClass = new AbstractAction("") {
    /**
     *
     */
    private static final long serialVersionUID = 1L;

    {
      putValue(Action.SHORT_DESCRIPTION, "Delete This Class");
      putValue(Action.SMALL_ICON, JMTImageLoader.loadImage("Close"));
    }

    public void actionPerformed(ActionEvent e) {
    }
  };

  private AbstractAction addClass = new AbstractAction("New Class") {
    /**
     *
     */
    private static final long serialVersionUID = 1L;

    {
      putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.ALT_MASK));
      putValue(Action.SHORT_DESCRIPTION, "Adds a new Class to Model");
    }

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

  public ClassesPanel(JabaWizard ew) {
    this.ew = ew;
    help = ew.getHelp();
    classOps = new ArrayList<ListOp>();

    sync();

    initComponents();
    makeNames();

  }

  private void sync() {

    hasDeletes = false;
    classOps.clear();

    /* sync status with data object */
    /* arrays are copied to ensure data object consistency is preserved */
    JabaModel data = ew.getData();
    synchronized (data) {
      classes = data.getClasses();
      isLd = data.isLd();
      classNames = ArrayUtils.copy(data.getClassNames());
      classTypes = ArrayUtils.copy(data.getClassTypes());
      classData = ArrayUtils.copy(data.getClassData());

      //NEW
      //@author Stefano Omini
      if (isLd) {
        //if load dependent is no more supported after class changes
        //remove all load dependent stations
        if (!(data.isClosed() && !data.isMultiClass())) {
          JOptionPane
              .showMessageDialog(
                  this,
                  "<html><center>jMVA allows Load Dependent stations only for single class closed model. <br> Load Dependent stations will be replaced with Load Independent stations.</center></html>",
                  "Warning", JOptionPane.WARNING_MESSAGE);
          data.removeLD();
          isLd = false;
        }
      }
      //end NEW
    }
    classSpinner.setValue(new Integer(classes));
  }

  /**
   * make up names for null entries
   */
  private void makeNames() {
    for (int i = 0; i < classNames.length; i++) {
      if (classNames[i] == null) {
        //classNames[i] = "Class" + (++nameCounter);
        //NEW Zanzottera
        // ++nameCounter+1 per avere subito class3; la soluzione precedente immetteva class2 che è già presente
        classNames[i] = "Class" + (++nameCounter + 1);
        //END NEW
      }
    }
  }

  /**
   * resize internal data structures according to new values. intended to be called from a listener.
   */
  private void updateSizes()
  //todo aggiunto controllo sul numero delle classi
  {
    if (((Integer) classSpinner.getValue()).intValue() <= MAXCLASSES) {
      setNumberOfClasses(((Integer) classSpinner.getValue()).intValue());
    } else if (((Integer) classSpinner.getValue()).intValue() < MINCLASSES) {
      JOptionPane.showMessageDialog(this, "Sorry, jABA needs at least " + MINCLASSES + " classes.", "jABA classes warning",
          JOptionPane.ERROR_MESSAGE);
    } else {
      JOptionPane.showMessageDialog(this, "Sorry, jABA admits only up to " + MAXCLASSES + " classes.", "jABA classes warning",
          JOptionPane.ERROR_MESSAGE);
    }

  }

  private void addClass() {
    setNumberOfClasses(classes + 1);
  }

  private void setNumberOfClasses(int number) {
    classTable.stopEditing();

    if (number <= MAXCLASSES) {
      classes = number;
    } else {
      JOptionPane.showMessageDialog(this, "Sorry, jABA admits only up to " + MAXCLASSES + " classes", "jABA classes warning",
          JOptionPane.ERROR_MESSAGE);
      return;
    }

    classNames = ArrayUtils.resize(classNames, classes, null);
    makeNames();

    classTypes = ArrayUtils.resize(classTypes, classes, CLASS_CLOSED);
    classData = ArrayUtils.resize(classData, classes, 0.0);

    classTable.updateStructure();
    if (!deleting) {
      classOps.add(ListOp.createResizeOp(classes));
    }

    classSpinner.setValue(new Integer(classes));
    classTable.updateDeleteCommand();
  }

  /**
   * Set up the panel contents and layout
   */
  private void initComponents() {
    classSpinner.addChangeListener(spinnerListener);
    help.addHelp(classSpinner, "Enter the number of classes for this system");

    classTable = new ClassTable();

    /* and now some Box black magic */
    //DEK (Federico Granata) 26-09-2003
    Box classSpinnerBox = Box.createHorizontalBox();
    //OLD
    //JLabel spinnerLabel = new JLabel("<html><font size=\"4\">Set the Number of classes (1-" + MAX_CLASSES + "):</font></html>");
    //NEW
    //@author Stefano
    JLabel spinnerLabel = new JLabel(DESCRIPTION_CLASSES);

    classSpinnerBox.add(spinnerLabel);
    //END
    //BEGIN Federico Dall'Orso 9/3/2005
    //OLD
    /*
    classSpinnerBox.add(Box.createGlue());
    */
    //NEW
    classSpinnerBox.add(Box.createHorizontalStrut(10));
    Box numberBox = Box.createVerticalBox();

    JPanel spinnerPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
    JLabel numberLabel = new JLabel("Number (Max=3):");
    classSpinner.setMaximumSize(new Dimension(600, 18));
    spinnerPanel.add(numberLabel);
    spinnerPanel.add(classSpinner);
    numberBox.add(spinnerPanel);

    numberBox.add(new JButton(addClass));

    numberBox.setMaximumSize(new Dimension(150, 50));

    classSpinnerBox.add(numberBox);
    //END  Federico Dall'Orso 9/3/2005

    Box classBox = Box.createVerticalBox();
    classBox.add(Box.createVerticalStrut(20));
    classBox.add(classSpinnerBox);
    classBox.add(Box.createVerticalStrut(10));
    JScrollPane classTablePane = new JScrollPane(classTable);
    classTablePane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    classTablePane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
    classBox.add(classTablePane);
    classBox.add(Box.createVerticalStrut(20));

    Box totalBox = Box.createHorizontalBox();
    totalBox.add(Box.createHorizontalStrut(20));
    totalBox.add(classBox);
    totalBox.add(Box.createHorizontalStrut(20));

    setLayout(new BorderLayout());
    add(totalBox, BorderLayout.CENTER);

  }

  /**
   * @return the total number of customers in the system
   */
  private int sumPop() {
    int pop = 0;
    for (int i = 0; i < classes; i++) {
      if (classTypes[i] == CLASS_CLOSED) {
        pop += classData[i];
      }
    }
    return pop;
  }

  @Override
  public String getName() {
    return "Classes";
  }

  @Override
  public void lostFocus() {
    commit();
    //release();
  }

  @Override
  public void gotFocus() {
    sync();
    classTable.update();
  }

  @Override
  public boolean canFinish() {
    return checkPop() && !areThereDuplicates();
  }

  @Override
  public boolean canGoBack() {
    checkPop();
    if (areThereDuplicates()) {
      return false;
    }
    return true; //so that the user can correct errors
  }

  @Override
  public boolean canGoForward() {
    checkPop();
    if (areThereDuplicates()) {
      return false;
    }
    return true; // so that the user can correct errors
  }

  //checks wether population is greater than 0
  private boolean checkPop() {
    classTable.stopEditing();
    if (isLd && sumPop() < 1) {
      JOptionPane
          .showMessageDialog(
              this,
              "<html><center>A system with load dependent stations cannot have zero customers.<br>Increase the number of customers or remove all load dependent stations.</center></html>",
              "Warning", JOptionPane.WARNING_MESSAGE);
      return false;
    }
    return true;
  }

  //checks for presence of classes with same name
  private boolean areThereDuplicates() {
    boolean thereAreDupl = false;
    for (int i = 0; i < classNames.length; i++) {
      for (int j = i + 1; j < classNames.length; j++) {
        thereAreDupl = thereAreDupl || classNames[i].equalsIgnoreCase(classNames[j]);
      }
    }
    if (thereAreDupl) {
      JOptionPane.showMessageDialog(this,
          "<html><center>Two or more classes in this system are identified by the same name.<br>Please modify names.</center></html>",
          "Warning", JOptionPane.WARNING_MESSAGE);
      return true;
    } else {
      return false;
    }
  }

  private void commit() {
    /* stop any editing in progress */
    if (classSpinner.getEditor().getComponent(0).hasFocus()) {
      //disgusting. there must be a better way...
      try {
        classSpinner.commitEdit();
        updateSizes();
      } catch (java.text.ParseException e) {
      }
    }

    classTable.stopEditing();

    JabaModel data = ew.getData();

    synchronized (data) {

      if (hasDeletes) {
        //if at some point rows have been deleted
        //play back all ops in the same order on the data object
        playbackClassOps(data);
      } else {
        data.resize(data.getStations(), classes); //otherwise a simple resize is ok
      }

      data.setClassNames(classNames);
      data.setClassTypes(classTypes);
      data.setClassData(classData);

      //NEW
      //@author Stefano Omini
      sync();
      //end NEW
    }
  }

  private void deleteSelectedClasses() {
    int[] selectedRows = classTable.getSelectedRows();
    //System.out.println("deleteSelectedRows(): "+ArrayUtils.toString(selectedRows));
    int nrows = selectedRows.length;
    int left = classTable.getRowCount() - nrows;
    if (left < 1) {
      classTable.removeRowSelectionInterval(selectedRows[nrows - 1], selectedRows[nrows - 1]);
      deleteSelectedClasses();
      return;
    }
    deleteClasses(selectedRows);
  }

  private void deleteClasses(int[] idx) {
    deleting = true;
    Arrays.sort(idx);
    for (int i = idx.length - 1; i >= 0; i--) {
      deleteClass(idx[i]);
    }
    updateSizes();
    deleting = false;
  }

  private void deleteClass(int i) {

    classes--;
    classSpinner.setValue(new Integer(classes));

    classNames = ArrayUtils.delete(classNames, i);
    classTypes = ArrayUtils.delete(classTypes, i);
    classData = ArrayUtils.delete(classData, i);

    classOps.add(ListOp.createDeleteOp(i));
    hasDeletes = true;

  }

  private void playbackClassOps(JabaModel data) {
    for (int i = 0; i < classOps.size(); i++) {
      ListOp lo = classOps.get(i);
      if (lo.isDeleteOp()) {
        data.deleteClass(lo.getData());
      }
      if (lo.isResizeOp()) {
        data.resize(data.getStations(), lo.getData());
      }

    }
  }

  @Override
  public void help() {
    JOptionPane.showMessageDialog(this, helpText, "Help", JOptionPane.INFORMATION_MESSAGE);

  }

  //NEW Federico Dall'Orso
  //Methods added to implement forcing of data refresh
  public void retrieveData() {
    sync();
  }

  public void commitData() {
    commit();
  }

  //END

  /* ------------------------------------------------------------------
     The ClassTable is a fairly complex object that would be probably better of as an outer class.
     However, it is very specialized and it needs access to the data structures of the ClassesPanel,
     so having it as an inner class is *much* more practical
     ------------------------------------------------------------------
     */

  /**
   * Her Majesty, the class table herself
   */
  private class ClassTable extends ExactTable {

    /**
     *
     */
    private static final long serialVersionUID = 1L;
    TableCellRenderer disabledCellRenderer;
    TableCellEditor classTypeCellEditor;
    //BEGIN Federico Dall'Orso 8/3/2005
    ComboBoxCell classTypeComboBoxCell;
    ButtonCellEditor deleteButtonCellRenderer;
    JButton deleteButton;

    //END Federico Dall'Orso 8/3/2005

    ClassTable() {
      super(new ClassTableModel());

      disabledCellRenderer = new DisabledCellRenderer();

      //BEGIN Federico Dall'Orso 8/3/2005
      //NEW
      classTypeComboBoxCell = new ComboBoxCell(CLASS_TYPENAMES);
      //todo sostituire quando saranno inserite le classi aperte
      classTypeComboBoxCell.getComboBox().setEnabled(false);

      deleteButton = new JButton(deleteOneClass);
      deleteButtonCellRenderer = new ButtonCellEditor(deleteButton);
      enableDeletes();
      rowHeader.setRowHeight(18);
      setRowHeight(18);
      //END Federico Dall'Orso 8/3/2005

      JComboBox classTypeBox = new JComboBox(CLASS_TYPENAMES);
      //todo sostituire quando saranno inserite le classi aperte
      classTypeBox.setEnabled(false);

      classTypeCellEditor = new DefaultCellEditor(classTypeBox);
      classTypeBox.setEditable(false);

      setColumnSelectionAllowed(false);
      setRowSelectionAllowed(true);

      // not beautiful, but effective. See ClassTableModel.getColumnClass()
      setDefaultRenderer(DisabledCellRenderer.class, disabledCellRenderer);
      setDefaultEditor(String.class, classTypeCellEditor);

      setDisplaysScrollLabels(true);

      installKeyboardAction(getInputMap(), getActionMap(), deleteClass);
      mouseHandler = new ExactTable.MouseHandler(makeMouseMenu());
      mouseHandler.install();

      help.addHelp(this,
          "Click or drag to select classes; to edit data single-click and start typing. Right-click for a list of available operations");
      help.addHelp(moreRowsLabel, "There are more classes: scroll down to see them");
      help.addHelp(selectAllButton, "Click to select all classes");
      tableHeader.setToolTipText(null);
      rowHeader.setToolTipText(null);
      help.addHelp(rowHeader, "Click, SHIFT-click or drag to select classes");

    }

    //BEGIN Federico Dall'Orso 14/3/2005
    /*enables deleting operations with last column's button*/
    private void enableDeletes() {
      //deleteOneClass.setEnabled(classes>1);
      //todo zanzottera inserito controllo inizialmente non si possono cancellare le 2 classi
      deleteOneClass.setEnabled(classes > MINCLASSES);
      /*It seems the only way to implement row deletion...*/
      this.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
          if (classes > MINCLASSES && (columnAtPoint(e.getPoint()) == getColumnCount() - 1) && getRowCount() > 1) {
            setRowSelectionInterval(rowAtPoint(e.getPoint()), rowAtPoint(e.getPoint()));
            deleteSelectedClasses();
          }
        }
      });
      getColumnModel().getColumn(getColumnCount() - 1).setMinWidth(20);
      getColumnModel().getColumn(getColumnCount() - 1).setMaxWidth(20);
    }

    //END Federico Dall'Orso 14/3/2005

    //new Federico Dall'Orso 8/3/2005

    @Override
    public TableCellRenderer getCellRenderer(int row, int column) {
      //if this is type column, i must render it as a combo box instead of a jtextfield
      if (column == 1) {
        return classTypeComboBoxCell;
      } else if (column == 4) {
        return deleteButtonCellRenderer;
      } else {
        return disabledCellRenderer;
      }
    }

    //end Federico Dall'Orso 8/3/2005

    @Override
    protected void installKeyboard() {
    }

    @Override
    protected void installMouse() {
    }

    @Override
    protected JPopupMenu makeMouseMenu() {
      JPopupMenu menu = new JPopupMenu();
      menu.add(deleteClass);
      return menu;
    }

    /**
     * Make sure the table reflects changes on editing end
     * Overridden to truncate decimals in data if current class is closed
     */
    @Override
    public void editingStopped(ChangeEvent ce) {
      if (classTypes[editingRow] == CLASS_CLOSED) {
        classData[editingRow] = (int) classData[editingRow];
      }
      updateRow(editingRow);
      super.editingStopped(ce);
    }

    //BEGIN Federico Dall'Orso 14/3/2005
    //NEW
    //Updates appearence of last column's buttons
    void updateDeleteCommand() {
      //todo inserito controllo non si possono cancellare classi se ce ne sono solo 2
      deleteOneClass.setEnabled(classes > MINCLASSES);
      getColumnModel().getColumn(getColumnCount() - 1).setMinWidth(20);
      getColumnModel().getColumn(getColumnCount() - 1).setMaxWidth(20);

    }

    //END Federico Dall'Orso 14/3/2005

    @Override
    protected void updateActions() {
      boolean isEnabled = classes > MINCLASSES && getSelectedRowCount() > 0;
      deleteClass.setEnabled(isEnabled);
      deleteOneClass.setEnabled(classes > MINCLASSES);
    }
  }

  /**
   * the model backing the class table
   */
  private class ClassTableModel extends ExactTableModel {

    /**
     *
     */
    private static final long serialVersionUID = 1L;
    private Object[] prototypes = { "10000", new String(new char[12]), "closed+cbox", new Integer(1000), new String(new char[12]), "" };
    private int suffixClassCollision = 1;

    @Override
    public Object getPrototype(int columnIndex) {
      return prototypes[columnIndex + 1];
    }

    public int getRowCount() {
      return classes;
    }

    @Override
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public Class getColumnClass(int col) {
      switch (col) {
        case 1:
          return String.class;
        case 2:
        case 3:
          return DisabledCellRenderer.class;
        default:
          return Object.class;
      }
    }

    public int getColumnCount() {
      return 5;
    }

    @Override
    public String getColumnName(int index) {
      switch (index) {
        case 0:
          return "Name";
        case 1:
          return "Type (Closed Only)";
        case 2:
          return "No. of Customers (+inf.)";
        case 3:
          //return "Arrival Rate (\u03BB)";
          return "Arrival Rate (Further versions)";
        default:
          return null;
      }
    }

    @Override
    protected Object getValueAtImpl(int rowIndex, int columnIndex) {
      switch (columnIndex) {
        case 0://name
          return classNames[rowIndex];
        case 1://type
          return CLASS_TYPENAMES[classTypes[rowIndex]];
        case 2://customers
          /*
          if (classTypes[rowIndex] == CLASS_CLOSED) {
            return new Integer((int) classData[rowIndex]);
          } else {
            return null;
          }
          */
        case 3://arrival rate
          /*
          if (classTypes[rowIndex] == CLASS_OPEN) {
            return new Double(classData[rowIndex]);
          } else {
            return null;
          }
          */
        default:
          return null;
      }
    }

    @Override
    protected Object getRowName(int rowIndex) {
      return new Integer(rowIndex + 1);
    }
   
    @Override
    public void setValueAt(Object value, int rowIndex, int columnIndex) {
      switch (columnIndex) {
        case 0: //name
          String tmpName = (String) value;
          //Check for class name collision
          for(int i = 0; i < classNames.length; i++ ){
            if(classNames[i].equals(tmpName) && i != rowIndex) {
              tmpName = tmpName + "_" + suffixClassCollision++;
              break;
            }
          }
          classNames[rowIndex] = tmpName;
          break;
        case 1: //type
          for (int i = 0; i < CLASS_TYPENAMES.length; i++) {
            if (value == CLASS_TYPENAMES[i]) { //literal strings are canonicalized, hence == is ok
              classTypes[rowIndex] = i;
              break;
            }
          }
          break;
        case 2: {//customers
          try {
            int newval = (int) Double.parseDouble((String) value);
            if (newval >= 0) {
              classData[rowIndex] = newval;
            }
          } catch (NumberFormatException e) {
          }
          break;
        }
        case 3: { //arrival rate
          try {
            double newval = Double.parseDouble((String) value);
            if (newval >= 0.0) {
              classData[rowIndex] = newval;
            }
          } catch (NumberFormatException e) {
          }
          break;
        }
        default:
      }
    }


    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
      switch (columnIndex) {
        case 0:
          return true;
        case 1:
          return false;
        case 2:
          //todo ripristinare quando saranno accettate le classi aperte
          //return (classTypes[rowIndex] == CLASS_CLOSED);
        case 3:
          return (classTypes[rowIndex] == CLASS_OPEN);
        default:
          return false;
      }
    }
  }

}
TOP

Related Classes of jmt.gui.jaba.panels.ClassesPanel$ClassTableModel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.