/**
* Copyright (C) 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package mujava.gui;
import java.util.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.border.*;
import mujava.*;
import mujava.util.Debug;
/**
* <p>Template for generating mutants</p>
* <p> supporting function:
* (1) choose Java program(s) to be tested,
* (2) choose mutation operator(s) to applied </p>
* @author Yu-Seung Ma
* @version 1.0
*/
public class MutantsGenPanel extends JPanel
{
private static final long serialVersionUID = 103L;
GenMutantsMain parent_frame;
JButton runB = new JButton("Generate");
JComboBox logCB = new JComboBox(new String[]{"1","2","3"});
JTable fileTable = new JTable();
JButton fileNoneB = new JButton("None");
JButton fileAllB = new JButton("All");
JTable traditionalOpTable = new JTable();
JButton traditionalNoneB = new JButton("None");
JButton traditionalAllB = new JButton("All");
JTable classOpTable = new JTable();
JButton classNoneB = new JButton("None");
JButton classAllB = new JButton("All");
// Upsorn (05/18/2009): add button for mutation operators' description
// JButton descriptionB = new JButton("Mutation operators\' description");
public MutantsGenPanel(GenMutantsMain parent_frame)
{
try
{
this.parent_frame = parent_frame;
jbInit();
} catch (Exception ex)
{
ex.printStackTrace();
}
}
/**
* Initialization
*/
void jbInit()
{
this.setLayout (new BoxLayout (this, BoxLayout.LINE_AXIS));
JPanel leftPanel = new JPanel();
JPanel rightPanel = new JPanel();
// LEFT part
leftPanel.setLayout (new BoxLayout (leftPanel, BoxLayout.PAGE_AXIS));
JPanel usagePanel = new JPanel();
usagePanel.setLayout(new FlowLayout(FlowLayout.LEADING));
// instruction
JPanel tempP = new JPanel();
JLabel temp = new JLabel(" Usage : " );
temp.setForeground(Color.gray);
tempP.add(temp);
tempP.setPreferredSize(new Dimension(70, 70));
tempP.setBorder(new EtchedBorder());
JPanel usgeContentP = new JPanel();
usgeContentP.setLayout(new BoxLayout(usgeContentP, BoxLayout.PAGE_AXIS));
usgeContentP.add(new JLabel(" [1] Select files to test"));
usgeContentP.add(new JLabel(" [2] Select mutation operators to apply"));
usgeContentP.add(new JLabel(" [3] Push \"RUN\" button"));
usgeContentP.add(new JLabel(" [4] Wait with endurance. ^^;"));
usagePanel.add(tempP);
usagePanel.add(usgeContentP);
usagePanel.setBorder(new EtchedBorder());
leftPanel.add(usagePanel);
leftPanel.add(Box.createRigidArea(new Dimension(0, 10)));
// list of (target) files to be tested
JPanel filePanel = new JPanel();
filePanel.setLayout(new BorderLayout());
JScrollPane fileSP = new JScrollPane();
FileTableModel fTableModel = new FileTableModel(MutationSystem.getNewTragetFiles());
fileTable = new JTable(fTableModel);
initFileColumnSizes(fileTable,fTableModel);
fileSP.getViewport().add(fileTable, null);
fileSP.setPreferredSize(new Dimension(500, 500));
leftPanel.add(fileSP);
leftPanel.add(Box.createRigidArea(new Dimension(10, 10)));
JPanel fileBP = new JPanel();
fileBP.setLayout(new BoxLayout(fileBP, BoxLayout.LINE_AXIS));
fileBP.add(Box.createRigidArea(new Dimension(10, 10)));
fileBP.add(fileNoneB);
fileNoneB.addMouseListener(new java.awt.event.MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
fileNoneB_mouseClicked(e);
}
});
fileBP.add(Box.createRigidArea(new Dimension(10, 10)));
fileBP.add(fileAllB);
fileAllB.addMouseListener(new java.awt.event.MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
fileAllB_mouseClicked(e);
}
});
// Debug level Add
JPanel logP = new JPanel();
JLabel logL= new JLabel("Log level ");
logP.add(logL);
//logCB.setEditable(false);
logP.add(logCB);
logCB.setPreferredSize(new Dimension(50,25));
logCB.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(ActionEvent e)
{
changeLogLevel();
}
});
leftPanel.add(logP);
fileBP.add(Box.createHorizontalGlue());
// Generate button
runB.setBackground(Color.YELLOW);
fileBP.add(runB);
runB.addMouseListener(new java.awt.event.MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
runB_mouseClicked(e);
}
});
leftPanel.add(fileBP);
fileBP.add(Box.createRigidArea(new Dimension(10, 10)));
leftPanel.add(Box.createRigidArea(new Dimension(20, 20)));
// RIGHT part
rightPanel.setPreferredSize(new Dimension(300, 660));
rightPanel.setMaximumSize(new Dimension(300, 660));
rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.PAGE_AXIS));
rightPanel.setBorder(new EtchedBorder());
// Upsorn (05/18/2009): add button for mutation operators' description
// JPanel descriptionBPanel = new JPanel();
// descriptionBPanel.setLayout(new FlowLayout());
// descriptionBPanel.add(descriptionB);
// descriptionB.addMouseListener(new java.awt.event.MouseAdapter()
// {
// public void mouseClicked(MouseEvent e)
// {
// descriptionB_mouseClicked(e);
// }
// });
// rightPanel.add(descriptionBPanel);
JTextField titleOP= new JTextField(" Java Mutation Operator");
titleOP.setBackground(Color.black);
titleOP.setPreferredSize(new Dimension(300, 30));
titleOP.setMaximumSize(new Dimension(300, 30));
titleOP.setEnabled(false);
rightPanel.add(titleOP);
// method-level operator selection
JPanel traditional_operator_panel = new JPanel();
traditional_operator_panel.setBorder(new TitledBorder("Method-level"));
traditional_operator_panel.setPreferredSize(new Dimension(140, 550));
traditional_operator_panel.setMaximumSize(new Dimension(140, 550));
traditional_operator_panel.setLayout(new BoxLayout(traditional_operator_panel, BoxLayout.PAGE_AXIS));
JScrollPane traditional_operator_scrollP = new JScrollPane();
traditional_operator_panel.add(traditional_operator_scrollP);
TMOTableModel tmTableModel = new TMOTableModel();
traditionalOpTable = new JTable(tmTableModel);
initColumnSizes(traditionalOpTable,tmTableModel);
traditional_operator_scrollP.getViewport().add(traditionalOpTable, null);
traditional_operator_scrollP.setPreferredSize(new Dimension(115, 400));
traditional_operator_scrollP.setMaximumSize(new Dimension(115, 400));
traditional_operator_panel.add(traditional_operator_scrollP);
JPanel traditionalBPanel = new JPanel();
traditionalBPanel.setLayout(new FlowLayout());
traditionalBPanel.add(traditionalNoneB);
traditionalNoneB.addMouseListener(new java.awt.event.MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
traditionalNoneB_mouseClicked(e);
}
});
traditionalBPanel.add(traditionalAllB);
traditionalAllB.addMouseListener(new java.awt.event.MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
traditionalAllB_mouseClicked(e);
}
});
traditional_operator_panel.add(traditionalBPanel);
// class-level operator selection
JPanel class_operator_panel = new JPanel();
class_operator_panel.setBorder(new TitledBorder("Class-level"));
class_operator_panel.setPreferredSize(new Dimension(140, 550));
class_operator_panel.setMaximumSize(new Dimension(140, 550));
class_operator_panel.setLayout(new BoxLayout(class_operator_panel,BoxLayout.PAGE_AXIS));
JScrollPane class_operator_scrollP = new JScrollPane();
class_operator_panel.add(class_operator_scrollP);
CMOTableModel cmTableModel = new CMOTableModel();
classOpTable = new JTable(cmTableModel);
initColumnSizes(classOpTable,cmTableModel);
class_operator_scrollP.getViewport().add(classOpTable, null);
class_operator_scrollP.setPreferredSize(new Dimension(115, 550));
class_operator_scrollP.setMaximumSize(new Dimension(115, 550));
class_operator_panel.add(class_operator_scrollP);
JPanel classBPanel = new JPanel();
classBPanel.setLayout(new FlowLayout());
classBPanel.add(classNoneB);
classNoneB.addMouseListener(new java.awt.event.MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
classNoneB_mouseClicked(e);
}
});
classBPanel.add(classAllB);
classAllB.addMouseListener(new java.awt.event.MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
classAllB_mouseClicked(e);
}
});
class_operator_panel.add(classBPanel);
// This is the original part.
//rightPanel.add(Box.createRigidArea(new Dimension(0,5)));
// Traditional operators ar not supported they are newly designed.
//rightPanel.add(traditional_operator_panel);
//rightPanel.add(temp_traditional_panel);
// rightPanel.add(class_operator_panel);
//----
JPanel operator_panel = new JPanel();
operator_panel.setLayout(new FlowLayout());
operator_panel.add(traditional_operator_panel);
operator_panel.add(class_operator_panel);
//rightPanel.add(Box.createRigidArea(new Dimension(0,4)));
rightPanel.add(operator_panel);
this.add(leftPanel);
this.add(Box.createRigidArea(new Dimension(10, 10)));
this.add(rightPanel);
}
void changeLogLevel()
{
String selectedLevel = logCB.getSelectedItem().toString();
if (selectedLevel == null) return;
if (selectedLevel.equals("1"))
{
Debug.setDebugLevel(1);
}
else if (selectedLevel.equals("2"))
{
Debug.setDebugLevel(2);
}
else
{
Debug.setDebugLevel(3);
}
}
protected void initTripleColumnWidth(JTable table, AbstractTableModel model,
int w1, int w2, int w3)
{
TableColumn column = null;
for (int i = 0; i < table.getColumnCount(); i++)
{
column = table.getColumnModel().getColumn(i);
switch(i)
{
case 0 : column.setMaxWidth(w1);
break;
case 1 : column.setMaxWidth(w2);
break;
case 2 : column.setMaxWidth(w3);
break;
}
}
}
protected void initColumnSizes(JTable table, AbstractTableModel model)
{
initTripleColumnWidth(table, model, 30, 90, 80);
/*
TableColumn column = null;
for (int i = 0; i < table.getColumnCount(); i++)
{
column = table.getColumnModel().getColumn(i);
switch(i)
{
case 0 : column.setMaxWidth(30);
break;
case 1 : column.setMaxWidth(90);
break;
case 2 : column.setMaxWidth(80);
break;
}
}*/
}
void fileAllB_mouseClicked(MouseEvent e)
{
FileTableModel table = (FileTableModel)fileTable.getModel();
table.setAllSelectValue(true);
fileTable.setModel(table);
fileTable.repaint();
}
void fileNoneB_mouseClicked(MouseEvent e)
{
FileTableModel table = (FileTableModel)fileTable.getModel();
table.setAllSelectValue(false);
fileTable.setModel(table);
fileTable.repaint();
}
void runB_mouseClicked(MouseEvent e)
{
//check if any files are selected, return an error message if no files have been selected
FileTableModel fTableModel = (FileTableModel)fileTable.getModel();
String[] file_list = fTableModel.getSelectedFiles();
if (file_list == null || file_list.length == 0)
{
System.err.println("[ERROR] No class is selected. Please select one or more .java files for which you'd like to generate mutants.");
return;
}
//check if any operators are selected, return an error message if no files have been selected
CMOTableModel cmoTableModel = (CMOTableModel)classOpTable.getModel();
String[] class_ops = cmoTableModel.getSelectedOprators();
TMOTableModel tmoTableModel = (TMOTableModel)traditionalOpTable.getModel();
String[] traditional_ops = tmoTableModel.getSelectedOprators();
if ( (class_ops == null || class_ops.length == 0) &&
(traditional_ops == null || traditional_ops.length == 0) )
{
System.out.println("[ERROR] No operators are selected. Please select one or more mutation operators.");
return;
}
//disable the button
runB.setEnabled(false);
for (int i=0; i<file_list.length; i++)
{
// file_name = ABSTRACT_PATH - MutationSystem.SRC_PATH
// For example: org/apache/bcel/Class.java
String file_name = file_list[i];
try
{
//System.out.println(i + " : " + file_name);
// [1] Examine if the target class is interface or abstract class
// In that case, we can't apply mutation testing.
// Generate class name from file_name
String temp = file_name.substring(0,file_name.length()-".java".length());
String class_name="";
for (int j=0; j<temp.length(); j++)
{
if ( (temp.charAt(j) == '\\') || (temp.charAt(j) == '/') )
{
class_name = class_name + ".";
}
else
{
class_name = class_name + temp.charAt(j);
}
}
int class_type = MutationSystem.getClassType(class_name);
if (class_type == MutationSystem.NORMAL)
{ // do nothing?
}
else if (class_type == MutationSystem.MAIN)
{
System.out.println(" -- " + file_name + " class contains 'static void main()' method.");
System.out.println(" Pleas note that mutants are not generated for the 'static void main()' method");
}
//Added on 1/19/2013, no mutants will be generated for a class having only one main method
else if(class_type == MutationSystem.MAIN_ONLY){
System.out.println("Class " + file_name + " has only the 'static void main()' method and no mutants will be generated.");
break;
}
// else
// {
// switch (class_type)
// {
// case MutationSystem.INTERFACE :
// System.out.println(" -- Can't apply because " + file_name+ " is 'interface' ");
// break;
// case MutationSystem.ABSTRACT :
// System.out.println(" -- Can't apply because " + file_name+ " is 'abstract' class ");
// break;
// case MutationSystem.APPLET :
// System.out.println(" -- Can't apply because " + file_name+ " is 'applet' class ");
// break;
// case MutationSystem.GUI :
// System.out.println(" -- Can't apply because " + file_name+ " is 'GUI' class ");
// break;
// }
// deleteDirectory();
// continue;
// }
// [2] Apply mutation testing
setMutationSystemPathFor(file_name);
//File[] original_files = new File[1];
//original_files[0] = new File(MutationSystem.SRC_PATH,file_name);
File original_file = new File(MutationSystem.SRC_PATH, file_name);
/*AllMutantsGenerator genEngine;
genEngine = new AllMutantsGenerator(original_file,class_ops,traditional_ops);
genEngine.makeMutants();
genEngine.compileMutants();*/
ClassMutantsGenerator cmGenEngine;
//do not generate class mutants if no class mutation operator is selected
if(class_ops != null){
cmGenEngine = new ClassMutantsGenerator(original_file,class_ops);
cmGenEngine.makeMutants();
cmGenEngine.compileMutants();
}
//do not generate traditional mutants if no class traditional operator is selected
if(traditional_ops != null){
TraditionalMutantsGenerator tmGenEngine;
//System.out.println("original_file: " + original_file);
//System.out.println("traditional_ops: " + traditional_ops);
tmGenEngine = new TraditionalMutantsGenerator(original_file,traditional_ops);
tmGenEngine.makeMutants();
tmGenEngine.compileMutants();
}
} catch (OpenJavaException oje)
{
System.out.println("[OJException] " + file_name + " " + oje.toString());
//System.out.println("Can't generate mutants for " +file_name + " because OpenJava " + oje.getMessage());
deleteDirectory();
} catch(Exception exp)
{
System.out.println("[Exception] " + file_name + " " + exp.toString());
exp.printStackTrace();
//System.out.println("Can't generate mutants for " +file_name + " due to exception" + exp.getClass().getName());
//exp.printStackTrace();
deleteDirectory();
} catch(Error er)
{
System.out.println("[Error] " + file_name + " " + er.toString());
System.out.println("MutantsGenPanel: ");
er.printStackTrace();
//System.out.println("Can't generate mutants for " +file_name + " due to error" + er.getClass().getName());
deleteDirectory();
}
}
runB.setEnabled(true);
parent_frame.cvPanel.refreshEnv();
parent_frame.tvPanel.refreshEnv();
System.out.println("------------------------------------------------------------------");
System.out.println("All files are handled");
}
void deleteDirectory()
{
File originalDir = new File(MutationSystem.MUTANT_HOME + "/" + MutationSystem.DIR_NAME
+ "/" + MutationSystem.ORIGINAL_DIR_NAME);
while (originalDir.delete())
{ // do nothing?
}
File cmDir = new File(MutationSystem.MUTANT_HOME + "/" + MutationSystem.DIR_NAME
+ "/" + MutationSystem.CM_DIR_NAME);
while (cmDir.delete())
{ // do nothing?
}
File tmDir = new File (MutationSystem.MUTANT_HOME + "/" + MutationSystem.DIR_NAME
+ "/" + MutationSystem.TM_DIR_NAME);
while (tmDir.delete())
{ // do nothing?
}
File myHomeDir = new File(MutationSystem.MUTANT_HOME + "/" + MutationSystem.DIR_NAME);
while (myHomeDir.delete())
{ // do nothing?
}
}
void setMutationSystemPathFor(String file_name)
{
try
{
String temp;
temp = file_name.substring(0, file_name.length()-".java".length());
temp = temp.replace('/', '.');
temp = temp.replace('\\', '.');
int separator_index = temp.lastIndexOf(".");
if (separator_index >= 0)
{
MutationSystem.CLASS_NAME=temp.substring(separator_index+1, temp.length());
}
else
{
MutationSystem.CLASS_NAME = temp;
}
String mutant_dir_path = MutationSystem.MUTANT_HOME + "/" + temp;
File mutant_path = new File(mutant_dir_path);
mutant_path.mkdir();
String class_mutant_dir_path = mutant_dir_path + "/" + MutationSystem.CM_DIR_NAME;
File class_mutant_path = new File(class_mutant_dir_path);
class_mutant_path.mkdir();
String traditional_mutant_dir_path = mutant_dir_path + "/" + MutationSystem.TM_DIR_NAME;
File traditional_mutant_path = new File(traditional_mutant_dir_path);
traditional_mutant_path.mkdir();
String original_dir_path = mutant_dir_path + "/" + MutationSystem.ORIGINAL_DIR_NAME;
File original_path = new File(original_dir_path);
original_path.mkdir();
MutationSystem.CLASS_MUTANT_PATH = class_mutant_dir_path;
MutationSystem.TRADITIONAL_MUTANT_PATH = traditional_mutant_dir_path;
MutationSystem.ORIGINAL_PATH = original_dir_path;
MutationSystem.DIR_NAME = temp;
} catch(Exception e)
{
System.err.println(e);
}
}
void descriptionB_mouseClicked(MouseEvent e)
{
}
void traditionalAllB_mouseClicked(MouseEvent e)
{
TMOTableModel table = (TMOTableModel) traditionalOpTable.getModel();
table.setAllSelectValue(true);
traditionalOpTable.setModel(table);
traditionalOpTable.repaint();
}
void traditionalNoneB_mouseClicked(MouseEvent e)
{
TMOTableModel table = (TMOTableModel)traditionalOpTable.getModel();
table.setAllSelectValue(false);
traditionalOpTable.setModel(table);
traditionalOpTable.repaint();
}
void classAllB_mouseClicked(MouseEvent e)
{
CMOTableModel table = (CMOTableModel)classOpTable.getModel();
table.setAllSelectValue(true);
classOpTable.setModel(table);
classOpTable.repaint();
}
void classNoneB_mouseClicked(MouseEvent e)
{
CMOTableModel table = (CMOTableModel)classOpTable.getModel();
table.setAllSelectValue(false);
classOpTable.setModel(table);
classOpTable.repaint();
}
protected void initFileColumnSizes(JTable table, AbstractTableModel model)
{
initTripleColumnWidth(table,model,30,700,80);
}
}
/**
* <p>Description: Template containing method-level mutation operators
* and class-level mutation operators</p>
* <p>Copyright: Copyright (c) 2005 by Yu-Seung Ma, ALL RIGHTS RESERVED </p>
* @author Yu-Seung Ma
* @version 1.0
*/
abstract class MOTableModel extends AbstractTableModel
{
String[] columnHeader = new String[]{"", "Operator"};
String[] op;
Object[][] data;
static final int CMO = 0;
static final int TMO = 1;
abstract int getOperatorType();
public MOTableModel()
{
if (getOperatorType() == CMO)
{
op = MutationSystem.cm_operators;
}
else
{
op = MutationSystem.tm_operators;
}
data = new Object[op.length][2];
for (int i=0; i<op.length; i++)
{
data[i][0] = new Boolean(false);
data[i][1] = op[i];
}
}
public void setAllSelectValue(boolean b)
{
for (int i=0; i<data.length; i++)
{
data[i][0] = new Boolean(b);
}
}
public String getColumnName(int col)
{
return columnHeader[col];
}
public int getColumnCount()
{
return columnHeader.length;
}
public Object getValueAt(int row, int col)
{
return data[row][col];
}
public int getRowCount()
{
return data.length;
}
public Class getColumnClass(int c)
{
return getValueAt(0, c).getClass();
}
public void setValueAt(Object value, int row, int col)
{
if (data[0][col] instanceof Integer &&
!(value instanceof Integer))
{
try
{
data[row][col] = new Integer(value.toString());
fireTableCellUpdated(row, col);
} catch (NumberFormatException e)
{ // do nothing?
}
}
else
{
data[row][col] = value;
fireTableCellUpdated(row, col);
}
}
public boolean isCellEditable(int row, int col)
{
//Note that the data/cell address is constant,
//no matter where the cell appears on screen.
if (col < 1)
return true;
else
return false;
}
public String[] getSelectedOprators()
{
Vector set = new Vector();
int numRows = getRowCount();
int i;
for (i=0; i<numRows; i++)
{
if (data[i][0].toString().equals("true"))
{
set.add(data[i][1]);
}
}
String[] names = new String[set.size()];
if (set.size() > 0)
{
for (i=0; i<set.size(); i++)
{
names[i] = set.get(i).toString();
}
return names;
}
else
{
return null;
}
}
}
class CMOTableModel extends MOTableModel
{
private static final long serialVersionUID = 104L;
int getOperatorType(){ return CMO; }
}
class TMOTableModel extends MOTableModel
{
private static final long serialVersionUID = 105L;
int getOperatorType(){ return TMO; }
}
class FileTableModel extends AbstractTableModel
{
private static final long serialVersionUID = 106L;
String[] columnHeader = new String[]{"","File"};
String[] op;
Object[][] data;
public FileTableModel(Vector value)
{
data = new Object[value.size()][2];
for (int i=0; i<value.size(); i++)
{
data[i][0] = new Boolean(false);
data[i][1] = value.get(i);
}
}
public String getColumnName(int col)
{
return columnHeader[col];
}
public int getColumnCount()
{
return columnHeader.length;
}
public void setAllSelectValue(boolean b)
{
for (int i=0; i<data.length; i++)
{
data[i][0] = new Boolean(b);
}
}
public Object getValueAt(int row, int col)
{
return data[row][col];
}
public int getRowCount()
{
return data.length;
}
public String[] getSelectedFiles()
{
Vector set = new Vector();
int numRows = getRowCount();
int i;
for (i=0; i<numRows; i++)
{
if (data[i][0].toString().equals("true"))
set.add(data[i][1]);
}
String[] names = new String[set.size()];
if (set.size() > 0)
{
for (i=0; i<set.size(); i++)
{
names[i] = set.get(i).toString();
}
return names;
}
else
{
return null;
}
}
public Class getColumnClass(int c)
{
return getValueAt(0, c).getClass();
}
public void setValue(Object[] value)
{
data = new Object[value.length][2];
for (int i=0; i<value.length; i++)
{
data[i][0] = new Boolean(true);
data[i][1] = value[i];
}
}
public void setValueAt(Object value, int row, int col)
{
if (data[0][col] instanceof Integer &&
!(value instanceof Integer))
{
try
{
data[row][col] = new Integer(value.toString());
fireTableCellUpdated(row, col);
} catch (NumberFormatException e)
{ // do nothing?
}
}
else
{
data[row][col] = value;
fireTableCellUpdated(row, col);
}
}
public boolean isCellEditable(int row, int col)
{
//Note that the data/cell address is constant,
//no matter where the cell appears on screen.
if (col < 1)
{
return true;
}
else
{
return false;
}
}
}