TableModelListener Problem

Hi, My application has a JTree and a PropertyInspector which has a JTable.
When a user selects any node in JTree, I refresh the PropertyInspector and displays the property of the selected node. Now I have a problem in TableModelListener.
For example, I select a node, it has 5 properties, so my Table display 5 properties, I edit the 1st one, and selects the second row to edit, It works fine. TableModelListener called and works perfectly.
But when I edit the 1st property and choose another Tree Node, then TableModelListener returns the getFirstRow to -1 and my programs fails there.
My code is as follows:
   class TableListener
       implements TableModelListener {
      private JTable table;
      public TableListener(JTable table) {
      this.table = table;
      public void tableChanged(TableModelEvent e) {
      int firstRow = e.getFirstRow();
      System.out.println("First Row: " + firstRow); // This is -1 when I select another node.
      int lastRow = e.getLastRow();
      System.out.println("Last Row: " + lastRow);
      int editCol = e.getColumn();
      TableModel model = (TableModel) e.getSource();
      if (e.getType() == TableModelEvent.UPDATE) {
         if (editCol == 0) {
            /*Boolean chk = (Boolean)table.getValueAt(editRow, 0);
              if(chk.booleanValue()) {
                 System.out.println("Box is Selected");
              else {
                 System.out.println("Box is Not Selected");
         else {
            try {
            save(dataObject, model.getValueAt(firstRow, PROPERTY_COLUMN).toString(),
                 model.getValueAt(firstRow, VALUE_COLUMN).toString());
            System.out.println("Saving: " + model.getValueAt(firstRow, PROPERTY_COLUMN).toString() + " " +
                         model.getValueAt(firstRow, VALUE_COLUMN).toString());
            } catch (ArrayIndexOutOfBoundsException ex) {
            System.out.println("ArrayIndexOutOfBoundsException");
   }Any help plz.
Thanks

Hi, My application has a JTree and a PropertyInspector which has a JTable.
When a user selects any node in JTree, I refresh the PropertyInspector and displays the property of the selected node. Now I have a problem in TableModelListener.
For example, I select a node, it has 5 properties, so my Table display 5 properties, I edit the 1st one, and selects the second row to edit, It works fine. TableModelListener called and works perfectly.
But when I edit the 1st property and choose another Tree Node, then TableModelListener returns the getFirstRow to -1 and my programs fails there.
My code is as follows:
   class TableListener
       implements TableModelListener {
      private JTable table;
      public TableListener(JTable table) {
      this.table = table;
      public void tableChanged(TableModelEvent e) {
      int firstRow = e.getFirstRow();
      System.out.println("First Row: " + firstRow); // This is -1 when I select another node.
      int lastRow = e.getLastRow();
      System.out.println("Last Row: " + lastRow);
      int editCol = e.getColumn();
      TableModel model = (TableModel) e.getSource();
      if (e.getType() == TableModelEvent.UPDATE) {
         if (editCol == 0) {
            /*Boolean chk = (Boolean)table.getValueAt(editRow, 0);
              if(chk.booleanValue()) {
                 System.out.println("Box is Selected");
              else {
                 System.out.println("Box is Not Selected");
         else {
            try {
            save(dataObject, model.getValueAt(firstRow, PROPERTY_COLUMN).toString(),
                 model.getValueAt(firstRow, VALUE_COLUMN).toString());
            System.out.println("Saving: " + model.getValueAt(firstRow, PROPERTY_COLUMN).toString() + " " +
                         model.getValueAt(firstRow, VALUE_COLUMN).toString());
            } catch (ArrayIndexOutOfBoundsException ex) {
            System.out.println("ArrayIndexOutOfBoundsException");
   }Any help plz.
Thanks

Similar Messages

  • JTable , TableModelListener problem

    Hi,
    I have a question about using the JTable with a TableModelListener.It might be a very silly question for some but .. Jtable I still haven't got it right ..always get confused
    I have TableModelListener for my Jtable Model .. I want the listener to be called only when the
    data in the editable cell changes .. as per now .. each time I tab through the table cells without even changing the data in the cell .
    Can someone help me how this can be done .. so that the control goes into the listener only when the data in the cell has been changed .
    One more issuse is that .. the listener is called more than once ..
    I have added a addListSelectionListener for the same JTable and each time a particular row in the table
    is selected .. it called more than once
    Can some one help me with this one please
    thanks
    sandsouza

    import java.awt.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.table.*;
    public class TableProcessing extends JFrame implements TableModelListener
        JTable table;
        public TableProcessing()
            String[] columnNames = {"Item", "Quantity", "Price", "Cost"};
            Object[][] data =
                {"Bread", new Integer(1), new Double(1.11), new Double(1.11)},
                {"Milk", new Integer(1), new Double(2.22), new Double(2.22)},
                {"Tea", new Integer(1), new Double(3.33), new Double(3.33)},
                {"Cofee", new Integer(1), new Double(4.44), new Double(4.44)}
            DefaultTableModel model = new DefaultTableModel(data, columnNames);
            model.addTableModelListener( this );
            table = new JTable( model )
                //  Returning the Class of each column will allow different
                //  renderers to be used based on Class
                public Class getColumnClass(int column)
                    return getValueAt(0, column).getClass();
                //  The Cost is not editable
                public boolean isCellEditable(int row, int column)
                     int modelColumn = convertColumnIndexToModel( column );
                    return (modelColumn == 3) ? false : true;
            table.setPreferredScrollableViewportSize(table.getPreferredSize());
            JScrollPane scrollPane = new JScrollPane( table );
            getContentPane().add( scrollPane );
         *  The cost is recalculated whenever the quantity or price is changed
        public void tableChanged(TableModelEvent e)
            if (e.getType() == TableModelEvent.UPDATE)
                int row = e.getFirstRow();
                int column = e.getColumn();
                System.out.println(row + " : " + column);
                if (column == 1 || column == 2)
                    int    quantity = ((Integer)table.getModel().getValueAt(row, 1)).intValue();
                    double price = ((Double)table.getModel().getValueAt(row, 2)).doubleValue();
                    Double value = new Double(quantity * price);
                    table.getModel().setValueAt(value, row, 3);
        public static void main(String[] args)
            TableProcessing frame = new TableProcessing();
            frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
            frame.pack();
            frame.setLocationRelativeTo( null );
            frame.setVisible(true);
    }

  • Problem with TableModelListener - it's just not working

    Hi all - I have a TableModelListener like the one bellow but when I edit data in the table and press enter nothing happens - I'm guessing I'm doing something wrong but I can't work out what - has anyone got any ideas?
    teamManageTable.getModel().addTableModelListener( new TableModelListener() {
                public void tableChanged(TableModelEvent e) {
                    int row = e.getFirstRow();
                    int column = e.getColumn();
                    TableModel model = (TableModel)e.getSource();
                    String columnName = model.getColumnName(column);
                    Object data = model.getValueAt(row, column);
                    // Do something with the data...
                    System.out.println("hi");
            });Thanks

    Hi there - it took me a while to replicate the problem (I'm not going to post the whole program - too big) - basically it seems that it is only not working once I add data too the table, so I guess I am adding it incorrectly
    If you run this and click the add button you will then see that it is not working
    * Main.java
    * Created on 17 November 2007, 10:55
    * To change this template, choose Tools | Template Manager
    * and open the template in the editor.
    package tester;
    * @author kilps
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.event.*;
    import javax.swing.table.TableModel;
    public class Main extends JFrame {
        JScrollPane teamManageScrollPane = new javax.swing.JScrollPane();
        JTable teamManageTable = new javax.swing.JTable();
        JLabel addTeamLabel = new javax.swing.JLabel("Add a new team: ");
        JLabel addTeamNameLabel = new javax.swing.JLabel("Name: ");
        JTextField addTeamName = new javax.swing.JTextField();
        JLabel addTeamContactNumberLabel = new javax.swing.JLabel("Contact Number: ");
        JTextField addTeamContactNumber = new javax.swing.JTextField();
        JLabel addTeamContactEmailLabel = new javax.swing.JLabel("Contact Email: ");
        JTextField addTeamContactEmail = new javax.swing.JTextField();
        JLabel addTeamOtherInfoLabel = new javax.swing.JLabel("Other Info: ");
        JScrollPane addTeamOtherInfo = new javax.swing.JScrollPane();
        JTextArea addTeamOtherInfoBox = new javax.swing.JTextArea(5,20);
        JButton addTeamSubmit = new javax.swing.JButton("Submit New Team");
        String [] tableHeader = new String[] {"Team Name", "Contact Number", "Contact Email","Other Info"};//table header
        /** Creates a new instance of Main */
        public Main() {
            method();
        public void method() {
            teamManageTable.setModel(new javax.swing.table.DefaultTableModel(new String[][] {{"some","data"},{"some","more"}},new String[] {"1","2"}));
            //object specific stuff
            teamManageScrollPane.setViewportView(teamManageTable);
            addTeamLabel.setFont(new java.awt.Font("Dialog", 1, 14));
            addTeamOtherInfo.setViewportView(addTeamOtherInfoBox);
            //setup window
            JFrame teamsWindow=new JFrame("Manage Teams");
            //fancy layout stuff courtesy netbeans gui builder
            GroupLayout layout = new javax.swing.GroupLayout(teamsWindow.getContentPane());
            teamsWindow.getContentPane().setLayout(layout);
            layout.setHorizontalGroup(
                    layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(addTeamLabel)
                    .addGroup(layout.createSequentialGroup()
                    .addComponent(addTeamNameLabel)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(addTeamName, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                    .addComponent(addTeamContactNumberLabel)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(addTeamContactNumber, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                    .addComponent(addTeamContactEmailLabel)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(addTeamContactEmail, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(layout.createSequentialGroup()
                    .addComponent(addTeamOtherInfoLabel)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(addTeamOtherInfo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addComponent(teamManageScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 420, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(addTeamSubmit))
                    .addContainerGap(20, Short.MAX_VALUE))
            layout.setVerticalGroup(
                    layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                    .addContainerGap()
                    .addComponent(teamManageScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 112, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(addTeamLabel)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(addTeamNameLabel)
                    .addComponent(addTeamName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(addTeamContactNumberLabel)
                    .addComponent(addTeamContactNumber, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(addTeamContactEmailLabel)
                    .addComponent(addTeamContactEmail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(addTeamOtherInfoLabel)
                    .addComponent(addTeamOtherInfo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                    .addComponent(addTeamSubmit)
                    .addContainerGap(28, Short.MAX_VALUE))
            teamsWindow.pack();
            teamsWindow.setVisible(true);
            addTeamSubmit.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    //first do fancy check so we have a dynamic array type thing
                     teamManageTable.setModel(new javax.swing.table.DefaultTableModel(new String[][] {{"some","data"},{"some","more"},{"even","more"}},new String[] {"1","2"}));
            teamsWindow.addWindowListener(new WindowListener() {
                public void windowClosed(WindowEvent arg0) {}
                public void windowActivated(WindowEvent arg0) {}
                public void windowClosing(WindowEvent arg0) {
                    //on close
                public void windowDeactivated(WindowEvent arg0) {}
                public void windowDeiconified(WindowEvent arg0) { }
                public void windowIconified(WindowEvent arg0) {}
                public void windowOpened(WindowEvent arg0) {}
            teamManageTable.getModel().addTableModelListener( new TableModelListener() {
                public void tableChanged(TableModelEvent e) {
                    int row = e.getFirstRow();
                    int column = e.getColumn();
                    TableModel model = (TableModel)e.getSource();
                    String columnName = model.getColumnName(column);
                    Object data = model.getValueAt(row, column);
                    // Do something with the data...
                    System.out.println("hi");
         * @param args the command line arguments
        public static void main(String[] args) {
            // TODO code application logic here
            new Main();
    }thanks

  • URGENT HELP NEEDED FOR JTABLE PROBLEM!!!!!!!!!!!!!!!!!

    firstly i made a jtable to adds and deletes rows and passes the the data to the table model from some textfields. then i wanted to add a tablemoselistener method in order to change the value in the columns 1,2,3,4 and set the result of them in the column 5. when i added that portion of code the buttons that added and deleted rows had problems to function correctly..they dont work at all..can somebody have a look in my code and see wot is wrong..thanx in advance..
    below follows the code..sorry for the mesh of the code..you can use and run the code and notice the problem when you press the add button..also if you want delete the TableChanged method to see that the add button works perfect.
    * Created on 03-Aug-2005
    * TODO To change the template for this generated file go to
    * Window - Preferences - Java - Code Style - Code Templates
    * @author Administrator
    * TODO To change the template for this generated type comment go to
    * Window - Preferences - Java - Code Style - Code Templates
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.Vector;
    import javax.swing.*;
    import javax.swing.table.*;
    import javax.swing.event.TableModelEvent;
    import javax.swing.event.TableModelListener;
    import java.io.*;
    public class NodesTable extends JFrame implements TableModelListener, ActionListener {
    JTable jt;
    DefaultTableColumnModel dtcm;
    TableColumn column[] = new TableColumn[100];
    DefaultTableModel dtm;
    JLabel Name,m1,w1,m2,w2;
    JTextField NameTF,m1TF,w1TF,m2TF,w2TF;
    String c [] ={ "Name", "Assessment1", "Weight1" , "Assessment2","Weight2 ","TotalMark"};
    float x=0,y=0,tMark=0,z = 0;
    float j=0;
    int i;
         JButton DelButton;
         JButton AddButton;
         JScrollPane scrollPane;
         JPanel mainPanel,buttonPanel;
         JFrame frame;
         Object[][] data =
              {"tami", new Float(1), new Float(1.11), new Float(1.11),new Float(1),new Float(1)},
              {"tami", new Float(1), new Float(2.22), new Float(2.22),new Float(1),new Float(1)},
              {"petros", new Float(1), new Float(3.33), new Float(3.33),new Float(1),new Float(1)},
              {"petros", new Float(1), new Float(4.44), new Float(4.44),new Float(1),new Float(1)}
    public NodesTable() {
    super("Student Marking Spreadsheet");
    this.AddNodesintoTable();
    setSize(400,250);
    setVisible(true);
    public void AddNodesintoTable(){
    // Create a vector object and load them with the data
    // to be placed on each row of the table
    dtm = new DefaultTableModel(data,c);
    dtm.addTableModelListener( this );
    jt = new JTable(dtm){
         // Returning the Class of each column will allow different
              // renderers to be used based on Class
              public Class getColumnClass(int column)
                   return getValueAt(0, column).getClass();
              // The Cost is not editable
              public boolean isCellEditable(int row, int column)
                   int modelColumn = convertColumnIndexToModel( column );
                   return (modelColumn == 5) ? false : true;
    //****************************User Input**************************
    //Add another node
    //Creating and setting the properties
    //of the panel's component (panels and textfields)
    Name = new JLabel("Name");
    Name.setForeground(Color.black);
    m1 = new JLabel("Mark1");
    m1.setForeground(Color.black);
    w1 = new JLabel("Weigth1");
    w1.setForeground(Color.black);
    m2= new JLabel("Mark2");
    m2.setForeground(Color.black);
    w2 = new JLabel("Weight2");
    w2.setForeground(Color.black);
    NameTF = new JTextField(5);
    NameTF.setText("Node");
    m1TF = new JTextField(5);
    w1TF = new JTextField(5);
    m2TF=new JTextField(5);
    w2TF=new JTextField(5);
    //creating the buttons
    JPanel buttonPanel = new JPanel();
    AddButton=new JButton("Add Row");
    DelButton=new JButton("Delete") ;
    buttonPanel.add(AddButton);
    buttonPanel.add(DelButton);
    //adding the components to the panel
    JPanel inputpanel = new JPanel();
    inputpanel.add(Name);
    inputpanel.add(NameTF);
    inputpanel.add(m1);
    inputpanel.add(m1TF);
    inputpanel.add(w1);
    inputpanel.add(w1TF);
    inputpanel.add(m2);
    inputpanel.add(m2TF);
    inputpanel.add(w2TF);
    inputpanel.add(w2);
    inputpanel.add(AddButton);
    inputpanel.add(DelButton);
    //creating the panel and setting its properties
    JPanel tablepanel = new JPanel();
    tablepanel.add(new JScrollPane(jt, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED
    , JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS));
    getContentPane().add(tablepanel, BorderLayout.CENTER);
    getContentPane().add(inputpanel, BorderLayout.SOUTH);
    //Method to add row for each new entry
    public void addRow()
    Vector r=new Vector();
    r=createBlankElement();
    dtm.addRow(r);
    jt.addNotify();
    public Vector createBlankElement()
    Vector t = new Vector();
    t.addElement((String) " ");
    t.addElement((String) " ");
    t.addElement((String) " ");
    t.addElement((String) " ");
    t.addElement((String) " ");
    return t;
    // Method to delete a row from the spreadsheet
    void deleteRow(int index)
    if(index!=-1) //At least one Row in Table
    dtm.removeRow(index);
    jt.addNotify();
    // Method that adds and deletes rows
    // from the table by pressing the
    //corresponding buttons
    public void actionPerformed(ActionEvent ae){
         Float z=new Float (m2TF.getText());
    String Name= NameTF.getText();
    Float x= new Float(m1TF.getText());
    Float y= new Float(w1TF.getText());
    Float j=new Float (w2TF.getText());
    JFileChooser jfc2 = new JFileChooser();
    String newdata[]= {Name,String.valueOf(x),String.valueOf(y),
    String.valueOf(z),String.valueOf(j)};
    Object source = ae.getSource();
    if(ae.getSource() == (JButton)AddButton)
    addRow();
    if (ae.getSource() ==(JButton) DelButton)
    deleteRow(jt.getSelectedRow());
    //method to calculate the total mark in the TotalMark column
    //that updates the values in every other column
    //It takes the values from the column 1,2,3,4
    //and changes the value in the column 5
    public void tableChanged(TableModelEvent e) {
         System.out.println(e.getSource());
         if (e.getType() == TableModelEvent.UPDATE)
              int row = e.getFirstRow();
              int column = e.getColumn();
              if (column == 1 || column == 2 ||column == 3 ||column == 4)
                   TableModel model = jt.getModel();
              float     q= ((Float)model.getValueAt(row,1)).floatValue();
              float     w= ((Float)model.getValueAt(row,2)).floatValue();
              float     t= ((Float)model.getValueAt(row,3)).floatValue();
              float     r= ((Float)model.getValueAt(row,4)).floatValue();
                   Float tMark = new Float((q*w+t*r)/(w+r) );
                   model.setValueAt(tMark, row, 5);
    // Which cells are editable.
    // It is only necessary to implement this method
    // if the table is editable
    public boolean isCellEditable(int row, int col)
    { return true; //All cells are editable
    public static void main(String[] args) {
         NodesTable t=new NodesTable();
    }

    There are too many mistakes in your program. It looks like you are new to java.
    Your add and delete row buttons are not working because you haven't registered your action listener with these buttons.
    I have modifide your code and now it works fine. Just put some validation code for the textboxes becuase it throws exception when user presses add button without entering anything.
    Here is the updated code: Do the diff and u will know my changes
    * Created on 03-Aug-2005
    * TODO To change the template for this generated file go to
    * Window - Preferences - Java - Code Style - Code Templates
    * @author Administrator
    * TODO To change the template for this generated type comment go to Window -
    * Preferences - Java - Code Style - Code Templates
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.JTextField;
    import javax.swing.event.TableModelEvent;
    import javax.swing.event.TableModelListener;
    import javax.swing.table.DefaultTableColumnModel;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableColumn;
    import javax.swing.table.TableModel;
    public class NodesTable extends JFrame implements TableModelListener,
              ActionListener {
         JTable jt;
         DefaultTableColumnModel dtcm;
         TableColumn column[] = new TableColumn[100];
         DefaultTableModel dtm;
         JLabel Name, m1, w1, m2, w2;
         JTextField NameTF, m1TF, w1TF, m2TF, w2TF;
         String c[] = { "Name", "Assessment1", "Weight1", "Assessment2", "Weight2 ",
                   "TotalMark" };
         float x = 0, y = 0, tMark = 0, z = 0;
         float j = 0;
         int i;
         JButton DelButton;
         JButton AddButton;
         JScrollPane scrollPane;
         JPanel mainPanel, buttonPanel;
         JFrame frame;
         public NodesTable() {
              super("Student Marking Spreadsheet");
              this.AddNodesintoTable();
              setSize(400, 250);
              setVisible(true);
         public void AddNodesintoTable() {
              // Create a vector object and load them with the data
              // to be placed on each row of the table
              dtm = new DefaultTableModel(c,0);
              dtm.addTableModelListener(this);
              jt = new JTable(dtm) {
                   // The Cost is not editable
                   public boolean isCellEditable(int row, int column) {
                        int modelColumn = convertColumnIndexToModel(column);
                        return (modelColumn == 5) ? false : true;
              //****************************User Input**************************
              //Add another node
              //Creating and setting the properties
              //of the panel's component (panels and textfields)
              Name = new JLabel("Name");
              Name.setForeground(Color.black);
              m1 = new JLabel("Mark1");
              m1.setForeground(Color.black);
              w1 = new JLabel("Weigth1");
              w1.setForeground(Color.black);
              m2 = new JLabel("Mark2");
              m2.setForeground(Color.black);
              w2 = new JLabel("Weight2");
              w2.setForeground(Color.black);
              NameTF = new JTextField(5);
              NameTF.setText("Node");
              m1TF = new JTextField(5);
              w1TF = new JTextField(5);
              m2TF = new JTextField(5);
              w2TF = new JTextField(5);
              //creating the buttons
              JPanel buttonPanel = new JPanel();
              AddButton = new JButton("Add Row");
              AddButton.addActionListener(this);
              DelButton = new JButton("Delete");
              DelButton.addActionListener(this);
              buttonPanel.add(AddButton);
              buttonPanel.add(DelButton);
              //adding the components to the panel
              JPanel inputpanel = new JPanel();
              inputpanel.add(Name);
              inputpanel.add(NameTF);
              inputpanel.add(m1);
              inputpanel.add(m1TF);
              inputpanel.add(w1);
              inputpanel.add(w1TF);
              inputpanel.add(m2);
              inputpanel.add(m2TF);
              inputpanel.add(w2TF);
              inputpanel.add(w2);
              inputpanel.add(AddButton);
              inputpanel.add(DelButton);
              //creating the panel and setting its properties
              JPanel tablepanel = new JPanel();
              tablepanel.add(new JScrollPane(jt,
                        JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                        JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS));
              getContentPane().add(tablepanel, BorderLayout.CENTER);
              getContentPane().add(inputpanel, BorderLayout.SOUTH);
         //Method to add row for each new entry
         public void addRow() {
              Float z = new Float(m2TF.getText());
              String Name = NameTF.getText();
              Float x = new Float(m1TF.getText());
              Float y = new Float(w1TF.getText());
              Float j = new Float(w2TF.getText());
              String newdata[] = { Name, String.valueOf(x), String.valueOf(y),
                        String.valueOf(z), String.valueOf(j) };
              dtm.addRow(newdata);
         // Method to delete a row from the spreadsheet
         void deleteRow(int index) {
              if (index != -1) //At least one Row in Table
                   dtm.removeRow(index);
                   jt.addNotify();
         // Method that adds and deletes rows
         // from the table by pressing the
         //corresponding buttons
         public void actionPerformed(ActionEvent ae) {
              Object source = ae.getSource();
              if (ae.getSource() == (JButton) AddButton) {
                   addRow();
              if (ae.getSource() == (JButton) DelButton) {
                   deleteRow(jt.getSelectedRow());
         //method to calculate the total mark in the TotalMark column
         //that updates the values in every other column
         //It takes the values from the column 1,2,3,4
         //and changes the value in the column 5
         public void tableChanged(TableModelEvent e) {
              System.out.println(e.getSource());
              //if (e.getType() == TableModelEvent.UPDATE) {
                   int row = e.getFirstRow();
                   int column = e.getColumn();
                   if (column == 1 || column == 2 || column == 3 || column == 4) {
                        TableModel model = jt.getModel();
                        float q = (new Float(model.getValueAt(row, 1).toString())).floatValue();
                        float w = (new Float(model.getValueAt(row, 2).toString())).floatValue();
                        float t = (new Float(model.getValueAt(row, 3).toString())).floatValue();
                        float r = (new Float(model.getValueAt(row, 4).toString())).floatValue();
                        Float tMark = new Float((q * w + t * r) / (w + r));
                        model.setValueAt(tMark, row, 5);
         // Which cells are editable.
         // It is only necessary to implement this method
         // if the table is editable
         public boolean isCellEditable(int row, int col) {
              return true; //All cells are editable
         public static void main(String[] args) {
              NodesTable t = new NodesTable();
    }

  • Problem with checkbox in JTable when using MyTableModel

    Hi all,
    I have been trawling these message boards for days looking for the answer to my question but have not had any success.
    I am extending AbstractTabel model to create MyTableModel which returns a vector containing the results of a MySql query. One column in this query returns a "0" or "1" which I then store as the boolean value into the vector so that it is rendered as a checkbox on the screen.
    I have also overridden the setValueAt method. THe problem is that when I attempt to check the box in the table, the checkbox isn't actually checking.
    Do I need to implement some sort of listener which picks up the user clicking the box and refresh the model?
    Here is my model code:
    public class MyTableModel extends AbstractTableModel {
        private Vector v = null;
        int listId;
        MyTableModel(int listId){
            this.listId = listId;
            v = new ListItemManagement().getFullList(listId);
       public Class getColumnClass(int c) {
            switch(c) {
                case 6:
                    return Boolean.class;
                default:
                    return Object.class;
        public String getColumnName(int colIndex){
            return ((String[])v.get(0))[colIndex];
        public int getColumnCount() {
            return ((String[])v.get(0)).length;
        public int getRowCount() {
            return (v.size() - 1);
        public Object getValueAt(int rowIndex, int colIndex) {
            return ((Object[])v.get(rowIndex + 1))[colIndex];
        public void setValueAt(Object aValue, int rowIndex, int colIndex) {
            System.out.println("Value: " + String.valueOf(aValue));
            Object row[] = (Object[]) v.elementAt(rowIndex);
            if(colIndex<6){
                row[colIndex] = (String)aValue;
            else{
                row[colIndex] = (Boolean)aValue;
            v.setElementAt(row, rowIndex);
            fireTableCellUpdated(rowIndex, colIndex);
        public boolean isCellEditable(int row, int col) {
            //Note that the data/cell address is constant,
            //no matter where the cell appears onscreen.
            return ! (col < 6);
        }Here is the getFullList function which returns the vector:
                rs = stmt.executeQuery();
                ResultSetMetaData colData = rs.getMetaData();
                int columnCount = colData.getColumnCount();
                String[] columnNames = new String[columnCount];
                for (int i = 0; i < columnCount; i++){
                    columnNames[i] = colData.getColumnName(i + 1);
                Vector v = new Vector();
                v.add(columnNames);
                while (rs.next()){
                    Object[] values = new Object[columnCount];
                    for (int i = 0; i < (columnCount-1); i++){
                        values[i] = rs.getString(i + 1);
                    int sel = rs.getInt("selected");
                    System.out.println(sel);;
                    if(sel==0){
                        values[columnCount-1]=new Boolean(false);
                    else if (sel==1)
                        values[columnCount-1]=new Boolean(true);
                    v.add(values);
                rs.close();
                stmt.close();
                return v;

    Thanks for the replies, much appreciated.
    I've looked at the Swing jtable tutorial and added a TableModelListener and have managed to achieve the desired results but for one thing.
    When I attempt to check the box on the first row of the jTable I get a runtime error:
    Exception in thread "AWT-EventQueue-0" java.lang.ArrayStoreException: java.lang.Boolean
    at project.MyTableModel.setValueAt(MyTableModel.java:65)
    I have been playing around with the setValueAt method and it is in my original post. Here is how it currently looks:
        public void setValueAt(Object aValue, int rowIndex, int colIndex) {
            System.out.println("Value: " + String.valueOf(aValue));
            Object row[] = (Object[]) v.elementAt(rowIndex);
            if(colIndex<6){
                row[colIndex] = (String)aValue;
            else{
                    if(getValueAt(rowIndex,colIndex).toString()=="true"){
                    row[6] = new Boolean(false);
                else{
                    row[6] = new Boolean(true);
            v.setElementAt(row, rowIndex);
            fireTableCellUpdated(rowIndex, colIndex);
        }

  • JTable displays string in wrong order : my code problem or Java problem ?

    I have the following code that displays data in a JTable, most of the time it works fine, but I've realized when I have a cell with values like : "Snowboarding"+"[123456789]"
    It would display it as : [Snowboarding[123456789
    For a string like : "Chasing toddlers"+"<123456789>"
    It would display it as : <Chasing toddlers<123456789
    It not only moved the last bracket to the front, but also changed its direction from "]" to "[" and from ">" to "<"
    Is there anything wrong with my code ? Or is this a Java problem ?
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.table.*;
    import java.io.*;
    import java.sql.*;
    import java.util.*;
    import java.util.List;
    import javax.swing.event.TableModelEvent;
    import javax.swing.event.TableModelListener;
    public class Table_Panel extends JPanel implements ItemListener
      public static final long serialVersionUID=26362862L;
      static final int Row_Color_Style_Default=-1,Row_Color_Style_None=0,Row_Color_Style_Blue_Gray=1,Row_Color_Style_Cyan_Gray=2,Row_Color_Style_Blue=3,
                       Row_Color_Style_Gray=4,Row_Color_Style_Red_Green=5,Row_Color_Style_Green_Yellow=6,Row_Color_Style_Red_Yellow=7,
                       Max_Header_Cell_Width=0,Header_Width=1,Cell_Width=2;
      static int Row_Color_Style=Row_Color_Style_Cyan_Gray,Preffered_Width=Header_Width;
    //  static int Row_Color_Style=Row_Color_Style_None,Preffered_Width=Header_Width;
    //boolean        Debug=true,
      boolean        Debug=false,
    //               Use_Row_Colors=true,
                     Use_Row_Colors=false;
      JFrame Table_Frame;
      TableModel My_Model;
      JScrollPane scrollPane=new JScrollPane();
      public JTable Table;
      static String columnNames[],Default_Delimiter=\",\";
      Object[][] data;
      static Dimension Screen_Size=Toolkit.getDefaultToolkit().getScreenSize();
      int Column_Width[];
      static Color Default_Selection_Color=new Color(250,135,200);
      Color Selection_Color=Default_Selection_Color;
      public Table_Panel(ResultSet RS,String Table_Name,boolean Show_External_Table,int Row_Color_Style,int Preffered_Width,boolean In_Original_Order)
        String Value,Table_Column_Names[]=null;
        Object[][] Table_Data=null;
        int Row_Count,Index=0;
        try
          if (RS==null) return;
          else
            RS.last();
            Row_Count=RS.getRow();
            RS.beforeFirst();
          ResultSetMetaData rsmd=RS.getMetaData();
          int Column_Count=rsmd.getColumnCount();
          Table_Column_Names=new String[Column_Count];
          Table_Data=new Object[Row_Count][Column_Count];
          for (int i=1;i<=Column_Count;i++) Table_Column_Names[i-1]=rsmd.getColumnLabel(i);            // Get column names
    //Out("Row_Count="+Row_Count+"  Column_Count="+Column_Count);
          while (RS.next())                                                                            // Get all rows
            for (int i=1;i<=Column_Count;i++)
              Value=RS.getString(i);
              Table_Data[Index][i-1]=(Value==null)?"null":Value;
            Index++;
    //      if (Test_Ct++>300) break;
        catch (Exception e) { e.printStackTrace(); }
        scrollPane=new Table_Panel(Table_Name,Table_Column_Names,Table_Data,Table_Data.length,false,Show_External_Table,false,Row_Color_Style,Preffered_Width,Selection_Color,In_Original_Order).scrollPane;
      public Table_Panel(String[] Table_Column_Names,Object[][] Table_Data,Color Selection_Color,boolean In_Original_Order)
        this("",Table_Column_Names,Table_Data,Table_Data.length,false,false,false,Row_Color_Style,Preffered_Width,Selection_Color,In_Original_Order);
      public Table_Panel(String Table_Name,String[] Table_Column_Names,Object[][] Table_Data,boolean Show_External_Table,Color Selection_Color,boolean In_Original_Order)
        this(Table_Name,Table_Column_Names,Table_Data,Table_Data.length,false,Show_External_Table,false,Row_Color_Style,Preffered_Width,Selection_Color,In_Original_Order);
      public Table_Panel(String Table_Name,String[] Table_Column_Names,Object[][] Table_Data,int Row_Count,boolean Is_Child,boolean Show_External_Table,boolean Manage_Attachment,int Row_Color_Style,int Preffered_Width,Color Selection_Color,boolean In_Original_Order)
        columnNames=Table_Column_Names;
        if (In_Original_Order) data=Table_Data;
        else
          data=new Object[Table_Data.length][columnNames.length];
          for (int row=0;row<Table_Data.length;row++)
            data[row]=new Object[columnNames.length];
            for (int Column=0;Column<Table_Data[row].length;Column++) data[row][Column]=Table_Data[Table_Data.length-1-row][Column];
        Column_Width=new int[columnNames.length];
        this.Row_Color_Style=Row_Color_Style;
        Use_Row_Colors=(Row_Color_Style!=Row_Color_Style_None);
        this.Preffered_Width=Preffered_Width;
        if (Selection_Color!=null) this.Selection_Color=Selection_Color;
    //    Out("this.Selection_Color="+this.Selection_Color);
    //    TableModel My_Model=new DefaultTableModel(Table_Data,columnNames)
        TableModel My_Model=new DefaultTableModel(data,columnNames)
          public int getColumnCount() { return columnNames.length; }
          public int getRowCount() { return data.length; }
          public String getColumnName(int col) { return columnNames[col]; }
          public Object getValueAt(int row,int col)
    //      Out(row+","+col+"["+data[row][col]+"]   data.length="+data.length+"  data[0].length="+data[0].length);
            return (data[row][col]==null)?"":((data[row][col] instanceof Boolean)?data[row][col]:data[row][col].toString()); // Non-boolean values will have bgcolor
          public Class getColumnClass(int column)
            Class returnValue;
            if ((column>=0) && (column<getColumnCount())) returnValue=getValueAt(0,column).getClass();
            else returnValue=Object.class;
            return returnValue;
        // JTable uses this method to determine the default renderer/editor for each cell. If we didn't implement this method, then the last column would contain text ("true"/"false"), rather than a check box.
    //    public Class getColumnClass(int c) { return getValueAt(0,c).getClass(); }
          // Don't need to implement this method unless your table's editable.
          public boolean isCellEditable(int row,int col)
            //Note that the data/cell address is constant, no matter where the cell appears onscreen.
            if (col<0) return false;
            else return true;
          // Don't need to implement this method unless your table's data can change.
          public void setValueAt(Object value,int row,int col)
            String Execution_Dir=getClass().getProtectionDomain().getCodeSource().getLocation().toString();
            if (Debug) System.out.println("Execution_Dir="+Execution_Dir+"\nLast_Value="+Table_Grid_Cell_Renderer.Last_Value+"  Setting value at [ "+row+","+col+" ] to "+value+" (an instance of "+value.getClass()+")");
            if (Execution_Dir.toLowerCase().indexOf("c:/")!=-1 || value.getClass()==Boolean.class || !Use_Row_Colors) data[row][col]=value;
    //     else data[row][col]=(Table_Grid_CellRenderer.Last_Value==null)?value:value.toString().substring(Table_Grid_CellRenderer.Last_Value.toString().length());
            fireTableCellUpdated(row,col);
            if (Debug)
              System.out.println("New value of data :");
              printDebugData();
          private void printDebugData()
            int numRows=getRowCount();
            int numCols=getColumnCount();
            for (int i=0;i<numRows;i++)
              System.out.print("    row "+i+":");
              for (int j=0;j<numCols;j++) System.out.print("  "+data[i][j]);
              System.out.println();
            System.out.println("--------------------------------------------------------------------------");
        TableSorter sorter=new TableSorter(My_Model);
        Table=new JTable(sorter)
    //    Table=new JTable(My_Model)
          public static final long serialVersionUID=26362862L;
          public String getToolTipText(MouseEvent e)           // Implement table cell tool tips.
            Object Cell_Tip;
            String tip=null;
            java.awt.Point p=e.getPoint();
            int rowIndex=rowAtPoint(p);
            int colIndex=columnAtPoint(p);
            int realColumnIndex=convertColumnIndexToModel(colIndex);
            Cell_Tip=getValueAt(rowIndex,colIndex);
    //        if (realColumnIndex == 2)                         //Sport column
              tip=Cell_Tip.toString();
            else if (realColumnIndex == 4)                      //Veggie column
              TableModel model=getModel();
              String firstName=(String)model.getValueAt(rowIndex,0);
              String lastName=(String)model.getValueAt(rowIndex,1);
              Boolean veggie=(Boolean)model.getValueAt(rowIndex,4);
              if (Boolean.TRUE.equals(veggie)) tip=firstName+" "+lastName+" is a vegetarian";
              else tip=firstName+" "+lastName+" is not a vegetarian";
            else
              // You can omit this part if you know you don't have any renderers that supply their own tool tips.
              tip=super.getToolTipText(e);
            return tip;
    //    RowSorter<TableModel> sorter=new TableRowSorter<TableModel>(My_Model);
    //    Table.setRowSorter(sorter);
        Table.setSelectionBackground(this.Selection_Color);
        int Table_Height=Table.getRowHeight()*Row_Count;
        // sorter.addMouseListenerToHeaderInTable(Table);      // ADDED THIS
        sorter.setTableHeader(Table.getTableHeader());
        if (Table_Column_Names.length>20) Table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        if (Manage_Attachment) Table.setPreferredScrollableViewportSize(new Dimension(500,(Table_Height>850)?850:Table_Height));
        else Table.setPreferredScrollableViewportSize(new Dimension(1000,(Table_Height>850)?850:Table_Height));
        if (Use_Row_Colors) Table.setDefaultRenderer(Object.class,new Table_Grid_Cell_Renderer());
        //Create the scroll pane and add the table to it.
        scrollPane=new JScrollPane(Table);
        //Set up column sizes.
        initColumnSizes(Table,My_Model);
        //Add the scroll pane to this window.
        if (Show_External_Table)
          Table_Frame=new JFrame(Table_Name);
          Table_Frame.getContentPane().add(scrollPane);
          Table_Frame.addWindowListener(new WindowAdapter()
            public void windowActivated(WindowEvent e) { }
            public void windowClosed(WindowEvent e) { }
            public void windowClosing(WindowEvent e)  { System.exit(0); }
            public void windowDeactivated(WindowEvent e)  { }
            public void windowDeiconified(WindowEvent e)  { scrollPane.repaint(); }
            public void windowGainedFocus(WindowEvent e)  { scrollPane.repaint(); }
            public void windowIconified(WindowEvent e)  { }
            public void windowLostFocus(WindowEvent e)  { }
            public void windowOpening(WindowEvent e) { scrollPane.repaint(); }
            public void windowOpened(WindowEvent e)  { }
            public void windowResized(WindowEvent e) { scrollPane.repaint(); } 
            public void windowStateChanged(WindowEvent e) { scrollPane.repaint(); }
          Table_Frame.pack();
          Table_Frame.setBounds((Screen_Size.width-Table_Frame.getWidth())/2,(Screen_Size.height-Table_Frame.getHeight())/2,Table_Frame.getWidth(),Table_Frame.getHeight());
          Table_Frame.setVisible(true);
          if (Is_Child) Table_Frame.addComponentListener(new ComponentAdapter() { public void componentClosing(ComponentEvent e) { System.exit(0); } });
        else add(scrollPane);
      public Table_Panel(String File_Name) { this(File_Name,false,Row_Color_Style_Cyan_Gray,Preffered_Width,null,Default_Selection_Color,true); }
      public Table_Panel(String File_Name,int Row_Color_Style,boolean In_Original_Order) { this(File_Name,false,Row_Color_Style,Preffered_Width,null,Default_Selection_Color,In_Original_Order); }
      public Table_Panel(String File_Name,String Delimiter,boolean In_Original_Order) { this(File_Name,false,Row_Color_Style_Cyan_Gray,Preffered_Width,Delimiter,Default_Selection_Color,In_Original_Order); }
      public Table_Panel(String File_Name,int Preffered_Width,String Delimiter,boolean In_Original_Order) { this(File_Name,false,Row_Color_Style,Preffered_Width,Delimiter,Default_Selection_Color,In_Original_Order); }
      public Table_Panel(String File_Name,int Row_Color_Style,int Preffered_Width,String Delimiter,boolean In_Original_Order) { this(File_Name,false,Row_Color_Style,Preffered_Width,Delimiter,Default_Selection_Color,In_Original_Order); }
      public Table_Panel(String File_Name,boolean Show_External_Table,boolean In_Original_Order) { this(File_Name,Show_External_Table,Row_Color_Style,Preffered_Width,null,Default_Selection_Color,In_Original_Order); }
      public Table_Panel(String File_Name,boolean Show_External_Table,String Delimiter,boolean In_Original_Order) { this(File_Name,Show_External_Table,Row_Color_Style,Preffered_Width,Delimiter,Default_Selection_Color,In_Original_Order); }
      public Table_Panel(String File_Name,boolean Show_External_Table,int Row_Color_Style,int Preffered_Width,String Delimiter,Color Selection_Color,boolean In_Original_Order)
        String Table_Column_Names[],Column_Name_Line="";
        int Row_Count=0,Index=0;
        boolean Is_Child=false,Manage_Attachment=false;
        StringTokenizer ST;
        if (Delimiter==null) Delimiter=Default_Delimiter;
        if (new File(File_Name).exists())
          try
            String Line,Str=Tool_Lib.Read_File(File_Name).toString();
            ST=new StringTokenizer(Str,"\n");
            Line=ST.nextToken();
            Row_Count=ST.countTokens();
            Object[][] Table_Data=new Object[Row_Count][];
            if (Delimiter.equals(" ")) Line=Line.replaceAll(" {2,}"," ").trim();     // Replace multiple spaces with the delimiter space
            Table_Column_Names=Line.split(Delimiter);
            columnNames=Table_Column_Names;
            for (int i=0;i<Table_Column_Names.length;i++) Column_Name_Line+=Table_Column_Names[i]+"  ";
    //Out("Column_Name_Line [ "+Table_Column_Names.length+" ]="+Column_Name_Line);
            while (ST.hasMoreTokens())
              Line=ST.nextToken();
    //Out(Line);
              if (Delimiter.equals(" ")) Line=Line.replaceAll(" {2,}"," ").trim();   // Replace multiple spaces with the delimiter space
              if (Line.indexOf(Delimiter)!=-1) Table_Data[Index]=Line.split(Delimiter);
              else
                Table_Data[Index]=new Object[Table_Column_Names.length];
                Table_Data[Index][0]=Line;
                for (int i=1;i<Table_Column_Names.length;i++) Table_Data[Index]="";
    Index++;
    Line="";
    for (int i=0;i<Table_Data.length;i++)
    Line+="[ "+Table_Data[i].length+" ] ";
    for (int j=0;j<Table_Data[i].length;j++) Line+=Table_Data[i][j]+" ";
    Line+="\n";
    Out(Line);
    Table_Panel A_Table_Panel=new Table_Panel(File_Name,Table_Column_Names,Table_Data,Row_Count,Is_Child,Show_External_Table,Manage_Attachment,Row_Color_Style,Preffered_Width,Selection_Color,In_Original_Order);
    Table=A_Table_Panel.Table;
    scrollPane=A_Table_Panel.scrollPane;
    Column_Width=A_Table_Panel.Column_Width;
    data=A_Table_Panel.data;
    catch (Exception e) { e.printStackTrace(); }
    public void setPreferredSize(Dimension A_Dimension) { scrollPane.setPreferredSize(A_Dimension); }
    // This method picks good column sizes. If all column heads are wider than the column's cells' contents, then you can just use column.sizeWidthToFit().
    void initColumnSizes(JTable table,TableModel model)
    TableColumn column=null;
    Component comp=null;
    int headerWidth=0,cellWidth=0;
    Object[] longValues=(data.length>0)?data[0]:null;
    TableCellRenderer headerRenderer=table.getTableHeader().getDefaultRenderer();
    if (data.length<1) return;
    for (int i=0;i<model.getColumnCount();i++)
    column=table.getColumnModel().getColumn(i);
    comp=headerRenderer.getTableCellRendererComponent(null,column.getHeaderValue(),false,false,0,0);
    headerWidth=comp.getPreferredSize().width;
    comp=table.getDefaultRenderer(model.getColumnClass(i)).
    getTableCellRendererComponent(table,longValues[i],false,false,0,i);
    cellWidth=comp.getPreferredSize().width;
    switch (Preffered_Width)
    case Max_Header_Cell_Width : column.setPreferredWidth(Math.max(headerWidth,cellWidth));break;
    case Header_Width : column.setPreferredWidth(headerWidth);break;
    case Cell_Width : column.setPreferredWidth(cellWidth);break;
    Column_Width[i]=column.getPreferredWidth();
    if (Debug) Out("Initializing width of column "+i+". "+"headerWidth="+headerWidth+"; cellWidth="+cellWidth+" Column_Width["+i+"]="+Column_Width[i]);
    // Detects a state change in any of the Lists. Resets the variable corresponding to the selected item in a particular List. Invokes changeFont with the currently selected fontname, style and size attributes.
    public void itemStateChanged(ItemEvent e)
    Out(e.toString());
    if (e.getStateChange() != ItemEvent.SELECTED) return;
    Object list=e.getSource();
    public static void Out(String message) { System.out.println(message); }
    // Create the GUI and show it. For thread safety, this method should be invoked from the event-dispatching thread.
    static void Create_And_Show_GUI()
    boolean Demo_External_Table=true;
    // boolean Demo_External_Table=false;
    final Table_Panel demo;
    String[] columnNames={"First Names","Last Names","Sport","Num of Years","Vegetarian"};
    Object[][] data={{"Mary","Campione","Snowboarding"+"[123456789]",new Integer(5),new Boolean(false)},
    {"Alison","Huml","Rowing"+":123456789]",new Integer(3),new Boolean(true)},
    {"Frank","Ni","Running"+":123456789", new Integer(12), new Boolean(false)},
    {"Kathy","Walrath","Chasing toddlers"+"<123456789>", new Integer(2), new Boolean(false)},
    {"Mark", "Andrews","Speed reading",new Integer(20),new Boolean(true)},
    {"Angela","Lih","Teaching high school",new Integer(36),new Boolean(false)} };
    // Row_Color_Style=Row_Color_Style_Default;
    // Row_Color_Style=Row_Color_Style_None;
    // Row_Color_Style=Row_Color_Style_Blue_Gray;
    Row_Color_Style=Row_Color_Style_Cyan_Gray;
    // Row_Color_Style=Row_Color_Style_Blue;
    // Row_Color_Style=Row_Color_Style_Gray;
    // Row_Color_Style=Row_Color_Style_Red_Green;
    // Row_Color_Style=Row_Color_Style_Green_Yellow;
    // Row_Color_Style=Row_Color_Style_Red_Yellow;
    Preffered_Width=Max_Header_Cell_Width;
    if (Demo_External_Table) demo=new Table_Panel("External Table Demo",columnNames,data,data.length,false,Demo_External_Table,false,Row_Color_Style,Max_Header_Cell_Width,Default_Selection_Color,true);
    else
    JFrame Table_Frame=new JFrame("Internal Table Demo");
    // demo=new Table_Panel(Nm_Lib.Dir_A_Test+"ELX.csv",false,Row_Color_Style,Preffered_Width,null);
    // demo=new Table_Panel(Nm_Lib.Dir_Stock_Data+"ABV_Data.txt",false,Row_Color_Style,Preffered_Width," ");
    demo=new Table_Panel("C:/Dir_Stock_Data/EOP.txt",",",false);
    // demo=new Table_Panel(Nm_Lib.Dir_Stock_Data+"ABV_Data.txt"," ",false);
    Table_Frame.getContentPane().add(demo.scrollPane);
    Table_Frame.addWindowListener(new WindowAdapter()
    public void windowActivated(WindowEvent e) { }
    public void windowClosed(WindowEvent e) { }
    public void windowClosing(WindowEvent e) { System.exit(0); }
    public void windowDeactivated(WindowEvent e) { }
    public void windowDeiconified(WindowEvent e) { demo.repaint(); }
    public void windowGainedFocus(WindowEvent e) { demo.repaint(); }
    public void windowIconified(WindowEvent e) { }
    public void windowLostFocus(WindowEvent e) { }
    public void windowOpening(WindowEvent e) { demo.repaint(); }
    public void windowOpened(WindowEvent e) { }
    public void windowResized(WindowEvent e) { demo.repaint(); }
    public void windowStateChanged(WindowEvent e) { demo.repaint(); }
    Table_Frame.pack();
    Table_Frame.setBounds((Screen_Size.width-Table_Frame.getWidth())/2,(Screen_Size.height-Table_Frame.getHeight())/2,Table_Frame.getWidth(),Table_Frame.getHeight());
    Table_Frame.setVisible(true);
    public static void main(String[] args)
    // Schedule a job for the event-dispatching thread : creating and showing this application's GUI.
    SwingUtilities.invokeLater(new Runnable() { public void run() { Create_And_Show_GUI(); } });
    * TableSorter is a decorator for TableModels; adding sorting functionality to a supplied TableModel. TableSorter does not store
    * or copy the data in its TableModel; instead it maintains a map from the row indexes of the view to the row indexes of the
    * model. As requests are made of the sorter (like getValueAt(row, col)) they are passed to the underlying model after the row numbers
    * have been translated via the internal mapping array. This way, the TableSorter appears to hold another copy of the table
    * with the rows in a different order.
    * <p/>
    * TableSorter registers itself as a listener to the underlying model, just as the JTable itself would. Events recieved from the model
    * are examined, sometimes manipulated (typically widened), and then passed on to the TableSorter's listeners (typically the JTable).
    * If a change to the model has invalidated the order of TableSorter's rows, a note of this is made and the sorter will resort the
    * rows the next time a value is requested.
    * <p/>
    * When the tableHeader property is set, either by using the setTableHeader() method or the two argument constructor, the table
    * header may be used as a complete UI for TableSorter. The default renderer of the tableHeader is decorated with a renderer
    * that indicates the sorting status of each column. In addition, a mouse listener is installed with the following behavior:
    * <ul>
    * <li>
    * Mouse-click: Clears the sorting status of all other columns and advances the sorting status of that column through three
    * values: {NOT_SORTED, ASCENDING, DESCENDING} (then back to NOT_SORTED again).
    * <li>
    * SHIFT-mouse-click: Clears the sorting status of all other columns and cycles the sorting status of the column through the same
    * three values, in the opposite order: {NOT_SORTED, DESCENDING, ASCENDING}.
    * <li>
    * CONTROL-mouse-click and CONTROL-SHIFT-mouse-click: as above except that the changes to the column do not cancel the statuses of columns
    * that are already sorting - giving a way to initiate a compound sort.
    * </ul>
    * <p/>
    * This is a long overdue rewrite of a class of the same name that first appeared in the swing table demos in 1997.
    * @author Philip Milne
    * @author Brendon McLean
    * @author Dan van Enckevort
    * @author Parwinder Sekhon
    * @version 2.0 02/27/04
    class TableSorter extends AbstractTableModel
    public static final long serialVersionUID=26362862L;
    protected TableModel tableModel;
    public static final int DESCENDING = -1;
    public static final int NOT_SORTED = 0;
    public static final int ASCENDING = 1;
    private static Directive EMPTY_DIRECTIVE = new Directive(-1, NOT_SORTED);
    public static final Comparator COMPARABLE_COMAPRATOR = new Comparator() { public int compare(Object o1, Object o2) { return ((Comparable) o1).compareTo(o2); } };
    public static final Comparator LEXICAL_COMPARATOR = new Comparator() { public int compare(Object o1, Object o2) { return o1.toString().compareTo(o2.toString()); } };
    private Row[] viewToModel;
    private int[] modelToView;
    private JTableHeader tableHeader;
    private MouseListener mouseListener;
    private TableModelListener tableModelListener;
    private Map<Class,Comparator> columnComparators = new HashMap<Class,Comparator>();
    private List<Directive> sortingColumns = new ArrayList<Directive>();
    public TableSorter()
    this.mouseListener = new MouseHandler();
    this.tableModelListener = new TableModelHandler();
    public TableSorter(TableModel tableModel)
    this();
    setTableModel(tableModel);
    public TableSorter(TableModel tableModel, JTableHeader tableHeader)
    this();
    setTableHeader(tableHeader);
    setTableModel(tableModel);
    private void clearSortingState()
    viewToModel = null;
    modelToView = null;
    public TableModel getTableModel() { return tableModel; }
    public void setTableModel(TableModel tableModel)
    if (this.tableModel != null) { this.tableModel.removeTableModelListener(tableModelListener); }
    this.tableModel = tableModel;
    if (this.tableModel != null) { this.tableModel.addTableModelListener(tableModelListener); }
    clearSortingState();
    fireTableStructureChanged();
    public JTableHeader getTableHeader() { return tableHeader; }
    public void setTableHeader(JTableHeader tableHeader)
    if (this.tableHeader != null)
    this.tableHeader.removeMouseListener(mouseListener);
    TableCellRenderer defaultRenderer = this.tableHeader.getDefaultRenderer();
    if (defaultRenderer instanceof SortableHeaderRenderer) this.tableHeader.setDefaultRenderer(((SortableHeaderRenderer) defaultRenderer).tableCellRenderer);
    this.tableHeader = tableHeader;
    if (this.tableHeader != null)
    this.tableHeader.addMouseListener(mouseListener);
    this.tableHeader.setDefaultRenderer(
    new SortableHeaderRenderer(this.tableHeader.getDefaultRenderer()));
    public boolean isSorting() { return sortingColumns.size() != 0; }
    private Directive getDirective(int column)
    for (int i = 0; i < sortingColumns.size(); i++)
    Directive directive = (Directive)sortingColumns.get(i);
    if (directive.column == column) { return directive; }
    return EMPTY_DIRECTIVE;
    public int getSortingStatus(int column) { return getDirective(column).direction; }
    private void sortingStatusChanged()
    clearSortingState();
    fireTableDataChanged();
    if (tableHeader != null) { tableHeader.repaint(); }
    public void setSortingStatus(int column, int status)
    Directive directive = getDirective(column);
    if (directive != EMPTY_DIRECTIVE) { sortingColumns.remove(directive); }
    if (status != NOT_SORTED) { sortingColumns.add(new Directive(column, status)); }
    sortingStatusChanged();
    protected Icon getHeaderRendererIcon(int column, int size)
    Directive directive = getDirective(column);
    if (directive == EMPTY_DIRECTIVE) { return null; }
    return new Arrow(directive.direction == DESCENDING, size, sortingColumns.indexOf(directive));
    private void cancelSorting()
    sortingColumns.clear();
    sortingStatusChanged();
    public void setColumnComparator(Class type, Comparator comparator)
    if (comparator == null) { columnComparators.remove(type); }
    else { columnComparators.put(type, comparator); }
    protected Comparator getComparator(int column)
    Class columnType = tableModel.getColumnClass(column);
    Comparator comparator = (Comparator) columnComparators.get(columnType);
    if (comparator != null) { return comparator; }
    if (Comparable.class.isAssignableFrom(columnType)) { return COMPARABLE_COMAPRATOR; }
    return LEXICAL_COMPARATOR;
    private Row[] getViewToModel()
    if (viewToModel == null)
    int tableModelRowCount = tableModel.getRowCount();
    viewToModel = new Row[tableModelRowCount];
    for (int row = 0; row < tableModelRowCount; row++) { viewToModel[row] = new Row(row); }
    if (isSorting()) { Arrays.sort(viewToModel); }
    return viewToModel;
    public int modelIndex(int viewIndex) { return getViewToModel()[viewIndex].modelIndex; }
    private int[] getModelToView()
    if (modelToView == null)
    int n = getViewToModel().length;
    modelToView = new int[n];
    for (int i = 0; i < n; i++) { modelToView[modelIndex(i)] = i; }
    return modelToView;
    // TableModel interface methods
    public int getRowCount() { return (tableModel == null) ? 0 : tableModel.getRowCount(); }
    public int getColumnCount() { return (tableModel == null) ? 0 : tableModel.getColumnCount(); }
    public String getColumnName(int column) { return tableModel.getColumnName(column); }
    public Class getColumnClass(int column) { return tableModel.getColumnClass(column); }
    public boolean isCellEditable(int row, int column) { return tableModel.isCellEditable(modelIndex(row), column); }
    public Object getValueAt(int row, int column) { return tableModel.getValueAt(modelIndex(row), column); }
    public void setValueAt(Object aValue, int row, int column) { tableModel.setValueAt(aValue, modelIndex(row), column); }
    // Helper classes
    private class Row implements Comparable
    private int modelIndex;
    public Row(int index) { this.modelIndex = index; }
    public int compareTo(Object o)
    int row1 = modelIndex;
    int row2 = ((Row) o).modelIndex;
    for (Iterator it = sortingColumns.iterator(); it.hasNext();)
    Directive directive = (Directive) it.next();
    int column = directive.column;
    Object o1 = tableModel.getValueAt(row1, column);
    Object o2 = tableModel.getValueAt(row2, column);
    int comparison = 0;
    // Define null less than everything, except null.

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.table.*;
    import java.io.*;
    import java.sql.*;
    import java.util.*;
    import java.util.List;
    import javax.swing.event.TableModelEvent;
    import javax.swing.event.TableModelListener;
    public class Table_Panel extends JPanel implements ItemListener
      public static final long serialVersionUID=26362862L;
      static final int Row_Color_Style_Default=-1,Row_Color_Style_None=0,Row_Color_Style_Blue_Gray=1,Row_Color_Style_Cyan_Gray=2,Row_Color_Style_Blue=3,
                       Row_Color_Style_Gray=4,Row_Color_Style_Red_Green=5,Row_Color_Style_Green_Yellow=6,Row_Color_Style_Red_Yellow=7,
                       Max_Header_Cell_Width=0,Header_Width=1,Cell_Width=2;
      static int Row_Color_Style=Row_Color_Style_Cyan_Gray,Preffered_Width=Header_Width;
    //  static int Row_Color_Style=Row_Color_Style_None,Preffered_Width=Header_Width;
    //boolean        Debug=true,
      boolean        Debug=false,
    //               Use_Row_Colors=true,
                     Use_Row_Colors=false;
      JFrame Table_Frame;
      TableModel My_Model;
      JScrollPane scrollPane=new JScrollPane();
      public JTable Table;
      static String columnNames[],Default_Delimiter=",";
      Object[][] data;
      static Dimension Screen_Size=Toolkit.getDefaultToolkit().getScreenSize();
      int Column_Width[];
      static Color Default_Selection_Color=new Color(250,135,200);
      Color Selection_Color=Default_Selection_Color;
      public Table_Panel(ResultSet RS,String Table_Name,boolean Show_External_Table,int Row_Color_Style,int Preffered_Width,boolean In_Original_Order)
        String Value,Table_Column_Names[]=null;
        Object[][] Table_Data=null;
        int Row_Count,Index=0;
        try
          if (RS==null) return;
          else
            RS.last();
            Row_Count=RS.getRow();
            RS.beforeFirst();
          ResultSetMetaData rsmd=RS.getMetaData();
          int Column_Count=rsmd.getColumnCount();
          Table_Column_Names=new String[Column_Count];
          Table_Data=new Object[Row_Count][Column_Count];
          for (int i=1;i<=Column_Count;i++) Table_Column_Names[i-1]=rsmd.getColumnLabel(i);            // Get column names
    //Out("Row_Count="+Row_Count+"  Column_Count="+Column_Count);
          while (RS.next())                                                                            // Get all rows
            for (int i=1;i<=Column_Count;i++)
              Value=RS.getString(i);
              Table_Data[Index][i-1]=(Value==null)?"null":Value;
            Index++;
    //      if (Test_Ct++>300) break;
        catch (Exception e) { e.printStackTrace(); }
        scrollPane=new Table_Panel(Table_Name,Table_Column_Names,Table_Data,Table_Data.length,false,Show_External_Table,false,Row_Color_Style,Preffered_Width,Selection_Color,In_Original_Order).scrollPane;
      public Table_Panel(String[] Table_Column_Names,Object[][] Table_Data,Color Selection_Color,boolean In_Original_Order)
        this("",Table_Column_Names,Table_Data,Table_Data.length,false,false,false,Row_Color_Style,Preffered_Width,Selection_Color,In_Original_Order);
      public Table_Panel(String Table_Name,String[] Table_Column_Names,Object[][] Table_Data,boolean Show_External_Table,Color Selection_Color,boolean In_Original_Order)
        this(Table_Name,Table_Column_Names,Table_Data,Table_Data.length,false,Show_External_Table,false,Row_Color_Style,Preffered_Width,Selection_Color,In_Original_Order);
      public Table_Panel(String Table_Name,String[] Table_Column_Names,Object[][] Table_Data,int Row_Count,boolean Is_Child,boolean Show_External_Table,boolean Manage_Attachment,int Row_Color_Style,int Preffered_Width,Color Selection_Color,boolean In_Original_Order)
        columnNames=Table_Column_Names;
        if (In_Original_Order) data=Table_Data;
        else
          data=new Object[Table_Data.length][columnNames.length];
          for (int row=0;row<Table_Data.length;row++)
            data[row]=new Object[columnNames.length];
            for (int Column=0;Column<Table_Data[row].length;Column++) data[row][Column]=Table_Data[Table_Data.length-1-row][Column];
        Column_Width=new int[columnNames.length];
        this.Row_Color_Style=Row_Color_Style;
        Use_Row_Colors=(Row_Color_Style!=Row_Color_Style_None);
        this.Preffered_Width=Preffered_Width;
        if (Selection_Color!=null) this.Selection_Color=Selection_Color;
    //    Out("this.Selection_Color="+this.Selection_Color);
    //    TableModel My_Model=new DefaultTableModel(Table_Data,columnNames)
        TableModel My_Model=new DefaultTableModel(data,columnNames)
          public int getColumnCount() { return columnNames.length; }
          public int getRowCount() { return data.length; }
          public String getColumnName(int col) { return columnNames[col]; }
          public Object getValueAt(int row,int col)
    //      Out(row+","+col+"["+data[row][col]+"]   data.length="+data.length+"  data[0].length="+data[0].length);
            return (data[row][col]==null)?"":((data[row][col] instanceof Boolean)?data[row][col]:data[row][col].toString()); // Non-boolean values will have bgcolor
          public Class getColumnClass(int column)
            Class returnValue;
            if ((column>=0) && (column<getColumnCount())) returnValue=getValueAt(0,column).getClass();
            else returnValue=Object.class;
            return returnValue;
        // JTable uses this method to determine the default renderer/editor for each cell. If we didn't implement this method, then the last column would contain text ("true"/"false"), rather than a check box.
    //    public Class getColumnClass(int c) { return getValueAt(0,c).getClass(); }
          // Don't need to implement this method unless your table's editable.
          public boolean isCellEditable(int row,int col)
            //Note that the data/cell address is constant, no matter where the cell appears onscreen.
            if (col<0) return false;
            else return true;
          // Don't need to implement this method unless your table's data can change.
          public void setValueAt(Object value,int row,int col)
            String Execution_Dir=getClass().getProtectionDomain().getCodeSource().getLocation().toString();
            if (Debug) System.out.println("Execution_Dir="+Execution_Dir+"\nLast_Value="+Table_Grid_Cell_Renderer.Last_Value+"  Setting value at [ "+row+","+col+" ] to "+value+" (an instance of "+value.getClass()+")");
            if (Execution_Dir.toLowerCase().indexOf("c:/")!=-1 || value.getClass()==Boolean.class || !Use_Row_Colors) data[row][col]=value;
    //     else data[row][col]=(Table_Grid_CellRenderer.Last_Value==null)?value:value.toString().substring(Table_Grid_CellRenderer.Last_Value.toString().length());
            fireTableCellUpdated(row,col);
            if (Debug)
              System.out.println("New value of data :");
              printDebugData();
          private void printDebugData()
            int numRows=getRowCount();
            int numCols=getColumnCount();
            for (int i=0;i<numRows;i++)
              System.out.print("    row "+i+":");
              for (int j=0;j<numCols;j++) System.out.print("  "+data[i][j]);
              System.out.println();
            System.out.println("--------------------------------------------------------------------------");
        TableSorter sorter=new TableSorter(My_Model);
        Table=new JTable(sorter)
    //    Table=new JTable(My_Model)
          public static final long serialVersionUID=26362862L;
          public String getToolTipText(MouseEvent e)           // Implement table cell tool tips.
            Object Cell_Tip;
            String tip=null;
            java.awt.Point p=e.getPoint();
            int rowIndex=rowAtPoint(p);
            int colIndex=columnAtPoint(p);
            int realColumnIndex=convertColumnIndexToModel(colIndex);
            Cell_Tip=getValueAt(rowIndex,colIndex);
    //        if (realColumnIndex == 2)                         //Sport column
              tip=Cell_Tip.toString();
            else if (realColumnIndex == 4)                      //Veggie column
              TableModel model=getModel();
              String firstName=(String)model.getValueAt(rowIndex,0);
              String lastName=(String)model.getValueAt(rowIndex,1);
              Boolean veggie=(Boolean)model.getValueAt(rowIndex,4);
              if (Boolean.TRUE.equals(veggie)) tip=firstName+" "+lastName+" is a vegetarian";
              else tip=firstName+" "+lastName+" is not a vegetarian";
            else
              // You can omit this part if you know you don't have any renderers that supply their own tool tips.
              tip=super.getToolTipText(e);
            return tip;
    //    RowSorter<TableModel> sorter=new TableRowSorter<TableModel>(My_Model);
    //    Table.setRowSorter(sorter);
        Table.setSelectionBackground(this.Selection_Color);
        int Table_Height=Table.getRowHeight()*Row_Count;
        // sorter.addMouseListenerToHeaderInTable(Table);      // ADDED THIS
        sorter.setTableHeader(Table.getTableHeader());
        if (Table_Column_Names.length>20) Table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        if (Manage_Attachment) Table.setPreferredScrollableViewportSize(new Dimension(500,(Table_Height>850)?850:Table_Height));
        else Table.setPreferredScrollableViewportSize(new Dimension(1000,(Table_Height>850)?850:Table_Height));
        if (Use_Row_Colors) Table.setDefaultRenderer(Object.class,new Table_Grid_Cell_Renderer());
        //Create the scroll pane and add the table to it.
        scrollPane=new JScrollPane(Table);
        //Set up column sizes.
        initColumnSizes(Table,My_Model);
        //Add the scroll pane to this window.
        if (Show_External_Table)
          Table_Frame=new JFrame(Table_Name);
          Table_Frame.getContentPane().add(scrollPane);
          Table_Frame.addWindowListener(new WindowAdapter()
            public void windowActivated(WindowEvent e) { }
            public void windowClosed(WindowEvent e) { }
            public void windowClosing(WindowEvent e)  { System.exit(0); }
            public void windowDeactivated(WindowEvent e)  { }
            public void windowDeiconified(WindowEvent e)  { scrollPane.repaint(); }
            public void windowGainedFocus(WindowEvent e)  { scrollPane.repaint(); }
            public void windowIconified(WindowEvent e)  { }
            public void windowLostFocus(WindowEvent e)  { }
            public void windowOpening(WindowEvent e) { scrollPane.repaint(); }
            public void windowOpened(WindowEvent e)  { }
            public void windowResized(WindowEvent e) { scrollPane.repaint(); } 
            public void windowStateChanged(WindowEvent e) { scrollPane.repaint(); }
          Table_Frame.pack();
          Table_Frame.setBounds((Screen_Size.width-Table_Frame.getWidth())/2,(Screen_Size.height-Table_Frame.getHeight())/2,Table_Frame.getWidth(),Table_Frame.getHeight());
          Table_Frame.setVisible(true);
          if (Is_Child) Table_Frame.addComponentListener(new ComponentAdapter() { public void componentClosing(ComponentEvent e) { System.exit(0); } });
        else add(scrollPane);
      public Table_Panel(String File_Name) { this(File_Name,false,Row_Color_Style_Cyan_Gray,Preffered_Width,null,Default_Selection_Color,true); }
      public Table_Panel(String File_Name,int Row_Color_Style,boolean In_Original_Order) { this(File_Name,false,Row_Color_Style,Preffered_Width,null,Default_Selection_Color,In_Original_Order); }
      public Table_Panel(String File_Name,String Delimiter,boolean In_Original_Order) { this(File_Name,false,Row_Color_Style_Cyan_Gray,Preffered_Width,Delimiter,Default_Selection_Color,In_Original_Order); }
      public Table_Panel(String File_Name,int Preffered_Width,String Delimiter,boolean In_Original_Order) { this(File_Name,false,Row_Color_Style,Preffered_Width,Delimiter,Default_Selection_Color,In_Original_Order); }
      public Table_Panel(String File_Name,int Row_Color_Style,int Preffered_Width,String Delimiter,boolean In_Original_Order) { this(File_Name,false,Row_Color_Style,Preffered_Width,Delimiter,Default_Selection_Color,In_Original_Order); }
      public Table_Panel(String File_Name,boolean Show_External_Table,boolean In_Original_Order) { this(File_Name,Show_External_Table,Row_Color_Style,Preffered_Width,null,Default_Selection_Color,In_Original_Order); }
      public Table_Panel(String File_Name,boolean Show_External_Table,String Delimiter,boolean In_Original_Order) { this(File_Name,Show_External_Table,Row_Color_Style,Preffered_Width,Delimiter,Default_Selection_Color,In_Original_Order); }
      public Table_Panel(String File_Name,boolean Show_External_Table,int Row_Color_Style,int Preffered_Width,String Delimiter,Color Selection_Color,boolean In_Original_Order)
        String Table_Column_Names[],Column_Name_Line="";
        int Row_Count=0,Index=0;
        boolean Is_Child=false,Manage_Attachment=false;
        StringTokenizer ST;
        if (Delimiter==null) Delimiter=Default_Delimiter;
        if (new File(File_Name).exists())
          try
            String Line,Str=Tool_Lib.Read_File(File_Name).toString();
            ST=new StringTokenizer(Str,"\n");
            Line=ST.nextToken();
            Row_Count=ST.countTokens();
            Object[][] Table_Data=new Object[Row_Count][];
            if (Delimiter.equals(" ")) Line=Line.replaceAll(" {2,}"," ").trim();     // Replace multiple spaces with the delimiter space
            Table_Column_Names=Line.split(Delimiter);
            columnNames=Table_Column_Names;
            for (int i=0;i<Table_Column_Names.length;i++) Column_Name_Line+=Table_Column_Names[i]+"  ";
    //Out("Column_Name_Line [ "+Table_Column_Names.length+" ]="+Column_Name_Line);
            while (ST.hasMoreTokens())
              Line=ST.nextToken();
    //Out(Line);
              if (Delimiter.equals(" ")) Line=Line.replaceAll(" {2,}"," ").trim();   // Replace multiple spaces with the delimiter space
              if (Line.indexOf(Delimiter)!=-1) Table_Data[Index]=Line.split(Delimiter);
              else
                Table_Data[Index]=new Object[Table_Column_Names.length];
                Table_Data[Index][0]=Line;
                for (int i=1;i<Table_Column_Names.length;i++) Table_Data[Index]="";
    Index++;
    Line="";
    for (int i=0;i<Table_Data.length;i++)
    Line+="[ "+Table_Data[i].length+" ] ";
    for (int j=0;j<Table_Data[i].length;j++) Line+=Table_Data[i][j]+" ";
    Line+="\n";
    Out(Line);
    Table_Panel A_Table_Panel=new Table_Panel(File_Name,Table_Column_Names,Table_Data,Row_Count,Is_Child,Show_External_Table,Manage_Attachment,Row_Color_Style,Preffered_Width,Selection_Color,In_Original_Order);
    Table=A_Table_Panel.Table;
    scrollPane=A_Table_Panel.scrollPane;
    Column_Width=A_Table_Panel.Column_Width;
    data=A_Table_Panel.data;
    catch (Exception e) { e.printStackTrace(); }
    public void setPreferredSize(Dimension A_Dimension) { scrollPane.setPreferredSize(A_Dimension); }
    // This method picks good column sizes. If all column heads are wider than the column's cells' contents, then you can just use column.sizeWidthToFit().
    void initColumnSizes(JTable table,TableModel model)
    TableColumn column=null;
    Component comp=null;
    int headerWidth=0,cellWidth=0;
    Object[] longValues=(data.length>0)?data[0]:null;
    TableCellRenderer headerRenderer=table.getTableHeader().getDefaultRenderer();
    if (data.length<1) return;
    for (int i=0;i<model.getColumnCount();i++)
    column=table.getColumnModel().getColumn(i);
    comp=headerRenderer.getTableCellRendererComponent(null,column.getHeaderValue(),false,false,0,0);
    headerWidth=comp.getPreferredSize().width;
    comp=table.getDefaultRenderer(model.getColumnClass(i)).
    getTableCellRendererComponent(table,longValues[i],false,false,0,i);
    cellWidth=comp.getPreferredSize().width;
    switch (Preffered_Width)
    case Max_Header_Cell_Width : column.setPreferredWidth(Math.max(headerWidth,cellWidth));break;
    case Header_Width : column.setPreferredWidth(headerWidth);break;
    case Cell_Width : column.setPreferredWidth(cellWidth);break;
    Column_Width[i]=column.getPreferredWidth();
    if (Debug) Out("Initializing width of column "+i+". "+"headerWidth="+headerWidth+"; cellWidth="+cellWidth+" Column_Width["+i+"]="+Column_Width[i]);
    // Detects a state change in any of the Lists. Resets the variable corresponding to the selected item in a particular List. Invokes changeFont with the currently selected fontname, style and size attributes.
    public void itemStateChanged(ItemEvent e)
    Out(e.toString());
    if (e.getStateChange() != ItemEvent.SELECTED) return;
    Object list=e.getSource();
    public static void Out(String message) { System.out.println(message); }
    // Create the GUI and show it. For thread safety, this method should be invoked from the event-dispatching thread.
    static void Create_And_Show_GUI()
    boolean Demo_External_Table=true;
    // boolean Demo_External_Table=false;
    final Table_Panel demo;
    String[] columnNames={"First Names","Last Names","Sport","Num of Years","Vegetarian"};
    Object[][] data={{"Mary","Campione","Snowboarding"+"[123456789]",new Integer(5),new Boolean(false)},
    {"Alison","Huml","Rowing"+":123456789]",new Integer(3),new Boolean(true)},
    {"Frank","Ni","Running"+":123456789", new Integer(12), new Boolean(false)},
    {"Kathy","Walrath","Chasing toddlers"+"<123456789>", new Integer(2), new Boolean(false)},
    {"Mark", "Andrews","Speed reading",new Integer(20),new Boolean(true)},
    {"Angela","Lih","Teaching high school",new Integer(36),new Boolean(false)} };
    // Row_Color_Style=Row_Color_Style_Default;
    // Row_Color_Style=Row_Color_Style_None;
    // Row_Color_Style=Row_Color_Style_Blue_Gray;
    Row_Color_Style=Row_Color_Style_Cyan_Gray;
    // Row_Color_Style=Row_Color_Style_Blue;
    // Row_Color_Style=Row_Color_Style_Gray;
    // Row_Color_Style=Row_Color_Style_Red_Green;
    // Row_Color_Style=Row_Color_Style_Green_Yellow;
    // Row_Color_Style=Row_Color_Style_Red_Yellow;
    Preffered_Width=Max_Header_Cell_Width;
    if (Demo_External_Table) demo=new Table_Panel("External Table Demo",columnNames,data,data.length,false,Demo_External_Table,false,Row_Color_Style,Max_Header_Cell_Width,Default_Selection_Color,true);
    else
    JFrame Table_Frame=new JFrame("Internal Table Demo");
    // demo=new Table_Panel(Nm_Lib.Dir_A_Test+"ELX.csv",false,Row_Color_Style,Preffered_Width,null);
    // demo=new Table_Panel(Nm_Lib.Dir_Stock_Data+"ABV_Data.txt",false,Row_Color_Style,Preffered_Width," ");
    demo=new Table_Panel("C:/Dir_Stock_Data/EOP.txt",",",false);
    // demo=new Table_Panel(Nm_Lib.Dir_Stock_Data+"ABV_Data.txt"," ",false);
    Table_Frame.getContentPane().add(demo.scrollPane);
    Table_Frame.addWindowListener(new WindowAdapter()
    public void windowActivated(WindowEvent e) { }
    public void windowClosed(WindowEvent e) { }
    public void windowClosing(WindowEvent e) { System.exit(0); }
    public void windowDeactivated(WindowEvent e) { }
    public void windowDeiconified(WindowEvent e) { demo.repaint(); }
    public void windowGainedFocus(WindowEvent e) { demo.repaint(); }
    public void windowIconified(WindowEvent e) { }
    public void windowLostFocus(WindowEvent e) { }
    public void windowOpening(WindowEvent e) { demo.repaint(); }
    public void windowOpened(WindowEvent e) { }
    public void windowResized(WindowEvent e) { demo.repaint(); }
    public void windowStateChanged(WindowEvent e) { demo.repaint(); }
    Table_Frame.pack();
    Table_Frame.setBounds((Screen_Size.width-Table_Frame.getWidth())/2,(Screen_Size.height-Table_Frame.getHeight())/2,Table_Frame.getWidth(),Table_Frame.getHeight());
    Table_Frame.setVisible(true);
    public static void main(String[] args)
    // Schedule a job for the event-dispatching thread : creating and showing this application's GUI.
    SwingUtilities.invokeLater(new Runnable() { public void run() { Create_And_Show_GUI(); } });
    * TableSorter is a decorator for TableModels; adding sorting functionality to a supplied TableModel. TableSorter does not store
    * or copy the data in its TableModel; instead it maintains a map from the row indexes of the view to the row indexes of the
    * model. As requests are made of the sorter (like getValueAt(row, col)) they are passed to the underlying model after the row numbers
    * have been translated via the internal mapping array. This way, the TableSorter appears to hold another copy of the table
    * with the rows in a different order.
    * <p/>
    * TableSorter registers itself as a listener to the underlying model, just as the JTable itself would. Events recieved from the model
    * are examined, sometimes manipulated (typically widened), and then passed on to the TableSorter's listeners (typically the JTable).
    * If a change to the model has invalidated the order of TableSorter's rows, a note of this is made and the sorter will resort the
    * rows the next time a value is requested.
    * <p/>
    * When the tableHeader property is set, either by using the setTableHeader() method or the two argument constructor, the table
    * header may be used as a complete UI for TableSorter. The default renderer of the tableHeader is decorated with a renderer
    * that indicates the sorting status of each column. In addition, a mouse listener is installed with the following behavior:
    * <ul>
    * <li>
    * Mouse-click: Clears the sorting status of all other columns and advances the sorting status of that column through three
    * values: {NOT_SORTED, ASCENDING, DESCENDING} (then back to NOT_SORTED again).
    * <li>
    * SHIFT-mouse-click: Clears the sorting status of all other columns and cycles the sorting status of the column through the same
    * three values, in the opposite order: {NOT_SORTED, DESCENDING, ASCENDING}.
    * <li>
    * CONTROL-mouse-click and CONTROL-SHIFT-mouse-click: as above except that the changes to the column do not cancel the statuses of columns
    * that are already sorting - giving a way to initiate a compound sort.
    * </ul>
    * <p/>
    * This is a long overdue rewrite of a class of the same name that first appeared in the swing table demos in 1997.
    * @author Philip Milne
    * @author Brendon McLean
    * @author Dan van Enckevort
    * @author Parwinder Sekhon
    * @version 2.0 02/27/04
    class TableSorter extends AbstractTableModel
    public static final long serialVersionUID=26362862L;
    protected TableModel tableModel;
    public static final int DESCENDING = -1;
    public static final int NOT_SORTED = 0;
    public static final int ASCENDING = 1;
    private static Directive EMPTY_DIRECTIVE = new Directive(-1, NOT_SORTED);
    public static final Comparator COMPARABLE_COMAPRATOR = new Comparator() { public int compare(Object o1, Object o2) { return ((Comparable) o1).compareTo(o2); } };
    public static final Comparator LEXICAL_COMPARATOR = new Comparator() { public int compare(Object o1, Object o2) { return o1.toString().compareTo(o2.toString()); } };
    private Row[] viewToModel;
    private int[] modelToView;
    private JTableHeader tableHeader;
    private MouseListener mouseListener;
    private TableModelListener tableModelListener;
    private Map<Class,Comparator> columnComparators = new HashMap<Class,Comparator>();
    private List<Directive> sortingColumns = new ArrayList<Directive>();
    public TableSorter()
    this.mouseListener = new MouseHandler();
    this.tableModelListener = new TableModelHandler();
    public TableSorter(TableModel tableModel)
    this();
    setTableModel(tableModel);
    public TableSorter(TableModel tableModel, JTableHeader tableHeader)
    this();
    setTableHeader(tableHeader);
    setTableModel(tableModel);
    private void clearSortingState()
    viewToModel = null;
    modelToView = null;
    public TableModel getTableModel() { return tableModel; }
    public void setTableModel(TableModel tableModel)
    if (this.tableModel != null) { this.tableModel.removeTableModelListener(tableModelListener); }
    this.tableModel = tableModel;
    if (this.tableModel != null) { this.tableModel.addTableModelListener(tableModelListener); }
    clearSortingState();
    fireTableStructureChanged();
    public JTableHeader getTableHeader() { return tableHeader; }
    public void setTableHeader(JTableHeader tableHeader)
    if (this.tableHeader != null)
    this.tableHeader.removeMouseListener(mouseListener);
    TableCellRenderer defaultRenderer = this.tableHeader.getDefaultRenderer();
    if (defaultRenderer instanceof SortableHeaderRenderer) this.tableHeader.setDefaultRenderer(((SortableHeaderRenderer) defaultRenderer).tableCellRenderer);
    this.tableHeader = tableHeader;
    if (this.tableHeader != null)
    this.tableHeader.addMouseListener(mouseListener);
    this.tableHeader.setDefaultRenderer(
    new SortableHeaderRenderer(this.tableHeader.getDefaultRenderer()));
    public boolean isSorting() { return sortingColumns.size() != 0; }
    private Directive getDirective(int column)
    for (int i = 0; i < sortingColumns.size(); i++)
    Directive directive = (Directive)sortingColumns.get(i);
    if (directive.column == column) { return directive; }
    return EMPTY_DIRECTIVE;
    public int getSortingStatus(int column) { return getDirective(column).direction; }
    private void sortingStatusChanged()
    clearSortingState();
    fireTableDataChanged();
    if (tableHeader != null) { tableHeader.repaint(); }
    public void setSortingStatus(int column, int status)
    Directive directive = getDirective(column);
    if (directive != EMPTY_DIRECTIVE) { sortingColumns.remove(directive); }
    if (status != NOT_SORTED) { sortingColumns.add(new Directive(column, status)); }
    sortingStatusChanged();
    protected Icon getHeaderRendererIcon(int column, int size)
    Directive directive = getDirective(column);
    if (directive == EMPTY_DIRECTIVE) { return null; }
    return new Arrow(directive.direction == DESCENDING, size, sortingColumns.indexOf(directive));
    private void cancelSorting()
    sortingColumns.clear();
    sortingStatusChanged();
    public void setColumnComparator(Class type, Comparator comparator)
    if (comparator == null) { columnComparators.remove(type); }
    else { columnComparators.put(type, comparator); }
    protected Comparator getComparator(int column)
    Class columnType = tableModel.getColumnClass(column);
    Comparator comparator = (Comparator) columnComparators.get(columnType);
    if (comparator != null) { return comparator; }
    if (Comparable.class.isAssignableFrom(columnType)) { return COMPARABLE_COMAPRATOR; }
    return LEXICAL_COMPARATOR;
    private Row[] getViewToModel()
    if (viewToModel == null)
    int tableModelRowCount = tableModel.getRowCount();
    viewToModel = new Row[tableModelRowCount];
    for (int row = 0; row < tableModelRowCount; row++) { viewToModel[row] = new Row(row); }
    if (isSorting()) { Arrays.sort(viewToModel); }
    return viewToModel;
    public int modelIndex(int viewIndex) { return getViewToModel()[viewIndex].modelIndex; }
    private int[] getModelToView()
    if (modelToView == null)
    int n = getViewToModel().length;
    modelToView = new int[n];
    for (int i = 0; i < n; i++) { modelToView[modelIndex(i)] = i; }
    return modelToView;
    // TableModel interface methods
    public int getRowCount() { return (tableModel == null) ? 0 : tableModel.getRowCount(); }
    public int getColumnCount() { return (tableModel == null) ? 0 : tableModel.getColumnCount(); }
    public String getColumnName(int column) { return tableModel.getColumnName(column); }
    public Class getColumnClass(int column) { return tableModel.getColumnClass(column); }
    public boolean isCellEditable(int row, int column) { return tableModel.isCellEditable(modelIndex(row), column); }
    public Object getValueAt(int row, int column) { return tableModel.getValueAt(modelIndex(row), column); }
    public void setValueAt(Object aValue, int row, int column) { tableModel.setValueAt(aValue, modelIndex(row), column); }
    // Helper classes
    private class Row implements Comparable
    private int modelIndex;
    public Row(int index) { this.modelIndex = index; }
    public int compareTo(Object o)
    int row1 = modelIndex;
    int row2 = ((Row) o).modelIndex;
    for (Iterator it = sortingColumns.iterator(); it.hasNext();)
    Directive directive = (Directive) it.next();
    int column = directive.column;
    Object o1 = tableModel.getValueAt(row1, column);
    Object o2 = tableModel.getValueAt(row2, column);
    int comparison = 0;
    // Define null less than everything, except null.
    if (o1 == null && o2 == null) { comparison = 0; }
    else if (o1 == null) { comparison = -1; }
    else if (o2 == null) { comparison = 1; }
    else { comparison = getComparator(column).compare(o1, o2); }
    if (comparison != 0) { return directive.direction == DESCENDING ? -comparison : comparison; }
    return 0;
    private class TableModelHandler implements TableModelListener
    public void tableChanged(TableModelEvent e)
    // If we're not sorting by anything

  • Problem with adding a new row in JTable

    Hi,
    I've created a JTable using DefaultTableModel with DefaultTableModel(Object[][] obj,Object[] col) constructor.I've written actionListener for a JButton which should add new row to the tablemodel.Now, the listener adds the row to the model.But its throwing an ArrayOutofBoundsException and the added row is not visible unless I click on any column of the table.
    Kindly help me to resolve this problem
    TIA
    Regards
    Gopi

    Thanks a lot for the reply. Here is the complete code
    TableImpl.java
    import javax.swing.*;
    import javax.swing.event.*;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.table.*;
    import java.util.Vector;
    public class TableImpl extends JFrame {
    DefaultTableModel dataModel;     // TableModel Variable
    /* Constructor to add table and button to the frame     */
    TableImpl() {
              getContentPane().setLayout(null);
              setSize(800,600);
              myModel();
              final JTable table = new JTable(dataModel);
              JScrollPane scrollpane = new JScrollPane(table);
              getContentPane().add(scrollpane);
              scrollpane.setBounds(10,10,700,300);
              TableColumn tcCol = table.getColumnModel().getColumn(1);
              /* Adding ComboBox to the CellEditor of Column 2 of table     */
              JComboBox jcbComboBox = new JComboBox();
              final ReturnVector vctDBAccess = new ReturnVector();
              jcbComboBox.addItem(vctDBAccess.vctGetOidList().elementAt(0).toString());
              jcbComboBox.addItem(vctDBAccess.vctGetOidList().elementAt(2).toString());
              jcbComboBox.addItem(vctDBAccess.vctGetOidList().elementAt(4).toString());
              tcCol.setCellEditor(new DefaultCellEditor(jcbComboBox));
              /*     Adding Listener for Table      */
              dataModel.addTableModelListener(new TableModelListener() {
                   public void tableChanged(TableModelEvent e) {
              /* Columns Manipulation */
                        if(dataModel.getColumnName(e.getColumn()).equals("Second")) {
                        int iRow = e.getFirstRow();
                        int iColumn = e.getColumn();
                        String strColName = dataModel.getColumnName(iColumn);
                        String strData = (String)dataModel.getValueAt(iRow,iColumn);
                        String strNextColumn = dataModel.getColumnName(iColumn+1);
                        dataModel.setValueAt(vctDBAccess.vctGetOidList().elementAt(vctDBAccess.iGetIndex(strData)+1),iRow,iColumn+1);
              /* Adding button to Frame     */
              JButton jbInsert = new JButton("Insert");
              /* Adding new row to the Tablemodel -- Probelm is here     */
              jbInsert.addActionListener(new ActionListener(){
              public void actionPerformed(ActionEvent e){
                        try {
                   Object[] nrow = {"what", "ever", "you"};
                   dataModel.addRow(nrow);
                   }catch(Exception ex) {
                   System.out.println("Exception at adding row = " + ex);
    getContentPane().add(jbInsert);
    jbInsert.setBounds(100,350,100,20);
    addWindowListener(new WindowAdapter() {
              public void windowClosing(WindowEvent e) {
                   System.exit(0);
         /* Method to initialise new tablemodel     */
         public void myModel() {
              Object[][] data = { {new Integer(10),"two","three"},
                                                 {new Integer(5),"two","three"},
                                                 {new Integer(4),"two","three"},
              String[] col = { "First", "Second", "Third"};
              dataModel = new DefaultTableModel(data,col);
    public static void main(String arg[]) {
              TableImpl ct = new TableImpl();
              ct.setVisible(true);
    /* Class that returns a Vector of String for populating ComboBox entries and
              for getting the index of a particular element of the vector          */
    class ReturnVector {
                   Vector vctOidName=null;
                   ReturnVector() {
                        this.vctOidName = new Vector();
                        vAddOidList();
                   public void vAddOidList() {
                        String[] dbResult = {      "system", "1.3.6.1.2.1.1" ,
                                                      "interface", "1.3.6.1.2.1.2" ,
                                                      "snmp", "1.3.6.1.2.1.3" };
                        for(int i=0;i<dbResult.length;i++) {
                             System.out.println("Value = " + dbResult);
                             vctOidName.addElement(dbResult[i]);
                   public Vector vctGetOidList() {
                        return vctOidName;
                   public int iGetIndex(String strData) {
                        System.out.println("Index = " + vctOidName.indexOf(strData));
                        return vctOidName.indexOf(strData);

  • JTable sorting - problem when adding elements (complete code inside)

    I�m writing this email with reference to a recent posting here but this time with the code example. (I apologize for the duplicated posting � this time it will be with the code)
    Problem: when adding more elements to the JTable (sorted) the exception: ArrayIndexOutOfBoundsException is thrown.
    Example: If the elements in the table are 10 and then the user requests for 8 � the table will produce the correct result. However, if the user will ask for 11 items (>10) the exception will be thrown.
    The program: The program below (compiles and running). A JTable is constructed with 3 items, when you click the button - the return result should be 4 items - this will generate the error, WHY?
    I would highly appreciate your thoughts why this is happening and most importantly � how to fix it.
    Thanks a lot
    3 files:
    (1) TableSorterDemo
    (2) Traveler
    (3)TableSorter
    //TableSorterDemo:
    package sorter;
    import javax.swing.DefaultListModel;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.table.AbstractTableModel;
    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    * TableSorterDemo is like TableDemo, except that it
    * inserts a custom model -- a sorter -- between the table
    * and its data model.  It also has column tool tips.
    public class TableSorterDemo implements ActionListener
         private JPanel superPanel;
         private JButton clickMe = new JButton("click me to get diff data");
         private boolean DEBUG = false;
         private DefaultListModel defaultListModel;
         private JTable table;
        public TableSorterDemo()
             superPanel = new JPanel(new BorderLayout());
             defaultListModel = new DefaultListModel();
             init1();
            TableSorter sorter = new TableSorter(new MyTableModel(defaultListModel)); //ADDED THIS     
            table = new JTable(sorter);             //NEW
            sorter.setTableHeader(table.getTableHeader()); //ADDED THIS
            table.setPreferredScrollableViewportSize(new Dimension(500, 70));
            //Set up tool tips for column headers.
            table.getTableHeader().setToolTipText(
                    "Click to specify sorting; Control-Click to specify secondary sorting");
            //Create the scroll pane and add the table to it.
            JScrollPane scrollPane = new JScrollPane(table);
            //Add the scroll pane to this panel.
            superPanel.add("Center", scrollPane);
            superPanel.add("South",clickMe);
            clickMe.addActionListener(this);              
        public JPanel getPanel()
             return superPanel;
        public void init1()
             //in real life this will be done from the db
             Traveler a = new Traveler();
             Traveler b = new Traveler();
             Traveler c = new Traveler();
             a.setFirstName("Elvis");
             a.setLastName("Presley");
             a.setSprot("Ping Pong");
             a.setNumYears(3);
             a.setVegetarian(true);
             b.setFirstName("Elton");
             b.setLastName("John");
             b.setSprot("Soccer");
             b.setNumYears(2);
             b.setVegetarian(true);
             c.setFirstName("shaquille");
             c.setLastName("oneil");
             c.setSprot("Golf");
             c.setNumYears(22);
             c.setVegetarian(true);
             defaultListModel.addElement(a);
             defaultListModel.addElement(b);
             defaultListModel.addElement(c);
        public void init2()
             //in real life this will be done from the db
             Traveler d = new Traveler();
             Traveler e = new Traveler();
             Traveler f = new Traveler();
             Traveler g = new Traveler();
             d.setFirstName("John");
             d.setLastName("Smith");
             d.setSprot("Tennis");
             d.setNumYears(32);
             d.setVegetarian(true);
             e.setFirstName("Ron");
             e.setLastName("Cohen");
             e.setSprot("Baseball");
             e.setNumYears(12);
             e.setVegetarian(true);
             f.setFirstName("Donald");
             f.setLastName("Mac Novice");
             f.setSprot("Vallyball");
             f.setNumYears(1);
             f.setVegetarian(true);
             g.setFirstName("Eithan");
             g.setLastName("Superstar");
             g.setSprot("Vallyball");
             g.setNumYears(21);
             g.setVegetarian(true);
             defaultListModel.addElement(d);
             defaultListModel.addElement(e);
             defaultListModel.addElement(f);
             defaultListModel.addElement(g);            
        class MyTableModel extends AbstractTableModel
             private DefaultListModel myModel;
             public MyTableModel(DefaultListModel m)
                  myModel=m;
            private String[] columnNames = {"First Name",
                                            "Last Name",
                                            "Sport",
                                            "# of Years",
                                            "Vegetarian"};
            public int getColumnCount()
                return columnNames.length;
            public int getRowCount()
                return myModel.size();
            public String getColumnName(int column)
                 return getNames()[column];             
             public String[] getNames()
                  String[] names = {"First Name", "Last Name", "Sport", "# of Years", "Vegetarian"};
                  return names;
            public Object getValueAt(int row, int col)
                 return distributeObjectsInTable(row, col, (Traveler) myModel.elementAt(row));
            public Object distributeObjectsInTable(int row, int col, Traveler tr)
               switch(col)
                         case 0:
                              return tr.getFirstName();
                         case 1:
                           return tr.getLastName();
                      case 2:
                           return tr.getSprot();
                      case 3:
                           return new Integer(tr.getNumYears());
                      case 4:
                           return new Boolean (tr.isVegetarian());
                     default:
                         return "Error";
            public Class getColumnClass(int c)
                return getValueAt(0, c).getClass();
        private static void createAndShowGUI()
            //Make sure we have nice window decorations.
            JFrame.setDefaultLookAndFeelDecorated(true);
            //Create and set up the window.
            JFrame frame = new JFrame("TableSorterDemo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            //Create and set up the content pane.
            TableSorterDemo newContentPane = new TableSorterDemo();
            newContentPane.getPanel().setOpaque(true); //content panes must be opaque
            frame.setContentPane(newContentPane.getPanel());
            //Display the window.
            frame.pack();
            frame.setVisible(true);
        public static void main(String[] args)
            //Schedule a job for the event-dispatching thread:
            //creating and showing this application's GUI.
            javax.swing.SwingUtilities.invokeLater(new Runnable()                   
                public void run()
                    createAndShowGUI();
         public void actionPerformed(ActionEvent ae)
              if (ae.getSource()==clickMe)
                   defaultListModel.removeAllElements();
                   init2(); //if the size of the model was less than 2 items - the result will be ok.
                              //in other words, if you commens the last 2 rows of this method (addElement(f) & g)
                             // the result will be fine.
                   table.updateUI();          
    }//(2) Traveler
    package sorter;
    public class Traveler
         private String firstName;
         private String lastName;
         private String sprot;
         private int numYears;
         private boolean vegetarian;
         public String getFirstName()
              return firstName;
         public String getLastName()
              return lastName;
         public int getNumYears()
              return numYears;
         public String getSprot()
              return sprot;
         public boolean isVegetarian()
              return vegetarian;
         public void setFirstName(String firstName)
              this.firstName = firstName;
         public void setLastName(String lastName)
              this.lastName = lastName;
         public void setNumYears(int numYears)
              this.numYears = numYears;
         public void setSprot(String sprot)
              this.sprot = sprot;
         public void setVegetarian(boolean vegetarian)
              this.vegetarian = vegetarian;
    }//(3)TableSorter
    package sorter;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import java.util.List;
    import javax.swing.*;
    import javax.swing.event.TableModelEvent;
    import javax.swing.event.TableModelListener;
    import javax.swing.table.*;
    public class TableSorter extends AbstractTableModel {
        protected TableModel tableModel;
        public static final int DESCENDING = -1;
        public static final int NOT_SORTED = 0;
        public static final int ASCENDING = 1;
        private static Directive EMPTY_DIRECTIVE = new Directive(-1, NOT_SORTED);
        public static final Comparator COMPARABLE_COMAPRATOR = new Comparator() {
            public int compare(Object o1, Object o2) {
                return ((Comparable) o1).compareTo(o2);
        public static final Comparator LEXICAL_COMPARATOR = new Comparator() {
            public int compare(Object o1, Object o2) {
                return o1.toString().compareTo(o2.toString());
        private Row[] viewToModel;
        private int[] modelToView;
        private JTableHeader tableHeader;
        private MouseListener mouseListener;
        private TableModelListener tableModelListener;
        private Map columnComparators = new HashMap();
        private List sortingColumns = new ArrayList();
        public TableSorter() {
            this.mouseListener = new MouseHandler();
            this.tableModelListener = new TableModelHandler();
        public TableSorter(TableModel tableModel) {
            this();
            setTableModel(tableModel);
        public TableSorter(TableModel tableModel, JTableHeader tableHeader) {
            this();
            setTableHeader(tableHeader);
            setTableModel(tableModel);
        private void clearSortingState() {
            viewToModel = null;
            modelToView = null;
        public TableModel getTableModel() {
            return tableModel;
        public void setTableModel(TableModel tableModel) {
            if (this.tableModel != null) {
                this.tableModel.removeTableModelListener(tableModelListener);
            this.tableModel = tableModel;
            if (this.tableModel != null) {
                this.tableModel.addTableModelListener(tableModelListener);
            clearSortingState();
            fireTableStructureChanged();
        public JTableHeader getTableHeader() {
            return tableHeader;
        public void setTableHeader(JTableHeader tableHeader) {
            if (this.tableHeader != null) {
                this.tableHeader.removeMouseListener(mouseListener);
                TableCellRenderer defaultRenderer = this.tableHeader.getDefaultRenderer();
                if (defaultRenderer instanceof SortableHeaderRenderer) {
                    this.tableHeader.setDefaultRenderer(((SortableHeaderRenderer) defaultRenderer).tableCellRenderer);
            this.tableHeader = tableHeader;
            if (this.tableHeader != null) {
                this.tableHeader.addMouseListener(mouseListener);
                this.tableHeader.setDefaultRenderer(
                        new SortableHeaderRenderer(this.tableHeader.getDefaultRenderer()));
        public boolean isSorting() {
            return sortingColumns.size() != 0;
        private Directive getDirective(int column) {
            for (int i = 0; i < sortingColumns.size(); i++) {
                Directive directive = (Directive)sortingColumns.get(i);
                if (directive.column == column) {
                    return directive;
            return EMPTY_DIRECTIVE;
        public int getSortingStatus(int column) {
            return getDirective(column).direction;
        private void sortingStatusChanged() {
            clearSortingState();
            fireTableDataChanged();
            if (tableHeader != null) {
                tableHeader.repaint();
        public void setSortingStatus(int column, int status) {
            Directive directive = getDirective(column);
            if (directive != EMPTY_DIRECTIVE) {
                sortingColumns.remove(directive);
            if (status != NOT_SORTED) {
                sortingColumns.add(new Directive(column, status));
            sortingStatusChanged();
        protected Icon getHeaderRendererIcon(int column, int size) {
            Directive directive = getDirective(column);
            if (directive == EMPTY_DIRECTIVE) {
                return null;
            return new Arrow(directive.direction == DESCENDING, size, sortingColumns.indexOf(directive));
        private void cancelSorting() {
            sortingColumns.clear();
            sortingStatusChanged();
        public void setColumnComparator(Class type, Comparator comparator) {
            if (comparator == null) {
                columnComparators.remove(type);
            } else {
                columnComparators.put(type, comparator);
        protected Comparator getComparator(int column) {
            Class columnType = tableModel.getColumnClass(column);
            Comparator comparator = (Comparator) columnComparators.get(columnType);
            if (comparator != null) {
                return comparator;
            if (Comparable.class.isAssignableFrom(columnType)) {
                return COMPARABLE_COMAPRATOR;
            return LEXICAL_COMPARATOR;
        private Row[] getViewToModel() {
            if (viewToModel == null) {
                int tableModelRowCount = tableModel.getRowCount();
                viewToModel = new Row[tableModelRowCount];
                for (int row = 0; row < tableModelRowCount; row++) {
                    viewToModel[row] = new Row(row);
                if (isSorting()) {
                    Arrays.sort(viewToModel);
            return viewToModel;
        public int modelIndex(int viewIndex)
            return getViewToModel()[viewIndex].modelIndex;
        private int[] getModelToView()
            if (modelToView == null) {
                int n = getViewToModel().length;
                modelToView = new int[n];
                for (int i = 0; i < n; i++) {
                    modelToView[modelIndex(i)] = i;
            return modelToView;
        // TableModel interface methods
        public int getRowCount() {
            return (tableModel == null) ? 0 : tableModel.getRowCount();
        public int getColumnCount() {
            return (tableModel == null) ? 0 : tableModel.getColumnCount();
        public String getColumnName(int column) {
            return tableModel.getColumnName(column);
        public Class getColumnClass(int column) {
            return tableModel.getColumnClass(column);
        public boolean isCellEditable(int row, int column) {
            return tableModel.isCellEditable(modelIndex(row), column);
        public Object getValueAt(int row, int column) {
            return tableModel.getValueAt(modelIndex(row), column);
        public void setValueAt(Object aValue, int row, int column) {
            tableModel.setValueAt(aValue, modelIndex(row), column);
        // Helper classes
        private class Row implements Comparable {
            private int modelIndex;
            public Row(int index) {
                this.modelIndex = index;
            public int compareTo(Object o) {
                int row1 = modelIndex;
                int row2 = ((Row) o).modelIndex;
                for (Iterator it = sortingColumns.iterator(); it.hasNext();) {
                    Directive directive = (Directive) it.next();
                    int column = directive.column;
                    Object o1 = tableModel.getValueAt(row1, column);
                    Object o2 = tableModel.getValueAt(row2, column);
                    int comparison = 0;
                    // Define null less than everything, except null.
                    if (o1 == null && o2 == null) {
                        comparison = 0;
                    } else if (o1 == null) {
                        comparison = -1;
                    } else if (o2 == null) {
                        comparison = 1;
                    } else {
                        comparison = getComparator(column).compare(o1, o2);
                    if (comparison != 0) {
                        return directive.direction == DESCENDING ? -comparison : comparison;
                return 0;
        private class TableModelHandler implements TableModelListener {
            public void tableChanged(TableModelEvent e) {
                // If we're not sorting by anything, just pass the event along.            
                if (!isSorting()) {
                    clearSortingState();
                    fireTableChanged(e);
                    return;
                // If the table structure has changed, cancel the sorting; the            
                // sorting columns may have been either moved or deleted from            
                // the model.
                if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {
                    cancelSorting();
                    fireTableChanged(e);
                    return;
                // We can map a cell event through to the view without widening            
                // when the following conditions apply:
                // a) all the changes are on one row (e.getFirstRow() == e.getLastRow()) and,
                // b) all the changes are in one column (column != TableModelEvent.ALL_COLUMNS) and,
                // c) we are not sorting on that column (getSortingStatus(column) == NOT_SORTED) and,
                // d) a reverse lookup will not trigger a sort (modelToView != null)
                // Note: INSERT and DELETE events fail this test as they have column == ALL_COLUMNS.
                // The last check, for (modelToView != null) is to see if modelToView
                // is already allocated. If we don't do this check; sorting can become
                // a performance bottleneck for applications where cells 
                // change rapidly in different parts of the table. If cells
                // change alternately in the sorting column and then outside of            
                // it this class can end up re-sorting on alternate cell updates -
                // which can be a performance problem for large tables. The last
                // clause avoids this problem.
                int column = e.getColumn();
                if (e.getFirstRow() == e.getLastRow()
                        && column != TableModelEvent.ALL_COLUMNS
                        && getSortingStatus(column) == NOT_SORTED
                        && modelToView != null) {
                    int viewIndex = getModelToView()[e.getFirstRow()];
                    fireTableChanged(new TableModelEvent(TableSorter.this,
                                                         viewIndex, viewIndex,
                                                         column, e.getType()));
                    return;
                // Something has happened to the data that may have invalidated the row order.
                clearSortingState();
                fireTableDataChanged();
                return;
        private class MouseHandler extends MouseAdapter {
            public void mouseClicked(MouseEvent e) {
                JTableHeader h = (JTableHeader) e.getSource();
                TableColumnModel columnModel = h.getColumnModel();
                int viewColumn = columnModel.getColumnIndexAtX(e.getX());
                int column = columnModel.getColumn(viewColumn).getModelIndex();
                if (column != -1) {
                    int status = getSortingStatus(column);
                    if (!e.isControlDown()) {
                        cancelSorting();
                    // Cycle the sorting states through {NOT_SORTED, ASCENDING, DESCENDING} or
                    // {NOT_SORTED, DESCENDING, ASCENDING} depending on whether shift is pressed.
                    status = status + (e.isShiftDown() ? -1 : 1);
                    status = (status + 4) % 3 - 1; // signed mod, returning {-1, 0, 1}
                    setSortingStatus(column, status);
        private static class Arrow implements Icon {
            private boolean descending;
            private int size;
            private int priority;
            public Arrow(boolean descending, int size, int priority) {
                this.descending = descending;
                this.size = size;
                this.priority = priority;
            public void paintIcon(Component c, Graphics g, int x, int y) {
                Color color = c == null ? Color.GRAY : c.getBackground();            
                // In a compound sort, make each succesive triangle 20%
                // smaller than the previous one.
                int dx = (int)(size/2*Math.pow(0.8, priority));
                int dy = descending ? dx : -dx;
                // Align icon (roughly) with font baseline.
                y = y + 5*size/6 + (descending ? -dy : 0);
                int shift = descending ? 1 : -1;
                g.translate(x, y);
                // Right diagonal.
                g.setColor(color.darker());
                g.drawLine(dx / 2, dy, 0, 0);
                g.drawLine(dx / 2, dy + shift, 0, shift);
                // Left diagonal.
                g.setColor(color.brighter());
                g.drawLine(dx / 2, dy, dx, 0);
                g.drawLine(dx / 2, dy + shift, dx, shift);
                // Horizontal line.
                if (descending) {
                    g.setColor(color.darker().darker());
                } else {
                    g.setColor(color.brighter().brighter());
                g.drawLine(dx, 0, 0, 0);
                g.setColor(color);
                g.translate(-x, -y);
            public int getIconWidth() {
                return size;
            public int getIconHeight() {
                return size;
        private class SortableHeaderRenderer implements TableCellRenderer {
            private TableCellRenderer tableCellRenderer;
            public SortableHeaderRenderer(TableCellRenderer tableCellRenderer) {
                this.tableCellRenderer = tableCellRenderer;
            public Component getTableCellRendererComponent(JTable table,
                                                           Object value,
                                                           boolean isSelected,
                                                           boolean hasFocus,
                                                           int row,
                                                           int column) {
                Component c = tableCellRenderer.getTableCellRendererComponent(table,
                        value, isSelected, hasFocus, row, column);
                if (c instanceof JLabel) {
                    JLabel l = (JLabel) c;
                    l.setHorizontalTextPosition(JLabel.LEFT);
                    int modelColumn = table.convertColumnIndexToModel(column);
                    l.setIcon(getHeaderRendererIcon(modelColumn, l.getFont().getSize()));
                return c;
        private static class Directive {
            private int column;
            private int direction;
            public Directive(int column, int direction) {
                this.column = column;
                this.direction = direction;
    }

    The table listens to the TableModel for changes. Changing the table by adding/removing
    rows or columns has no affect on its table model. If you make changes to the table model
    the table will be notified by its TableModelListener and change its view. So tell
    MyTableModel about the change of data:
    public class TableSorterDemo implements ActionListener
        MyTableModel tableModel;
        public TableSorterDemo()
            defaultListModel = new DefaultListModel();
            init1();
            tableModel = new MyTableModel(defaultListModel);
            TableSorter sorter = new TableSorter(tableModel);
        public void actionPerformed(ActionEvent ae)
            if (ae.getSource()==clickMe)
                defaultListModel.removeAllElements();
                init2();
                tableModel.fireTableStructureChanged();
    }

  • TableModelListener doesn't appear to be working

    Hi,
    I have the following code that is called when a menu item is selected. When the method tableChanged is commented out, the table is displayed just fine. With it in, even if the if statements are commented out, it doesn't display. I just get the frame title being displayed.
    import javax.swing.*;
    import java.awt.*;
    import javax.swing.table.*;
    import java.awt.event.*;
    import javax.swing.event.*;
    import javax.swing.event.TableModelEvent;
    public class updateCurrentHiLo extends JTable implements TableModelListener {
            public updateCurrentHiLo() {
                    super();
                    String[] columnNames = {"Currency",
                                    "Current Hi",
                                    "Current Lo"};
                    Object[][] data = {
                            {"AUD/USD",DataCapture.currentHigh[0], DataCapture.currentLow[0]},
                            {"GBP/USD",DataCapture.currentHigh[1], DataCapture.currentLow[1]},
                            {"EUR/USD",DataCapture.currentHigh[2], DataCapture.currentLow[2]},
                            {"EUR/JPY",DataCapture.currentHigh[3], DataCapture.currentLow[3]},
                            {"USD/JPY",DataCapture.currentHigh[4], DataCapture.currentLow[4]},
                            {"USD/CHF",DataCapture.currentHigh[5], DataCapture.currentLow[5]},
                            {"USD/CAD",DataCapture.currentHigh[6], DataCapture.currentLow[6]},
                            {"NZD/USD",DataCapture.currentHigh[7], DataCapture.currentLow[7]}
                    DefaultTableModel model = new DefaultTableModel(data, columnNames);
                    //model.addTableModelListener( this ); //We can now check whether the table has been updated.
                    setModel(model);
                    //setFont( new Font("Garamond", Font.BOLD, 50));  //Set the look and feel of the table
                    //setRowHeight(50);  //If you change font size don't forget to change the row height.
                    setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
                    doLayout();
                    setPreferredScrollableViewportSize(getPreferredSize());      
                    model.addTableModelListener( this ); //We can now check whether the table has been updated.
            public void tableChanged(TableModelEvent e)     {
                    TableModel model = getModel();
                    if (e.getType() == TableModelEvent.UPDATE)
                   int row = e.getFirstRow();
                            int column = e.getColumn();
                            /*if ( column == 1 && DhbMath.equals( ((Double)model.getValueAt(row,column)).doubleValue(),DataCapture.currentHigh[row] ) == false ) {
                                    DataCapture.currentHigh[row] = ((Double)model.getValueAt(row,column)).doubleValue();
                                    System.out.println(DataCapture.currentHigh[row]);
                            /*else if ( column == 2 ) {
                                    DataCapture.currentLow[row] = ((Double)model.getValueAt(row,column)).doubleValue();
    }This is the code that calls the table:
    public void actionPerformed(ActionEvent e) {
            JMenuItem source = (JMenuItem)(e.getSource());
            if ( source.getText().equals("Exit") ) {
                    int clickVALUE = JOptionPane.showConfirmDialog(null, "Are you sure you want to quit?", "Quit Confirmation", JOptionPane.YES_NO_OPTION);                    
              if (clickVALUE == 0)     {
                         System.exit(0);
            else {
                            if ( source.getActionCommand().equals("HiLo") ) {
                                    //Do summin
                                    JFrame test = new JFrame("Update Current Highs and Lows");
                                    test.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
                                    //JOptionPane.showInputDialog(
                                    updateCurrentHiLo table = new updateCurrentHiLo();
                                    JScrollPane scrollPane = new JScrollPane( table );
                                    test.add( scrollPane );
                                    test.pack();
                              test.setLocationRelativeTo( null );
                              test.setVisible(true);
        }Any help would be appreciated.
    Regards,
    Dave

    Hi,
    I've made a SSCE to illustrate the problem:
    Main class: RateTable.java
    import javax.swing.*;
    import java.awt.*;
    import javax.swing.table.*;
    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.GridLayout;
    import java.awt.event.KeyEvent;
    import javax.swing.JTabbedPane;
    import javax.swing.ImageIcon;
    import javax.swing.JLabel;
    import javax.swing.JTable;
    import javax.swing.JPanel;
    import javax.swing.JFrame;
    import javax.swing.JComponent;
    import javax.swing.SwingUtilities;
    import javax.swing.UIManager;
    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.GridLayout;
    import java.awt.event.KeyEvent;
    import java.awt.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.table.*;
    import javax.swing.JTabbedPane;
    import javax.swing.JFrame;
    import java.awt.event.WindowEvent;
    import java.awt.event.WindowAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.KeyEvent;
    import java.awt.event.ActionEvent;
    import java.util.Date;
    import java.util.LinkedList;
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.text.DecimalFormat;
    import java.text.ParseException;
    import java.util.StringTokenizer;
    import java.net.URL;
    import java.io.*;
    import java.io.*;
    public class RateTable {
        private static void createAndShowGUI() {
            //Create and set up the window.
            MenuCreator createMenu = new MenuCreator();
            JFrame frame = new JFrame("TabbedPaneDemo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setJMenuBar(createMenu.createMenuBar());
            //Create and set up the content pane.
            JComponent newContentPane = new TabbedPaneDemo();
            newContentPane.setOpaque(true); //content panes must be opaque
            frame.getContentPane().add(new TabbedPaneDemo(), BorderLayout.CENTER);
            //Display the window.
            frame.pack();
            frame.setVisible(true);
        public static void main(String[] args)  throws IOException {
                    createAndShowGUI();
    }SimpleTable.java
    import javax.swing.*;
    import java.awt.*;
    import javax.swing.table.*;
    import javax.swing.event.TableModelEvent;
    public class SimpleTable extends JTable {
            public SimpleTable() {
                    super();
                    String[] columnNames = {"Column 1", "Column 2"};
                    Object[][] data = {
                            {"AUD/USD",new Double(0)},
                            {"GBP/USD",new Double(0)},
                    DefaultTableModel model = new DefaultTableModel(data, columnNames);
                    model.addTableModelListener( this ); //We can now check whether the table has been updated.
                    setModel(model);
                    setFont( new Font("Garamond", Font.BOLD, 50));  //Set the look and feel of the table
                    setRowHeight(50);  //If you change font size don't forget to change the row height.
                    setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
                    doLayout();
    }MenuCreator.java
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.table.*;
    import javax.swing.event.*;
    import javax.swing.event.TableModelEvent;
    import java.lang.Number;
    public class MenuCreator implements ActionListener, TableModelListener {
        JTextArea output;
        JScrollPane scrollPane;
        String newline = "\n";
        updateCurrentHiLo table;
        public JMenuBar createMenuBar() {
                    JMenuBar menuBar;
                    JMenu menu, menu2, submenu;
                    JMenuItem menuItem;
                    JRadioButtonMenuItem rbMenuItem;
                    JCheckBoxMenuItem cbMenuItem;
                    //Create the menu bar.
                    menuBar = new JMenuBar();
                    //Build the first menu.
                    menu = new JMenu("RateTable");
                    menu.setMnemonic(KeyEvent.VK_R);
                    menuBar.add(menu);
                    menuItem = new JMenuItem("Update Current High & Low");
                    menuItem.setMnemonic(KeyEvent.VK_U);
                    menuItem.setActionCommand("HiLo");
                    menuItem.addActionListener(this);
                    menu.add(menuItem);
            return menuBar;
        public void actionPerformed(ActionEvent e) {
            JMenuItem source = (JMenuItem)(e.getSource());
            if ( source.getActionCommand().equals("HiLo") ) {
                    JFrame test = new JFrame("Update Current Highs and Lows");
                    test.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
                    table = new updateCurrentHiLo();
                    TableModel model = table.getModel();
                    model.addTableModelListener( this );
                    JScrollPane scrollPane = new JScrollPane( table );
                    test.add( scrollPane );
                    test.pack();
              test.setLocationRelativeTo( null );
              test.setVisible(true);
        public void tableChanged(TableModelEvent e)     {
                    TableModel model = table.getModel();
                    if (e.getType() == TableModelEvent.UPDATE)
                   int row = e.getFirstRow();
                            int column = e.getColumn();
                            System.out.println("Row "+row);
                            System.out.println("Column "+column);
                            if ( column == 1 ) {
                                    Object test = table.getValueAt(row,column);
                                    System.out.println(test);
                                    //If the following line is commented out, we don't have a problem
                                    Double value = (Double)test;
    }updateCurrentHiLo.java
    import javax.swing.*;
    import java.awt.*;
    import javax.swing.table.*;
    import java.awt.event.*;
    import javax.swing.event.*;
    import javax.swing.event.TableModelEvent;
    public class updateCurrentHiLo extends JTable  {
            public updateCurrentHiLo() {
                    super();
                    String[] columnNames = {"Currency",
                                    "Current Hi",
                                    "Current Lo"};
                    Object[][] data = {
                            {"AUD/USD", new Double(0), new Double(0)},
                            {"GBP/USD", new Double(0), new Double(0)},
                            {"EUR/USD", new Double(0), new Double(0)},
                            {"EUR/JPY", new Double(0), new Double(0)},
                            {"USD/JPY", new Double(0), new Double(0)},
                            {"USD/CHF", new Double(0), new Double(0)},
                            {"USD/CAD", new Double(0), new Double(0)},
                            {"NZD/USD", new Double(0), new Double(0)},
                    TableModel model = new DefaultTableModel(data, columnNames);
                    setModel(model);
                    setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
                    doLayout();
                    setPreferredScrollableViewportSize(getPreferredSize());      
    }TabbedPaneDemo.java
    import java.awt.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.table.*;
    import javax.swing.JTabbedPane;
    import javax.swing.JFrame;
    import java.awt.event.*;
    public class TabbedPaneDemo extends JPanel {
        SimpleTable table = new SimpleTable();
        public TabbedPaneDemo() {
            super(new GridLayout(1, 1));
            JTabbedPane tabbedPane = new JTabbedPane();
            //SimpleTable table = new SimpleTable();
            JScrollPane scrollPane = new JScrollPane( table );
            JPanel panel = new JPanel(false);
            panel.add(scrollPane);
            panel.setPreferredSize(new Dimension(410, 50));
            tabbedPane.addTab("Tab 1", null, panel,
                    "Does nothing");
            tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
            //Add the tabbed pane to this panel.
            add(tabbedPane);
            //The following line enables to use scrolling tabs.
            tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
    }Hope someone can help me track down this error.

  • Problem in capturing the edited data while the table is sorted

    hi,
    i am using the TableSorter class provided by the sun tutorials to add sorting capability for my JTable. i need to print on the screen, the value of the cell whenever it is updated. so i am using TableModelListener and its tableChanged() method for this purpose. if i edit the data without applying the sorting then its printing fine. But if i edit the data with table sorted in a particular order by clicking on the table header then the tableChanged method is not being called. So some problem lies in the table sorter which is preventing the call to the tableChanged method whenver table it is sorted. Below is my implementation of JTable.
    TableSorter sorter = new TableSorter(new MyTableModel());
    final JTable table = new JTable(sorter);
    table.getModel().addTableModelListener(new
    TableModelListener()
         public void tableChanged(TableModelEvent e)
              int row = e.getFirstRow();
                                               int column = e.getColumn();
              System.out.println("Row: "+row+" Coloumn:  "+column);
    );Hope u understood the problem. plzz help
    thanx

    hi camickr,
    However the row number displayed is always the row of
    the TableModel before the data has been sorted. this is the feature i am trying for and couldnt achieve it. i do want to print the row of tablemodel before data is sorted but i am getting 0 and -1 as row and column numbers.
    I never saw -1 as a column number.
    if you have never seen -1 as column number then just compile and run the code given below. I just added a table model listener to the table model to capture data editing. So if u edit any cell without applying sorting then its row and column number is printed properly but if u sort a particlar column and with sorting on if u edit any cell you will get row No. as 0 and column No. as -1. try running below code and please let me know where the problem exists or post your code which worked without any of the above problems.
    I believe the code was updated in Feb of this year,
    so make sure you have the most recent version.yes i have the latest version of tablesorter.
    below is my source code for table sorting just compile and run it
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import java.sql.*;
    import javax.swing.table.*;
    import java.util.*;
    class TableSorterDemo extends JFrame
         public TableSorterDemo()
         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         TableSorter sorter=new TableSorter(new MyTableModel());
         JTable table=new JTable(sorter);
         sorter.setTableHeader(table.getTableHeader());
         table.getModel().addTableModelListener(new
    TableModelListener()
         public void tableChanged(TableModelEvent e)
              int row = e.getFirstRow();
            int column = e.getColumn();
              System.out.println("Row :"+row+" Column: "+column);
         JScrollPane scrollPane = new JScrollPane(table);
         scrollPane.setBackground(new Color(198,232,189));
         add(scrollPane);
         pack();
         setVisible(true);
          class MyTableModel extends AbstractTableModel {
            final String[] columnNames = {"First Name",
                                          "Last Name",
                                          "Sport",
                                          "# of Years",
                                          "Vegetarian"};
            final Object[][] data = {
                {"Mary", "Campione",
                 "Snowboarding", new Integer(5), new Boolean(false)},
                {"Alison", "Huml",
                 "Rowing", new Integer(3), new Boolean(true)},
                {"Kathy", "Walrath",
                 "Chasing toddlers", new Integer(2), new Boolean(false)},
                {"Sharon", "Zakhour",
                 "Speed reading", new Integer(20), new Boolean(true)},
                {"Angela", "Lih",
                 "Teaching high school", new Integer(4), new Boolean(false)}
            public int getColumnCount() {
                return columnNames.length;
            public int getRowCount() {
                return data.length;
            public String getColumnName(int col) {
                return columnNames[col];
            public Object getValueAt(int row, int col) {
                return data[row][col];
             * JTable uses this method to determine the default renderer/
             * editor for each cell.  If we didn't implement this method,
             * then the last column would contain text ("true"/"false"),
             * rather than a check box.
            public Class getColumnClass(int c) {
                return getValueAt(0, c).getClass();
             * Don't need to implement this method unless your table's
             * editable.
            public boolean isCellEditable(int row, int col) {
                //Note that the data/cell address is constant,
                //no matter where the cell appears onscreen.
                if (col < 2) {
                    return false;
                } else {
                    return true;
             * Don't need to implement this method unless your table's
             * data can change.
            public void setValueAt(Object value, int row, int col) {
                    data[row][col] = value;
                    fireTableCellUpdated(row, col);
                   //     System.out.println("row "+row+"Col "+col+"Val "+value);
         public static void main(String[] args)
         new TableSorterDemo();
       /*Table Sorter Class*/
    class TableSorter extends AbstractTableModel {
        protected TableModel tableModel;
        public static final int DESCENDING = -1;
        public static final int NOT_SORTED = 0;
        public static final int ASCENDING = 1;
        private static Directive EMPTY_DIRECTIVE = new Directive(-1, NOT_SORTED);
        public static final Comparator COMPARABLE_COMAPRATOR = new Comparator() {
            public int compare(Object o1, Object o2) {
                return ((Comparable) o1).compareTo(o2);
        public static final Comparator LEXICAL_COMPARATOR = new Comparator() {
            public int compare(Object o1, Object o2) {
                return o1.toString().compareTo(o2.toString());
        private Row[] viewToModel;
        private int[] modelToView;
        private JTableHeader tableHeader;
        private MouseListener mouseListener;
        private TableModelListener tableModelListener;
        private Map columnComparators = new HashMap();
        private java.util.List sortingColumns = new ArrayList();
        public TableSorter() {
            this.mouseListener = new MouseHandler();
            this.tableModelListener = new TableModelHandler();
        public TableSorter(TableModel tableModel) {
            this();
            setTableModel(tableModel);
        public TableSorter(TableModel tableModel, JTableHeader tableHeader) {
            this();
            setTableHeader(tableHeader);
            setTableModel(tableModel);
        private void clearSortingState() {
            viewToModel = null;
            modelToView = null;
        public TableModel getTableModel() {
            return tableModel;
        public void setTableModel(TableModel tableModel) {
            if (this.tableModel != null) {
                this.tableModel.removeTableModelListener(tableModelListener);
            this.tableModel = tableModel;
            if (this.tableModel != null) {
                this.tableModel.addTableModelListener(tableModelListener);
            clearSortingState();
            fireTableStructureChanged();
        public JTableHeader getTableHeader() {
            return tableHeader;
        public void setTableHeader(JTableHeader tableHeader) {
            if (this.tableHeader != null) {
                this.tableHeader.removeMouseListener(mouseListener);
                TableCellRenderer defaultRenderer = this.tableHeader.getDefaultRenderer();
                if (defaultRenderer instanceof SortableHeaderRenderer) {
                    this.tableHeader.setDefaultRenderer(((SortableHeaderRenderer) defaultRenderer).tableCellRenderer);
            this.tableHeader = tableHeader;
            if (this.tableHeader != null) {
                this.tableHeader.addMouseListener(mouseListener);
                this.tableHeader.setDefaultRenderer(
                        new SortableHeaderRenderer(this.tableHeader.getDefaultRenderer()));
        public boolean isSorting() {
            return sortingColumns.size() != 0;
        private Directive getDirective(int column) {
            for (int i = 0; i < sortingColumns.size(); i++) {
                Directive directive = (Directive)sortingColumns.get(i);
                if (directive.column == column) {
                    return directive;
            return EMPTY_DIRECTIVE;
        public int getSortingStatus(int column) {
            return getDirective(column).direction;
        private void sortingStatusChanged() {
            clearSortingState();
            fireTableDataChanged();
            if (tableHeader != null) {
                tableHeader.repaint();
        public void setSortingStatus(int column, int status) {
            Directive directive = getDirective(column);
            if (directive != EMPTY_DIRECTIVE) {
                sortingColumns.remove(directive);
            if (status != NOT_SORTED) {
                sortingColumns.add(new Directive(column, status));
            sortingStatusChanged();
        protected Icon getHeaderRendererIcon(int column, int size) {
            Directive directive = getDirective(column);
            if (directive == EMPTY_DIRECTIVE) {
                return null;
            return new Arrow(directive.direction == DESCENDING, size, sortingColumns.indexOf(directive));
        private void cancelSorting() {
            sortingColumns.clear();
            sortingStatusChanged();
        public void setColumnComparator(Class type, Comparator comparator) {
            if (comparator == null) {
                columnComparators.remove(type);
            } else {
                columnComparators.put(type, comparator);
        protected Comparator getComparator(int column) {
            Class columnType = tableModel.getColumnClass(column);
            Comparator comparator = (Comparator) columnComparators.get(columnType);
            if (comparator != null) {
                return comparator;
            if (Comparable.class.isAssignableFrom(columnType)) {
                return COMPARABLE_COMAPRATOR;
            return LEXICAL_COMPARATOR;
        private Row[] getViewToModel() {
            if (viewToModel == null) {
                int tableModelRowCount = tableModel.getRowCount();
                viewToModel = new Row[tableModelRowCount];
                for (int row = 0; row < tableModelRowCount; row++) {
                    viewToModel[row] = new Row(row);
                if (isSorting()) {
                    Arrays.sort(viewToModel);
            return viewToModel;
        public int modelIndex(int viewIndex) {
            return getViewToModel()[viewIndex].modelIndex;
        private int[] getModelToView() {
            if (modelToView == null) {
                int n = getViewToModel().length;
                modelToView = new int[n];
                for (int i = 0; i < n; i++) {
                    modelToView[modelIndex(i)] = i;
            return modelToView;
        // TableModel interface methods
        public int getRowCount() {
            return (tableModel == null) ? 0 : tableModel.getRowCount();
        public int getColumnCount() {
            return (tableModel == null) ? 0 : tableModel.getColumnCount();
        public String getColumnName(int column) {
            return tableModel.getColumnName(column);
        public Class getColumnClass(int column) {
            return tableModel.getColumnClass(column);
        public boolean isCellEditable(int row, int column) {
            return tableModel.isCellEditable(modelIndex(row), column);
        public Object getValueAt(int row, int column) {
            return tableModel.getValueAt(modelIndex(row), column);
        public void setValueAt(Object aValue, int row, int column) {
            tableModel.setValueAt(aValue, modelIndex(row), column);
        // Helper classes
        private class Row implements Comparable {
            private int modelIndex;
            public Row(int index) {
                this.modelIndex = index;
            public int compareTo(Object o) {
                int row1 = modelIndex;
                int row2 = ((Row) o).modelIndex;
                for (Iterator it = sortingColumns.iterator(); it.hasNext();) {
                    Directive directive = (Directive) it.next();
                    int column = directive.column;
                    Object o1 = tableModel.getValueAt(row1, column);
                    Object o2 = tableModel.getValueAt(row2, column);
                    int comparison = 0;
                    // Define null less than everything, except null.
                    if (o1 == null && o2 == null) {
                        comparison = 0;
                    } else if (o1 == null) {
                        comparison = -1;
                    } else if (o2 == null) {
                        comparison = 1;
                    } else {
                        comparison = getComparator(column).compare(o1, o2);
                    if (comparison != 0) {
                        return directive.direction == DESCENDING ? -comparison : comparison;
                return 0;
        private class TableModelHandler implements TableModelListener {
            public void tableChanged(TableModelEvent e) {
                // If we're not sorting by anything, just pass the event along.            
                if (!isSorting()) {
                    clearSortingState();
                    fireTableChanged(e);
                    return;
                if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {
                    cancelSorting();
                    fireTableChanged(e);
                    return;
                int column = e.getColumn();
                if (e.getFirstRow() == e.getLastRow()
                        && column != TableModelEvent.ALL_COLUMNS
                        && getSortingStatus(column) == NOT_SORTED
                        && modelToView != null) {
                    int viewIndex = getModelToView()[e.getFirstRow()];
                    fireTableChanged(new TableModelEvent(TableSorter.this,
                                                         viewIndex, viewIndex,
                                                         column, e.getType()));
                    return;
                // Something has happened to the data that may have invalidated the row order.
                clearSortingState();
                fireTableDataChanged();
                return;
        private class MouseHandler extends MouseAdapter {
            public void mouseClicked(MouseEvent e) {
                JTableHeader h = (JTableHeader) e.getSource();
                TableColumnModel columnModel = h.getColumnModel();
                int viewColumn = columnModel.getColumnIndexAtX(e.getX());
                int column = columnModel.getColumn(viewColumn).getModelIndex();
                if (column != -1) {
                    int status = getSortingStatus(column);
                    if (!e.isControlDown()) {
                        cancelSorting();
                    // Cycle the sorting states through {NOT_SORTED, ASCENDING, DESCENDING} or
                    // {NOT_SORTED, DESCENDING, ASCENDING} depending on whether shift is pressed.
                    status = status + (e.isShiftDown() ? -1 : 1);
                    status = (status + 4) % 3 - 1; // signed mod, returning {-1, 0, 1}
                    setSortingStatus(column, status);
        private static class Arrow implements Icon {
            private boolean descending;
            private int size;
            private int priority;
            public Arrow(boolean descending, int size, int priority) {
                this.descending = descending;
                this.size = size;
                this.priority = priority;
            public void paintIcon(Component c, Graphics g, int x, int y) {
                Color color = c == null ? Color.GRAY : c.getBackground();            
                // In a compound sort, make each succesive triangle 20%
                // smaller than the previous one.
                int dx = (int)(size/2*Math.pow(0.8, priority));
                int dy = descending ? dx : -dx;
                // Align icon (roughly) with font baseline.
                y = y + 5*size/6 + (descending ? -dy : 0);
                int shift = descending ? 1 : -1;
                g.translate(x, y);
                // Right diagonal.
                g.setColor(color.darker());
                g.drawLine(dx / 2, dy, 0, 0);
                g.drawLine(dx / 2, dy + shift, 0, shift);
                // Left diagonal.
                g.setColor(color.brighter());
                g.drawLine(dx / 2, dy, dx, 0);
                g.drawLine(dx / 2, dy + shift, dx, shift);
                // Horizontal line.
                if (descending) {
                    g.setColor(color.darker().darker());
                } else {
                    g.setColor(color.brighter().brighter());
                g.drawLine(dx, 0, 0, 0);
                g.setColor(color);
                g.translate(-x, -y);
            public int getIconWidth() {
                return size;
            public int getIconHeight() {
                return size;
        private class SortableHeaderRenderer implements TableCellRenderer {
            private TableCellRenderer tableCellRenderer;
            public SortableHeaderRenderer(TableCellRenderer tableCellRenderer) {
                this.tableCellRenderer = tableCellRenderer;
            public Component getTableCellRendererComponent(JTable table,
                                                           Object value,
                                                           boolean isSelected,
                                                           boolean hasFocus,
                                                           int row,
                                                           int column) {
                Component c = tableCellRenderer.getTableCellRendererComponent(table,
                        value, isSelected, hasFocus, row, column);
                if (c instanceof JLabel) {
                    JLabel l = (JLabel) c;
                    l.setHorizontalTextPosition(JLabel.LEFT);
                    int modelColumn = table.convertColumnIndexToModel(column);
                    l.setIcon(getHeaderRendererIcon(modelColumn, l.getFont().getSize()));
                return c;
        private static class Directive {
            private int column;
            private int direction;
            public Directive(int column, int direction) {
                this.column = column;
                this.direction = direction;
    }

  • JCheckBox clicking problem in JTable

    Hi,
    I have a column of JCheckBox in a JTable. The JTable is only used to layout the controls(for lagecy reason). The JCheckBox has an item change listener attached. The problem is that OCCASIONALLY when the JCheckBox[i] was clicked, the debug in itemStateChanged show the source object was NOT JChechBox, it was JCheckBox[i+1] or JCheckBox[i-1]. In other word, it was the check box in the previous or next row changed state.
    Has anybody experienced similar problems? Is it a problem of JTable dispatching mouse click event?
    How to solve the problem?
    Thanks

    I'm not sure why you get the results you do, but instead of adding a change listener to the JCheckBox you could add a TableModelListener to the TableModel. This will fire an event whenever any data is changed. This thread shows a simple example:
    http://forum.java.sun.com/thread.jsp?forum=57&thread=425540

  • Can't add TableModelListener

    I'm getting an abstract error with the following line:
    serviceModel.addTableModelListener(new TableModelListener()...
    Additionaly I would like to know when you can use:
    serviceModel.addTableModelListener(new TableModelListener(){
                   public final void tableChanged(TableModelEvent e)
                        TableModel source = (TableModel)e.getSource();
                             System.out.println("Source is:"+source);
    I've noticed some examples putting the enitre method inside () like this one, and other examples where it isn't
    Anyways, here is my code.
    Thanks in advance
    import javax.swing.*;
    import java.util.*;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.event.*;
    import javax.swing.plaf.metal.MetalLookAndFeel;
    import javax.swing.table.TableModel;
    import javax.swing.event.TableModelEvent;
    import javax.swing.event.TableModelListener;
    import javax.swing.table.*;
    public class Table extends JFrame implements ActionListener,TableModelListener
         private JPanel      testPanel;
         private JTextField  tf;
         private JButton          btn;
         private JScrollPane scroll;
         public JTable table;
         private String timeText;
         private String service;
         DefaultTableModel serviceModel;
         public Table()
              setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              Container pane = getContentPane();
              //Object data[][] = { {"hair cut", new Integer(5), new Boolean(false)} };
              Object data[][]=null;
              String columnNames[] = {"Service", "Minutes", "Select"};
              serviceModel= new DefaultTableModel(data,columnNames);
             table = new JTable(serviceModel);
                   public Class getColumnClass(int c)
                   return getValueAt(0, c).getClass();
              TableColumn chkCol = table.getColumnModel().getColumn(2);
              chkCol.setCellEditor(table.getDefaultEditor(Boolean.class));
              chkCol.setCellRenderer(table.getDefaultRenderer(Boolean.class));
              table.setPreferredScrollableViewportSize(new Dimension(200,200));
              scroll = new JScrollPane(table);
              testPanel = new JPanel();
              testPanel.setLayout(new GridLayout(0,1));
              tf = new JTextField();
              btn = new JButton("Click");
              btn.addActionListener(this);
              testPanel.add(btn);
              testPanel.add(tf);
              testPanel.add(scroll);
              pane.add(testPanel);
         }//end constructor
         public void actionPerformed(ActionEvent e)
              String cmd = e.getActionCommand();
              if(cmd.equals("Click"))
                   service=tf.getText();
                   timeText=JOptionPane.showInputDialog("Enter the time allowed in minutes for \n a "+service+ " appointment");
                   serviceModel.addRow(createRow(service,timeText));
                   serviceModel.addTableModelListener(new TableModelListener(){
                   public final void tableChanged(TableModelEvent e)
                            TableModel source = (TableModel)e.getSource();
                             System.out.println("Source is:"+source);
                   tf.requestFocusInWindow();
                   tf.setText("");
         private Object[] createRow(String s,String t)
                             Object[] newRow = new Object[3];
                             //TableColumn chkCol = table.getColumnModel().getColumn(2);
                             //chkCol.setCellEditor(new DefaultCellEditor(c));
                             newRow[0] = s;
                             newRow[1] =t;
                             newRow[2] = new Boolean(false);
                             repaint();
                             return newRow;
         public static void main(String[] args)
              Frame f = new Table();
              f.setSize(300,300);
              f.setVisible(true);
    }//end class

    What do you mean by "abstract error"? I think your problem is that the Table class doesn't implement the
    public void tableChanged(. . .) method of TableModelListener interface. Adding an anonymous listener in your actionPerformed method doesn't count.
    When you declare that a class implenents an interface you are promising that it well provide concrete implementations for the interface's methods. You did that for the ActionListener interface. You can also use an anonymous listener using the code:
    serviceModel.addTableModelListener(new TableModelListener(){
    public final void tableChanged(TableModelEvent e)
    TableModel source = (TableModel)e.getSource();
    System.out.println("Source is:"+source);
    remove the reference to implementing a TableModelListener in your class declaration and try again
    Cheers
    DB

  • Item Listener problem

    I have an item listener on a checkbox within a table cell.
    At the time I get the SELECTED or DELECTED event, I invoke a method to update the gui based on the event.
    Well, to be precise, I retrieve data from the table model to get the status of each checkbox in the column and base a decision on whether any checkboxes in the column are checked. The problem is -- and it may be timing related -- is that sometimes the table model doesn't seem to reflect the new selected status of the checkbox I just clicked.
    Does anyone know the sequence of events when an item listener is hit -- does the table model get updated first, or perhaps the event happens and the model gets updated a bit later and I'm trying to do my evaluation too soon. If the latter case is true, does anyone have any thoughts on how to best workaround this situation? I've tried putting the evaluation code in a runnable with invokeLater and it doesn't help.
    Thanks for any thoughts on this.

    Thank you. I added a TableModelListener to listen for UPDATES to the cells in my column and fire the events for evaluation then and it works much better. Thanks for the clue.
    Isn't JTable's flexibility wonderful but mastering it a chore?! I'm getting there....

  • Problem with comboBox editor

    Hi experts,
    i am keeping a combobox renderer and editor in my JTable for 2 columns say 5th column and 7th column.
    In renderer no Problem.
    But while i am editing ,whenever i am choosing a perticular item from the drop down in the first row of table,it is affecting the remaining set of rows.,not all the rows also.
    for example,next 5 rows are getting the same selected value.
    next some 2 rows are getting affected.
    the below 2 class are my renderer and editor.public class ComboBoxRenderer extends JComboBox implements TableCellRenderer {
            public ComboBoxRenderer(String[] items) {
                            super(items);
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                    if (isSelected) {
                    // Select the current value
                    setSelectedItem(value);
                    return this;
    }My ComboBox editor is public class ComboBoxEditor extends DefaultCellEditor {
            public ComboBoxEditor(String[] items) {
                   super(new JComboBox(items));
    }so i am using this render and editor in my swing screen by the following codeString strSP[] = {"P", "O", "H", " "};
    column5.setCellEditor(new ComboBoxEditor(strSP));
    column5.setCellRenderer(new ComboBoxRenderer(strSP));I am sure like the problem with my renderer and editoronly,but i am helpless.
    Please if someone help me to come out of this problem,it will be much helpful for me .
    thanks

    Hi,
    Thanks for u'r reply
    I tried in so many ways.
    I tried with u'r editor,and sun forum examples also.
    I brief what i want.
    I am having table with 3 column.
    The zeroth col, and the 2 col is a combo box.so i am rendering.
    when i choose a one from zeroth col combo Box ,the 2nd col ComboBox value has to change into YES
    when i choose a apart from one from zeroth col combo Box ,the 2nd col combo Box value has to change into NO.
    Here my Problem is
    When ever i am choosing the particular value from the 1st combo box,it is affecting the all the combobox values below(set of values,not all)..To solve that i kept the commented line in the renderer but it is creating the new problem.
    I am very seriously working to solve this problem,if any one suggest to solve this,it will be very much helpful to me.
    I am posting my code belowimport java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.TableModelEvent;
    import javax.swing.event.TableModelListener;
    import javax.swing.table.*;
    public class TableComboBox extends JFrame implements TableModelListener
         public JTable table;
            DefaultTableModel model = null;
            JComboBox editor2 = null;
         public TableComboBox()
              Object[][] data = { {" ", "A" , " "}, {" ", "B", " "}, {" ", "C", " "}, {" ", "D", " "}, {" ", "E", " "}, {" ", "F", " "}, {" ", "G", " "}, {" ", "H", " "}  };
                    String[] columnNames = {"FIRST","SECOND", "THIRD" };
                    String[] column0Items = { "one", "two", "three", "four" };
                    String column2Items[] = {"YES","NO"};
              model = new DefaultTableModel(data, columnNames);
                    model.addTableModelListener(this);
              table = new JTable(model);
              //  Set the Zeroth column to use a combobox as its editor,renderer
                    table.getColumnModel().getColumn(0).setCellRenderer(new ComboBoxRenderer(column0Items));
              table.getColumnModel().getColumn(0).setCellEditor(new ComboBoxEditor(column0Items));
                    //  Set the second column to use a combobox as its editor,renderer
                    table.getColumnModel().getColumn(2).setCellRenderer(new ComboBoxRenderer(column2Items));
              table.getColumnModel().getColumn(2).setCellEditor(new ComboBoxEditor(column2Items));
                    JScrollPane scrollPane = new JScrollPane( table );
              getContentPane().add( scrollPane );
             public void tableChanged(TableModelEvent e) {
                    int row = e.getFirstRow();
                    int column = e.getColumn();
                    if(e.getType() == TableModelEvent.INSERT) {
                    if (e.getType() == TableModelEvent.UPDATE) {
                            if(table.getEditingRow() != table.getSelectedRow())
                                    ((DefaultCellEditor)table.getCellEditor()).cancelCellEditing();                      
                   if ( column == 0 ) {
                                    if(model.getValueAt(row, 0).equals("one")) {
                                            model.setValueAt("YES", row, 2);
                                    } else if(model.getValueAt(row, 0).equals("two")){
                                            model.setValueAt("NO", row, 2);
                                    } else if(model.getValueAt(row, 0) == "three"){
                                            model.setValueAt("NO", row, 2);
                                    } else if(model.getValueAt(row, 0) == "four"){
                                            model.setValueAt("NO", row, 2);
                           }else{
                                    //do nothing
         public static void main(String[] args)
              final TableComboBox frame = new TableComboBox();
              frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
              frame.pack();
              frame.setVisible(true);
            class ComboBoxRenderer extends JComboBox implements TableCellRenderer {
                    String items[];
                    public ComboBoxRenderer(String[] items) {
                                    super(items);
                                    this.items = items;
                    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                                   if(isSelected){
                                            setSelectedItem(value.toString());
                                            return this;
                                    }/*else{
                                            setSelectedItem(items[0]));
                            return this;
            class ComboBoxEditor extends DefaultCellEditor {
                    public ComboBoxEditor(String[] items) {
                           super(new JComboBox(items));
            }

  • A problem with threads

    I am trying to implement some kind of a server listening for requests. The listener part of the app, is a daemon thread that listens for connections and instantiates a handling daemon thread once it gets some. However, my problem is that i must be able to kill the listening thread at the user's will (say via a sto button). I have done this via the Sun's proposed way, by testing a boolean flag in the loop, which is set to false when i wish to kill the thread. The problem with this thing is the following...
    Once the thread starts excecuting, it will test the flag, find it true and enter the loop. At some point it will LOCK on the server socket waiting for connection. Unless some client actually connects, it will keep on listening indefinatelly whithought ever bothering to check for the flag again (no matter how many times you set the damn thing to false).
    My question is this: Is there any real, non-theoretical, applied way to stop thread in java safely?
    Thank you in advance,
    Lefty

    This was one solution from the socket programming forum, have you tried this??
    public Thread MyThread extends Thread{
         boolean active = true;          
         public void run(){
              ss.setSoTimeout(90);               
              while (active){                   
                   try{                       
                        serverSocket = ss.accept();
                   catch (SocketTimeoutException ste){
                   // do nothing                   
         // interrupt thread           
         public void deactivate(){               
              active = false;
              // you gotta sleep for a time longer than the               
              // accept() timeout to make sure that timeout is finished.               
              try{
                   sleep(91);               
              }catch (InterruptedException ie){            
              interrupt();
    }

Maybe you are looking for

  • My text on a dv progressive output isn't clear

    Ok I got in an editor for two days because I was insecure about outputting myself and didn't know how to work with compressor. I have a dv progressive 4:3 letterboxed feature 24p. It's edited down from an earlier version where the output didn't have

  • Iphone keeps crashing constantly...

    So I open an app, crash I open up pandora radio app (internet radio) *skip skip skip* I do a google search crash then just sends me back to home screen. Any idea why my iphone keeps crashing? I'm running a 3g. I try to do a restart but still does the

  • Crash on Tweening a TextField with a mask AS3 CS3

    I have yet to hunt down exactly what it is about this situation that makes it crash, but when I tween the position of a TextField that has a mask, as soon as I close the movie window the program crashes, whether it be in the Flash (CS3) IDE or in a b

  • Cannot connect to internet at all.

    On my current desktop my enthernet and WiFi or wireless drivers have been deleted from my HP Pavilon p7-1240 desktop and I can not access the internet on it at all. I cannot install the drivers because I can't download them off the internet because I

  • Imported image and making white space transparent...

    I need to make the white space around an image transparent without having to use the clipping mask tool. In Freehand, you simply click a button and the white background disappears. I need to use that exact technique to hide the white background. How