GetColumnClass() method of JTables

Is it possible to display 2 different types in the same column of a JTable?
For example: In some rows should be CheckBoxes and in some should be nothing displayed.But the problem is that I've to implement the getColumnClass() method.
Or is there another way with a different method to tell each cell which type of component it contains so that it can tell this to its renderer and display it in the right way

It depends on what you're really trying to do. The theory behind tablular data is that a column contains values of a particular data type. the getColumnClass(int col) method returns the Class of the data objects. A JCheckBox is commonly used to render Boolean objects but the getColumnClass call would return Boolean.class.
So, In your design, what would determine when a JCheckBox should be in a particular cell and when "nothing" should be displayed? Are you planning a check box for true and nothing for false, or maybe a check box for true or false and nothing if that value is null.
You could probably accomplish would you want by implementing a custom TableCellRenderer.
Cheers
DB

Similar Messages

  • Regarding setValueAt method in JTable

    sir,
    i have a problem regarding JTable.
    now if u enter the data in cell
    then setvalueAt() method is called once
    now if u enter the data in a cell which is already
    having a dat in that cell, then the setvalueAt method
    is called twice.........
    why it so and how can i prevent it as i needed it in
    getting dataVector and when i print the values of dataVactor
    it gives recent values not the previuos set values
    i m just beginner in this concern
    i hope u be able to understand and solve
    thanks in advance

    Hi,
    I have looked at your code. You are still trying to control too much yourself. Let the table do it instead. The table is designed to handle all of its events and works best when you let it. I made a few code suggestions here. I didn't compile it, so please don't expect it to just work. It is merely a suggestion of an approach that may make your work easier.
      Vector tableData = new Vector();
      ArrayList newValues;
      ViewModel ()
        // in the constructor create an ArrayList for each row that will be displayed
        // and put them in the tableData Vector
        int count = newViewFrame.sortCombo.getItemCount(); // Count is the number of rows?
        for(int i=0;i<count;i++)
          newValues = new ArrayList();
          for (int j = 0; j < numColumns; j++)
            newValues.add();
          tableData.add (newValues);
      // These methods are used by the table and should be supplied
      public int getRowCount ()
      { return tableData.size(); }
      public int getColumnCount ()
      { return 5; }   // the number of columns in your table - this number is used a lot
                      // do not make it complicated to compute
      public void setValueAt(Object value,int row, int col)
        //super.setValueAt(value,row,col); - No point, this is an empty method
        // if the index is out of bounds or nothing was changed return
        if (row < 0 || row >= getRowCount())
          return;
        if (o == null)
        { return; }
        // get the data array for the row which was changed 
        newValues = (ArrayList)tableData.elementAt (row);
        // it doesn't look like your are doing anything for columns 1 -4 ?
        if (column == 0)
          return;
        if (column == 1) 
          return
        else if (column == 2)  
          return;
        else if (column == 3)   
          return;
        else if (column == 4) 
          // not first - do this after you have changed the array
          // fireTableChanged(new TableModelEvent(this,0,4,4));
          Integer colValues[] = TableComboBoxEditor.getColumnValues(((ViewModel)newViewFrame.viewTable.getModel()).getDataVector(),col);
          int retrunValue = alreadyExists(colValues , value);
          System.out.println("the value of row is "+retrunValue);
          if( retrunValue != Integer.MIN_VALUE && retrunValue != row)
            System.out.println("heyheyeheyeheye");
            Set setOfRows = TableComboBoxEditor.hash.keySet();
            Iterator iterator = setOfRows.iterator();
            setValueAtCalled=true;
            int count = newViewFrame.sortCombo.getItemCount();
            // newValues = new ArrayList(); use the one from the dataVector
            for(int i=0;i<count;i++)
              newValues.add(newViewFrame.sortCombo.getItemAt(i));
            // while(iterator.hasNext()){
            // setValueAt(new Integer(0),((Integer)iterator.next()).intValue(),col);
            validatingRemainingColumns(iterator,value,row);
            setValueAtCalled = false;
          // now refresh the table
          fireTableChanged(new TableModelEvent(this,0,4,4));
      // this method creates Integers to set the values in the table
      // If you want Strings instead change it
      public Object getValueAt (int row, int column)
        if (row < 0 || row >= getRowCount())
          return " ";
        newValues = (ArrayList) tableData.elementAt (row);
        if (column == 0)         // set number
          return new Integer (newValues.get(0));
        else if (column == 1)   
          return new Integer (newValues.get(1));
        else if (column == 2)  
          return new Integer (newValues.get(2));
        else if (column == 3)  
          return new Integer (newValues.get(3)));
        else if (column == 4)  
          return new Integer (newValues.get(4)));
        else if (column == 5)  
          return new Integer (newValues.get(5)));
      {\code]

  • Why is my JTable row sort is not working?

    Hey all,
    I wrote the following code for a JTable and I'm trying to use a table sorter to sort the first column content alphabetically, for now. Later, I'd like to use the third column and sort the table's rows based on ascending dates.
    For some reason, my comparator is not being called at all and I'm not sure what I'm doing wrong. I'm using JDK 6, which allows me to use a TableRowSorter. It is the first time I'm using this, so I may not know how to use it correctly. Does anybody have any idea what I'm doing wrong?
    Please advice.
    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.util.Comparator;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTable;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.table.TableRowSorter;
    public class MyTable {
         JTable table;
         public MyTable() {
              JFrame frame = new JFrame("My Table");
              JPanel panel = new JPanel(new BorderLayout());
              table = createTable();
              panel.add(table.getTableHeader(), BorderLayout.NORTH);
              panel.add(table);
              frame.getContentPane().add(panel);
              frame.setSize(new Dimension(400,150));
              frame.setVisible(true);
         private JTable createTable()
              Object [][] data = {{"Nazli", "Shahi", "Wed, Mar 31, 1982"},{"Nima", "Sohrabi", "Thu, Jul 15, 1982"},
                                    {"Farsheed", "Tari", "Mon, Jun 13, 1967"}, {"Anousheh", "Modaressi", "Tue, Sep 18, 1964"}};
              String [] columnNames = {"First Name","Last Name","DOB"};
              DefaultTableModel model = new DefaultTableModel(data, columnNames);
              table = new JTable(model);
              TableRowSorter sorter = new TableRowSorter(model);
            sorter.setComparator(0, new MyComparator());
             table.setRowSorter(sorter);
              return table;
         private class MyComparator implements Comparator {
              public int compare(Object s1, Object s2) {
                   String first = s1.toString();
                   String second = s2.toString();               
                   System.err.println("returning "+(first.substring(0, 1)).compareTo(second.substring(0, 1)));
                   return (first.substring(0, 1)).compareTo(second.substring(0, 1));
         public static void main(String[] args) {
              MyTable test = new MyTable();
    }

    Alrite, so now I have Date objects in the model instead of String objects. Now, my question is, how can I actually sort the Date column with the latest dates showing on top and earlier dates showing on the bottom?
    The table provides a default Comparator to sort dates. You just need to tell the table what type of data is stored in each column. This is done by overriding the getColumnClass() method of JTable or TableModel.
    Camickr, you once said that the table provides a default Comparator to sort dates. and I just need to tell the table what type of data is stored in each column. This is done by overriding the getColumnClass() method of JTable or TableModel.
    With the current code that I have in getColumnClass I am not able to compare anything yet. Is there anything else I need to do? I'm a bit clueless, so I'd appreciate your help.
    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.util.Date;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JTable;
    import javax.swing.table.DefaultTableModel;
    public class MyTable {
        JTable table;
        DefaultTableModel model;
        public MyTable() {
            JFrame frame = new JFrame("My Table");
            JPanel panel = new JPanel(new BorderLayout());
            table = createTable();
            panel.add(table.getTableHeader(), BorderLayout.NORTH);
            panel.add(table);
            frame.getContentPane().add(panel);
            frame.setSize(new Dimension(400,150));
            frame.setVisible(true);
        private JTable createTable() {
            Object [][] data = {{"Nazli", "Sh", new Date(192837429L)},{"Nima", "So", new Date(1293847L)},
                                {"Farsheed", "T", new Date(9872347892L)}, {"Anousheh", "M", new Date(234321234L)}};
            String [] columnNames = {"First Name","Last Name","DOB"};
            model = new MyTableModel(data, columnNames);
            table = new JTable(model);
            return table;
        public static void main(String[] args) {
            MyTable test = new MyTable();
        private class MyTableModel extends DefaultTableModel {
             public MyTableModel(Object [][] data, String [] columnNames) {
                  super(data, columnNames);
             public Class getColumnClass(int column) {
                  System.err.println(column);
                  if(column==2)
                       return getValueAt(column, 2).getClass();
                  else
                       return Object.class;
    }

  • JTable checkboxes doesn't retain their selection when a new row is added!!

    HI,
    My gui has the JTable component which has 5 columns. out of which 4 columns are checkboxes. whenever i select an item from the Jlist and click on the add button it will add a new row in JTable.
    but the problem is whenever a new row is added to the table. the previously selected checkboxes of previous rows are being deselected. But i want to retain the selection of my previous rows even when a new row is added. please help me how to achieve this..i am posting my JTable code here:
    class FunctionTableModel extends AbstractTableModel{
           /** The instances who's attribute structure we are reporting */
        //protected InitModel m_init;
        protected String func_element;
        protected int counter;
        //protected String[] func_array;
        protected Vector func_vector;
        /** The flag for whether the instance will be included */
        protected boolean [] m_Sum;
        protected boolean [] m_Min;
        protected boolean [] m_Avg;
        protected boolean [] m_Max;
        protected boolean [] m_SD;
         * Creates the tablemodel with the given set of instances.
         * @param instances the initial set of Instances
        public FunctionTableModel() {
          counter =0;
             func_vector = new Vector();
         public FunctionTableModel(Vector vec) {
            func_vector = vec;
        public Vector getDataVector(){
            return func_vector;
         * Sets the tablemodel to look at a new set of instances.
         * @param instances the new set of Instances.
        public void setElement(Vector vec) {
               for(int i=0;i<vec.size();i++){
            func_vector.add(vec.elementAt(i));
            counter++;
          fireTableDataChanged();   
          m_Sum = new boolean [counter];
          m_Min = new boolean[counter];
          m_Avg = new boolean[counter];
          m_Max = new boolean[counter];
          m_SD = new boolean[counter];
         * Gets the number of attributes.
         * @return the number of attributes.
        public int getRowCount() {
               return func_vector.size();
         * Gets the number of columns: 3
         * @return 3
        public int getColumnCount() {
          return 6;
         * Gets a table cell
         * @param row the row index
         * @param column the column index
         * @return the value at row, column
        public Object getValueAt(int row, int column) {
          switch (column) {
          case 0:
            return func_vector.elementAt(row);
          case 1:
            return new Boolean(m_Sum[row]);
          case 2:
            return new Boolean(m_Min[row]);
          case 3:
            return new Boolean(m_Avg[row]);
          case 4:
            return new Boolean(m_Max[row]);
          case 5:
            return new Boolean(m_SD[row]); 
          default:
            return null;
        public void removeAll(){
            func_vector.removeAllElements();
            fireTableDataChanged();
         * Gets the name for a column.
         * @param column the column index.
         * @return the name of the column.
        public String getColumnName(int column) {
          switch (column) {
          case 0:
            return new String("Function Selected");
          case 1:
            return new String("Sum");
          case 2:
            return new String("Min");
          case 3:
            return new String("Avg");
          case 4:
            return new String("Max");
          case 5:
            return new String("SD");   
          default:
         return null;
         * Sets the value at a cell.
         * @param value the new value.
         * @param row the row index.
         * @param col the column index.
        public void setValueAt(Object value, int row, int col) {
          if(col == 0){
            counter++;
            func_vector.add(counter,value.toString());
          if (col == 1)
            m_Sum[row] = ((Boolean) value).booleanValue();
          if (col == 2)
            m_Min[row] = ((Boolean) value).booleanValue();
          if (col == 3)
            m_Avg[row] = ((Boolean) value).booleanValue();
          if (col == 4)
            m_Max[row] = ((Boolean) value).booleanValue();
          if (col == 5)
            m_SD[row] = ((Boolean) value).booleanValue();       
         * Gets the class of elements in a column.
         * @param col the column index.
         * @return the class of elements in the column.
        public Class getColumnClass(int col) {
             return getValueAt(0, col).getClass();
         * Returns true if the column is the "selected" column.
         * @param row ignored
         * @param col the column index.
         * @return true if col == 1.
        public boolean isCellEditable(int row, int col) {
          if (col >= 1) {
             return true;
          return false;
        public void removeRow(int row){
            if(row<=func_vector.size()){
                          func_vector.removeElementAt(row);
                counter--;
            fireTableDataChanged();
        }

    hi parvathi,
    i have made changes to my previous code and here's the code:
      class FunctionTableModel extends DefaultTableModel{
           /** The instances who's attribute structure we are reporting */
        //protected InitModel m_init;
        protected String func_element;
        protected int counter;
        protected int counter1;
        //protected String[] func_array;
        protected Vector func_vector;
        /** The flag for whether the instance will be included */
        protected boolean [] m_Sum;
        protected boolean [] m_Min;
        protected boolean [] m_Avg;
        protected boolean [] m_Max;
        protected boolean [] m_SD;
        //protected Vector m_Sum1;
        //protected Vector m_Min1;
        //protected Vector m_Avg1;
        //protected Vector m_Max1;
        //protected Vector m_SD1;
         * Creates the tablemodel with the given set of instances.
         * @param instances the initial set of Instances
        public FunctionTableModel() {
            System.out.println("entered the constr");
          counter =0;
          //counter1=0;
          //m_Sum1 = new Vector();
          //m_Min1 = new Vector();
          //m_Avg1 = new Vector();
          //m_Max1 = new Vector();
          //m_SD1 = new Vector();
          //func_array = new String[];
          func_vector = new Vector();
         public FunctionTableModel(Vector vec) {
            func_vector = vec;
            //setElement(func_vector);
        public Vector getDataVector(){
            return func_vector;
         * Sets the tablemodel to look at a new set of instances.
         * @param instances the new set of Instances.
        public void addRow(Vector vec) {
          //counter++; 
          //func_element = ele;
          //System.out.println("FunctionTableModel- setElement() method");
          for(int i=0;i<vec.size();i++){
            func_vector.add(vec.elementAt(i));
            counter++;  
           //System.out.println("counter ="+counter+new boolean[counter]); 
            //m_Sum1 = m_Sum;
            //m_Min1 = m_Min;
            //m_Avg1 = m_Avg;
            //m_Max1 = m_Max;
            //m_SD1 = m_SD;
            //m_Sum = new boolean[counter];
            //System.out.println("at setElement");
            m_Sum = new boolean[counter];
            //System.out.println(counter);
            m_Min = new boolean[counter];
            //m_Min;
            m_Avg = new boolean[counter];
            //m_Avg1 = m_Avg;
            m_Max = new boolean[counter];
            //m_Max1 = m_Max;
            m_SD = new boolean[counter];
            //m_SD1 = m_SD;
            //counter1++;
          //func_array[counter]=ele;
          //func_vector.add(counter,ele);
          fireTableDataChanged();  
         * Gets the number of attributes.
         * @return the number of attributes.
        //public int getRowCount() {
          //System.out.println("FunctionTableModel- getRowCount() method");
          //return func_vector.size();
         * Gets the number of columns: 3
         * @return 3
        public int getColumnCount() {
          return 6;
         * Gets a table cell
         * @param row the row index
         * @param column the column index
         * @return the value at row, column
        public Object getValueAt(int row, int column) {
          switch (column) {
          case 0:
            return func_vector.elementAt(row);
          case 1:{
            //System.out.println("in case 1");
            //Boolean m_Sum_Value = new Boolean(m_Sum[row]);
            //System.out.println("m_Sum_Value:"+m_Sum_Value.booleanValue());
            return new Boolean(m_Sum[row]);
            //m_Sum1.add(m_Sum_Value);
            //return m_Sum_Value;
          case 2:
            return new Boolean(m_Min[row]);
          case 3:
            return new Boolean(m_Avg[row]);
          case 4:
            return new Boolean(m_Max[row]);
          case 5:
            return new Boolean(m_SD[row]); 
          default:
            return null;
        public void removeAll(){
            func_vector.removeAllElements();
            //m_Sum1.removeAllElements();
            fireTableDataChanged();
         * Gets the name for a column.
         * @param column the column index.
         * @return the name of the column.
        public String getColumnName(int column) {
          switch (column) {
          case 0:
            return new String("Function Selected");
          case 1:
            return new String("Sum");
          case 2:
            return new String("Min");
          case 3:
            return new String("Avg");
          case 4:
            return new String("Max");
          case 5:
            return new String("SD");   
          default:
         return null;
         * Sets the value at a cell.
         * @param value the new value.
         * @param row the row index.
         * @param col the column index.
        public void setValueAt(Object value, int row, int col) {
          if(col == 0){
            counter++;
            func_vector.add(counter,value.toString());
          if (col == 1) {
            m_Sum[row] = ((Boolean) value).booleanValue();
            //System.out.println("m_Sum length "+m_Sum.length);
            //for(int i=0;i<=row;i++)
            //    System.out.println("m_Sum1 "+i+((Boolean)m_Sum1.elementAt(i)).booleanValue());
            //System.out.println("m_Sum1["+row+"] "+ ((Boolean)m_Sum1.elementAt(row)).booleanValue());
            //    System.out.println("m_Sum["+i+"] "+ m_Sum);
    if (col == 2)
    m_Min[row] = ((Boolean) value).booleanValue();
    if (col == 3)
    m_Avg[row] = ((Boolean) value).booleanValue();
    if (col == 4)
    m_Max[row] = ((Boolean) value).booleanValue();
    if (col == 5)
    m_SD[row] = ((Boolean) value).booleanValue();
    * Gets the class of elements in a column.
    * @param col the column index.
    * @return the class of elements in the column.
    public Class getColumnClass(int col) {
    return getValueAt(0, col).getClass();
    * Returns true if the column is the "selected" column.
    * @param row ignored
    * @param col the column index.
    * @return true if col == 1.
    public boolean isCellEditable(int row, int col) {
    if (col >= 1) {
         return true;
    return false;
    public void removeRow(int row){
    if(row<=func_vector.size()){
    func_vector.removeElementAt(row);
    counter--;
    fireTableDataChanged();
    previouslu i was using the setElement method. now i have replaced with the addRow method...
    but anyways...the control is not going to any of these overridden methods...and none of the elements are added to the table. But i comment of all the addRow, getValueAt, getColumnClass methods...then it's adding rows to the table but with only the first column all the remaiing columns are just empty...
    i am fed up with this...if you observe i have commented out somany lines...becoz i am trying to save my boolean array values into a vector..but that was also in vain...
    i appreciate for ur help...
    thanks
    sri

  • To change the font of a selected row in a Jtable

    Hello,
    Is it possible to change the font of a selected row in a jtable?
    i.e. if all the table is set to a bold font, how would you change the font of the row selected to a normal (not bold) font?
    thank you.

    String will be left justified
    Integer will be right justified
    Date will be a simple date without the time.
    As it will with this renderer.Only if your custom renderer duplicates the code
    found in each of the above renderers. This is a waste
    of time to duplicate code. The idea is to reuse code
    not duplicate and debug again.
    No, no, no there will be NO duplicated code.
    A single renderer class can handle all types ofdata.
    Sure you can fit a square peg into a round hole if
    you work hard enough. Why does the JDK come with
    separate renderers for Date, Integer, Double, Icon,
    Boolean? So that, by default the rendering for common classes is done correctly.
    Because its a better design then having code
    with a bunch of "instanceof" checks and nested
    if...else code.This is only required for customization BEYOND what the default renderers provide
    >
    And you would only have to use instanceof checkswhen you required custom
    rendering for a particular classAgreed, but as soon as you do require custom
    renderering you need to customize your renderer.
    which you would also have to do with theprepareRenderer calls too
    Not true. The code is the same whether you treat
    every cell as a String or whether you use a custom
    renderer for every cell. Here is the code to make the
    text of the selected line(s) bold:
    public Component prepareRenderer(TableCellRenderer
    renderer, int row, int column)
    Component c = super.prepareRenderer(renderer, row,
    , column);
         if (isRowSelected(row))
              c.setFont( c.getFont().deriveFont(Font.BOLD) );
         return c;
    }It will work for any renderer used by the table since
    the prepareRenderer(...) method returns a Component.
    There is no need to do any kind of "instanceof"
    checking. It doesn't matter whether the cell is
    renderered with the "Object" renderer or the
    "Integer" renderer.
    If the user wants to treat all columns as Strings or
    treat individual columns as String, Integer, Data...,
    then they only need to override the getColumnClass()
    method. There is no change to the prepareRenderer()
    code.
    Have you actually tried the code to see how simple it
    is?
    I've posted my code. Why don't you post your solution
    that will allow the user to bold the text of a Date,
    Integer, and String data in separate column and then
    let the poster decide.Well, I don't see a compilable, runnable demo anywhere in this thread. So here's one
    import javax.swing.*;
    import javax.swing.table.*;
    import java.awt.*;
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Arrays;
    import java.util.Date;
    import java.util.Vector;
    public class TableRendererDemo extends JFrame{
        String[] headers = {"String","Integer","Float","Boolean","Date"};
        private JTable table;
        public TableRendererDemo() {
            buildGUI();
        private void buildGUI() {
            JPanel mainPanel = (JPanel) getContentPane();
            mainPanel.setLayout(new BorderLayout());
            Vector headerVector = new Vector(Arrays.asList(headers));
             Vector data = createDataVector();
            DefaultTableModel tableModel = new DefaultTableModel(data, headerVector){
                public Class getColumnClass(int columnIndex) {
                    return getValueAt(0,columnIndex).getClass();
            table = new JTable(tableModel);
    //        table.setDefaultRenderer(Object.class, new MyTableCellRenderer());
            table.setDefaultRenderer(String.class, new MyTableCellRenderer());
            table.setDefaultRenderer(Integer.class, new MyTableCellRenderer());
            table.setDefaultRenderer(Float.class, new MyTableCellRenderer());
            table.setDefaultRenderer(Date.class, new MyTableCellRenderer());
            JScrollPane jsp = new JScrollPane(table);
            mainPanel.add(jsp, BorderLayout.CENTER);
            pack();
            setLocationRelativeTo(null);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        private Vector createDataVector(){
            Vector dataVector = new Vector();
            for ( int i = 0 ; i < 10; i++){
                Vector rowVector = new Vector();
                rowVector.add(new String("String "+i));
                rowVector.add(new Integer(i));
                rowVector.add(new Float(1.23));
                rowVector.add( (i % 2 == 0 ? Boolean.TRUE : Boolean.FALSE));
                rowVector.add(new Date());
                dataVector.add(rowVector);
            return dataVector;
        public static void main(String[] args) {
            Runnable runnable = new Runnable() {
                public void run() {
                    TableRendererDemo tableRendererDemo = new TableRendererDemo();
                    tableRendererDemo.setVisible(true);
            SwingUtilities.invokeLater(runnable);
        class MyTableCellRenderer extends DefaultTableCellRenderer{
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                 super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                if ( isSelected){
                    setFont(getFont().deriveFont(Font.BOLD));
                else{
                    setFont(getFont().deriveFont(Font.PLAIN));
                if ( value instanceof Date){
                    SimpleDateFormat formatter =(SimpleDateFormat) SimpleDateFormat.getDateInstance(DateFormat.MEDIUM);
                    setText(formatter.format((Date)value));
                if(value instanceof Number){
                   setText(((Number)value).toString());
                return this;
    }Hardly a "bunch of instanceof or nested loops. I only used the Date instanceof to allow date format to be specified/ modified. If it was left out the Date column would be "18 Apr 2005" ( DateFormat.MEDIUM, which is default).
    Cheers
    DB

  • Deleting a row from JTable

    I am trying to delete a row from a JTable whenever the button on the last column is pressed. I know to do this, I can use the removeRow(int) method of the tableModel. But the odd thing is when I try to get a handle to the TableModel from the JTable to use that function, i.e. table.getModel().removeRow(int) it doesn't work. But if I explicitly pass in the tableModel into my class it does work. Here's the code below:
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.table.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.UIManager;
    import javax.swing.table.TableCellRenderer;
    import javax.swing.table.TableCellEditor;
    import javax.swing.AbstractCellEditor;
    import javax.swing.table.DefaultTableModel;
    public class tester4 extends JFrame
         protected final int BUTTON_COL = 2;
         private TableCellRenderer defaultRenderer;
         private TableCellEditor defaultEditor;
         private JTable workingTable;
         private String[] transactionCols = {"Qty", "Product", "Cancel"};
         private Object[][] data = {{5, "prod1", "Cancel"},
                   {6, "prod2", "Cancel"},
                   {7, "prod3", "Cancel"}};
        public tester4()
              workingTable = new JTable(tableModel);
              workingTable.setName("Working Table");
              defaultRenderer = workingTable.getDefaultRenderer(JButton.class);
              defaultEditor = workingTable.getDefaultEditor(Object.class);
              StatusTableRenderer testRenderer = new StatusTableRenderer(defaultRenderer, defaultEditor, workingTable, tableModel);
              workingTable.setDefaultRenderer(Object.class, testRenderer);
              workingTable.setDefaultEditor(Object.class, testRenderer);
            JScrollPane scrollPane = new JScrollPane( workingTable );
            getContentPane().add( scrollPane );
         private DefaultTableModel tableModel = new DefaultTableModel(data, transactionCols){
              // Only allow button column to be editable, if there is an actual
              // button in that row          
              public boolean isCellEditable(int row, int col){
                   return (col == BUTTON_COL && data[row][col] != "") ? true : false;
              // Overriden getColumnClass method that will return the object
              // class type of the first instance of the data type otherwise
              // returns the Object.class
              public Class getColumnClass(int column){
                for (int row = 0; row < getRowCount(); row++){
                    Object o = getValueAt(row, column);
                    if (o != null){ return o.getClass(); }
                return Object.class;
        public static void main(String[] args)
            tester4 frame = new tester4();
            frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
            frame.pack();
            frame.setVisible(true);
        public class StatusTableRenderer extends AbstractCellEditor
                                                implements TableCellRenderer,
                                                               TableCellEditor,
                                                               ActionListener{
             private TableCellRenderer defaultRenderer;
             private TableCellEditor defaultEditor;
             private JButton cancelButton;
             private JButton editButton;
             private String text;
             private int buttonColumn;
             private int selectedRow;
             private JTable table;
             private DefaultTableModel tableModel;
             public StatusTableRenderer(TableCellRenderer renderer,
                                           TableCellEditor editor,
                                           JTable table,
                                           DefaultTableModel tableModel){
                  defaultRenderer = renderer;
                  defaultEditor = editor;
                  this.table = table;
                  this.tableModel = tableModel;
                  buttonColumn = table.getColumnCount() - 1;
                cancelButton = new JButton();
                editButton = new JButton();
                editButton.setFocusPainted(true);
                editButton.addActionListener(this);
             public StatusTableRenderer(TableCellRenderer renderer,
                                                TableCellEditor editor,
                                                JTable table,
                                                DefaultTableModel tableModel,
                                                int _buttonColumn){
                  this(renderer, editor, table, tableModel);
                  buttonColumn = _buttonColumn;
             public Component getTableCellRendererComponent(JTable table, Object value,
                       boolean isSelected, boolean hasFocus, int row, int column) {
                  if (column == buttonColumn){
                       if (hasFocus){
                            cancelButton.setForeground(table.getForeground());
                            cancelButton.setBackground(UIManager.getColor("Button.background"));
                       else if (isSelected){
                            cancelButton.setForeground(table.getSelectionForeground());
                            cancelButton.setBackground(table.getSelectionBackground());
                       else{
                            cancelButton.setForeground(table.getForeground());
                            cancelButton.setBackground(UIManager.getColor("Button.background"));
                       cancelButton.setText( (value == null) ? "" : value.toString() );
                       return cancelButton;
                return defaultRenderer.getTableCellRendererComponent(
                            table, value, isSelected, hasFocus, row, column);
             public Component getTableCellEditorComponent(JTable table, Object value,
                       boolean isSelected, int row, int column){
                  if (column == buttonColumn){
                       text = ((value == null) ? "": value.toString());
                       editButton.setText(text);
                       selectedRow = row;
                       return editButton;
                  return defaultEditor.getTableCellEditorComponent(
                            table, value, isSelected, row, column);
            public Object getCellEditorValue()
                return text;
            public void actionPerformed(ActionEvent e)
                fireEditingStopped();
                // This works
                tableModel.removeRow(selectedRow);
               // This does not work
              //  table.getModel().removeRow(selectedRow);
    }Take a look at the actionPerfformed method. One way of doing it works, one doesn't. Just trying to understand why me getting a handle to the tableModel through the table doesn't work.
    Message was edited by:
    deadseasquirrels

    It gives me a run-time error Well then your question should be "why do I get this run-time error" and then you would quote the error. Be more descriptive. "It doesn't work" is not descriptive.
    table.getModel().removeRow(selectedRow);I don't use JDK1.5 either. But if you are saying that the above line compiles cleanly with JDK1.5 (because of the auto-boxing feature, or whatever its called), then I see no reason why the code wouldn't work since it recognizes the class as a DefaultTableModel.
    Presumably you commented out the other line so you don't try to delete the row twice. Otherwise you might be getting a indexing error.

  • I can't get ArrayList to work in my JTable

    I want to be able to dynamically add and remove data (and rows) from my JTable, and so I wanted to just Lists when I implemented it. I've tried 2 ways and they both didn't work. Can someone show me some sample code to do this?
    I tried 2 different methods:
    method 1:
    JTable Data_Table = new  JTable(data_Vector, Collumn_Names_Vector);when I started the applet I got an error saying Applet init error
    But the error could also have happened in 2 other places here. 1, I created 2 Lists instead of Vectors and converted them to Vectors when passing them to JTable using:
    new Vector(data)
    and 2, I may have created my 2 dimensional data List incorrectly. I tried:
    List Parent = new ArrayList();
    List child1 = new ArrayList();
    List child2 = new ArrayList();
    child1.add(data1)
    child2 ...
    Parent.add(child1)
    Parent.add(child2)and I tried:
    List Parent = new ArrayList();
    Object[] temp = { new Integer(); new Integer()};
    Parent.add(temp.asList);But as I said method 1 did not work.
    method 2:
    I tried creating my own TableModel.
    In this way, the applet would start, and I can see my collumn names, but the data is blank and all cells are invisible or nonexistent, I don't know which. How do I initialize the Table values? I'd like to have one row with all 0's when the Applet opens? I'd also like to see a row so I can edit it.
    then I used this code (inside my model):
            public int getColumnCount() {
                return Analog_columnNames.length;
            public int getRowCount() {
                return Analog_data.size();
            public String getColumnName(int col) {
                return Analog_columnNames[col];
            public Object getValueAt(int row, int col) {
                java.util.List aRow = (ArrayList)Analog_data.get(row);
             return  aRow.get(col);
            public void setValueAt(Object value, int row, int col) {
                if (getValueAt(0,col) instanceof Integer                       
                        && !(value instanceof Integer)) {                 
                    try {
                         java.util.List tmp =  (java.util.List) Analog_data.get(row);
                  tmp.set(col, (Object)new Integer(value.toString()));
                  fireTableCellUpdated(row, col);
                    } catch (NumberFormatException e) {
                } else {
                     java.util.List tmp =  (java.util.List) Analog_data.get(row);
              tmp.set(col, (Object)new Integer(value.toString()));
                    fireTableCellUpdated(row, col);
            }Analog_columnNames is a normal array

    this may help You have to remove the button from the columns
    otherwise You need som other classes.
           jTable1.addextrarowtotable(Name, aantal , prijs);CopyCalcTable.java
    import javax.swing.*;
    import java.util.Vector;
    import javax.swing.table.*;
    import java.text.DecimalFormat;
    public class CopyCalcTable extends JTable{
        protected CopyCalcTableModel model;
        CopyCalcTable(){
            super();
            Vector columns= new Vector();
            columns.add("Type");
            columns.add("Omschrijving");
            columns.add("P/S");
            columns.add("Aantal");
            columns.add("Prijs");
            columns.add("Verwijderen");
            model = new CopyCalcTableModel(columns,1);
            setModel(model);
        public void setColumSize(){
            TableColumn column;
            int width = getWidth();
            column = getColumnModel().getColumn(0);
            column.setResizable(false);
            column.setMinWidth((width*2)/14);
            column.setPreferredWidth((width*2)/14);
            column = getColumnModel().getColumn(1);
            column.setResizable(false);
            column.setMinWidth((width*6)/12);
            column.setPreferredWidth((width*2)/14);
            column = getColumnModel().getColumn(2);
            column.setMinWidth((width*1)/14);
            column.setResizable(false);
            column.setPreferredWidth((width*1)/14);
            column = getColumnModel().getColumn(3);
            column.setResizable(false);
            column.setMinWidth((width*1)/14);
            column.setPreferredWidth((width*1)/14);
            column = getColumnModel().getColumn(4);
            column.setResizable(false);
            column.setMinWidth((width*1)/14);
            column.setPreferredWidth((width*1)/14);
            column = getColumnModel().getColumn(5);
            column.setResizable(false);
            column.setMinWidth((width*2)/14);
            column.setPreferredWidth((width*2)/14);
        public void HideColum(){
            TableColumn column;
            int width = getWidth();
            column = getColumnModel().getColumn(0);
            column.setResizable(false);
            column.setMinWidth((width*2)/14);
            column.setPreferredWidth((width*2)/14);
            column = getColumnModel().getColumn(1);
            column.setResizable(false);
            column.setMinWidth((width*6)/12);
            column.setPreferredWidth((width*2)/14);
            column = getColumnModel().getColumn(2);
            column.setMinWidth((width*1)/14);
            column.setResizable(false);
            column.setPreferredWidth((width*1)/14);
            column = getColumnModel().getColumn(3);
            column.setResizable(false);
            column.setMinWidth((width*1)/14);
            column.setPreferredWidth((width*1)/14);
            column = getColumnModel().getColumn(4);
            column.setResizable(false);
            column.setMinWidth((width*1)/14);
            column.setPreferredWidth((width*1)/14);
            column = getColumnModel().getColumn(5);
            column.setResizable(false);
            column.setMinWidth(0);
            column.setPreferredWidth(0);
        public void removefirstrow(){
            model.removeRow(0);
        public void removeTotalrow(){
            model.removeRow(model.getRowCount()-1);
        public void addTotalrow(){
            Vector data;
            String Col_Bediening = "";
            String Col_Uitboek ="";
            String Col_Rectoverso="";
            String Col_Formaat="";
            String Col_Kleur="";
            String Col_Gewicht="";
            Double Col_PS;
            String Col_Aantal;
            Double Col_Prijs;
            data = new Vector();
            Col_Prijs = new Double("0.00");
            double totaal= Col_Prijs.doubleValue();
            // number of extra's
            java.text.NumberFormat nf =  java.text.NumberFormat.getInstance();
            // set whether you want commas (or locale equivalent) inserted
            nf.setGroupingUsed(true );
            // set how many places you want to the right of the decimal.
            nf.setMinimumFractionDigits(2 );
            nf.setMaximumFractionDigits(2 );
            // set how many places you want to the left of the decimal.
            nf.setMinimumIntegerDigits(1 );
            int rows = model.getRowCount();
            for (int i = 0;i < rows; i++){
                Double d = new Double((String) model.getValueAt(i, 4));
                totaal += d.doubleValue();
            Col_Prijs = new Double(totaal*1.00);
            data.add("Totaal : EUR");
            data.add("");
            data.add(new String(""));
            data.add("");
            data.add(nf.format(Col_Prijs));
            //data.add(Col_Prijs.toString());
            javax.swing.JButton button = new javax.swing.JButton("EUR");
            data.add(button);
            model.addRow(data);
            setColumSize();
        public void addkopierowtotable(Integer aantal, double prijs, String omschrijving){
            Vector data;
            CopyCalcTableModel model = (CopyCalcTableModel) getModel();
            Double Col_PS;
            String Col_Aantal;
            Double Col_Prijs;
            //model.addColumn("Verwijderen");
            data = new Vector();
            Col_PS = new Double(prijs);
            Col_Aantal = new String(aantal.toString());
            Col_Prijs = new Double(prijs*aantal.intValue());
            data.add("Kopie�n");
            data.add(omschrijving);
            data.add(Col_PS.toString());
            data.add(Col_Aantal);
            data.add(Col_Prijs.toString());
            javax.swing.JButton button = new JButton("Verwijderen");
            button.addMouseListener(new MyJButtonMouseListener(this));
            data.add(button);
            removeTotalrow();
            model.addRow(data);
            addTotalrow();
        public void addextrarowtotable(String Name, Integer aantal, double prijs){
            Vector data;
            Double Col_PS;
            String Col_Aantal;
            Double Col_Prijs;
            data = new Vector();
            Col_PS = new Double(prijs);
            Col_Aantal = new String(aantal.toString());
            Col_Prijs = new Double(prijs*aantal.intValue());
            data.add("Extra");
            data.add(Name);
            data.add(Col_PS.toString());
            data.add(Col_Aantal);
            data.add(Col_Prijs.toString());
            javax.swing.JButton button = new javax.swing.JButton("Verwijderen");
            button.addMouseListener(new MyJButtonMouseListener(this));
            data.add(button);
            removeTotalrow();
            model.addRow(data);
            addTotalrow();
        public void addspiraalrowtotable(String Name, Integer aantal, double prijs){
            Vector data;
            Double Col_PS;
            String Col_Aantal;
            Double Col_Prijs;
            //model.addColumn("Verwijderen");
            data = new Vector();
            Col_PS = new Double(prijs);;
            Col_Aantal = new String(aantal.toString());
            Col_Prijs = new Double(prijs*aantal.intValue());
            data.add("Spiraal");
            data.add(Name);
            data.add(Col_PS.toString());
            data.add(Col_Aantal);
            data.add(Col_Prijs.toString());
            javax.swing.JButton button = new javax.swing.JButton("Verwijderen");
            button.addMouseListener(new MyJButtonMouseListener(this));
            data.add(button);
            removeTotalrow();
            model.addRow(data);
            addTotalrow();
        public void addklemrugrowtotable(String Name, Integer aantal, double prijs){
            Vector data;
            Double Col_PS;
            String Col_Aantal;
            Double Col_Prijs;
            //model.addColumn("Verwijderen");
            data = new Vector();
            Col_PS = new Double(prijs);
            Col_Aantal = new String(aantal.toString());
            Col_Prijs = new Double(prijs*aantal.intValue());
            data.add("Klemrug");
            data.add(Name);
            data.add(Col_PS.toString());
            data.add(Col_Aantal);
            data.add(Col_Prijs.toString());
            javax.swing.JButton button = new javax.swing.JButton("Verwijderen");
            button.addMouseListener(new MyJButtonMouseListener(this));
            data.add(button);
            removeTotalrow();
            model.addRow(data);
            addTotalrow();
        public void addplastificerenrowtotable(String Name, Integer aantal, double prijs){
            Vector data;
            Double Col_PS;
            String Col_Aantal;
            Double Col_Prijs;
            //model.addColumn("Verwijderen");
            data = new Vector();
            Col_PS = new Double(prijs);
            Col_Aantal = new String(aantal.toString());
            Col_Prijs = new Double(prijs*aantal.intValue());
            data.add("Plastcificeren");
            data.add(Name);
            data.add(Col_PS.toString());
            data.add(Col_Aantal);
            data.add(Col_Prijs.toString());
            javax.swing.JButton button = new javax.swing.JButton("Verwijderen");
            button.addMouseListener(new MyJButtonMouseListener(this));
            data.add(button);
            removeTotalrow();
            model.addRow(data);
            addTotalrow();
        public int getRowCount() {
            if ( model == null ){
                return 0;
            }else {
                return model.getRowCount();
    class CopyCalcTableModel extends AbstractTableModel {
        Vector data;
        Vector columnNames;
        CopyCalcTableModel(Vector head_vec, int rows) {
            columnNames = (Vector) head_vec.clone();
            //    coldata = new Vector(columnNames.size());
            data = new Vector(rows);
        CopyCalcTableModel(Vector head_vec) {
            columnNames = (Vector) head_vec.clone();
            //    coldata = new Vector(columnNames.size());
            data = new Vector();
        CopyCalcTableModel(Vector col_vec, Vector head_vec) {
            Vector coldata;
            columnNames = (Vector) head_vec.clone();
            data = (Vector) col_vec.clone();
        public int getColumnCount() {
            //        System.out.println(columnNames);
            return columnNames.size();
        public int getRowCount() {
            //        System.out.println(data);
            return data.size();
        public void removeRow(int row) {
            //        System.out.println(data);
            data.removeElementAt(row);
            fireTableStructureChanged();
        public String getColumnName(int col) {
            return (String) columnNames.elementAt(col);
        public Object getValueAt(int row, int col) {
            Vector v_row;
            Vector v_col;
            v_row = (Vector) data.elementAt(row);
            return v_row.elementAt(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();
            int rowIndex = 0;
            Object o = getValueAt(rowIndex, c);
            if (o == null) {
                return Object.class;
            } else {
                // System.out.println(o.getClass());
                return o.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.
            /*Vector v_row;
            v_row = (Vector) data.elementAt(row);
            if (col == 10 ) {
                return true;
            } else {
                return false;
            return false;
         * add collumn
        public void addColumn(String label, Object value){
            columnNames.add(label);
            for ( int i=0;data.size()>i;i++){
                Vector row = (Vector) data.elementAt(i);
                row.add(value);
                data.setElementAt(row, i);
            fireTableStructureChanged();
        public void addRow(Vector values){
            data.add(values);
            fireTableStructureChanged();
         * Don't need to implement this method unless your table's
         * data can change.
        public void setValueAt(Object value, int lrow, int lcol) {
    }

  • Rephrasing of JTable question

    Ok, I'm going to rephrase a question I put up pretty poorly about JTables. This is what how I see it. I wanted to create a JTable with a button as the last column, a delete button that will allow you to delete that row. Sounds simple enough - I figured out how to add that last column, and how to create my own TableCellRenderers such that it rendered the last column as a button representation.
    Now my design question relates to the fact that the actual data, doesn't reside on the table...the actual data sits in another data object (a data array), and the table merely renders that information in a specific way. So when I hit the delete button, I really don't have a handle to the data, I need to somehow have an actionListener listening to that button which then sends a message to something else that is holding that data, and informs it to delete that item. The only way I see that is to pass a handle in the constructor of the TableCellRenderer of the actionListener which has a handle to the actual data. Is that how things are done? All this just so that an action performed on the Jtable looks like it's affecting the data itself?
    Correct me if I'm wrong, but it seems like the implementation of this JTable has it such that even though when I addRows to the JTable I am passing an actual object to the JTable. The JTable will just convert the object into textual information, and the handle of that actual object will be lost. In some ways it seems like it would have been better if that JTable kept a handle to the object passed into it from addRow(), so that if I ever said delete this row, I don't have to jump through hoops to find which data object is represented by that particular row and then have something else delete. Instead it would say "Ok, delete this row, which is really this object." Or maybe there is a reason that isn't done.
    Message was edited by:
    deadseasquirrels

    I read the post where you used the removeColumn method of the columnModel to remove the columns that you do not want to display. The way I understand it is that it is implementation of the MVC model, where the data is still there, but the Viewer aspect of the table just isn't displaying the data - and as you showed in your example, that gives more flexibility when you want to share a certain data table, but have it displayed differently.
    But it seems to me that the lines of code:
    columnModel1.removeColumn( columnModel1.getColumn( 4 ) );should really be sitting in either the tableModel class, or the renderer class. At this point that line of code, which defines which columns table1 or table2 should display just sits in the main object class. It seems to me that to be more robust in your tableModel definition, somewhere it should say "any table that uses this table model will have columns x, y, z removed from the columnModel." Instead by having that line of code just sitting outside of either a renderer class or a tableModel class that line could be anywhere, and it doesn't seem too robust. I guess I'm mentioning it, because I would like to put it in either the renderer class or my tableModel class (shown below), but I don't see how I can do that. If I can't do that perhaps you can shed some light as to why my understanding is flawed, and why they designed it in such a way that you can't - right now it seems like the tableModel class would be a great place to put a line of code like that.
    private DefaultTableModel filledTableModel = new DefaultTableModel(data, transactionCols){
    // Only allow button column to be editable, if there is an actual
    // button in that row          
        public boolean isCellEditable(int row, int col){
            return (col == CANCEL_COL && getValueAt(row, col) != "") ? true : false;
        // Overriden getColumnClass method that will return the object
        // class type of the first instance of the data type otherwise
        // returns the Object.class
        public Class getColumnClass(int column){
            for (int row = 0; row < getRowCount(); row++){
                Object o = getValueAt(row, column);
                if (o != null){ return o.getClass();
            return Object.class;
    };

  • JTable: Custom Table Model (pII)

    As was explained in pI, I'm creating a custom table model to overcome a few pitfalls I came across using the DefaultTableModel class, such as aligning cells, and getting certain columns to return only numeric type data. However, I've come upon a few roadblocks myself.
    How do I create each of the following methods:
    insertRow(int ow, int column)
    remove row(int row)
    addRow(Object[] rowData)Assuming that I decide to allow the user to add a column to the table, how would I create the methodaddColumn(Object columnName, Object[] columnData)And also, as I'm creating a custom table model, would I need to replicate DefaultTableModel's methods that inform the listeners that a change has been made to the table?
    Thanks!

    Thanks!
    I just got this response. Anyways, I found another solution that was, interestingly, from one of your threads written in 2005.
    This is what I did:
    // Letting the JTable know what each column stores and should return by
       // overloading the getColumnClass() method
       public Class getColumnClass(int column)
            if(recordsTable.getColumnName(column) == "Ranking")
              return Integer.class;
         /* Why do I keep ketting an IllegalArgumentException here? *
           * It keeps saying it cannot format given object as a Number */            
            else if(recordsTable.getColumnName(column) == "Price (�) ")
              return Float.class;
         else
           return getValueAt(0, column).getClass();         
       }However, another problem has arisen.
    The if method for the int column (Ranking column) works okay, and is even right-aligned. The else if arguments for the Price (�) column however is returning an IllegalArgumentException. This I just cannot figure out.
    Here's the code:package Practice;
      import java.awt.BorderLayout;
      import java.awt.Frame;
      import java.awt.Menu;
      import java.awt.MenuBar;
      import java.awt.MenuItem;
      import java.awt.MenuShortcut;
      import java.awt.event.ActionEvent;
      import java.awt.event.ActionListener;
      import java.awt.event.KeyEvent; // for MenuItem shortcuts
      import java.awt.event.WindowAdapter;
      import java.awt.event.WindowEvent;
      import java.awt.event.WindowListener;
      import javax.swing.JOptionPane;
      import javax.swing.JScrollPane; // JTable added to it, aiding flexibility
      import javax.swing.JTable; // The personally preferred GUI for this purpose
            // Provides a basic implementation of TableModel
      import javax.swing.table.DefaultTableModel;
              // This class uses Vector to store the rows and columns of data, though
              // programmer will be using LinkedLists
      import java.util.LinkedList;
      // User-defined classes
      import Practice.MusicDatabase;
      public class MusicBank extends Frame implements ActionListener
         MusicDatabase mDBase;
         Frame frame;
         String title = "",      // Frame's title
                file = "";           // pathname of the file to be opened
          // Declaring Menu and MenuItem variables
         Menu recordM; // ...
         // recordM
         MenuItem newRecordR_MI, deleteRecordR_MI;
         // Other irrelevant menus and sub items
        DefaultTableModel recordDetails;
        JTable recordsTable;
        LinkedList musicList;
        public MusicBank()
            musicList = new LinkedList();
            frame = new Frame(title);
            frame.setMenuBar(menuSystem());
            // Should user seek to close window externally
            frame.addWindowListener(new WindowAdapter()
                 public void windowClosing(WindowEvent we)
                     frame.dispose();
                     System.exit(0);
         recordDetails = new DefaultTableModel();
         // Creating the relevant columns
         recordDetails.addColumn("Title");
         recordDetails.addColumn("Identity");
         recordDetails.addColumn("Music Company");
         recordDetails.addColumn("Ranking");
         recordDetails.addColumn("Price (�) ");
         // Ensuring the table has at least one visible record (empty)
         recordDetails.addRow(populateRow("", "", "", 0, 0.00f));
         // Creating the table to display the data files (music record details)
         recordsTable = new JTable(recordDetails)
             // Letting the JTable know what each column stores and should return by
             // overloading the getColumnClass() method
            public Class getColumnClass(int column)
               if(recordsTable.getColumnName(column) == "Ranking")
                   return Integer.class;
                /* Why do I keep ketting an IllegalArgumentException here? *
                 * It keeps saying it cannot format given object as a Number */            
                else if(recordsTable.getColumnName(column) == "Price (�) ")
                    return Float.class;
                else
                    return getValueAt(0, column).getClass();         
      // Creating the menus
      public MenuBar menuSystem()
          MenuBar bar = new MenuBar();
          // Record menu and related items
          recordM = new Menu("Record");
          recordM.setShortcut(new MenuShortcut(KeyEvent.VK_R, false));        
          newRecordR_MI = new MenuItem("New record");
          newRecordR_MI.setShortcut(new MenuShortcut(KeyEvent.VK_N, false));
          deleteRecordR_MI = new MenuItem("Delete record");
          deleteRecordR_MI.setShortcut(new MenuShortcut(KeyEvent.VK_D, false));
           recordM.add(newRecordR_MI);
           recordM.addSeparator();
           recordM.add(deleteRecordR_MI);
            // Enabling menus with functionality
           newRecordR_MI.addActionListener(this);
           deleteRecordR_MI.addActionListener(this);
           // Adding menus and items to menu bar
           bar.add(recordM);
           return bar;        
      public void actionPerformed(ActionEvent ae)
          if(ae.getSource() == newRecordR_MI)
             newRecord();
          else if(ae.getSource() == deleteRecordR_MI)
             deleteRecord();       
      // Object that will be used, in conjunction with MusicDatabase's, to 
      // populate the JTable
      // A record in a JTable is equivalent to an element in a LinkedList
      public Object[] populateRow(String title, String name, String comp, int rank, float price)
          // First, update the LinkedList
          mDBase = new MusicDatabase(title, name, comp, rank, price);
          musicList.add(mDBase);
           // Then, update the table
           // As the parameters of Object tableDetails can only take a String or
           // object, rank and price will have to be cast as a String and later
           // parsed to their original form before use.
           String rankPT = ""+rank, pricePT = ""+price;        
           Object rowDetails[] = {title, name, comp, rankPT, pricePT};
           return rowDetails;
      public static void main(String args[])
          MusicBank app = new MusicBank();
           // Using the platform's L&F (if Win32,  Windows L&F; Mac OS, Mac OS L&F,
           // Sun, CDE/Motif L&F)
           // For more on this, refer to the WinHelp Java tutorial by F. Allimont
           try
               UIManager.getSystemLookAndFeelClassName();
           catch(Exception e)
               JOptionPane.showMessageDialog(app,
                    "Failed to create the Windows Look and Feel for this program",
                    "Look and Feel (L&F) error",
                    JOptionPane.ERROR_MESSAGE);
           app.frame.setSize(500, 500);
           app.frame.setVisible(true);
            // Placing frame in the centre of the screen on-loading
           app.frame.setLocationRelativeTo(null);
      // action methods per menu items
      // Also, why do I keep getting an ArrayIndexOutOfBoundsException
      // here? I do know what this exception is, and how it works, but just cannot
      // understand what is causing it
      public void newRecord()
          // Before adding a new record, check if previous record has complete
          // entries. If not, either display a message (JOptionPane) or disallow
          // request (simply do nothing)        
          // Proceed based on assesment
          if(queryState() == true)
              // Inform user that all entries need to be filled in before a new
              // record can be created
              JOptionPane.showMessageDialog(this, // current frame
                       "There are incomplete cells in the table."+
                       "\nPlease fill these in before proceeding",       // Message to user
                       "Incomplete entries",                                // Title
                       JOptionPane.ERROR_MESSAGE);                           // Relevant icon
          else
               // To ensure that both the linked list & the table are simultaneously
               // updated, JOptionPane's input dialogs are used to temporarily store
               // the data which is then inputted into both (linked list and JTable)
              String titleN, identityN, companyN; int rankN; float priceN;
              titleN = JOptionPane.showInputDialog(this, "Enter song title");
              identityN = JOptionPane.showInputDialog(this,                                      "Enter name of singer/band");
             companyN = JOptionPane.showInputDialog(this,                                 "Enter signed/unsigned company");
             rankN = Integer.parseInt( JOptionPane.showInputDialog(this,
                             "Enter rank (a number)") );
            System.out.println("\n JTable rows = "+recordDetails.getRowCount());
             // Ensuring that the chosen rank is not already entered
             /* Problem lies here */
             for(int row = 1; row <= recordDetails.getRowCount(); ++row)
                 if((recordDetails.getValueAt(row, 4)).equals(""+rankN))
                     rankN = Integer.parseInt( JOptionPane.showInputDialog(this,
                             "That number's already chosen.\nPlease enter a rank ") );
             priceN = Float.parseFloat( JOptionPane.showInputDialog(this,                                 "Finally, enter price �") );
             mDBase = new MusicDatabase(titleN, identityN, companyN, rankN, priceN);
             musicList.add(mDBase);
             recordDetails.addRow(populateRow(titleN, identityN, companyN, rankN,
         priceN));
             System.out.println("JTable rows after creation = "+
                   recordDetails.getRowCount());
         // Enabling the delete record menu item (as necessary)
         if((recordsTable.getRowCount()) > 0)
              deleteRecordR_MI.setEnabled(true);
      } // newRecord()
      public void deleteRecord()
         int selectedRow = recordsTable.getSelectedRow();
         recordDetails.removeRow(selectedRow);
          // Removing the element from the LinkedList's corresponding index
          musicList.remove(selectedRow);
          System.out.println("Existing rows = "+recordsTable.getRowCount());
           // If there are no more rows, disallow user from trying to delete rows
           if(selectedRow <= 0)
              deleteRecordR_MI.setEnabled(false);
      } // deleteRecord()
      // Method to query if all cells have changed their states (empty or not)
      public boolean queryState()
          // Obtaining number of rows
          int rows = recordDetails.getRowCount();
          int columns = recordDetails.getColumnCount();
          boolean isEmpty = false; // cell
          System.out.println("Rows = "+rows);
          System.out.println("Columns = "+columns);
          try{
              // Assessing all cells for complete entries
              // This approach is flexible, rather than hardcoding the rows available,
              // making it more reusable (assuming it will always be 5 columns)
              for (int rowIndex = 0; rowIndex<=rows; ++rowIndex)
                  if((recordDetails.getValueAt(rowIndex, 1)).equals(""))
                 isEmpty = true;
                  else if((recordDetails.getValueAt(rowIndex, 2)).equals(""))
               isEmpty = true;
                  else if((recordDetails.getValueAt(rowIndex, 3)).equals(""))
               isEmpty = true;                
                  else if((recordDetails.getValueAt(rowIndex, 4)).equals("0"))
               isEmpty = true;
                  else if((recordDetails.getValueAt(rowIndex, 5)).equals("0.00"))
               isEmpty = true;
          catch(Exception e)
             System.out.println(e.getMessage());
          return isEmpty;
      Now here is the code for the MusicDatabase class
    package Practice;
    class MusicDatabase
        private String songTitle, identity, musicCompany;
        private int rank;
        private float priceF;
        // Defining the constructor
        public MusicDatabase(String title, String name, String company,                                int rankingInt, float price)
           songTitle = title;
           identity = name;
           musicCompany = company;
           rank = rankingInt;
           priceF = price;
        } // constructor
       // Other methods
    } // class MusicDatabaseSorry, but am not sure if these codes are executable, as where I am (a general library), JVM is not on the machine I am using. (Remember, i don't have ready acess to the Internet, so I could not use my machine, nor the facilities that had the JVM - unavailable to me at the time).
    Thanks!
    Reformer...
    PS I do hope the code pasted was not too much. Kind regards....

  • JTable cell add Image

    hi,
    pls let me know how to add image in JTable particular cell. I am trying to add image in a particular column each row at runtime ( developing database application), those images are in remote location and also directory files. I am trying to use below code. but it is now showing image instead it is giving message like "sun.awt.image.ToolkitImage@1b1aa65"
    ============my code is ===========
    Image image = java.awt.Toolkit.getDefaultToolki().getDefaultToolkit().getImage(file);
    dataValues[rowNum][6] =image;
    ================================
    awaiting solution.

    I am trying to add image in a particular column each row Override the getColumnClass() method of the JTable to return the class of data in each column and it will choose the appropiate renderer. I've posted examples. I think I called the class "Table Icon" (one word). Search the forum and you should find it.

  • Inserting imageicon in jtable

    Hi,
    I want to insert imageicon in Jtable using AbstractTableModel.
    Please help me out from this.

    Ravi_Gupta wrote:
    Use custon Cell RendererThere's no need to use a custom cell renderer.
    Just override getColumnClass method of your model to return ImageIcon.class for the appropriate column, and add the imageicon to the model.

  • JTable-TableModel

    class MyTableModel extends AbstractTableModel
    final String columnNames[] = {
    "Name", "Value"
    String tableData[][];
    public MyTableModel()
    tableData = new String[1][2];
    tableData[0][0] = new String("");
    tableData[0][1] = new String("");
    public Class getColumnClass(int i)
    return getValueAt(0, i).getClass();
    public int getColumnCount()
    return columnNames.length;
    public String getColumnName(int i)
    return columnNames;
    public int getRowCount()
    return tableData.length;
    public Object getValueAt(int i, int j)
    return tableData[i][j];
    public void setValueAt(String value, int row, int col) {
    tableData[row][col] = value;
    fireTableCellUpdated(row, col);
    public boolean isCellEditable(int i, int j)
    return true;
    myModel=new MyTableModel();
    table = new JTable(1,2);
    table.setModel(myModel);
    JScrollPane tablepane = new JScrollPane(table);
    container.add(tablepane);
    I want all cells in my table to be editable, and I think I've done everything that is necessary, but somehow it doesn't work. Initially all cells are empty. After I type on a cell and press enter or tab to change to other cell, the cell becomes empty again, the word I type disappears. What could be the problem & how to solve it? Thx.

    This looks incorrect.
    public Object getValueAt(int i, int j)
    return tableData[j];
    The object you are returning from getValueAt method is an Array.
    Try this:
    public Object getValueAt(int i, int j)
    return tableData[ i ] [ j ];
    Also (this is probably the one that's causing the problems) the
    setValueAt() method is not overriding the method you think it
    is. The method signature is incorrect. Change this:
    public void setValueAt(String value, int row, int col)
    tableData[row][col] = value;
    fireTableCellUpdated(row, col);
    to this:
    public void setValueAt(Object value, int row, int col)
    if ( value !=null )
    tableData[row][col] = value.toString();
    I don't think you need the fireTableCellUpdated() method call.
    And one more thing (this is just a performance improvement).
    You can remove the getColumnClass() method. The implementation
    on AbstractTableModel will do the same thing, and it will
    do it faster.
    later
    jc

  • Problem in populating jtable data from database

    hi,
    i am using JTable to retrieve data from database and show it in table. JTable
    is working fine with static data. but while retrieving from databse its giving a NullPointerException at getColumnClass() method. Below is complete source code. plzz help.
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import java.sql.*;
    import javax.swing.table.*;
    /*jdbc connection class*/
    class connect
    Connection con;
    Statement stat;
    public connect()throws Exception
    Class.forName("org.postgresql.Driver");
    con=DriverManager.getConnection("jdbc:postgresql://localhost/dl","dl","dl");
    stat=con.createStatement();
    public ResultSet rsf(String rsstr)throws Exception
    ResultSet rs=stat.executeQuery(rsstr);
    return rs;
    public void upf(String upstr)throws Exception
    stat.executeUpdate(upstr);
    class MyTableModel extends AbstractTableModel
    private String[] columnNames = {"name","id","dep","cat","rem","chkout"};
    Object[][] data;
    public MyTableModel()
    try{
    connect conn=new connect();
    ResultSet rs3=conn.rsf("select * from usertab");
    ResultSetMetaData rsmd=rs3.getMetaData();
    int col=rsmd.getColumnCount();
    int cou=0;while(rs3.next()){cou++;}
    data=new Object[cou][col];
    System.out.println(cou+" "+col);
    ResultSet rs2=conn.rsf("select * from usertab");
    int i=0;int j=0;
    for(i=0;i<cou;i++)
    rs2.next();
    for(j=0;j<col;j++)
    data[i][j]=rs2.getString(getColumnName(j));
    System.out.println(data[0][2]);
    }catch(Exception e){System.out.println("DFD "+e);}
            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];
           public Class getColumnClass(int c) {
              return getValueAt(0, c).getClass();
            public boolean isCellEditable(int row, int col) {
                if (col < 2) {
                    return false;
                } else {
                    return true;
            public void setValueAt(Object value, int row, int col) {
                data[row][col] = value;
                fireTableCellUpdated(row, col);
    class MyFrame extends JFrame
    public MyFrame()
         setSize(600,500);
         JPanel p1=new JPanel();
         p1.setBackground(new Color(198,232,189));
         JTable table = new JTable(new MyTableModel());
         table.setPreferredScrollableViewportSize(new Dimension(500,200));
         table.setBackground(new Color(198,232,189));
         JScrollPane scrollPane = new JScrollPane(table);
         scrollPane.setBackground(new Color(198,232,189));
         p1.add(scrollPane);
         getContentPane().add(p1);
    /*Main Class*/
    class test2
         public static void main(String args[])
         MyFrame fr =new MyFrame();
         fr.setVisible(true);
    }thanx

    hi nickelb,
    i had returned Object.class in the getColumnClass() method. But then i
    got NullPointerException at getRowCount() method. i could understand that the
    main problem is in data[][] object. In all the methods its returning null values as it is so declared outside the construtor. But if i declare the object inside the constructor, then the methods could not recognize the object. it seems i cant do the either ways. hope u understood the problem.
    thanx

  • Problem with a JTable Update

    I have a JDialog with a JTable and JScrollPane.
    JTable uses TableModel.java
    Now, when I am tryint to scroll to the right, the name of the columns, that was out of window won't redraw and the text is merged. The rows are ok. Only the titles.
    How to get the column names updated?
    Here is the code:
    TableTest.java (JDialog)
    import java.awt.BorderLayout;
    import javax.swing.JPanel;
    import javax.swing.JDialog;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    public class TableTest extends JDialog {
         private JPanel jContentPane = null;
         private JScrollPane jScrollPane = null;
         private JTable jTable = null;
         private TableModel tableModel = null; 
          * This is the default constructor
         public TableTest() {
              super();
              initialize();
          * This method initializes this
          * @return void
         private void initialize() {
              this.setSize(300, 200);
              this.setContentPane(getJContentPane());
          * This method initializes jContentPane
          * @return javax.swing.JPanel
         private JPanel getJContentPane() {
              if (jContentPane == null) {
                   jContentPane = new JPanel();
                   jContentPane.setLayout(new BorderLayout());
                   jContentPane.add(getJScrollPane(), java.awt.BorderLayout.NORTH);
              return jContentPane;
          * This method initializes jScrollPane     
          * @return javax.swing.JScrollPane     
         private JScrollPane getJScrollPane() {
              if (jScrollPane == null) {
                   jScrollPane = new JScrollPane();
                   jScrollPane.setPreferredSize(new java.awt.Dimension(453,100));
                   jScrollPane.setViewportView(getJTable());
              return jScrollPane;
          * This method initializes jTable     
          * @return javax.swing.JTable     
         private JTable getJTable() {
              if (jTable == null) {
                   jTable = new JTable();
                   jTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
                   jTable.setModel(getTableModel());
                   jTable.setPreferredSize(new java.awt.Dimension(500,80));
              return jTable;
          * This method initializes tableModel     
          * @return TableModel     
         private TableModel getTableModel() {
              if (tableModel == null) {
                   tableModel = new TableModel();
              return tableModel;
    TableModel.javaimport javax.swing.table.AbstractTableModel;
    public class TableModel extends AbstractTableModel {
         private String[] columnNames = {"First Name",
                   "Last Name",
                   "Sport",
                   "# of Years",
         "Vegetarian"};
         private Object[][] data = {
                   {"Mary", "Campione",
                        "Snowboarding", new Integer(5), new Boolean(false)},
                        {"Alison", "Huml",
                             "Rowing", new Integer(3), new Boolean(true)},
                             {"Kathy", "Walrath",
                                  "Knitting", new Integer(2), new Boolean(false)},
                                  {"Sharon", "Zakhour",
                                       "Speed reading", new Integer(20), new Boolean(true)},
                                       {"Philip", "Milne",
                                            "Pool", new Integer(10), new Boolean(false)}
         public final Object[] longValues = {"Sharon", "Campione",
                   "None of the above",
                   new Integer(20), Boolean.TRUE};
         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();
         public void setValueAt(Object value, int row, int col) {
              data[row][col] = value;
              fireTableCellUpdated(row, col);

    Heres your code (reworked a little to show what i mean)
    does this solve your issue?
    import java.awt.BorderLayout;
    import javax.swing.JPanel;
    import javax.swing.JDialog;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.table.AbstractTableModel;
    public class TableTest extends javax.swing.JFrame {
         private JPanel jContentPane = null;
         private JScrollPane jScrollPane = null;
         private JTable jTable = null;
         private TableModel tableModel = null; 
          * This is the default constructor
         public TableTest() {
              super();
              initialize();
          * This method initializes this
          * @return void
         private void initialize() {
              this.setSize(300, 200);
              this.setContentPane(getJContentPane());
          * This method initializes jContentPane
          * @return javax.swing.JPanel
         private JPanel getJContentPane() {
              if (jContentPane == null) {
                   jContentPane = new JPanel();
                   jContentPane.setLayout(new BorderLayout());
                   jContentPane.add(getJScrollPane(), java.awt.BorderLayout.NORTH);
              return jContentPane;
          * This method initializes jScrollPane     
          * @return javax.swing.JScrollPane     
         private JScrollPane getJScrollPane() {
              if (jScrollPane == null) {
                   jScrollPane = new JScrollPane();
                   jScrollPane.setPreferredSize(new java.awt.Dimension(453,100));
                   jScrollPane.setViewportView(getJTable());
              return jScrollPane;
          * This method initializes jTable     
          * @return javax.swing.JTable     
         private JTable getJTable() {
              if (jTable == null) {
                   jTable = new JTable();
                   jTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
                   jTable.setModel(getTableModel());
                   //jTable.setPreferredSize(new java.awt.Dimension(500,80)); //this line is causing your error, but i dont know why
              return jTable;
          * This method initializes tableModel     
          * @return TableModel     
         private TableModel getTableModel() {
              if (tableModel == null) {
                   tableModel = new TableModel();
              return tableModel;
            public static void main (String[] main)
                new TableTest().setVisible(true);
    class TableModel extends AbstractTableModel {
         private String[] columnNames = {"First Name",
                   "Last Name",
                   "Sport",
                   "# of Years",
         "Vegetarian"};
         private Object[][] data = {
                   {"Mary", "Campione",
                        "Snowboarding", new Integer(5), new Boolean(false)},
                        {"Alison", "Huml",
                             "Rowing", new Integer(3), new Boolean(true)},
                             {"Kathy", "Walrath",
                                  "Knitting", new Integer(2), new Boolean(false)},
                                  {"Sharon", "Zakhour",
                                       "Speed reading", new Integer(20), new Boolean(true)},
                                       {"Philip", "Milne",
                                            "Pool", new Integer(10), new Boolean(false)}
         public final Object[] longValues = {"Sharon", "Campione",
                   "None of the above",
                   new Integer(20), Boolean.TRUE};
         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();
         public void setValueAt(Object value, int row, int col) {
              data[row][col] = value;
              fireTableCellUpdated(row, col);
    }

  • Sort jTable rows by column as Integer value

    Hi all,
    I have problem with sort jTable rows. I have some columns and in first are integer data. jTable sort that as String value..1,10,11,12....2,21, ...
    How can I do that?
    Thanks

    In the future, please post Swing questions to the Swing forum: http://forum.java.sun.com/forum.jspa?forumID=57
    What does the TableModel's getColumnClass method return for that column?

Maybe you are looking for