JTableHeader problem

I have a custom JTableHeader and a MouseListener on the header because when i click the header i show an arrow icon that follow the order of the data.
The header works fine since i resize the column:when i resize the icon appear on all the column but i want i t only on the cliccked column.
public Component getTableCellRendererComponent(JTable table, Object value,boolean isSelected, boolean hasFocus, int row, int column) {
            super.getTableCellRendererComponent( table,  value, isSelected,  hasFocus,  row, column);
             this.setBorder(BorderFactory.createEtchedBorder());
            this.setOpaque(false);
          //  System.out.println("COLUMN " + column + " COLSELECTED "  + colSelected);
            if(!usingResizeCursor())
              if(colSelected == column)
                   if (getCurrentOrder() == ORD_CRESC) {
                          setText(table.getColumnName(column));
                          Icon icon = new ImageIcon(getClass().getResource(URLROWUP));
                          setIcon(icon);
                          this.setIconTextGap(10);
                          revalidate();
                   else
                         setText(table.getColumnName(column));
                         Icon icon = new ImageIcon(getClass().getResource(URLROWDOWN));
                         setIcon(icon);
                         this.revalidate();
                else
                  Icon icon = new ImageIcon(getClass().getResource  (URLROWEMPTY));
                  setIcon(icon);
                  setText(table.getColumnName(column));
                  this.revalidate();             
             return this;
        }

This section from the Swing tutorial on [url http://java.sun.com/docs/books/tutorial/uiswing/components/table.html#sorting]How to Use Tables has a working example of a TableHeader with sort icons.

Similar Messages

  • Problem with JTableHeader Render

    Hello,
    I am using JTableHeader renderer as below:
    TableHeaderRender headerRender;
    fixedModel.addColumn("");
                   TableColumnModel colModel = Table.getColumnModel();
                   for(int i=0; i<colModel.getColumnCount(); i++ )
                        colModel.getColumn(i).setHeaderRenderer(headerRender);
    And the renderer is as below:
    class FixedTableHeaderRender extends DefaultTableCellRenderer
              JLabel label = null;
              String[] selectList= {"Item1","item 2", Item 3", "Item 4"};
              JComboBox ColStatBox= new JComboBox(selectList);
    public FixedTableHeaderRender()
    super();
    label = new JLabel();
    label.setOpaque(true);
    label.setBorder(new LineBorder(Color.black));
    label.setHorizontalAlignment(SwingConstants.CENTER);
    label.setVerticalAlignment(SwingConstants.CENTER);
    ColStatBox.setSelectedIndex(0);
    ColStatBox.setEnabled(true);
    ColStatBox.setAutoscrolls(true);
    ColStatBox.addActionListener(new ActionHandler(){
    public Component getTableCellRendererComponent(JTable table, Object value,
              boolean isSelected,boolean hasFocus, int row,int column)
         Component comp= null;
         if(column==0)
              comp=ColStatBox;
         else
              label.setText("100");
              comp=label;
         return comp;
    Now in this for First column header the JComboBox is displayed and for rest of the column the label is displayed.
    But in this, the JComboBox is not working i.e. I am not able the browse through the list. If I want to select any item (Item 4), its not allowing me to select.
    How to make it enable and function normally?
    Do reply.
    Thanks and regards,
    Sheetal

    I've amended your code as shown. Some points:
    1) Not sure what all the scroll bar stuff is for, I've removed it.
    2) The method DefaultTableModel.addColumn is too crude. If you look at the JDK source it calls fireTableStructureChanged(). This has the effect of recreating the column model, which in turn resets all the widths. It will also clear out any renderers/editors you had set up within the TableColumn instances inside the TableColumnModel (if any). Those setup by column class would be OK (I think).
    I didn't look into the remainder of your problem, hopefully you are OK now...
    import java.awt.BorderLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JScrollBar;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.table.*;
    import javax.swing.table.DefaultTableModel;
    public class MyJTable extends JFrame
    DefaultTableModel model;
    JButton addBtn;
    JTable table;
    JScrollBar scrollBar;
    JScrollPane scrollPane;
         public MyJTable()
              getContentPane().setLayout(new BorderLayout());
              Object[] header= {"1", "2"};
              model= new DefaultTableModel();
              model.setDataVector(null,header);
               table = new JTable(model);
               table.getTableHeader().setReorderingAllowed(false);
               table.getTableHeader().setResizingAllowed(true);
               table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
               scrollBar=new JScrollBar();
              scrollBar.setOrientation(1);
              scrollBar.setBlockIncrement(1);
              scrollBar.setMinimum(0);
              scrollBar.setMaximum(50);
              scrollBar.setUnitIncrement(1);
              scrollBar.setVisibleAmount(1);
              table.add(scrollBar);
              scrollPane=new JScrollPane(table);
              scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
               addBtn=new JButton("Add Column");
               addBtn.addActionListener(new ActionHandler());
               getContentPane().add(scrollPane, BorderLayout.CENTER);
               getContentPane().add(addBtn, BorderLayout.SOUTH);
         class ActionHandler implements ActionListener
              //@Override
              public void actionPerformed(ActionEvent ae)
                   // TODO Auto-generated method stub
                   if(ae.getSource()==addBtn)
                        //model=(DefaultTableModel)table.getModel();
                        //model.addColumn("A");
                        //model.fireTableStructureChanged();
                        TableColumnModel tcm = table.getColumnModel();
                        TableColumn newCol = new TableColumn();
                        newCol.setHeaderValue("A");
                        tcm.addColumn(newCol);
          * @param args
         public static void main(String[] args)
              MyJTable frame = new MyJTable();
                  frame.addWindowListener(new WindowAdapter() {
                    public void windowClosing(WindowEvent e) {
                      System.exit(0);
                  frame.setSize( 300, 400 );
                  frame.setVisible(true);
    }

  • JTableHeader and LookAndFeel problem

    need help in solving the following problems
    1. i have a JTable that i want to display information in the table header from a JTextField am using to input data.please how do i handle it.
    inputfield = new JTextField(20);
    tablemodel = new DefaultTable();
    tablemodel.addColumn("Number");
    tablemodel.addColumn("Food Item");
    tablemodel.addColumn("Quantity");
    tablemodel.addColumn("Price");
    tablemodel.addColumn("Description");
    table = new JTable(tablemodel);
    TableColumn column = null;
    for (int i = 0; i < 5; i++) {
    column = table.getColumnModel().getColumn(i);
    if(i==0){
    column.setPreferredWidth(65);
    } else if(i==1){
    column.setPreferredWidth(100);
    } else if(i==2){
    column.setPreferredWidth(65);
    } else if(i==3){
    column.setPreferredWidth(65);
    } else{
    column.setPreferredWidth(100);
    2.need help in the Look and Feel of my JFrame have the look of a glass.please somebody tell to do this.
    thanks in advance.

    You are having five columns,
    which header should get a input from JTextfield,
    1. all the Five? or else some specific header?
    2. Is the table having the header when intially its load?
    3. when it should happen, like the user enter the heading in the text field and pressing enter button?
    4. When the user enter the 6th text and press enter key, what supposed to be happen?
    So pls describe what you want properly.
    For your second question u can use GlassPane

  • JTableHeader repaint problem.

    I am trying to add some filtering funtionality to my swing application that uses a JTable by opening a JDialog on top of the JTable.
    What I want to do is to filter the JTable's datamodel, and call repaint() on the jtable and JPanel, and do jframe.pack();
    //update tableModel
    //repaint() jtable;
    //repaint() jpanel;
    //jInterFrame.pack();
    but the momment i close the JDialog, the table header grid is vanishing.
    What can be the problem?

    post a sample code

  • 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

  • 1.2 / 1.3 JTable getHeaderRenderer() problem

    Hi,
    I've got a Swing Applet which is currently running on 1.2 which I'd now like to upgrade to 1.3 in order to take advantage of the new functionality.
    I've done some preliminary testing, and am encountering problems with the upgrades made to the JTable (see http://java.sun.com/j2se/1.3/docs/guide/swing/JTableChanges.html) in 1.3
    My code uses column.getHeaderRenderer().getTableCellRendererComponent() to get the Header renderer. Unfortunately, the 1.3 implementation has changed so that this now returns null. 1.3 uses table.getTableHeader().getDefaultRenderer() instead.... but this bit of the API doesn't exist in 1.2
    So, please can someone suggest how I might get the code to work for both 1.2 & 1.3 simultaneously?
    Cheers
    RT

    One of the quickest ways around would be to set the header renderer for each column:
    TableCellRenderer headerRenderer = new DefaultTableCellRenderer();
    for(...)
      column.setHeaderRenderer(headerRenderer);
    }That way the column's own renderer would always be used in preference to the default one for a JTableHeader. You might need to play around with the look of it, though.
    The more complete solution would be to use reflection to determine whether the "1.3" method exists and call it if is does. It would be a nasty way to do things, though, and be a maintenance issue in the future.
    try
      Class headerClass = tableHeader.getClass();
      Method method = headerClass.getDeclaredMethod("getDefaultRenderer", new Class[] {});
      headerRenderer = method.invoke(tableHeader, new Object[] {});
    catch(NoSuchMethodException e)
      headerRenderer = column.getHeaderRenderer();
    }Hope this helps.

  • 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();
    }

  • Unable to set background colour JTableHeader in Java 1.6_18

    We're moving our application from Java 1.4.2 to 1.6_18, so far without major problems but there's some small issues with the GUI. Originally we'd change the background colour of the JTableHeader, but in 1.6_18 that doesn't seem to work. Instead of colouring the complete header it just seems to draw an outline. It kind of gives the impression that there's something on top of the table header which hides the coloured background.
    The code below shows what I'm trying to do, and gives different results when compiled in Java 1.4.2 and Java 1.6_18. It makes no difference whether I'm using the UIManager or setting the background directly on the JTableHeader.
    The application still works fine of course, but it bugs me that I can't work out what the problem is, so any suggestions would be greatly appreciated! I've already had a look at bug [6521138|http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6521138], but it makes no difference whether a new JTableHeader is set, so I think it's different. Also, the workaround for bug [4776303|http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4776303] has no effect so I think that doesn't apply either.
        public static void main(String[] args) {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                // Doesn't give the expected result in Java 1.6_18, the background remains white-ish with only a coloured border.
                // UIManager.put("TableHeader.background", Color.GREEN);
                // UIManager.put("TableHeader.foreground", Color.BLUE);
            } catch (Exception exception) {
                exception.printStackTrace();
            final JFrame frame = new JFrame();
            frame.getContentPane().add(createPanel());
            frame.getContentPane().setLayout(new FlowLayout());
            frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            frame.pack();
            frame.setVisible(true);
        private static JPanel createPanel() {
            final JPanel panel = new JPanel();
            final DefaultTableModel model = new DefaultTableModel(3, 2);
            final JTable table = new JTable(model);
            // Tableheaders.
            final TableColumnModel columnModel = table.getColumnModel();
            columnModel.getColumn(0).setHeaderValue("First");
            columnModel.getColumn(1).setHeaderValue("Second");
            // Doesn't give the expected result in Java 1.6_18, the background remains white-ish with only a coloured border.
            table.getTableHeader().setBackground(Color.GREEN);
            table.getTableHeader().setForeground(Color.BLUE);
            final JScrollPane scrollPane = new JScrollPane(table);
            panel.add(scrollPane);
            scrollPane.setSize(400, 100);
            panel.setSize(500, 500);
            panel.setPreferredSize(panel.getSize());
            return panel;

    Hillster wrote:
    Ah yes, when I change that setting the background of the table header indeed gets the expected background colour. Unfortunately it also makes my desktop look hopelessly outdated :-( And I can't really expect my end-customers to change their settings just to run my little application. Still, I suppose this proves that the problem lies in the L&F?Seconded Jeanette's sentiment, this is definitely a feature, not a problem. You want system LaF, you get System LaF, with all the bells and whistles. If you're sure you don't want the system embellishments, you could consider using my [_default table header cell renderer_|http://tips4java.wordpress.com/2009/02/27/default-table-header-cell-renderer/].
    db

  • Problems with a JTable

    Hello folks,
    i got two problems with a JTable.
    1. how do I change the size of a table header???
    2. I know that it is possible to set different column-sizes. The problem in my table is that I don't know how long some cells are. In this case, I want to to get the biggest cell of one column and set its size as the default size of that specific column.
    Is that possilbe?
    Hopefully you can help me out,
    thank you

    A JTableHeader is just another Component, so you ought to be able to set its size like you would
    any other component; however, since its function is to act as a header for a table, it might constrain
    itself to fit the table.
    In order to size the column to fit the largest cell, for each row, go through each column and get the
    renderer component for that column (which configures the component for rendering) and get the width
    of that component. If that's bigger than the column's current width, set its width and preferred width.
    You'll also want to check the renderer component width for the header to make sure the header doesn't
    get truncated if the column doesn't have a cell whose value is longer than the header.
    : jay

  • Multiline cell table problem

    hi all
    i found in this forum a class that implements TableCellRenderer and that should allow my table to have multiline cells. i need it because if the content of my cell (retrieved via jdbc from a db) exceeds the cell width is truncated and a "..." appears.
    so i searched, i founded and i tried some example but with no results. i don't know where is the mistake, also because the code should work.
    i'll post the class code and my table's code and i hope someone could help me!!!
    import javax.swing.*;
    import javax.swing.table.*;
    import javax.swing.border.*;
    import java.awt.*;
    * @version 1.0 11/09/98
    public class MultiLineCellRenderer extends JTextArea implements TableCellRenderer {
      public MultiLineCellRenderer() {
        setLineWrap(true);
        setWrapStyleWord(true);
        setOpaque(true);
      public Component getTableCellRendererComponent(JTable table, Object value,
                   boolean isSelected, boolean hasFocus, int row, int column) {
        if (isSelected) {
          setForeground(table.getSelectionForeground());
          setBackground(table.getSelectionBackground());
        } else {
          setForeground(table.getForeground());
          setBackground(table.getBackground());
        setFont(table.getFont());
        if (hasFocus) {
          setBorder( UIManager.getBorder("Table.focusCellHighlightBorder") );
          if (table.isCellEditable(row, column)) {
            setForeground( UIManager.getColor("Table.focusCellForeground") );
            setBackground( UIManager.getColor("Table.focusCellBackground") );
        } else {
          setBorder(new EmptyBorder(1, 2, 1, 2));
        setText((value == null) ? "" : value.toString());
        return this;
    }i set the new tablecellrenderer in this way:
    table.setDefaultRenderer(String.class, new MultiLineCellRenderer() );
            Object[] columns=new Object[]{"Data","Ora","Nome","Referente","Indirizzo","Citt�","Telefono","Motivazione","App. con"};
            JTableHeader k=new JTableHeader();
            table.setTableHeader(k);
            table.setModel(new javax.swing.table.DefaultTableModel (o,columns)
                    Class[] types = new Class [] {
                        java.lang.Object.class, java.lang.Object.class, java.lang.Object.class, java.lang.Object.class
             anyone could help me?
    thanx a lot

    thanx to all my friends, but i still have my problem..
    viravan, i'm using the same MultiLineCellRenderer class as the example, the only thing different is my class from where i set the MultiLineCellRenderer the default Renderer for my table
    this is the code: (i post it because i didn't found any significant difference between the example class and the one of mine...) i suspect there is some problem in the table setting... but i don't know where...
    import java.lang.Thread;
    import java.sql.*;
    import java.util.Vector;
    import java.text.*;
    import javax.swing.table.*;
    public class AppTablePainter implements Runnable
        Thread t;
        DateFormat date;
        public AppTablePainter()
            t=new Thread(this);
            t.start();
        public void run()
            paint();
        void paint()
            Statement s=null;
            Vector clienti=new Vector();
            Vector appIl=new Vector();
            Vector hours=new Vector();
            Vector referenti=new Vector();
            Vector indirizzi=new Vector();
            Vector telefoni=new Vector();
            Vector citta=new Vector();
            Vector motivazioni=new Vector();
            Vector appCon=new Vector();
            Vector commerciali=new Vector();
            Vector commenti=new Vector();
            Vector ids=new Vector();       
            Vector tempCommerciali= new Vector();
            date=Jtm.date;
            String action="SELECT * FROM CONTATTI WHERE COMMERCIALE='"+Appuntamenti.cCommerciale.getSelectedItem()+"' AND APPUNTAMENTO_IL IS NOT NULL";
            //System.out.println(action);
            try
                s=Jtm.tmc.createStatement();
                ResultSet rs=s.executeQuery(action);           
                java.util.Date appDate;
                DateFormat appHour=new SimpleDateFormat("HH:mm");
                appHour.setLenient(false);
                String get=null;
                Appuntamenti.sp.set("Recupero appuntamenti in corso...");
                int maximum=0;
                while(rs.next())
                     try
                        maximum++;
                        get=rs.getString("appuntamento_il");                     
                        appDate=date.parse(get);               
                        String stringDate=date.format(appDate);                                       
                        if(!appDate.before(Jtm.now))
                            String id=rs.getString("id");
                            ids.add(id);  
                            appIl.add(get);                       
                            try
                                hours.add(appHour.format(appHour.parse(rs.getString("ore"))));                       
                            catch(ParseException p)
                                hours.add("23:00");
                            catch (NullPointerException np)
                                hours.add("23:01");
                    catch(SQLException sq)
                        //JOptionPane.showMessageDialog(this, sq.getMessage(), "",JOptionPane.ERROR_MESSAGE);
                        sq.printStackTrace();
                    catch(NullPointerException n){}
                    catch(ParseException p)  //se la data non � parseable � perch� � nulla visto che c'� un controllo all'inserimento
                        //System.out.println("parseException "+get);
                        //JOptionPane.showMessageDialog(this, p.getMessage(), "",JOptionPane.ERROR_MESSAGE);
                        //p.printStackTrace();
                Appuntamenti.sp.progBar.setMaximum(maximum);
            catch(SQLException sq)
                sq.printStackTrace();
            catch(NullPointerException n)
                n.printStackTrace();
            /*System.out.println("prima ordinamento:");
            for(int i=0; i<ids.size();i++)
                System.out.println("id "+ids.get(i).toString()+", data app "+appIl.get(i).toString()+", ore "+hours.get(i).toString());
            for(int i=0; i<ids.size(); i++)
                System.out.println("ids("+i+")= "+ids.get(i).toString());
            for(int i=0; i<appIl.size(); i++)
                System.out.println("appIl("+i+")= "+appIl.get(i).toString());
            for(int i=0; i<hours.size(); i++)
                System.out.println("hours("+i+")= "+hours.get(i).toString());
            myAppArray[] dateArr=new myAppArray[appIl.size()];
            Appuntamenti.sp.set("Inizio ordinamento in corso");
            Appuntamenti.sp.progBar.setMaximum(appIl.size());
            for(int i=0; i<dateArr.length; i++)
                Appuntamenti.sp.progBar.setValue(i);
                dateArr=new myAppArray(ids.get(i).toString(),appIl.get(i).toString(),hours.get(i).toString());
    java.util.Arrays.sort(dateArr, new ArrayAppDateComparator());
    Vector newIds=new Vector();
    for(int i=0; i< dateArr.length; i++)
    myAppArray temp=dateArr[i];
    //System.out.println("data: "+temp.getDate()+", ora: "+temp.getHour()+" id: "+temp.getId());
    newIds.add(temp.getId());
    appIl.clear();
    hours.clear();
    commerciali.clear();
    clienti.clear();
    commenti.clear();
    try
    Appuntamenti.sp.set("Recupero informazioni...");
    Appuntamenti.sp.progBar.setValue(0);
    Statement s1=Jtm.tmc.createStatement();
    for(int i=0; i<newIds.size(); i++)
    Appuntamenti.sp.progBar.setValue(i);
    String tempId=newIds.get(i).toString();
    //System.out.println("tempId: "+tempId);
    ResultSet rs1=s1.executeQuery("select * from contatti where id="+tempId);
    if(rs1.next())
    appIl.add(rs1.getString("appuntamento_il"));
    hours.add(rs1.getString("ore"));
    clienti.add(rs1.getString("nome"));
    referenti.add(rs1.getString("referente"));
    indirizzi.add(rs1.getString("indirizzo"));
    citta.add(rs1.getString("citta"));
    telefoni.add(rs1.getString("telefono"));
    motivazioni.add(rs1.getString("motivazione"));
    appCon.add(rs1.getString("appuntamento_con"));
    catch(SQLException sq)
    sq.printStackTrace();
    Object[][] o=new Object[ids.size()][9];
    System.out.println("o.length: "+o.length);
    String dataAppuntamento="";
    for(int i=0; i<o.length; i++)
    try
    String tempData=appIl.get(i).toString();
    if(tempData.equals(dataAppuntamento))
    o[i][0]="";
    else
    dataAppuntamento=tempData;
    o[i][0]=dataAppuntamento;
    catch(NullPointerException n){o[i][0]="";}
    for(int i=0; i<o.length; i++)
    try
    o[i][1]=hours.get(i).toString();
    catch(NullPointerException n){o[i][1]="";}
    for(int i=0; i<o.length; i++)
    try
    o[i][2]=clienti.get(i).toString();
    catch(NullPointerException n){o[i][2]="";}
    for(int i=0; i<o.length; i++)
    try
    o[i][3]=referenti.get(i).toString();
    catch(NullPointerException n){o[i][3]="";}
    for(int i=0; i<o.length; i++)
    try
    o[i][4]=indirizzi.get(i).toString();
    catch(NullPointerException n){o[i][4]="";}
    for(int i=0; i<o.length; i++)
    try
    o[i][5]=citta.get(i).toString();
    catch(NullPointerException n){o[i][5]="";}
    for(int i=0; i<o.length; i++)
    try
    o[i][6]=telefoni.get(i).toString();
    catch(NullPointerException n){o[i][6]="";}
    for(int i=0; i<o.length; i++)
    try
    o[i][7]=motivazioni.get(i).toString();
    catch(NullPointerException n){o[i][7]="";}
    for(int i=0; i<o.length; i++)
    try
    o[i][8]=appCon.get(i).toString();
    catch(NullPointerException n){o[i][8]="";}
    System.out.println("height: "+Appuntamenti.table.getRowHeight());
    System.out.println("olenght: "+o.length);
    System.out.println("risultato: "+ (Appuntamenti.table.getRowHeight() * o.length));
    Appuntamenti.table.setRowHeight( Appuntamenti.table.getRowHeight());
    //Appuntamenti.table.setRowHeight(16);
    Appuntamenti.table.setDefaultRenderer(String.class, new MultiLineCellRenderer() );
    Object[] columns=new Object[]{"Data","Ora","Nome","Referente","Indirizzo","Citt�","Telefono","Motivazione","App. con"};
    JTableHeader k=new JTableHeader();
    Appuntamenti.table.setTableHeader(k);
    Appuntamenti.table.setModel(new javax.swing.table.DefaultTableModel (o,columns)
    Class[] types = new Class [] {
    java.lang.String.class, java.lang.String.class, java.lang.String.class, java.lang.String.class
    TableColumnModel tcm = Appuntamenti.table.getColumnModel();
    TableColumn data = tcm.getColumn(0);
    TableColumn ora = tcm.getColumn(1);
    TableColumn cliente = tcm.getColumn(2);
    TableColumn referente = tcm.getColumn(3);
    TableColumn indirizzo = tcm.getColumn(4);
    TableColumn citt = tcm.getColumn(5);
    TableColumn telefono = tcm.getColumn(6);
    TableColumn motivazione = tcm.getColumn(7);
    TableColumn appcon = tcm.getColumn(8);
    System.out.println("data "+data.getPreferredWidth());
    System.out.println("ora "+ora.getPreferredWidth());
    System.out.println("cliente "+cliente.getPreferredWidth());
    System.out.println("referente "+referente.getPreferredWidth());
    System.out.println("indirizzo "+indirizzo.getPreferredWidth());
    System.out.println("citt "+citt.getPreferredWidth());
    System.out.println("telefono "+telefono.getPreferredWidth());
    System.out.println("motivazione "+motivazione.getPreferredWidth());
    System.out.println("appcon "+appcon.getPreferredWidth());
    data.setPreferredWidth(700);
    ora.setPreferredWidth(350);
    cliente.setPreferredWidth(1000);
    referente.setPreferredWidth(1000);
    indirizzo.setPreferredWidth(1300);
    citt.setPreferredWidth(1000);
    telefono.setPreferredWidth(1000);
    motivazione.setPreferredWidth(1500);
    appcon.setPreferredWidth(1000);
    //data.setCellRenderer(new MultiLineTableCellRenderer());
    //cliente.setCellRenderer(new MultiLineTableCellRenderer().getTableCellRendererComponent());
    Appuntamenti.lTotale.setText(Integer.toString(o.length));
    Appuntamenti.ids=newIds;
    Appuntamenti.sp.mostra();
    Appuntamenti.sp.dispose();
    //Integer[] integerIds=Integer.ids.toArray();
    for(int i=0; i<dateArr.length; i++)
    System.out.println("dateArr["+i+"]= "+date.format(dateArr[i]));
    java.util.Arrays.sort(dateArr);
    for(int i=0; i<dateArr.length; i++)
    System.out.println("ordinato dateArr["+i+"]= "+date.format(dateArr[i]));
    class myAppArray
    private String id;
    private String date;
    private String hour;
    public myAppArray(String id, String date, String hour)
    this.id=id;
    this.date=date;
    this.hour=hour;
    public String getDate()
    return date;
    public String getHour()
    return hour;
    public String getId()
    return id;
    class ArrayAppDateComparator implements java.util.Comparator
    private DateFormat date=Jtm.date;
    private DateFormat hour=new SimpleDateFormat("HH:mm");
    public int compare(Object o1, Object o2)
    hour.setLenient(false);
    myAppArray s1 = (myAppArray)o1;
    myAppArray s2 = (myAppArray)o2;
    java.util.Date d1=null;
    java.util.Date d2=null;
    java.util.Date h1=null;
    java.util.Date h2=null;
    try
    d1 = date.parse(s1.getDate());
    d2 = date.parse(s2.getDate());
    catch(ParseException pe)
    pe.printStackTrace();
    if(!d1.equals(d2))
    return d1.compareTo(d2);
    else
    try
    h1 = hour.parse(s1.getHour());
    h2 = hour.parse(s2.getHour());
    catch(ParseException pe)
    pe.printStackTrace();
    return h1.compareTo(h2);

  • Problem reading .txt-file into JTable

    My problem is that I�m reading a .txt-file into a J-Table. It all goes okay, the FileChooser opens and the application reads the selected file (line). But then I get a Null Pointer Exception and the JTable does not get updated with the text from the file.
    Here�s my code (I kept it simple, and just want to read the text from the .txt-file to the first cell of the table.
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.table.*;
    import java.util.*;
    import java.lang.*;
    import java.io.*;
    public class TeamTable extends JFrame implements ActionListener, ItemListener                {
    static JTable table;
         // constructor
    public TeamTable()                {
    super( "Invoermodule - Team Table" );
    setSize( 740, 365 );
              // setting the rownames
    ListModel listModel = new AbstractListModel()                     {
    String headers[] = {"Team 1", "Team 2", "Team 3", "Team 4", "Team 5", "Team 6", "Team 7", "Team 8", "Team 9",
    "Team 10", "Team 11", "Team 12", "Team 13", "Team 14", "Team 15", "Team 16", "Team 17", "Team 18"};
    public int getSize() { return headers.length; }
    public Object getElementAt(int index) { return headers[index]; }
              // add listModel & rownames to the table
              DefaultTableModel defaultModel = new DefaultTableModel(listModel.getSize(),3);
              JTable table = new JTable( defaultModel );
              // setting the columnnames and center alignment of table cells
              int width = 200;
              int[] vColIndex = {0,1,2};
              String[] ColumnName = {"Name Team", "Name Chairman", "Name Manager"};
              TableCellRenderer centerRenderer = new CenterRenderer();          
              for (int i=0; i < vColIndex.length;i++)          {
                             table.getColumnModel().getColumn(vColIndex).setHeaderValue(ColumnName[i]);
                             table.getColumnModel().getColumn(vColIndex[i]).setPreferredWidth(width);
                             table.getColumnModel().getColumn(vColIndex[i]).setCellRenderer(centerRenderer);
              table.setFont(new java.awt.Font("Dialog", Font.ITALIC, 12));
              // force the header to resize and repaint itself
              table.getTableHeader().resizeAndRepaint();
              // create single component to add to scrollpane (rowHeader is JList with argument listModel)
              JList rowHeader = new JList(listModel);
              rowHeader.setFixedCellWidth(100);
              rowHeader.setFixedCellHeight(table.getRowHeight());
              rowHeader.setCellRenderer(new RowHeaderRenderer(table));
              // add to scroll pane:
              JScrollPane scroll = new JScrollPane( table );
              scroll.setRowHeaderView(rowHeader); // Adds row-list left of the table
              getContentPane().add(scroll, BorderLayout.CENTER);
              // add menubar, menu, menuitems with evenlisteners to the frame.
              JMenuBar menubar = new JMenuBar();
              setJMenuBar (menubar);
              JMenu filemenu = new JMenu("File");
              menubar.add(filemenu);
              JMenuItem open = new JMenuItem("Open");
              JMenuItem save = new JMenuItem("Save");
              JMenuItem exit = new JMenuItem("Exit");
              open.addActionListener(this);
              save.addActionListener(this);
              exit.addActionListener(this);
              filemenu.add(open);
              filemenu.add(save);
              filemenu.add(exit);
              filemenu.addItemListener(this);
    // ActionListener for ActionEvents on JMenuItems.
    public void actionPerformed(ActionEvent e) {       
         String open = "Open";
         String save = "Save";
         String exit = "Exit";
              if (e.getSource() instanceof JMenuItem)     {
                   JMenuItem source = (JMenuItem)(e.getSource());
                   String x = source.getText();
                        if (x == open)          {
                             System.out.println("open file");
                        // create JFileChooser.
                        String filename = File.separator+"tmp";
                        JFileChooser fc = new JFileChooser(new File(filename));
                        // set default directory.
                        File wrkDir = new File("C:/Documents and Settings/Erwin en G-M/Mijn documenten/Erwin/Match Day");
                        fc.setCurrentDirectory(wrkDir);
                        // show open dialog.
                        int returnVal =     fc.showOpenDialog(null);
                        File selFile = fc.getSelectedFile();
                        if(returnVal == JFileChooser.APPROVE_OPTION) {
                        System.out.println("You chose to open this file: " +
                   fc.getSelectedFile().getName());
                        try          {
                             BufferedReader invoer = new BufferedReader(new FileReader(selFile));
                             String line = invoer.readLine();
                             System.out.println(line);
                             // THIS IS WHERE IT GOES WRONG, I THINK
                             table.setValueAt(line, 1, 1);
                             table.fireTableDataChanged();
                        catch (IOException ioExc){
                        if (x == save)          {
                             System.out.println("save file");
                        if (x == exit)          {
                             System.out.println("exit file");
    // ItemListener for ItemEvents on JMenu.
    public void itemStateChanged(ItemEvent e) {       
              String s = "Item event detected. Event source: " + e.getSource();
              System.out.println(s);
         public static void main(String[] args)                {
              TeamTable frame = new TeamTable();
              frame.setUndecorated(true);
         frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
              frame.addWindowListener( new WindowAdapter()           {
                   public void windowClosing( WindowEvent e )                {
         System.exit(0);
    frame.setVisible(true);
    * Define the look/content for a cell in the row header
    * In this instance uses the JTables header properties
    class RowHeaderRenderer extends JLabel implements ListCellRenderer           {
    * Constructor creates all cells the same
    * To change look for individual cells put code in
    * getListCellRendererComponent method
    RowHeaderRenderer(JTable table)      {
    JTableHeader header = table.getTableHeader();
    setOpaque(true);
    setBorder(UIManager.getBorder("TableHeader.cellBorder"));
    setHorizontalAlignment(CENTER);
    setForeground(header.getForeground());
    setBackground(header.getBackground());
    setFont(header.getFont());
    * Returns the JLabel after setting the text of the cell
         public Component getListCellRendererComponent( JList list,
    Object value, int index, boolean isSelected, boolean cellHasFocus)      {
    setText((value == null) ? "" : value.toString());
    return this;

    My problem is that I�m reading a .txt-file into a J-Table. It all goes okay, the FileChooser opens and the application reads the selected file (line). But then I get a Null Pointer Exception and the JTable does not get updated with the text from the file.
    Here�s my code (I kept it simple, and just want to read the text from the .txt-file to the first cell of the table.
    A MORE READABLE VERSION !
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.table.*;
    import java.util.*;
    import java.lang.*;
    import java.io.*;
    public class TeamTable extends JFrame implements ActionListener, ItemListener                {
    static JTable table;
         // constructor
        public TeamTable()                {
            super( "Invoermodule - Team Table" );
            setSize( 740, 365 );
              // setting the rownames
            ListModel listModel = new AbstractListModel()                     {
                String headers[] = {"Team 1", "Team 2", "Team 3", "Team 4", "Team 5", "Team 6", "Team 7", "Team 8", "Team 9",
                "Team 10", "Team 11", "Team 12", "Team 13", "Team 14", "Team 15", "Team 16", "Team 17", "Team 18"};
                public int getSize() { return headers.length; }
                public Object getElementAt(int index) { return headers[index]; }
              // add listModel & rownames to the table
              DefaultTableModel defaultModel = new DefaultTableModel(listModel.getSize(),3);
              JTable table = new JTable( defaultModel );
              // setting the columnnames and center alignment of table cells
              int width = 200;
              int[] vColIndex = {0,1,2};
              String[] ColumnName = {"Name Team", "Name Chairman", "Name Manager"};
              TableCellRenderer centerRenderer = new CenterRenderer();          
              for (int i=0; i < vColIndex.length;i++)          {
                             table.getColumnModel().getColumn(vColIndex).setHeaderValue(ColumnName[i]);
                             table.getColumnModel().getColumn(vColIndex[i]).setPreferredWidth(width);
                             table.getColumnModel().getColumn(vColIndex[i]).setCellRenderer(centerRenderer);
              table.setFont(new java.awt.Font("Dialog", Font.ITALIC, 12));
              // force the header to resize and repaint itself
              table.getTableHeader().resizeAndRepaint();
              // create single component to add to scrollpane (rowHeader is JList with argument listModel)
              JList rowHeader = new JList(listModel);
              rowHeader.setFixedCellWidth(100);
              rowHeader.setFixedCellHeight(table.getRowHeight());
              rowHeader.setCellRenderer(new RowHeaderRenderer(table));
              // add to scroll pane:
              JScrollPane scroll = new JScrollPane( table );
              scroll.setRowHeaderView(rowHeader); // Adds row-list left of the table
              getContentPane().add(scroll, BorderLayout.CENTER);
              // add menubar, menu, menuitems with evenlisteners to the frame.
              JMenuBar menubar = new JMenuBar();
              setJMenuBar (menubar);
              JMenu filemenu = new JMenu("File");
              menubar.add(filemenu);
              JMenuItem open = new JMenuItem("Open");
              JMenuItem save = new JMenuItem("Save");
              JMenuItem exit = new JMenuItem("Exit");
              open.addActionListener(this);
              save.addActionListener(this);
              exit.addActionListener(this);
              filemenu.add(open);
              filemenu.add(save);
              filemenu.add(exit);
              filemenu.addItemListener(this);
    // ActionListener for ActionEvents on JMenuItems.
    public void actionPerformed(ActionEvent e) {       
         String open = "Open";
         String save = "Save";
         String exit = "Exit";
              if (e.getSource() instanceof JMenuItem)     {
                   JMenuItem source = (JMenuItem)(e.getSource());
                   String x = source.getText();
                        if (x == open)          {
                             System.out.println("open file");
                        // create JFileChooser.
                        String filename = File.separator+"tmp";
                        JFileChooser fc = new JFileChooser(new File(filename));
                        // set default directory.
                        File wrkDir = new File("C:/Documents and Settings/Erwin en G-M/Mijn documenten/Erwin/Match Day");
                        fc.setCurrentDirectory(wrkDir);
                        // show open dialog.
                        int returnVal =     fc.showOpenDialog(null);
                        File selFile = fc.getSelectedFile();
                        if(returnVal == JFileChooser.APPROVE_OPTION) {
                        System.out.println("You chose to open this file: " +
                   fc.getSelectedFile().getName());
                        try          {
                             BufferedReader invoer = new BufferedReader(new FileReader(selFile));
                             String line = invoer.readLine();
                             System.out.println(line);
                             // THIS IS WHERE IT GOES WRONG, I THINK
                             table.setValueAt(line, 1, 1);
                             table.fireTableDataChanged();
                        catch (IOException ioExc){
                        if (x == save)          {
                             System.out.println("save file");
                        if (x == exit)          {
                             System.out.println("exit file");
    // ItemListener for ItemEvents on JMenu.
    public void itemStateChanged(ItemEvent e) {       
              String s = "Item event detected. Event source: " + e.getSource();
              System.out.println(s);
         public static void main(String[] args)                {
              TeamTable frame = new TeamTable();
              frame.setUndecorated(true);
         frame.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
              frame.addWindowListener( new WindowAdapter()           {
                   public void windowClosing( WindowEvent e )                {
         System.exit(0);
    frame.setVisible(true);
    * Define the look/content for a cell in the row header
    * In this instance uses the JTables header properties
    class RowHeaderRenderer extends JLabel implements ListCellRenderer           {
    * Constructor creates all cells the same
    * To change look for individual cells put code in
    * getListCellRendererComponent method
    RowHeaderRenderer(JTable table)      {
    JTableHeader header = table.getTableHeader();
    setOpaque(true);
    setBorder(UIManager.getBorder("TableHeader.cellBorder"));
    setHorizontalAlignment(CENTER);
    setForeground(header.getForeground());
    setBackground(header.getBackground());
    setFont(header.getFont());
    * Returns the JLabel after setting the text of the cell
         public Component getListCellRendererComponent( JList list,
    Object value, int index, boolean isSelected, boolean cellHasFocus)      {
    setText((value == null) ? "" : value.toString());
    return this;

  • 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;
    }

  • Groupable + multiline table header paint problem

    hi, i try to make a groupable + multiline table header
    based on Nobuo Tamesama's code...
    there are some problems which i considered tolerable except one...
    the header didn't paint correctly when i set the autoResizeMode into autoresizemode_off
    and resize the columns pass the scrollpane width...
    thx in advance
    here's the complete code :
    import java.io.*;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.table.*;
    import java.util.*;
    import javax.swing.border.*;
    import javax.swing.plaf.basic.*;
    public class GroupableHeaderExample extends JFrame {
        GroupableHeaderExample() {
            super("Groupable Header Example");
            JScrollPane sp = new JScrollPane();
            Object[][] data = {{"b1k1", "b1k2", "b1k3", "b1k4", "b1k5"}, {"b2k1", "b2k2", "b2k3", "b2k4", "b2k5"}};
            JTable table = new JTable(new DefaultTableModel(data, new Object[]{"Kol1", "Kol2\nmmm", "Kol3", "kol4\nmmm\nnnn", " \n \nKol5\nmmm"})) {
                protected JTableHeader createDefaultTableHeader() {
                    return new GroupableTableHeader(columnModel);
            table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
            ColumnGroup cg = new ColumnGroup("CG", 0, 3);
            ColumnGroup cg2 = new ColumnGroup("CG2\nmmm", 1, 3);
            ColumnGroup cg3 = new ColumnGroup("CG3", 1, 2);
            GroupableTableHeader header = (GroupableTableHeader)table.getTableHeader();
            header.addColumnGroup(cg3);
            header.addColumnGroup(cg);
            header.addColumnGroup(cg2);
            header.fitHeight();
            sp.setViewportView(table);
            getContentPane().add(sp);
            setSize(400, 300);  
        public static void main(String[] args) {
            GroupableHeaderExample frame = new GroupableHeaderExample();
            frame.addWindowListener( new WindowAdapter() {
                public void windowClosing( WindowEvent e ) {
                    System.exit(0);
            frame.setVisible(true);
    class GroupableTableHeader extends JTableHeader {
        private Vector<ColumnGroup> columnGroups = new Vector<ColumnGroup>(1, 1);
        public GroupableTableHeader(TableColumnModel model) {
            super(model);
            setUI(new GroupableTableHeaderUI());
            setReorderingAllowed(false);
        public void addColumnGroup(ColumnGroup cg) {
            if(columnGroups.size() == 0) {
                columnGroups.addElement(cg);
                return;
            int size = columnGroups.size();
            for(int i = 0; i < size; i++) {
                if(cg.getLength() > ((ColumnGroup)columnGroups.elementAt(i)).getLength())
                    columnGroups.insertElementAt(cg, i);
                else {
                    if(i == size - 1)
                        columnGroups.addElement(cg);           
        public void fitHeight() {
            int[] counter = new int[getTable().getColumnCount()];
            for(int i = 0; i < getTable().getColumnCount(); i++) {
                int level = 0;
                for(int j = 0; j < columnGroups.size(); j++) {
                    if(i >= ((ColumnGroup)columnGroups.elementAt(j)).getStartIndex() && i <= ((ColumnGroup)columnGroups.elementAt(j)).getEndIndex())
                        level = level + getNewLineCount(((ColumnGroup)columnGroups.elementAt(j)).getText());
                counter[i] = level + getNewLineCount(table.getColumnModel().getColumn(i).getHeaderValue().toString());
            int maxCounter = counter[0];
            for(int i = 0; i < counter.length; i++) {
                if(counter[i] > maxCounter)
                    maxCounter = counter;
    setPreferredSize(new Dimension(100, (maxCounter) * 20));
    public Vector getColumnGroups() {
    return columnGroups;
    public int getNewLineCount(String str) {
    BufferedReader br = new BufferedReader(new StringReader(str));
    String line;
    Vector<String> v = new Vector<String>(1, 1);
    try {           
    while((line = br.readLine()) != null) {
    v.addElement(line);
    catch(IOException ex) {
    JOptionPane.showMessageDialog(null, ex.getMessage(), "Informasi", JOptionPane.INFORMATION_MESSAGE);
    System.exit(0);
    int i = 0;
    boolean b = false;
    for(i = 0; i < v.size(); i++) {
    for(int j = 0; j < v.elementAt(i).length(); j++) {
    if(v.elementAt(i).charAt(j) != ' ') {
    b = true;
    break;
    if(b)
    break;
    if(i == v.size())
    i = 0;
    return v.size() - i;
    public void updateUI(){
    setUI(new GroupableTableHeaderUI());
    class GroupableTableHeaderUI extends BasicTableHeaderUI {     
    public void paint(Graphics g, JComponent c) {
    TableCellRenderer renderer = new MultiLineHeaderRendererEx();
    Component[] cmp = new Component[header.getColumnModel().getColumnCount()];
    Vector cg = ((GroupableTableHeader)header).getColumnGroups();
    Component[] cmpGroup = new Component[cg.size()];
    TableColumnModel tcm = header.getTable().getColumnModel();
    for(int i = 0; i < cmpGroup.length; i++) {
    cmpGroup[i] = renderer.getTableCellRendererComponent(header.getTable(), ((ColumnGroup)cg.elementAt(i)).getText(), false, false, -1, i);
    rendererPane.add(cmpGroup[i]);
    int x = 0;
    int y = 0;
    int height = 20 * ((GroupableTableHeader)header).getNewLineCount(((ColumnGroup)cg.elementAt(i)).getText());
    for(int j = 0; j < ((ColumnGroup)cg.elementAt(i)).getStartIndex(); j++)
    x += tcm.getColumn(j).getWidth();
    for(int j = 0; j < cmpGroup.length; j++) {
    if(i == j)
    continue;
    if(((ColumnGroup)cg.elementAt(i)).getStartIndex() >= ((ColumnGroup)cg.elementAt(j)).getStartIndex() && ((ColumnGroup)cg.elementAt(i)).getEndIndex() <= ((ColumnGroup)cg.elementAt(j)).getEndIndex())
    y = ((ColumnGroup)cg.elementAt(j)).getY() + ((ColumnGroup)cg.elementAt(j)).getHeight();
    ((ColumnGroup)cg.elementAt(i)).setY(y);
    ((ColumnGroup)cg.elementAt(i)).setHeight(height);
    int width = 0;
    for(int j = ((ColumnGroup)cg.elementAt(i)).getStartIndex(); j <= ((ColumnGroup)cg.elementAt(i)).getEndIndex(); j++)
    width += tcm.getColumn(j).getWidth();
    rendererPane.add(cmpGroup[i]);
    rendererPane.paintComponent(g, cmpGroup[i], header, x, y, width, height, true);
    for(int i = 0; i < cmp.length; i++) {
    cmp[i] = renderer.getTableCellRendererComponent(header.getTable(), header.getColumnModel().getColumn(i).getHeaderValue(), false, false, -1, i);
    rendererPane.add(cmp[i]);
    int x = 0;
    int y = 0;
    for(int j = 0; j < i; j++)
    x += tcm.getColumn(j).getWidth();
    for(int j = 0; j < cmpGroup.length; j++) {
    if(i >= ((ColumnGroup)cg.elementAt(j)).getStartIndex() && i <= ((ColumnGroup)cg.elementAt(j)).getEndIndex())
    y = ((ColumnGroup)cg.elementAt(j)).getY() + ((ColumnGroup)cg.elementAt(j)).getHeight();
    rendererPane.add(cmp[i]);
    rendererPane.paintComponent(g, cmp[i], header, x, y, tcm.getColumn(i).getWidth(), (header.getPreferredSize().height - y), true);
    class MultiLineHeaderRendererEx extends JList implements TableCellRenderer {
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
    if(((GroupableTableHeader)table.getTableHeader()).getNewLineCount(value.toString()) == 1) {
    JLabel header = new JLabel();
    header.setForeground(table.getTableHeader().getForeground());
    header.setBackground(table.getTableHeader().getBackground());
    header.setFont(table.getTableHeader().getFont());
    header.setHorizontalAlignment(JLabel.CENTER);
    header.setText(value.toString());
    header.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
    return header;
    else {
    setOpaque(true);
    setForeground(UIManager.getColor("TableHeader.foreground"));
    setBackground(UIManager.getColor("TableHeader.background"));
    setBorder(UIManager.getBorder("TableHeader.cellBorder"));
    setFont(UIManager.getFont("TableHeader.font"));
    ListCellRenderer renderer = getCellRenderer();
    ((JLabel)renderer).setHorizontalAlignment(SwingConstants.CENTER);
    setCellRenderer(renderer);
    String str = value.toString();
    BufferedReader br = new BufferedReader(new StringReader(str));
    String line;
    Vector<String> v = new Vector<String>(1, 1);
    try {           
    while((line = br.readLine()) != null) {
    v.addElement(line);
    catch(IOException ex) {
    JOptionPane.showMessageDialog(null, ex.getMessage(), "Informasi", JOptionPane.INFORMATION_MESSAGE);
    System.exit(0);
    setListData(v);
    return this;

    OMG ! the code i posted before is incomplete
    sorry...
    here's the complete one, pls help :
    import java.io.*;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.table.*;
    import java.util.*;
    import javax.swing.border.*;
    import javax.swing.plaf.basic.*;
    public class GroupableHeaderExample extends JFrame {
        GroupableHeaderExample() {
            super("Groupable Header Example");
            JScrollPane sp = new JScrollPane();
            Object[][] data = {{"b1k1", "b1k2", "b1k3", "b1k4", "b1k5"}, {"b2k1", "b2k2", "b2k3", "b2k4", "b2k5"}};
            JTable table = new JTable(new DefaultTableModel(data, new Object[]{"Kol1", "Kol2\nmmm", "Kol3", "kol4\nmmm\nnnn", "Kol5\nmmm"})) {
                protected JTableHeader createDefaultTableHeader() {
                    return new GroupableTableHeader(columnModel);
            table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
            ColumnGroup cg = new ColumnGroup("CG", 0, 4);
            ColumnGroup cg2 = new ColumnGroup("CG2\nmmm", 1, 4);
            ColumnGroup cg3 = new ColumnGroup("CG3", 1, 2);
            ColumnGroup cg4 = new ColumnGroup("CG4", 3, 4);
            GroupableTableHeader header = (GroupableTableHeader)table.getTableHeader();
            header.addColumnGroup(cg4);
            header.addColumnGroup(cg2);
            header.addColumnGroup(cg3);
            header.addColumnGroup(cg);
            header.fitHeight();
            sp.setViewportView(table);
            getContentPane().add(sp);
            setSize(400, 300);  
        public static void main(String[] args) {
            GroupableHeaderExample frame = new GroupableHeaderExample();
            frame.addWindowListener( new WindowAdapter() {
                public void windowClosing( WindowEvent e ) {
                    System.exit(0);
            frame.setVisible(true);
    class GroupableTableHeader extends JTableHeader {
        private Vector<ColumnGroup> columnGroups = new Vector<ColumnGroup>(1, 1);
        public GroupableTableHeader(TableColumnModel model) {
            super(model);
            setUI(new GroupableTableHeaderUI());
            setReorderingAllowed(false);
        public void addColumnGroup(ColumnGroup cg) {
            if(columnGroups.size() == 0) {
                columnGroups.addElement(cg);
                return;
            int size = columnGroups.size();
            for(int i = 0; i < size; i++) {
                if(cg.getLength() > ((ColumnGroup)columnGroups.elementAt(i)).getLength()) {
                    columnGroups.insertElementAt(cg, i);
                    break;
                else {
                    if(i == size - 1)
                        columnGroups.addElement(cg);           
        public void fitHeight() {
            int[] counter = new int[getTable().getColumnCount()];
            for(int i = 0; i < getTable().getColumnCount(); i++) {
                int level = 0;
                for(int j = 0; j < columnGroups.size(); j++) {
                    if(i >= ((ColumnGroup)columnGroups.elementAt(j)).getStartIndex() && i <= ((ColumnGroup)columnGroups.elementAt(j)).getEndIndex())
                        level = level + getNewLineCount(((ColumnGroup)columnGroups.elementAt(j)).getText());
                counter[i] = level + getNewLineCount(table.getColumnModel().getColumn(i).getHeaderValue().toString());
            int maxCounter = counter[0];
            for(int i = 0; i < counter.length; i++) {
                if(counter[i] > maxCounter)
                    maxCounter = counter;
    setPreferredSize(new Dimension(100, (maxCounter) * 20));
    public Vector getColumnGroups() {
    return columnGroups;
    public int getNewLineCount(String str) {
    BufferedReader br = new BufferedReader(new StringReader(str));
    String line;
    Vector<String> v = new Vector<String>(1, 1);
    try {           
    while((line = br.readLine()) != null) {
    v.addElement(line);
    catch(IOException ex) {
    JOptionPane.showMessageDialog(null, ex.getMessage(), "Informasi", JOptionPane.INFORMATION_MESSAGE);
    System.exit(0);
    int i = 0;
    boolean b = false;
    for(i = 0; i < v.size(); i++) {
    for(int j = 0; j < v.elementAt(i).length(); j++) {
    if(v.elementAt(i).charAt(j) != ' ') {
    b = true;
    break;
    if(b)
    break;
    if(i == v.size())
    i = 0;
    return v.size() - i;
    public void updateUI(){
    setUI(new GroupableTableHeaderUI());
    class GroupableTableHeaderUI extends BasicTableHeaderUI {     
    public void paint(Graphics g, JComponent c) {
    TableCellRenderer renderer = new MultiLineHeaderRendererEx();
    Component[] cmp = new Component[header.getColumnModel().getColumnCount()];
    Vector cg = ((GroupableTableHeader)header).getColumnGroups();
    Component[] cmpGroup = new Component[cg.size()];
    TableColumnModel tcm = header.getTable().getColumnModel();
    for(int i = 0; i < cmpGroup.length; i++) {
    cmpGroup[i] = renderer.getTableCellRendererComponent(header.getTable(), ((ColumnGroup)cg.elementAt(i)).getText(), false, false, -1, i);
    int x = 0;
    int y = 0;
    int height = 20 * ((GroupableTableHeader)header).getNewLineCount(((ColumnGroup)cg.elementAt(i)).getText());
    for(int j = 0; j < ((ColumnGroup)cg.elementAt(i)).getStartIndex(); j++)
    x += tcm.getColumn(j).getWidth();
    for(int j = 0; j < cmpGroup.length; j++) {
    if(i == j)
    continue;
    if(((ColumnGroup)cg.elementAt(i)).getStartIndex() >= ((ColumnGroup)cg.elementAt(j)).getStartIndex() && ((ColumnGroup)cg.elementAt(i)).getEndIndex() <= ((ColumnGroup)cg.elementAt(j)).getEndIndex())
    y = ((ColumnGroup)cg.elementAt(j)).getY() + ((ColumnGroup)cg.elementAt(j)).getHeight();
    ((ColumnGroup)cg.elementAt(i)).setY(y);
    ((ColumnGroup)cg.elementAt(i)).setHeight(height);
    int width = 0;
    for(int j = ((ColumnGroup)cg.elementAt(i)).getStartIndex(); j <= ((ColumnGroup)cg.elementAt(i)).getEndIndex(); j++)
    width += tcm.getColumn(j).getWidth();
    rendererPane.add(cmpGroup[i]);
    rendererPane.paintComponent(g, cmpGroup[i], header, x, y, width, height, true);
    for(int i = 0; i < cmp.length; i++) {
    cmp[i] = renderer.getTableCellRendererComponent(header.getTable(), header.getColumnModel().getColumn(i).getHeaderValue(), false, false, -1, i);
    int x = 0;
    int y = 0;
    for(int j = 0; j < i; j++)
    x += tcm.getColumn(j).getWidth();
    for(int j = 0; j < cmpGroup.length; j++) {
    if(i >= ((ColumnGroup)cg.elementAt(j)).getStartIndex() && i <= ((ColumnGroup)cg.elementAt(j)).getEndIndex())
    y = ((ColumnGroup)cg.elementAt(j)).getY() + ((ColumnGroup)cg.elementAt(j)).getHeight();
    rendererPane.add(cmp[i]);
    rendererPane.paintComponent(g, cmp[i], header, x, y, tcm.getColumn(i).getWidth(), (header.getPreferredSize().height - y), true);
    class MultiLineHeaderRendererEx extends JList implements TableCellRenderer {
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
    if(((GroupableTableHeader)table.getTableHeader()).getNewLineCount(value.toString()) == 1) {
    JLabel header = new JLabel();
    header.setForeground(table.getTableHeader().getForeground());
    header.setBackground(table.getTableHeader().getBackground());
    header.setFont(table.getTableHeader().getFont());
    header.setHorizontalAlignment(JLabel.CENTER);
    header.setText(value.toString());
    header.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
    return header;
    else {
    setOpaque(true);
    setForeground(UIManager.getColor("TableHeader.foreground"));
    setBackground(UIManager.getColor("TableHeader.background"));
    setBorder(UIManager.getBorder("TableHeader.cellBorder"));
    setFont(UIManager.getFont("TableHeader.font"));
    ListCellRenderer renderer = getCellRenderer();
    ((JLabel)renderer).setHorizontalAlignment(SwingConstants.CENTER);
    setCellRenderer(renderer);
    String str = value.toString();
    BufferedReader br = new BufferedReader(new StringReader(str));
    String line;
    Vector<String> v = new Vector<String>(1, 1);
    try {           
    while((line = br.readLine()) != null) {
    v.addElement(line);
    catch(IOException ex) {
    JOptionPane.showMessageDialog(null, ex.getMessage(), "Informasi", JOptionPane.INFORMATION_MESSAGE);
    System.exit(0);
    setListData(v);
    return this;
    class ColumnGroup {
    private String text;
    private int startIndex, endIndex, y, height;
    public ColumnGroup(String text, int startIndex, int endIndex) {
    this.text = text;
    this.startIndex = startIndex;
    this.endIndex = endIndex;
    public int getEndIndex() {
    return endIndex;
    public int getHeight() {
    return height;
    public int getLength() {
    return endIndex - startIndex;
    public int getStartIndex() {
    return startIndex;
    public String getText() {
    return text;
    public int getY() {
    return y;
    public void setHeight(int height) {
    this.height = height;
    public void setY(int y) {
    this.y = y;

  • JTableHeader + columns

    Hello to all!!!!!
    I speak spanish
    I am working with a jTable in which the idea is to take information from a DB and to show it by this component. But it is that the columns of the table can be changed of position and be changed the size of them. So that this does not happen I read in the API in the JTableHeader class the methods setReorderingAllowed() and setResizingAllowed() which handle this, but I can?t to know, of how they are used since I have proven several forms and throws errors, this is what I make:
    TableModel dataModel = new AbstractTableModel() {
    final String[ ] columnNames = { "Name", "Last name", "Pastime", "Years of Practices", "Soltero(a)" };
    Object[][ end ] dates = {
    { "Mary", "Campione"," To ski ", new Integer(5), new Boolean(false) },
    { "Lhucas", "Huml"," To slide ", new Integer(3), new Boolean(true) },
    { "Kathya", "Walrath"," To climb ", new Integer(2), new Boolean(false) },
    { "Marcus", "Andrews"," To run ", new Integer(7), new Boolean(true) },
    { "Angela", "Lalth"," To swim ", 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 ]; }
    public Class getColumnClass(int c) { return getValueAt(0, c).getClass(); }
    JTable jTable1 = new JTable(dataModel);
    JTableHeader to tableheader = jTable1.getTableHeader(); tableheader.setReorderingAllowed(false);
    JScrollPane jScrollPane1 = JTable.createScrollPaneForTable(jTable1);
    and the other form is to change:
    JTableHeader to tableheader = jTable1.getTableHeader(); tableheader.setReorderingAllowed(false);
    By:
    jTable1.getTableHeader().setReorderingAllowed(false);
    With first it throws the following error to me:
    invalid method declaration; return type required and illegal start of type.
    With second form: malformed passes + the same expression.
    In addition, I am working with JBuilder2, that comes with JDK 1.1
    How work these metodos and the JTableHeader class, Will be problem of my JDK of which it does not allow east type me of declarations? Why it throws these errors to me? Who me can throw a hand, beforehand many thanks.

    I attempted to use Darryl's Default Table Header Cell Renderer, but I was unable (it requires java 1.6).
    I modified the code to make a very simple renderer. It does the job apropriately, but the header cell does not change its color (to red or white) unless the window is resized. Here is my very simple renderer (based on Darryl's one). What am I missing now?
    Thanks once more,
    Federico
    public class MyDefaultTableHeaderCellRenderer extends DefaultTableCellRenderer {
         public String jorl = "hola";
         public boolean tmp = false;
         public MyDefaultTableHeaderCellRenderer() {
              setHorizontalAlignment(CENTER);
              setHorizontalTextPosition(LEFT);
              setOpaque(true);
         public Component getTableCellRendererComponent(JTable table, Object value,
                                                                   boolean isSelected, boolean hasFocus, int row, int column) {
              super.getTableCellRendererComponent(table, value,
                                                           isSelected, hasFocus, row, column);
              if(table.isColumnSelected(column)) {
                   setBackground(java.awt.Color.red.darker());
              } else {
                   setBackground(java.awt.Color.white);
              setBorder(UIManager.getBorder("TableHeader.cellBorder"));
              return this;
    }

  • Unusal problem..pls help

    hello...
    i wrote a a simple java program using java swing..but
    i am facing a unusal probem...whenever i run the program it only shows the title bar..u have to maximize the window to see the content...
    ....although i am specifing the sive of the window by setSize option...
    heres the sample code....
    import javax.swing.tree.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import java.io.*;
    import java.text.*;
    import javax.swing.*;
    import javax.swing.border.*;
    import javax.swing.event.*;
    import javax.swing.table.*;
    import setdbconnection.*;
    class MainWindowGui1 extends JFrame
    public static JTable hosttable;
    public static HostTableData hostdata;
    protected JLabel hosttitle;
    protected HostButton hostbutton;
    MainWindowGui1()
    super("Network Management Tool");
    Container contentpane=getContentPane();
    contentpane.setSize(640,480);
    contentpane.setLayout(new BorderLayout());
    JPanel leftpanel=new JPanel();
    leftpanel.setLayout(new BorderLayout());
    JPanel internet=new JPanel();
    internet.setLayout(new BorderLayout());
    internet.setBorder(BorderFactory.createTitledBorder("Left part"));
    leftpanel.add(internet);
    JPanel rightpanel=new JPanel();
    rightpanel.setLayout(new BorderLayout());
    rightpanel.setBorder(BorderFactory.createTitledBorder("Other part"));
    rightpanel.setBackground(Color.white);
    JSplitPane sp=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftpanel, rightpanel);
    sp.setContinuousLayout(false);
    sp.setOneTouchExpandable(true);
    sp.setDividerSize(2);
    sp.setDividerLocation(150);
    contentpane.add(sp,BorderLayout.CENTER);
    WindowListener wndCloser = new WindowAdapter()
    public void windowClosing(WindowEvent e)
    System.exit(0);
    addWindowListener(wndCloser);
    setVisible(true);
    class MainWindow1
    public static void main(String args[])
    new MainWindowGui1();
    now pls tell me how to overcome this problem....

    okk..heres the full code...since i face this problem..i havent set the content of the leftpanel...and the table values read from from access database... the database oriented code are written in setdbconnection package..
    import javax.swing.tree.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import java.io.*;
    import java.text.*;
    import javax.swing.*;
    import javax.swing.border.*;
    import javax.swing.event.*;
    import javax.swing.table.*;
    import setdbconnection.*;
    class MainWindowGui extends JFrame
    public JTable hosttable;
    public HostTableData hostdata;
    protected JLabel hosttitle;
    protected HostButton hostbutton;
    MainWindowGui()
    super("Network Management Tool");
    Container contentpane=getContentPane();
    contentpane.setSize(640,480);
    //contentpane.setLayout(new BorderLayout());
    JPanel leftpanel=new JPanel();
    leftpanel.setLayout(new BorderLayout());
    JPanel internet=new JPanel();
    internet.setLayout(new BorderLayout());
    internet.setBorder(BorderFactory.createTitledBorder("Internet Section"));
    leftpanel.add(internet);
    JPanel rightpanel=new JPanel();
    rightpanel.setLayout(new BorderLayout());
    rightpanel.setBorder(BorderFactory.createTitledBorder("Host information of the LAN"));
    rightpanel.setBackground(Color.white);
    hostdata = new HostTableData();
    hostbutton=new HostButton();
    hosttable = new JTable();
    hosttable.setAutoCreateColumnsFromModel(false);
    hosttable.setModel(hostdata);
    for (int k = 0; k < HostTableData.m_columns.length; k++) {
    DefaultTableCellRenderer renderer = new
    DefaultTableCellRenderer();
    renderer.setHorizontalAlignment(
    HostTableData.m_columns[k].m_alignment);
    TableColumn column = new TableColumn(k,
    HostTableData.m_columns[k].m_width, renderer, null);
    hosttable.addColumn(column);  
    JTableHeader header = hosttable.getTableHeader();
    header.setUpdateTableInRealTime(false);
    JScrollPane ps = new JScrollPane();
    ps.getViewport().add(hosttable);
    rightpanel.add(ps, BorderLayout.CENTER);
    getContentPane().add(hostbutton, BorderLayout.SOUTH);
    JSplitPane sp=new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, leftpanel, rightpanel);
    sp.setContinuousLayout(false);
    sp.setOneTouchExpandable(true);
    sp.setDividerSize(2);
    sp.setDividerLocation(150);
    contentpane.add(sp,BorderLayout.CENTER);
    hostbutton.mybutton2.addActionListener(
        new ActionListener() {
            public void actionPerformed(ActionEvent e) {
         new insertNodepanel();
    WindowListener wndCloser = new WindowAdapter()
    public void windowClosing(WindowEvent e)
    System.exit(0);
    addWindowListener(wndCloser);
    setVisible(true);
    class MainWindow
    public static void main(String args[])
    new MainWindowGui();
    class HostButton extends JPanel
    public Button mybutton1;
    public Button mybutton2;
    public Button mybutton3;
    public Button mybutton4;
    public Button mybutton5;
    HostButton()
      mybutton1=new Button("Connect");
      mybutton2=new Button("InsertNode");
      mybutton3=new Button("RemoveNode");
      add(mybutton1);
      add(mybutton2);
      add(mybutton3);
    class HostData
      public String  Hostname;
      public String  IPAddress;
      public String  Type;
      public String  Status;
      public HostData(String hostname, String ipaddress, String type,
       String status) {
        Hostname=hostname;
        IPAddress=ipaddress;
        Type=type;
        Status=status;
    class HostColumnData
      public String  m_title;
      public int     m_width;
      public int     m_alignment;
      public HostColumnData(String title, int width, int alignment) {
        m_title = title;
        m_width = width;
        m_alignment = alignment;
    class HostTableData extends AbstractTableModel
      static final public HostColumnData m_columns[] = {
        new HostColumnData( "HostName", 100, JLabel.LEFT ),
        new HostColumnData( "IP Address", 100, JLabel.CENTER),
        new HostColumnData( "Type", 60, JLabel.CENTER ),
        new HostColumnData( "Status", 60, JLabel.CENTER ),
      protected Vector m_vector;
      setDBConnection DB=new setDBConnection();
      public HostTableData() {
        m_vector = new Vector();
        setDefaultData();
      public void setDefaultData() {
        m_vector.removeAllElements();
        DB.gethostdata();
        for(int i=0;i<setDBConnection.highest;i++)
    System.out.println(setDBConnection.host);
    m_vector.addElement(new HostData(setDBConnection.host[i],setDBConnection.ip[i],setDBConnection.type[i],setDBConnection.status[i]));
    public int getRowCount() {
    return m_vector==null ? 0 : m_vector.size();
    public int getColumnCount() {
    return m_columns.length;
    public String getColumnName(int column) {
    return m_columns[column].m_title;
    public boolean isCellEditable(int nRow, int nCol) {
    return false;
    public Object getValueAt(int nRow, int nCol) {
    if (nRow < 0 || nRow>=getRowCount())
    return "";
    HostData row = (HostData)m_vector.elementAt(nRow);
    switch (nCol) {
    case 0: return row.Hostname;
    case 1: return row.IPAddress;
    case 2: return row.Type;
    case 3: return row.Status;
    return "";
    public String getTitle() {
    return "Process Information";
    class insertNodepanel extends JFrame
    protected Button ok;
    protected Button cancel;
    insertNodepanel()
    super("Node Information input");
    Container cont=getContentPane();
    cont.setSize(100,100);
    JPanel host=new JPanel();
    JPanel password=new JPanel();
    JPanel type=new JPanel();
    JPanel status=new JPanel();
    JPanel ipaddr=new JPanel();
    JPanel stty=new JPanel();
    JPanel conl=new JPanel();
    ok=new Button("ok");
    cancel=new Button("cancel");
    cont.setLayout(new GridLayout(5,1));
    JTextField hst=new JTextField(10);
    JTextField pwd=new JTextField(10);
    JTextField ip=new JTextField(10);
    JTextField typ=new JTextField(10);
    JTextField sts=new JTextField(10);
    host.setLayout(new BorderLayout());
    host.setBorder(BorderFactory.createTitledBorder("Host Name"));
    host.add(hst);
    cont.add(host);
    ipaddr.setLayout(new BorderLayout());
    ipaddr.setBorder(BorderFactory.createTitledBorder("IP Address"));
    ipaddr.add(ip);
    cont.add(ipaddr);
    password.setLayout(new BorderLayout());
    password.setBorder(BorderFactory.createTitledBorder("Password"));
    password.add(pwd);
    cont.add(password);
    stty.setLayout(new GridLayout(1,2));
    status.setLayout(new BorderLayout());
    type.setLayout(new BorderLayout());
    status.setBorder(BorderFactory.createTitledBorder("Status"));
    type.setBorder(BorderFactory.createTitledBorder("Type"));
    status.add(sts);
    type.add(typ);
    stty.add(status);
    stty.add(type);
    cont.add(stty);
    conl.setLayout(new FlowLayout());
    conl.add(ok);
    conl.add(cancel);
    cont.add(conl);
    WindowListener wndCloser2 = new WindowAdapter()
    public void windowClosing(WindowEvent e)
    dispose();
    addWindowListener(wndCloser2);
    setVisible(true);

Maybe you are looking for

  • How do I recover the music on my nano back to a new drive

    All data om my Western Digital external hard drive has been lost as the drive has failed completely with all data unrecoverable. How do I sync the music on my nano to the new hard drive - am worried that i will lose all this music - over 2.5k songs,

  • TS3938 PowerPC Error message won't go away

    The warning box displays showing 'You can't open the application NotificationsExec because PowerPC applications are no longer supported'. When ok is clicked a new box comes up within 10 seconds. How can I get rid of this? I don't know which program i

  • How can I get "Canceling sync" to stop?

    How can I stop "Canceling sync" to stop?  My iphone and ipad both got stuck on this step after syncing.  How can I stop it?

  • Import Integration Interface

    Hi, I have requirement to load data for the combination of Item, Organization, Qty, Date. For e.g. ABC Org1 100 01-01-2009 ABC Org1 200 01-04-2009 Here the Qty and Date are for each quarter.(My lowest time bucket is Week). 1. How can I load Quarterly

  • FOLDER LEVEL RESTRICTION IN SOLMAN

    SOLMAN PROJECT Dear All, I  have to create a new project in Sol man (eg."Document"). The requirement is to upload all the documents of the project into Sol man. Documents are already classified module wise as IT,MM,SD,Mktg,E Biz etc. and stored in re