JTable & MouseListener

Hi,
Im wanting to be able to make a JPopupMenu appear when i right click on a JTable, but ive found that when i right click over actual rows, it doesnt register the right click
but when i right click over blank space in the table it works fine
this isnt a selection issue, as it really has nothing to do with selection, but JTable not registering mouse clicks
:\

ahhh i found the problem
was using the netbeans gui designer to add the listeners and when i clicked on what i thought was the JTable it was actually adding the listener to the JScrollPane holding it
silly silly me

Similar Messages

  • JTable has two mouselistener?

    Hi,
    I have a JTable where one column is rendered by JCombobox and other column by JCheckbox. want to have this kind of functionality:
    I clicks several rows while ctrl is pressed (basic functionality) but when I click already selected row it becomes deselected (that is not what I want). So I wrote a mouse adapter to take care of this
    MouseAdapter mouse = new MouseAdapter() {
        public void mouseClicked(MouseEvent e) {
            int ctrlPressed = e.getModifiers()&InputEvent.CTRL_MASK;
            int clickedRow = table.rowAtPoint(e.getPoint());
            //no row
            if( clickedRow == -1 )
                return;
            // ctrl pressed and row clicked so select it
            if (e.getClickCount() == 1 && ctrlPressed == 2 )
                System.out.println("Was already selected "+table.isRowSelected( clickedRow ));
                if( !table.isRowSelected( clickedRow ) )
                    table.addRowSelectionInterval( clickedRow, clickedRow );
                    System.out.println("Row "+clickedRow+" selected");
            if (e.getClickCount() == 2 && ctrlPressed == 2 )
                if( table.isRowSelected( clickedRow ) )
                    System.out.println("Clicked row deselected");
                    table.removeRowSelectionInterval( clickedRow, clickedRow );
    };I add that to my table but when I click deselected row holding ctrl "Was already selected true" is printed. So some other mouselistener noticed before my listener that clicking and selected the row :o
    I tried to remove all mouselisteners with these lines and results was not what I was hoping for :)
    MouseListener[] listenerit = (MouseListener[])(table.getListeners(MouseListener.class));
    System.out.println(listenerit.length+" mouselisteners");
    for(int uu = 0; uu < listenerit.length; uu++)
        System.out.println("This will be removed "+listenerit[uu]);
        table.removeMouseListener(listenerit[uu]);
    System.out.println("There should be nothing: "+table.getMouseListeners());What Im doing wrong?

    So, did my first suggestion work?
    Is there some way to handle mouseclicking with those custom renders? Sure, there is always something you can do but you'll have to tell me more about what happens to the combo or check box when you do what you did with the mouse --e.g., did it go into an edit mode (if so, you should really make the cell editable on two mouse clicks).  Without more info, all I can suggest is for you to look into the JTable's editCellAt method, check to see if editing is being triggered by a mouse event, if so, do something about it there.  Let me emphasize again that I'm suggesting something that I know would work but is considered unconventional or even inappropriate by some experts.
    ;o)
    V.V.

  • MouseListener for JTable cells using html

    Hello,
    I'm trying to write a MouseListener that determines whether the cursor is positioned over a certain string within a JTable cell. The cell contains an html string to allow for some formatting.
    For instance, the table data for a certain cell could be "<html><b>SomeBoldText</b>moreText<html>". I would like to detect when a mouse click occurs on the bold text.
    My current solution is to create the glyph vector corresponding to the cell content stripped of all html tags and then check if the cursor position is within one of the glyphs that form the string. However, that obviously doesn't take into account the formatting done by html, so its not working very well.
    Any suggestions?

    the only way you could possibly do this, if you used JEditorPane as a renderer. even then i'm not sure.

  • JTable and MouseListener

    Hi,
    I am using JSDK 1.3.
    I am seeing some unpredictable behavior when using MouseListener on JTable.
    Here's the problem:
    When I click on row in the table, I am expecting that every time there is a click, application would process mouseClicked() event. However it does not always happen. I would say the event is not being fired about 5-10% of the time. I don't play with mouse listener during table selection. The mouse listener is added only once when seeting up the GUI.
    Does anybody know if this is a bug with Java?
    Thanks,
    Boris

    Hi, I'm a newbie and no expert in this, but I've had to deal with mouse listeners a lot in the past days. Apparently, those are known issues in Java, and sometimes you have to click twice in order to reset the mouse. Take a look at this, hope it helps:
    http://www.javaworld.com/javaworld/javaqa/2000-07/02-qa-0714-mouse.html
    Best,
    Marina.

  • MouseListener on JTable

    I am attempting to trap a mouse click on an editable JTable.
    I have the following set up (csjt is the JTable):
    csjt.addMouseListener ( new MouseAdapter()
         public void mouseClicked ( MouseEvent e )
              System.out.println ("in mouseclicked");
         public void mousePressed ( MouseEvent e )
              System.out.println ("in mousepressed");
         public void mouseReleased ( MouseEvent e )
              System.out.println ("in mousereleased");
    Initially, I had the mouseClicked method, but that was not getting invoked when clicking in the table (specifically, when clicking on an editable column in the table). I added the mousePressed and mouseReleased methods, and the console lines do appear (as expected) when clicking between editable columns in the JTable. While I can certainly trap for either mousePressed or mouseReleased, I am wondering why mouseClicked is not getting invoked???
    Thanks,
    Van Williams

    Hi Van,
    i don't no why your mouseadapter doesn't respond to event, just
    look at code bellow. it works with me.
    import javax.swing.JTable;
    import javax.swing.JScrollPane;
    import javax.swing.JPanel;
    import javax.swing.JFrame;
    import java.awt.*;
    import java.awt.event.*;
    public class SimpleTableDemo extends JFrame {
    public SimpleTableDemo() {
    super("SimpleTableDemo");
    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)},
    {"Mark", "Andrews",
    "Speed reading", new Integer(20), new Boolean(true)},
    {"Angela", "Lih",
    "Teaching high school", new Integer(4), new Boolean(false)}
    String[] columnNames = {"First Name",
    "Last Name",
    "Sport",
    "# of Years",
    "Vegetarian"};
    final JTable table = new JTable(data, columnNames);
    table.setPreferredScrollableViewportSize(new Dimension(500, 70));
    table.addMouseListener(new MouseAdapter() {
    public void mouseClicked(MouseEvent e) {
    printDebugData(table);
    //Create the scroll pane and add the table to it.
    JScrollPane scrollPane = new JScrollPane(table);
    //Add the scroll pane to this window.
    getContentPane().add(scrollPane, BorderLayout.CENTER);
    addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e) {
    System.exit(0);
    private void printDebugData(JTable table) {
    int numRows = table.getRowCount();
    int numCols = table.getColumnCount();
    javax.swing.table.TableModel model = table.getModel();
    System.out.println("Value of data: ");
    for (int i=0; i < numRows; i++) {
    System.out.print(" row " + i + ":");
    for (int j=0; j < numCols; j++) {
    System.out.print(" " + model.getValueAt(i, j));
    System.out.println();
    System.out.println("--------------------------");
    public static void main(String[] args) {
    SimpleTableDemo frame = new SimpleTableDemo();
    frame.pack();
    frame.setVisible(true);

  • Can You Help Me ABout getSelectedRow in JTable

    Can you help me on how to solve my problem about the getSelectedRow .....
    I have one JComboBox and a SearchButton
    ... Once I selected an Item in a JComboBox, I will press the SearchButton
    and then it will look up to the database and display it in the JTable..........
    i used the getSelectedRow to print the value that I selected in the table...
    like this...
    public void mouseClicked(MouseEvent e) {
    // Ilabas yung form
    if(e.getClickCount() == 1 ) {
    System.out.println(table1.getSelectedRow());
    In the first press in the SearchButton and then clicking the row
    , It will print the selected row...... but when i press again the SearchButton then clicking a row again........
    there is a problem occured....... selectedRow is always -1, can you help me to solve this.....

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.sql.*;
    import java.util.*;
    import javax.swing.plaf.metal.*;
    import javax.swing.border.*;
    import javax.swing.table.*;
    import java.text.*;
    import java.beans.*;
    public class OpenProject extends JDialog {
         ResultSet rs, rs1, rs2, rs3;
         JFrame JFParentFrame; // create a JFrame
         JFrame OwnerFrame; // create a JFrame
         public JLabel proj_name;
         public JLabel proj = new JLabel("Project Name:");
         public JLabel form = new JLabel("Form Name");
         public JLabel lang = new JLabel("Language");
         public JComboBox form_lang = new JComboBox();
         public JComboBox form_name = new JComboBox();
         public JButton edit = new JButton("Edit");
         public JButton reload = new JButton("Search");
         public JButton def = new JButton("Set Text Default");
         public JButton langs = new JButton("Add Language");
         public JButton exit = new JButton("Exit");
         public JPanel panel1 = new JPanel ();
         public JTable table1, table2, table3,table4;
         public JScrollPane scrollPane1, scrollPane2, scrollPane3, scrollPane4;
         public JTabbedPane UITab,UITab1;
         Container c = getContentPane();
         Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
         public String column[][];
         public String strRow;
         public String strCol;
         public String strForm;
         public String strGetProj_id;
         public String strForm_lang;
         public String strForm_name;
         private boolean DEBUG = false;
         public int getLang;
         public int getForm;
         public int getDef_id;
         public int count2 = 0,count3 = 0,count4 = 0;
         public int row2 = 0,row3 = 0,row4 = 0;
         public int selectedRow1 = 0, selectedRow2 = 0;
         public DbBean db = new DbBean();
         public OpenProject(JFrame OwnerForm, String getProj_id) {
              super(OwnerForm,true);
                   strGetProj_id = getProj_id;
              try{
                   db.connect();
              } catch(SQLException sqlex) {
              } catch(ClassNotFoundException cnfex) {
              try {
                   UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
              } catch(Exception e) {
              // Para ito sa paglalagay sa dalawang combo box ng value.......
              try {
                   rs = db.execSQL("Select * from mst_form where form_proj_id = "+strGetProj_id+"");
                   while(rs.next()) {
                        form_name.addItem(rs.getString("form_name"));
                        //System.out.println(strForm);
              } catch(SQLException sqlex) {
              try {
                   rs = db.execSQL("Select distinct from mst_form where form_proj_id = "+strGetProj_id+"");
                   while(rs.next()) {
                        form_name.addItem(rs.getString("form_name"));
                        //System.out.println(strForm);
              } catch(SQLException sqlex) {
              try {
                   int counts;
                   rs = db.execSQL("Select * from mst_project where proj_id = "+strGetProj_id+"");
                   while(rs.next()) {
                        counts = rs.getInt("proj_lang_id");
                        System.out.println(counts);
                        rs1 = db.execSQL("Select * from mst_language where lang_id = "+counts+"");
                        while (rs1.next()) {
                             form_lang.addItem(rs1.getString("lang_name"));     
              } catch(SQLException sqlex) {
              edit.setActionCommand("edit");
              edit.addActionListener(actions);
              reload.setActionCommand("load");
              reload.addActionListener(actions);
              def.setActionCommand("default");
              def.addActionListener(actions);
              langs.setActionCommand("lang");
              langs.addActionListener(actions);
              exit.setActionCommand("exit");
              exit.addActionListener(actions);
              proj_name = new JLabel();     
              proj_name.setBackground(new Color(255,255,255));
              form_name.setMaximumRowCount(5);
              form_name.setBackground(new Color(255,255,255));
              form_lang.setMaximumRowCount(5);
              form_lang.setBackground(new Color(255,255,255));
              proj.setBounds(20, 20,100,20);
              proj_name.setBounds(120, 20,250,20);
              form.setBounds(20, 50,100,20);
              form_name.setBounds(120, 50,150,20);
              lang.setBounds(300, 50,100,20);     
              form_lang.setBounds(380, 50,150,20);
              reload.setBounds(560,50,80, 20);
              edit.setBounds(110,360,115,20);
              def.setBounds(230,360,115,20);
              langs.setBounds(350,360,115,20);
              exit.setBounds(470,360,115,20);
              panel1.add(getTable());
              panel1.setLayout(null);     
              panel1.setBackground(Color.white);     
              panel1.add(proj);
              panel1.add(proj_name);
              panel1.add(form);
              panel1.add(form_name);
              panel1.add(lang);
              panel1.add(form_lang);
              panel1.add(reload);     
              panel1.add(def);
              panel1.add(langs);
              panel1.add(exit);
              panel1.add(edit);
              c.add(panel1);
              setSize(680,420);
              setTitle("Open Project");
              setLocation((screen.width - 590)/2,((screen.height - 280)/2) - 45);
         public JTabbedPane getTable() {
              UITab = new JTabbedPane();
              strForm_lang = form_lang.getSelectedItem().toString();
              strForm_name = form_name.getSelectedItem().toString();
              int count1=0;
              int row1=0;
              try {
                   rs = db.execSQL("Select * from mst_default where def_proj_id = '"+strGetProj_id+"' AND def_category = 'Title'" );
                   while(rs.next()) {
                        count1 += 1;
                        getDef_id = rs.getInt("def_id");
                   column = new String[count1][2];
                   rs1 = db.execSQL("Select form_id from mst_form WHERE form_name = '"+strForm_name+"'");
                   while(rs1.next()) {
                        getForm = rs1.getInt("form_id");
                        System.out.println("getForm");
                   rs2 = db.execSQL("Select lang_id from mst_language WHERE lang_name = '"+strForm_lang+"'");
                   while(rs2.next()) {
                        getLang = rs2.getInt("lang_id");
                        System.out.println("getLang");
                   rs3 = db.execSQL("Select * from mst_default a, mst_translation b WHERE a.def_form_id = '"+getForm+"' AND b.trans_lang_id = '"+getLang+"' AND a.def_proj_id = '"+strGetProj_id+"' AND b.trans_def_id = '"+getDef_id+"' AND a.def_category = 'Title' " );
                   while(rs3.next()) {
                        column[row1][0] = "" + rs3.getString("display_name");          // rowNum ay kung ilan ang row na ilalabas
                   column[row1][1] = "" + rs3.getString("translation"); // Default yung isang array ng column ko, kaya fixed
                        row1++;
                   row1 = 0;
              } catch(SQLException sqlex) {
                   sqlex.printStackTrace();
                   System.exit(1);
              // End
              table1 = new JTable(new MyTableModel()){
              scrollPane1 = new JScrollPane(table1);
              UITab.setBounds(30,100,610,250);
              UITab.add("Title",scrollPane1);
              return UITab;
         class MyTableModel extends AbstractTableModel {     
                   // Pagawa ng header Coloumn
                   String ColumnHeaderName[] = {
                        "Default Text",""+strForm_lang+" Translation"
                   //End
                   public int getColumnCount() {     
                        //System.out.println("The Column Count is" + ColumnHeaderName.length);
         return ColumnHeaderName.length;
         public int getRowCount() {
              //System.out.println("The Row Count is" + column.length);
         return column.length;
         public String getColumnName(int col) {
                        //System.out.println("The Column Name is" + ColumnHeaderName[col]);     
         return ColumnHeaderName[col];
         public Object getValueAt(int row,int col) {
              System.out.println("The value at row and column = " + column[row][col]);
         return column[row][col];
         public int getSelectedRow() {
              System.out.println("Integer" + column.length);
              return column.length;
         ActionListener actions = new ActionListener() {
              public void actionPerformed(ActionEvent ae) {
                   String source = ae.getActionCommand();
                   if (source == "load") {
                        table1.clearSelection();
                        panel1.add(getTable());
                        table1.addNotify();
                        repaint();
                   } else if (source == "default") {
                        dispose();
                        TextDefaultForm form = new TextDefaultForm(OwnerFrame,JFParentFrame);
                        form.setVisible(true);
                   } else if (source == "lang") {
                        dispose();
                        CreateProject lang = new CreateProject(JFParentFrame);
                        lang.setVisible(true);
                   } else if (source == "exit") {
                        dispose();
                   } else if (source == "edit") {
                        if (table1.getValueAt(table1.getSelectedRow(),table1.getSelectedColumn()) != null){
                             formLang lang = new formLang(OwnerFrame,strCol,strRow, strGetProj_id);
                             lang.setVisible(true);
         MouseListener MouseTableListener = new MouseListener() {
                   public void mouseClicked(MouseEvent e) {
                        // Ilabas yung form
                        if(e.getClickCount() == 2 ) {
                             dispose();
                             int col_a = 0;
                             int col_b = 1;
                             selectedRow1 = table1.getSelectedRow();     
                             Object objColumn1 = table1.getValueAt(selectedRow1, col_a);
                             Object objRow1 = table1.getValueAt(selectedRow1, col_b);
                             strCol = objColumn1.toString();
                             strRow = objRow1.toString();
                             formLang lang = new formLang(OwnerFrame,strCol,strRow,strGetProj_id);
                             System.out.println(selectedRow1);
                             System.out.println(strCol);
                             System.out.println(strRow);
                             lang.txtProj.setText(strCol);
                             lang.txtLang.setText(strRow);
                             lang.show();
                        } else if (e.getClickCount() == 1) {
                             table1.setSelectionBackground(Color.blue);
                             table1.setColumnSelectionAllowed(false);
                        table1.setRowSelectionAllowed(true);
                        table1.setFocusable(true);
                             int a = table1.getRowCount();
                             System.out.println("Row Count = " + a);
                             int sel = table1.getSelectedRow();     
                             //if (sel == -1) return;
                             System.out.println("Selected Row = " + sel);
                             System.out.println(table1.isRowSelected(sel));
                   public void mouseReleased(MouseEvent e) {
                   public void mouseExited(MouseEvent e) {
                   public void mouseEntered(MouseEvent e) {
                   public void mousePressed(MouseEvent e) {
         //public static void main(String leo[]) {
              //OpenProject open = new OpenProject();
    }

  • Problem with setCursor for JButton in cell on JTable

    i have a problem with setCursor to JButton that is in a cell of the JTable}
    this is the code
    public class JButtonCellRenderer extends JButton implements TableCellRenderer {
    public JButtonCellRenderer() {
    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(Color.WHITE);
    setBorder(null);
    if(table.getValueAt(row,column) == null){
    setText("");
    if(isSelected){
    setBackground(table.getSelectionBackground());
    }else{
    setBackground(Color.WHITE);
    }else{
    if(table.getValueAt(row,column) instanceof JButton){
    JButton _button = (JButton)table.getValueAt(row,column);
    if(_button.getText().trim().equals("")){
    setText("<html>"+ "<font size=\"3\" COLOR=\"#0000FF\"><u><b>Ver...</b></u></font>"+"");
    }else{
    setText("<html>"+ "<font size=\"3\" COLOR=\"#0000FF\"><u><b>" + _button.getText() + "</b></u></font>"+"");
    return this;
    }

    Not quite sure I understand the problem, but I guess you have tried to call setCursor on your renderer and found it didn't work? The reason, I think, is that the renderer only renders a JButton. The thing that ends up in the table is in fact only a "picture" of a JButton, and among other things it won't receive and interact with any events, such as MouseEvents (so it wouldn't know that the cursor should change).
    There are at least two alternatives for you: You can perhaps use a CellEditor instead of a CellRenderer. Or you can add a MouseListener to the table and then use the methods column/rowAtPoint to figure out if the cursor is over your JButton cell and change the cursor yourself if it is.

  • JTable with JComboBox

    Hi friends,
    I am adding JComboBox in JTable its working properly
    But data is not adding dynamically to JComboBox
    I am Sending my Code plz give me reply
    I am Struggleing from 1 week on wards
    package com.dnt.autopopulation;
    import javax.swing.*;
    import java.awt.*;
    import javax.swing.table.JTableHeader;
    import javax.swing.table.TableColumn;
    import java.awt.event.*;
    import javax.swing.JTable;
    import javax.swing.table.DefaultTableModel;
    import javax.swing.event.TableModelEvent;
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.Locale;
    import java.text.SimpleDateFormat;
    import java.util.Vector;
    import javax.swing.border.*;
    import com.dnt.eaip.Connectmagr;
    import com.dnt.eaip.*;
    import com.dnt.util.*;
    import javax.swing.plaf.ButtonUI;
    import com.dnt.admin.EndStartDateCheck;
    import javax.swing.table.TableCellRenderer;
    import javax.swing.table.TableColumnModel;
    public class AutoPopRollBack extends JPanel {
    boolean selection = false;
    public static final int HAND_CURSOR = 12;
    Cursor cursor = new Cursor(HAND_CURSOR);
    int selectedRow = -1;
    ImageIcon headertop1 = new ImageIcon("./images/k2topbar.gif");
    JLabel HeaderLabe = new JLabel(headertop1);
    Border border1 = new EtchedBorder(EtchedBorder.RAISED, Color.white, Color.blue);
    Border border2 = BorderFactory.createBevelBorder(BevelBorder.RAISED,
    new Color(154, 254, 211), new Color(108, 178, 148),
    new Color(37, 60, 50), new Color(53, 87, 72));
    DefaultTableModel dm = new DefaultTableModel();
    Vector searchlist = new Vector();
    Vector rows = new Vector();
    Vector returnList;
    Connectmagr objConnectmagr = new Connectmagr();
    JFrame frame = new JFrame();
    JLabel headlab = new JLabel();
    JCalendarComboBox EndDateTxt;
    JLabel HawbLab = new JLabel();
    JTextField HawbTxt = new JTextField();
    JLabel AgentLab = new JLabel();
    JLabel StartDateLab = new JLabel();
    JCalendarComboBox StartDateTxt;
    JComboBox AgentLBox = new JComboBox();
    JLabel EnddateLab = new JLabel();
    JPanel ReviewJobsPane = new JPanel();
    JButton SearchBtn = new JButton();
    ButtonUI ui = new com.sun.java.swing.plaf.motif.MotifButtonUI();
    ArrayList AgentList = new ArrayList();
    JComboBox DocTypeLBox = new JComboBox();
    JLabel doctypelab = new JLabel();
    JPanel displayPanel = new JPanel();
    ButtonGroup group1;
    JRadioButton rb;
    JTable table;
    public ArrayList jobList = new ArrayList();
    public AutoPopRollBack(JFrame frame, ArrayList agentArrayList) {
    this.frame = frame;
    this.AgentList = agentArrayList;
    try {
    jbInit();
    } catch (Exception e) {
    e.printStackTrace();
    public void jbInit() throws Exception {
    Calendar cal = Calendar.getInstance();
    Locale loc = new Locale("");
    SimpleDateFormat dateformat = new SimpleDateFormat("dd/MM/yyyy");
    EndDateTxt = new JCalendarComboBox(cal, loc, dateformat);
    StartDateTxt = new JCalendarComboBox(cal, loc, dateformat);
    HeaderLabe.setBackground(new Color(250, 233, 216));
    HeaderLabe.setBounds(new Rectangle(0, 0, 830, 33));
    this.setLayout(null);
    this.setBackground(SystemColor.control);
    headlab.setBackground(new Color(250, 233, 216));
    headlab.setFont(new java.awt.Font("Verdana", 1, 12));
    headlab.setForeground(Color.blue);
    headlab.setHorizontalAlignment(SwingConstants.CENTER);
    headlab.setText(" :: Auto Population Rollback");
    headlab.setBounds(new Rectangle(39, 2, 247, 25));
    EndDateTxt.setBounds(new Rectangle(474, 36, 116, 18));
    EndDateTxt.setBackground(Color.white);
    EndDateTxt.setFont(new java.awt.Font("Times New Roman", 1, 10));
    EndDateTxt.setForeground(Color.blue);
    EndDateTxt.setBorder(null);
    HawbLab.setFont(new java.awt.Font("Dialog", 0, 13));
    HawbLab.setForeground(Color.blue);
    HawbLab.setHorizontalAlignment(SwingConstants.RIGHT);
    HawbLab.setText("Job No/Airway Bill No:");
    HawbLab.setBounds(new Rectangle(326, 14, 146, 18));
    HawbTxt.setBounds(new Rectangle(474, 14, 125, 18));
    HawbTxt.setText("");
    HawbTxt.setFont(new java.awt.Font("Times New Roman", 1, 10));
    HawbTxt.setForeground(Color.blue);
    HawbTxt.setBorder(border1);
    AgentLab.setFont(new java.awt.Font("Dialog", 0, 13));
    AgentLab.setForeground(Color.blue);
    AgentLab.setHorizontalAlignment(SwingConstants.RIGHT);
    AgentLab.setText("<html>Agent:<font size=\'4\' color=\"#993333\">*</font></html>");
    AgentLab.setBounds(new Rectangle(31, 14, 97, 18));
    StartDateLab.setFont(new java.awt.Font("Dialog", 0, 13));
    StartDateLab.setForeground(Color.blue);
    StartDateLab.setHorizontalAlignment(SwingConstants.RIGHT);
    StartDateLab.setText("Start Date:");
    StartDateLab.setBounds(new Rectangle(23, 36, 105, 18));
    StartDateTxt.setBounds(new Rectangle(129, 36, 116, 18));
    StartDateTxt.setBackground(Color.white);
    StartDateTxt.setFont(new java.awt.Font("Times New Roman", 1, 10));
    StartDateTxt.setForeground(Color.blue);
    StartDateTxt.setBorder(null);
    AgentLBox.setBackground(Color.white);
    AgentLBox.setFont(new java.awt.Font("Verdana", 0, 13));
    AgentLBox.setForeground(Color.blue);
    AgentLBox.setBounds(new Rectangle(129, 14, 178, 18));
    AgentLBox.setFont(new java.awt.Font("Times New Roman", 1, 10));
    EnddateLab.setFont(new java.awt.Font("Dialog", 0, 13));
    EnddateLab.setForeground(Color.blue);
    EnddateLab.setHorizontalAlignment(SwingConstants.RIGHT);
    EnddateLab.setText("End Date:");
    EnddateLab.setBounds(new Rectangle(391, 36, 81, 18));
    ReviewJobsPane.setBackground(new Color(240, 233, 216));
    ReviewJobsPane.setBorder(BorderFactory.createLineBorder(Color.black));
    ReviewJobsPane.setBounds(new Rectangle(69, 47, 705, 96));
    ReviewJobsPane.setLayout(null);
    SearchBtn.setUI(ui);
    SearchBtn.setCursor(cursor);
    SearchBtn.setBackground(new Color(76, 125, 104));
    SearchBtn.setBounds(new Rectangle(377, 153, 89, 19));
    SearchBtn.setFont(new java.awt.Font("Tahoma", 1, 10));
    SearchBtn.setForeground(Color.white);
    SearchBtn.setBorder(border2);
    SearchBtn.setOpaque(true);
    SearchBtn.setFocusPainted(false);
    SearchBtn.setText("Search");
    SearchBtn.addActionListener(new AutoPopRollBack_SearchBtn_actionAdapter(this));
    for (int i = 0; i < AgentList.size(); i++)
    AgentLBox.addItem( (String) AgentList.get(i));
    DocTypeLBox.setFont(new java.awt.Font("Verdana", 0, 13));
    DocTypeLBox.setForeground(Color.blue);
    DocTypeLBox.setMinimumSize(new Dimension(22, 19));
    DocTypeLBox.setBounds(new Rectangle(129, 58, 179, 18));
    DocTypeLBox.setFont(new java.awt.Font("Times New Roman", 1, 10));
    DocTypeLBox.addItem("New Jobs");
    DocTypeLBox.addItem("Draft jobs");
    DocTypeLBox.addItem("Finished jobs");
    doctypelab.setBounds(new Rectangle(7, 58, 121, 18));
    doctypelab.setText("<html>Document Type:<font size=\'4\' color=\"#993333\">*</font></html>");
    doctypelab.setHorizontalAlignment(SwingConstants.RIGHT);
    doctypelab.setForeground(Color.blue);
    doctypelab.setFont(new java.awt.Font("Dialog", 0, 13));
    displayPanel.setBorder(BorderFactory.createLineBorder(Color.black));
    displayPanel.setBounds(new Rectangle(69, 182, 705, 315));
    this.add(headlab, null);
    this.add(HeaderLabe, null);
    this.add(ReviewJobsPane, null);
    ReviewJobsPane.add(HawbLab, null);
    ReviewJobsPane.add(AgentLab, null);
    ReviewJobsPane.add(AgentLBox, null);
    ReviewJobsPane.add(StartDateLab, null);
    ReviewJobsPane.add(StartDateTxt, null);
    ReviewJobsPane.add(HawbTxt, null);
    ReviewJobsPane.add(EnddateLab, null);
    ReviewJobsPane.add(EndDateTxt, null);
    ReviewJobsPane.add(DocTypeLBox, null);
    ReviewJobsPane.add(doctypelab, null);
    this.add(SearchBtn, null);
    this.add(displayPanel, null);
    //this.add(scrollPaneView, null);
    // scrollPaneView.getViewport().add(displayPanel, null);
    this.setVisible(true);
    void FieldEditable(boolean str) {
    StartDateTxt.setEnabled(str);
    EndDateTxt.setEnabled(str);
    public static void main(String args[]) {
    JFrame frame = new JFrame();
    ArrayList agentlist = new ArrayList();
    agentlist.add(0, "BF0651");
    agentlist.add(1, "PF0010");
    AutoPopRollBack objAutoPopRollBack = new AutoPopRollBack(frame, agentlist);
    frame.getContentPane().add(objAutoPopRollBack);
    frame.setBounds(new Rectangle(0, 0, 820, 593));
    frame.setVisible(true);
    void SearchBtn_actionPerformed(ActionEvent e) {
    displayPanel.setVisible(false);
    Vector data=new Vector();
    rows.removeAllElements();
    boolean flag = true;
    String che = new EndStartDateCheck().crossCheck(StartDateTxt.getCalendar(), EndDateTxt.getCalendar());
    try {
    if(HawbTxt.getText().equalsIgnoreCase("")){
    if (StartDateTxt._spinner.getText().equalsIgnoreCase("")) {
    JOptionPane.showMessageDialog(this, "Please Select Start Date",
    "Warning", JOptionPane.WARNING_MESSAGE);
    flag = false;
    else if (!che.equalsIgnoreCase("")) {
    JOptionPane.showMessageDialog(frame, che, "Message Window", JOptionPane.INFORMATION_MESSAGE);
    flag = false;
    }else{
    FieldEditable(true);
    if (flag) {
    try {
    displayPanel.removeAll();
    } catch (Exception ex) {
    rows.removeAllElements();
    data.removeAllElements();
    SearchBtn.setEnabled(true);
    searchlist.add(0, AgentLBox.getSelectedItem().toString().trim());
    if (!HawbTxt.getText().trim().equalsIgnoreCase(""))
    searchlist.add(1, HawbTxt.getText().toString().trim());
    else
    searchlist.add(1, "");
    searchlist.add(2, new Integer(DocTypeLBox.getSelectedIndex() + 1));
    String startDate = new ConvertDate().convertddMM_To_MMdd(StartDateTxt._spinner.getText());
    String endDate = new ConvertDate().convertddMM_To_MMdd(EndDateTxt._spinner.getText());
    Vector columns = new Vector();
    columns.add(0, "");
    columns.add(1, "JOB No");
    columns.add(2, "Status");
    columns.add(3, "Current Form Type");
    columns.add(4, "New Form Type");
    System.out.println("Before calling Data Base");
    jobList = objConnectmagr.AutoRollBackSearch(searchlist, startDate, endDate, "AutoPopRollBack");
    if (jobList.size() > 0) {
    for (int i = 0; i < jobList.size(); i++) {
    ArrayList temp = new ArrayList();
    temp = (ArrayList) jobList.get(i);
    Vector col = new Vector();
    col.add(0, new Boolean(false));
    col.add(1, temp.get(0).toString().trim());
    col.add(2, temp.get(1).toString().trim());
    col.add(3, temp.get(2).toString().trim());
    Vector tempstr=new Vector();
    String [] tem=temp.get(3).toString().trim().split("\\|");
    tempstr.removeAllElements();
    for(int k=0;k<tem.length;k++)
    tempstr.add(k,tem[k]);
    col.add(4, new JComboBox(tempstr));
    data.add(col);
    dm.setDataVector(data, columns);
    table = new JTable(dm) {
    public void tableChanged(TableModelEvent e) {
    super.tableChanged(e);
    public boolean isCellEditable(int rowIndex, int vColIndex) {
    return true;
    JScrollPane scroll = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    table.setColumnSelectionAllowed(false);
    table.setRowSelectionAllowed(false);
    table.setCellSelectionEnabled(false);
    table.setBackground(SystemColor.inactiveCaptionText);
    table.setRowHeight(20);
    JTableHeader head = table.getTableHeader();
    head.setSize(850, 75);
    table.setTableHeader(head);
    table.getTableHeader().setFont(new Font("Verdana", Font.BOLD, 11));
    table.getTableHeader().setBackground(new Color(130, 170, 150));
    table.getTableHeader().setForeground(Color.BLUE);
    table.getTableHeader().setReorderingAllowed(false);
    table.getTableHeader().setResizingAllowed(false);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
    table.setFont(new java.awt.Font("MS Sans Serif", 0, 13));
    table.setForeground(new Color(125, 25, 0));
    TableColumn col = table.getColumnModel().getColumn(0);
    col.setMinWidth(75);
    col.setMaxWidth(75);
    TableColumn col1 = table.getColumnModel().getColumn(1);
    col1.setMinWidth(150);
    col1.setMaxWidth(150);
    TableColumn col2 = table.getColumnModel().getColumn(2);
    col2.setMinWidth(150);
    col2.setMaxWidth(150);
    TableColumn col3 = table.getColumnModel().getColumn(3);
    col3.setMinWidth(150);
    col3.setMaxWidth(150);
    TableColumn col4 = table.getColumnModel().getColumn(4);
    col4.setMinWidth(160);
    col4.setMaxWidth(160);
    TableColumn tc = table.getColumnModel().getColumn(0);
    tc.setCellEditor(table.getDefaultEditor(Boolean.class));
    tc.setCellRenderer(table.getDefaultRenderer(Boolean.class));
    tc.setHeaderRenderer(new CheckBoxHeader(new MyItemListener()));
    Vector tempstr=new Vector();
    for(int j=0;j<jobList.size();j++){
    ArrayList temlist=(ArrayList)jobList.get(j);
    String [] tem=temlist.get(3).toString().trim().split("\\|");
    tempstr.removeAllElements();
    for(int k=0;k<tem.length;k++)
    tempstr.add(k,tem[k]);
    JComboBox portTypesCombo = new JComboBox(tempstr);
    col4.setCellEditor(new DefaultCellEditor(portTypesCombo));
    col4 = table.getColumnModel().getColumn(4);
    col4.setCellEditor(new MyComboBoxEditor(tempstr));
    // If the cell should appear like a combobox in its
    // non-editing state, also set the combobox renderer
    col4.setCellRenderer(new MyComboBoxRenderer(tempstr));
    System.out.println(tempstr);
    displayPanel.setLayout(new BorderLayout());
    displayPanel.add(table.getTableHeader(), BorderLayout.PAGE_START);
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    table.addMouseListener(new MouseAdapter() {
    public void mouseClicked(MouseEvent e) {
    table.setEditingColumn(0);
    int column = 0;
    if (e.getClickCount() == 1) {
    Point p = e.getPoint();
    selectedRow = table.rowAtPoint(p);
    column = table.columnAtPoint(p);
    System.out.println(table.isCellEditable(selectedRow, column));
    if (column != 0) {
    selectedRow = -1;
    returnList = new Vector();
    returnList = (Vector) rows.get(selectedRow);
    else if (column == 0) {
    table.revalidate();
    table.repaint();
    scroll.getViewport().add(table);
    displayPanel.add(scroll, BorderLayout.CENTER);
    displayPanel.setVisible(true);
    else {
    JOptionPane.showMessageDialog(this, "No Data Available");
    } catch (Exception e1) {
    e1.printStackTrace();
    class MyItemListener implements ItemListener {
    public void itemStateChanged(ItemEvent e) {
    Object source = e.getSource();
    if (source instanceof AbstractButton == false)return;
    boolean checked = e.getStateChange() == ItemEvent.SELECTED;
    for (int x = 0, y = table.getRowCount(); x < y; x++) {
    table.setValueAt(new Boolean(checked), x, 0);
    class AutoPopRollBack_SearchBtn_actionAdapter implements java.awt.event.ActionListener {
    AutoPopRollBack adaptee;
    AutoPopRollBack_SearchBtn_actionAdapter(AutoPopRollBack adaptee) {
    this.adaptee = adaptee;
    public void actionPerformed(ActionEvent e) {
    adaptee.SearchBtn_actionPerformed(e);
    class RadioButtonRenderer implements TableCellRenderer {
    public Component getTableCellRendererComponent(JTable table, Object value,
    boolean isSelected, boolean hasFocus, int row, int column) {
    if (value == null)return null;
    return (Component) value;
    class RadioButtonEditor extends DefaultCellEditor implements ItemListener {
    private JRadioButton button;
    public RadioButtonEditor(JCheckBox checkBox) {
    super(checkBox);
    public Component getTableCellEditorComponent(JTable table, Object value,
    boolean isSelected, int row,
    int column) {
    if (value == null)return null;
    button = (JRadioButton) value;
    button.addItemListener(this);
    return (Component) value;
    public Object getCellEditorValue() {
    button.removeItemListener(this);
    return button;
    public void itemStateChanged(ItemEvent e) {
    super.fireEditingStopped();
    class CheckCellRenderer extends JCheckBox implements TableCellRenderer {
    protected static Border m_noFocusBorder;
    public CheckCellRenderer() {
    super();
    m_noFocusBorder = new EmptyBorder(1, 2, 1, 2);
    setOpaque(true);
    setBorder(m_noFocusBorder);
    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
    int row, int column) {
    if (value instanceof Boolean) {
    Boolean b = (Boolean) value;
    setSelected(b.booleanValue());
    setBackground(isSelected && !hasFocus ?
    table.getSelectionBackground() : table.getBackground());
    setForeground(isSelected && !hasFocus ?
    table.getSelectionForeground() : table.getForeground());
    setFont(table.getFont());
    setBorder(hasFocus ? UIManager.getBorder(
    "Table.focusCellHighlightBorder") : m_noFocusBorder);
    return this;
    class CheckBoxHeader extends JCheckBox implements TableCellRenderer, MouseListener {
    protected CheckBoxHeader rendererComponent;
    protected int column;
    protected boolean mousePressed = false;
    public CheckBoxHeader(ItemListener itemListener) {
    rendererComponent = this;
    rendererComponent.addItemListener(itemListener);
    public Component getTableCellRendererComponent(
    JTable table, Object value,
    boolean isSelected, boolean hasFocus, int row, int column) {
    if (table != null) {
    JTableHeader header = table.getTableHeader();
    if (header != null) {
    rendererComponent.setForeground(header.getForeground());
    rendererComponent.setBackground(header.getBackground());
    rendererComponent.setFont(new java.awt.Font("Verdana", 1, 10));
    header.addMouseListener(rendererComponent);
    setColumn(column);
    rendererComponent.setText("Select All");
    setBorder(UIManager.getBorder("TableHeader.cellBorder"));
    return rendererComponent;
    protected void setColumn(int column) {
    this.column = column;
    public int getColumn() {
    return column;
    protected void handleClickEvent(MouseEvent e) {
    if (mousePressed) {
    mousePressed = false;
    JTableHeader header = (JTableHeader) (e.getSource());
    JTable tableView = header.getTable();
    TableColumnModel columnModel = tableView.getColumnModel();
    int viewColumn = columnModel.getColumnIndexAtX(e.getX());
    int column = tableView.convertColumnIndexToModel(viewColumn);
    if (viewColumn == this.column && e.getClickCount() == 1 && column != -1) {
    doClick();
    public void mouseClicked(MouseEvent e) {
    handleClickEvent(e);
    ( (JTableHeader) e.getSource()).repaint();
    public void mousePressed(MouseEvent e) {
    mousePressed = true;
    public void mouseReleased(MouseEvent e) {
    public void mouseEntered(MouseEvent e) {
    public void mouseExited(MouseEvent e) {
    class MyComboBoxRenderer extends JComboBox implements TableCellRenderer {
    public MyComboBoxRenderer(Vector items) {
    super(items);
    public Component getTableCellRendererComponent(JTable table, Object value,
    boolean isSelected, boolean hasFocus, int row, int column) {
    if (isSelected) {
    setForeground(table.getSelectionForeground());
    super.setBackground(table.getSelectionBackground());
    else {
    setForeground(table.getForeground());
    setBackground(table.getBackground());
    // Select the current value
    setSelectedItem(value);
    return this;
    class MyComboBoxEditor extends DefaultCellEditor {
    public MyComboBoxEditor(Vector items) {
    super(new JComboBox(items));
    and Bringing data from data base by using this method
    if (i == 0) sqlString = "SELECT * FROM FLIGHTSEARCH WHERE AGENT_CODE='" + agentCode + "' and ISSUEDATE BETWEEN '" + startDate + "' and '" + endDate + "'";
    else sqlString = "SELECT * FROM FLIGHTSEARCH WHERE AGENT_CODE='" + agentCode + "' and JOB_NO='" + JobNo + "%'";
    st = con.createStatement();
    System.out.println("---new jobs search-->" + sqlString);
    rs = st.executeQuery(sqlString);
    while (rs.next()) {
    retVector = new ArrayList();
    retVector.add(0, rs.getString("JOBNO"));
    retVector.add(1, "New Job");
    retVector.add(2, rs.getString("DOC_TYPE"));
    String temp="";
    if(retVector.get(2).toString().trim().equalsIgnoreCase("K1")){
    temp="K8I|K8T";
    }else if(retVector.get(2).toString().trim().equalsIgnoreCase("K2")){
    temp="K8E";
    }else if(retVector.get(2).toString().trim().equalsIgnoreCase("K8I")){
    // temp="K1|K8T";
    }else if(retVector.get(2).toString().trim().equalsIgnoreCase("K8T")){
    temp="K1|K8I";
    }else if(retVector.get(2).toString().trim().equalsIgnoreCase("K8E")){
    temp="K2";
    retVector.add(3,temp);
    retVector.add(3, rs.getString("AGENT_CODE"));
    retVectorlist.add(retVector);
    i am sending data To ComboBox like this
    if(retVector.get(2).toString().trim().equalsIgnoreCase("K1")){
    K8I and K8T
    if K2 adding k8E and for other types as mentioned above
    But for ComboBoxes it is showing same Items not changing
    Please any body can help to me
    Thanks and Regards
    Ravichandra

    If you want further help post a Short, Self Contained, Compilable and Executable, Example Program ([url http://homepage1.nifty.com/algafield/sscce.html]SSCCE) that demonstrates the problem.
    And don't forget to use [url http://forum.java.sun.com/help.jspa?sec=formatting]code formatting when posting code.

  • Mouselistner is not working with jtable in the browser

    Hi
    I am having a problem with jTable.
    I added a mouselistener to table header to sort table but when i run that applet from my netbean ide it works fine but when i run that applet in my browser it doesn't work, i have tested, its not even generate mouseclick event .Please help me guys.
    I call this function after calling initComponents() method of JApplet.
    public void setTableAction()
    //set mouselistener to sort table on click of table header
    final JTableHeader head= jTable1.getTableHeader();
    head.addMouseListener(new java.awt.event.MouseAdapter()
    public void mouseClicked(java.awt.event.MouseEvent evt)
    Vector data= ((DefaultTableModel)jTable1.getModel ()).getDataVector();
    sortTable(data, head.columnAtPoint(evt.getPoint()));
    //set action map to change the default action performed for enter key pressed
    InputMap imap = jTable1.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
    KeyStroke enterKey = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
    KeyStroke tabKey = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0);
    final Action oldAction= jTable1.getActionMap().get(imap.get(tabKey)); // get map to set enter key.
    imap.put(enterKey, "enter"); // set enter key
    Action newAction = new AbstractAction(){
    public void actionPerformed(ActionEvent e) {
    oldAction.actionPerformed(e);
    JTable table= (JTable)e.getSource();
    table.changeSelection(0,0,false,false);
    if(table.isCellEditable(0,0))
    String sTemp= (String)table.getValueAt(0,0);
    if(sTemp.length()>0) {
    if(bRenewItem)
    retrieveRcodeDetails("",sTemp);
    else
    processRCodeDetails(sTemp, e);
    }else
    table.editCellAt(0,0);
    jTable1.getActionMap().put("enter", newAction);
    jTable1.setPreferredScrollableViewportSize(jTable1.getPreferredSize());
    }

    Hi,
    I also am using the Bépo layout with an encrypted drive and encountered the same problem: the Return key does not work.
    It seems to work fine if you use the fr-bepo-latin9 keymap.
    # /etc/vconsole.conf
    KEYMAP=fr-bepo-latin9
    But I also looked at the files /usr/share/kbd/keymaps/i386/bepo/fr-bepo.map.gz and /usr/share/kbd/keymaps/i386/bepo/fr-bepo-latin9.map.gz (you can open gzipped files in vim directly). fr-bepo-latin9.map.gz defines keycode 28 (Return) but fr-bepo.map.gz does not.
    I modified fr-bepo.map.gz:
    # vim /usr/share/kbd/keymaps/i386/bepo/fr-bepo.map.gz # Append that line : "keycode 28 = Return".
    # mkinitcpio -p linux # Rebuild the initramfs.
    The Return key now works, but the Backspace (14, "Delete") and Shift (54) keys don’t work. I found that both the cf.map.gz (french canadian layout) and fr-bepo-latin9.map.gz files define those keycodes as well as other non-printing keys so I copied the following lines from fr-bepo-latin9.map.gz to fr-bepo.map.gz:
    keycode 1 = Escape Escape
    keycode 14 = Delete Delete
    keycode 15 = Tab Tab
    keycode 28 = Return
    keycode 29 = Control
    keycode 42 = Shift
    keycode 54 = Shift
    keycode 56 = Alt
    keycode 58 = Caps_Lock
    keycode 97 = Control
    It works! Don’t forget to rebuild the initramfs after you change the keymap file.
    # mkinitcpio -p linux
    I will send a message to the kbd and bépo projects mailing lists and report back.

  • How can i implement a mouse listener event on jtable cell?

    I create JTable using a resultset,at the end of each row i add an image using JLabel(set imageicon of the JLabel).
    i want to track the event when user click on that image.
    What can i do for that?.
    I tried by implementing mouseListener interface for the JLabel but it's not working properly.

    Hi,
    Add MouseListener to the JTable.
    when the user clicks on the table use the method
    getValueAt( int selectedRow,int selectedColumn) to get the contents.
    Object obj = getValueAt( int selectedRow,int selectedColumn) .
    (If obj instance of JLabel)
    do your functionality.
    Hope this helps
    Cheers :)
    Nagaraj

  • Add button to a JTable

    i added a button a Jtable.but am not able to dispatch the mouse click event to the button. I am not seeing any change in the button when clicked....its not getting the focus. the code is as below:
    class TableButtonMouseListener implements MouseListener {
    private JTable table;
    private void forwardEventToButton(MouseEvent e) {
    TableColumnModel columnModel = table.getColumnModel();
    int column = columnModel.getColumnIndexAtX(e.getX());
    System.out.println("column "+column);
    int row = e.getY() / table.getRowHeight();
    System.out.println("row "+row);
    Object value;
    JButton button;
    MouseEvent buttonEvent;
    if(row >= table.getRowCount() || row < 0 ||
    column >= table.getColumnCount() || column < 0)
    return;
    value = table.getValueAt(row, column);
    if(!(value instanceof JButton))
    return;
    button = (JButton)value;
    buttonEvent =(MouseEvent)SwingUtilities.convertMouseEvent(table, e, button);
    button.dispatchEvent(buttonEvent);
    // This is necessary so that when a button is pressed and released
    // it gets rendered properly. Otherwise, the button may still appear
    // pressed down when it has been released.
    table.repaint();
    public TableButtonMouseListener(JTable table) {
    this.table = table;
    public void mouseClicked(MouseEvent e) {
    forwardEventToButton(e);
    public void mouseEntered(MouseEvent e) {
    //forwardEventToButton(e);
    public void mouseExited(MouseEvent e) {
    //forwardEventToButton(e);
    public void mousePressed(MouseEvent e) {
    forwardEventToButton(e);
    public void mouseReleased(MouseEvent e) {
    forwardEventToButton(e);
    pls help ....

    -> I am a first time user.that is y....
    What does that have to do with anything. As a first time user you should take the time to learn how to use the forum. In any forum, not just this one, it is common sense to search first before asking questions.
    -> but can u pls tell me y the button is nt getting the event
    Did you read the JTable API? It has a link to the Swing tutorial that explains how tables work. You need to understand the section on renderers. In general a renderer is a drawing of the button, it is not a real button so it doesn't receive events.
    The problem has nothing to do with the TableModel.

  • 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

  • Adding a MouseListener to a JFrame

    I want my JFrame to be notified when a cell in a JTable is double clicked (so I can do some processing and then close the frame).
    I thought I could add a MouseListener to the JFrame. However, the JTable processes, then consumes, the mouse event so the JTable never receives the MouseEvent. I attempted to override the processMouseEvent method of JTable to dispatch an event to the JFrame, but it didn't work as the event was sent back to the JTable.
    Here is the simple program I am using to test my problem. (Note, in the real application the JFrame, contains class1, which contains class2, which contains the JTable, so it not simply a matter of the JTable invoking a method in the JFrame class.
    import java.awt.*;
    import java.awt.event.*;
    import java.util.*;
    import javax.swing.*;
    import javax.swing.table.*;
    public class MouseTable extends JFrame
         JFrame frame;
         public MouseTable()
              frame = this;
              JTable table = new JTable(4, 3)
                   protected void processMouseEvent(MouseEvent e)
                        System.out.println( "Click count: " + e.getClickCount() );
                        super.processMouseEvent(e);
                        //  this event is dispatched back to here, not the frame
                        if (e.getClickCount() == 2)
                             MouseEvent me =
                             new MouseEvent(frame, e.getID(), 0, 0, 0, 0, 9, false);
                             frame.dispatchEvent(me);
              JScrollPane scrollPane = new JScrollPane( table );
              getContentPane().add( scrollPane );
              frame.addMouseListener( new MouseAdapter()
                   public void mouseClicked(MouseEvent e)
                        System.out.println("Clicked: " + e);
         public static void main(String[] args)
              MouseTable frame = new MouseTable();
              frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
              frame.pack();
              frame.setVisible(true);
    }1) Click on the viewport, the JFrame receives the mouse event
    2) Click on the JTable, the JFrame does not receive the mouse event
    Any ideas on why the dispatchEvent doesn't work?
    Any other better approaches?

    I did read the documentation correctly. The ID field should represent the mouse event you want to generate. Here are the ids:
    MOUSE_CLICKED = 500
    MOUSE_PRESSED = 501
    MOUSE_RELEASED = 502
    MOUSE_MOVED = 503
    MOUSE_ENTERED = 504
    MOUSE_EXITED = 505
    In my simple example I used the following condition to dispatch an event to the JFrame:
    if (e.getClickCount() == 2)
    When I changed the condition to the following (which is what I really want), the program stops working:
    if (e.getID() == MouseEvent.MOUSE_CLICKED && e.getClickCount() == 2)
    The bottom line is that it appears the mouse event is still dispatched to the JTable even though the JFrame is specified as the object source. I gave up trying to figure out why.
    However, all is not lost as I have found a better(?) way to accomplish what I want. In the constructor of my JFrame I add an AWTListener to listen for double click events:
    //  Listen for mouse double clicks directly from the AWT Event Queue
    Toolkit.getDefaultToolkit().addAWTEventListener( new AWTEventListener()
         public void eventDispatched(AWTEvent e)
              if (e.getID() == MouseEvent.MOUSE_CLICKED)
                   MouseEvent me = (MouseEvent)e;
                   if (me.getClickCount() == 2)
                        doProcessingHere();
    }, AWTEvent.MOUSE_EVENT_MASK  );

  • Must click then click and drag for JTable Drag and Drop

    Hi All,
    I've been using Java 1.4 to drag and drop data between two tables in our application. Basically I need to drag the data from individual rows of the source table and insert it into one of the cells in the new table. This works absolutely fine and has made a huge improvement to this portion of our app. I've included example source code below that does a similar thing by transferring data from one table and inserting it into another (it's quite big and also not as well done as the example in our real app but unfortunately I can't send the source for that).
    The thing I've noticed though is that in order to start dragging data I need to click to select it and then press and hold the mouse button to start dragging, whereas under W**dows and just about every other OS you can just press and hold and start dragging straight away. If you try this with a JTable though it just changes the rows you have selected so the drag and drop works but feels a bit clunky and amateurish. I'd like to do something about this such that it works like Windows Explorer (or similar) where you can just press the mouse button and start dragging.
    Any help would be greatly appreciated - and if anybody finds the code useful you're more than welcome to it. Note that the business end of this is CustomTransferHandler.java - this will show you how to insert data at a specific position in a JTable, it's a bit of a faff but not too bad once you've got it sussed.
    Thanks,
    Bart Read
    ===============================================================
    TestFrame.java
    * TestFrame.java
    * Created on October 21, 2002, 4:59 PM
    import java.awt.*;
    import java.awt.datatransfer.*;
    import java.awt.dnd.*;
    import java.awt.event.*;
    import java.util.TooManyListenersException;
    import javax.swing.*;
    * @author  readb
    public class TestFrame extends javax.swing.JFrame
         private static final String [] NAMES     = {
              "John", "Geoff", "Madeleine", "Maria", "Flanders",
              "Homer", "Marge", "Bart", "Lisa", "Weird Baby" };
         private JTable source;
         private JTable dest;
         private MyTableModel     sourceModel;
         private MyTableModel     destModel;
         private Clipboard          clipboard;
         /** Creates a new instance of TestFrame */
         public TestFrame()
              clipboard = getToolkit().getSystemClipboard();
              Container c = getContentPane();
              c.setLayout( new BorderLayout( 40, 40 ) );
              source = new MyJTable();
              sourceModel = new MyTableModel();
              source.setModel( sourceModel );
              source.setDragEnabled( true );
              CustomTransferHandler handler = new CustomTransferHandler( "Source handler" );
              source.setTransferHandler( handler );
              try
                   source.getDropTarget().addDropTargetListener( handler );
              catch ( TooManyListenersException tmle )
                   tmle.printStackTrace();
              dest = new MyJTable();
              destModel = new MyTableModel();
              dest.setModel( destModel );
              dest.setDragEnabled( true );
              handler = new CustomTransferHandler( "Dest handler" );
              dest.setTransferHandler( handler );
              try
                   dest.getDropTarget().addDropTargetListener( handler );
              catch ( TooManyListenersException tmle )
                   tmle.printStackTrace();
              c.add( new JScrollPane( source ), BorderLayout.WEST );
              c.add( new JScrollPane( dest ), BorderLayout.EAST );
              populate();
         private void populate( MyTableModel model )
              for ( int index = 0; index < NAMES.length; ++index )
                   model.setRow( index, new DataRow( index + 1, NAMES[ index ] ) );
         private void populate()
              populate( sourceModel );
              populate( destModel );
         public static void main( String [] args )
              TestFrame app = new TestFrame();
              app.addWindowListener(
                   new WindowAdapter() {
                        public void windowClosing( WindowEvent we )
                             System.exit( 0 );
              app.pack();
              app.setSize( 1000, 600 );
              app.show();
         private class MyJTable extends JTable
              public boolean getScrollableTracksViewportHeight()
                   Component parent = getParent();
                   if (parent instanceof JViewport)
                        return parent.getHeight() > getPreferredSize().height;
                   return false;
    }=====================================================================
    MyTableModel.java
    * MyTableModel.java
    * Created on October 21, 2002, 4:43 PM
    import java.util.ArrayList;
    * @author  readb
    public class MyTableModel extends javax.swing.table.AbstractTableModel
         private static final int          NUMBER               = 0;
         private static final int          NAME               = 1;
         private static final String []     COLUMN_HEADINGS     = { "Number", "Name" };
         private ArrayList data;
         /** Creates a new instance of MyTableModel */
         public MyTableModel()
              super();
              data = new ArrayList();
         public int getColumnCount()
              return COLUMN_HEADINGS.length;
         public String getColumnName( int index )
              return COLUMN_HEADINGS[ index ];
         public Class getColumnClass( int index )
              switch ( index )
                   case NUMBER:
                        return Integer.class;
                   case NAME:
                        return String.class;
                   default:
                        throw new IllegalArgumentException( "Illegal column index: " + index );
         public int getRowCount()
              return ( null == data ? 0 : data.size() );
         public Object getValueAt( int row, int column )
              DataRow dataRow = ( DataRow ) data.get( row );
              switch ( column )
                   case NUMBER:
                        return new Integer( dataRow.getNumber() );
                   case NAME:
                        return dataRow.getName();
                   default:
                        throw new IllegalArgumentException( "Illegal column index: " + column );
         public void addRow( DataRow row )
              int rowIndex = data.size();
              data.add( row );
              fireTableRowsInserted( rowIndex, rowIndex );
         public void addRows( DataRow [] rows )
              int firstRow = data.size();
              for ( int index = 0; index < rows.length; ++index )
                   data.add( rows[ index ] );
              fireTableRowsInserted( firstRow, data.size() - 1 );
         public void setRow( int index, DataRow row )
              if ( index == data.size() )
                   data.add( row );
              else
                   data.set( index, row );
              fireTableRowsUpdated( index, index );
         public void insertRows( int index, DataRow [] rows )
              for ( int rowIndex = rows.length - 1; rowIndex >= 0; --rowIndex )
                   data.add( index, rows[ rowIndex ] );
              fireTableRowsInserted( index, index + rows.length - 1 );
         public DataRow getRow( int index )
              return ( DataRow ) data.get( index );
         public DataRow removeRow( int index )
              DataRow retVal = ( DataRow ) data.remove( index );
              fireTableRowsDeleted( index, index );
              return retVal;
         public boolean removeRow( DataRow row )
              int index = data.indexOf( row );
              boolean retVal = data.remove( row );
              fireTableRowsDeleted( index, index );
              return retVal;
         public void removeRows( DataRow [] rows )
              for ( int index = 0; index < rows.length; ++index )
                   data.remove( rows[ index ] );
              fireTableDataChanged();
    }=====================================================================
    DataRow.java
    * DataRow.java
    * Created on October 21, 2002, 4:41 PM
    import java.io.Serializable;
    * @author  readb
    public class DataRow implements Serializable
         private int          number;
         private String     name;
         /** Creates a new instance of DataRow */
         public DataRow( int number, String name )
              this.number = number;
              this.name = name;
         public int getNumber()
              return number;
         public String getName()
              return name;
         public String toString()
              return String.valueOf( number ) + ": " + name;
    }======================================================================
    CustomTransferHandler.java
    * CustomTransferHandler.java
    * Created on October 22, 2002, 8:36 AM
    import java.awt.*;
    import java.awt.datatransfer.Clipboard;
    import java.awt.datatransfer.ClipboardOwner;
    import java.awt.datatransfer.DataFlavor;
    import java.awt.datatransfer.Transferable;
    import java.awt.datatransfer.UnsupportedFlavorException;
    import java.awt.dnd.*;
    import java.awt.event.InputEvent;
    import java.io.IOException;
    import java.util.Arrays;
    import javax.swing.Icon;
    import javax.swing.ImageIcon;
    import javax.swing.JComponent;
    import javax.swing.JTable;
    import javax.swing.TransferHandler;
    * @author  readb
    public class CustomTransferHandler
                   extends TransferHandler
                   implements Transferable, ClipboardOwner, DropTargetListener
         public static final DataFlavor     ROW_ARRAY_FLAVOR     = new DataFlavor( DataRow[].class, "Multiple rows of data" );
         private String               name;
         private ImageIcon          myIcon;
         private     DataRow []          data;
         private boolean               clipboardOwner                    = false;
         private int                    rowIndex                         = -1;
         /** Creates a new instance of CustomTransferHandler */
         public CustomTransferHandler( String name )
              this.name = name;
         public boolean canImport( JComponent comp, DataFlavor [] transferFlavors )
              System.err.println( "CustomTransferHandler::canImport" );
              if ( comp instanceof JTable && ( ( JTable ) comp ).getModel() instanceof MyTableModel )
                   for ( int index = 0; index < transferFlavors.length; ++index )
                        if ( ! transferFlavors[ index ].equals( ROW_ARRAY_FLAVOR ) )
                             return false;
                   return true;
              else
                   return false;
         protected Transferable createTransferable( JComponent c )
              System.err.println( "CustomTransferHandler::createTransferable" );
              if ( ! ( c instanceof JTable ) || ! ( ( ( JTable ) c ).getModel() instanceof MyTableModel ) )
                   return null;
              this.data = null;
              JTable               table     = ( JTable ) c;
              MyTableModel     model     = ( MyTableModel ) table.getModel();
              Clipboard          cb          = table.getToolkit().getSystemClipboard();
              cb.setContents( this, this );
              clipboardOwner = true;
              int [] selectedRows = table.getSelectedRows();
              Arrays.sort( selectedRows );
              data = new DataRow[ selectedRows.length ];
              for ( int index = 0; index < data.length; ++index )
                   data[ index ] = model.getRow( selectedRows[ index ] );
              return this;
         public void exportAsDrag( JComponent comp, InputEvent e, int action )
              super.exportAsDrag( comp, e, action );
              Clipboard          cb          = comp.getToolkit().getSystemClipboard();
              cb.setContents( this, this );
         protected void exportDone( JComponent source, Transferable data, int action )
              System.err.println( "CustomTransferHandler::exportDone" );
              if ( TransferHandler.MOVE == action && source instanceof JTable && ( ( JTable ) source ).getModel() instanceof MyTableModel )
                   JTable table = ( JTable ) source;
                   MyTableModel model = ( MyTableModel ) table.getModel();
                   int [] selected = table.getSelectedRows();
                   for ( int index = selected.length - 1; index >= 0; --index )
                        model.removeRow( selected[ index ] );
         public void exportToClipboard( JComponent comp, Clipboard clip, int action )
              System.err.println( "CustomTransferHandler::exportToClipboard" );
         public int getSourceActions( JComponent c )
              System.err.println( "CustomTransferHandler::getSourceActions" );
              if ( ( c instanceof JTable ) && ( ( JTable ) c ).getModel() instanceof MyTableModel )
                   return MOVE;
              else
                   return NONE;
          *     I've commented this out because it doesn't appear to work in any case.
          *     The image isn't null but as far as I can tell this method is never
          *     invoked.
    //     public Icon getVisualRepresentation( Transferable t )
    //          System.err.println( "CustomTransferHandler::getVisualRepresentation" );
    //          if ( t instanceof CustomTransferHandler )
    //               if ( null == myIcon )
    //                    try
    //                         myIcon = new ImageIcon( getClass().getClassLoader().getResource( "dragimage.gif" ) );
    //                    catch ( Exception e )
    //                         System.err.println( "CustomTransferHandler::getVisualRepresentation: exception loading image" );
    //                         e.printStackTrace();
    //                    if ( null == myIcon )
    //                         System.err.println( "CustomTransferHandler::getVisualRepresentation: myIcon is still NULL" );
    //               return myIcon;
    //          else
    //               return null;
         public boolean importData( JComponent comp, Transferable t )
              System.err.println( "CustomTransferHandler::importData" );
              super.importData( comp, t );
              if ( ! ( comp instanceof JTable ) )
                   return false;
              if ( ! ( ( ( JTable ) comp ).getModel() instanceof MyTableModel ) )
                   return false;
              if ( clipboardOwner )
                   return false;
              if ( !t.isDataFlavorSupported( ROW_ARRAY_FLAVOR ) )
                   return false;
              try
                   data = ( DataRow [] ) t.getTransferData( ROW_ARRAY_FLAVOR );
                   return true;
              catch ( IOException ioe )
                   data = null;
                   return false;
              catch ( UnsupportedFlavorException ufe )
                   data = null;
                   return false;
         public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException
              System.err.println( "MyTransferable::getTransferData" );
              if ( flavor.equals( ROW_ARRAY_FLAVOR ) )
                   return data;
              else
                   throw new UnsupportedFlavorException( flavor );
         public DataFlavor[] getTransferDataFlavors()
              System.err.println( "MyTransferable::getTransferDataFlavors" );
              DataFlavor [] flavors = new DataFlavor[ 1 ];
              flavors[ 0 ] = ROW_ARRAY_FLAVOR;
              return flavors;
         public boolean isDataFlavorSupported( DataFlavor flavor )
              System.err.println( "MyTransferable::isDataFlavorSupported" );
              return flavor.equals( ROW_ARRAY_FLAVOR );
         public void lostOwnership( Clipboard clipboard, Transferable transferable )
              clipboardOwner = false;
         /** Called while a drag operation is ongoing, when the mouse pointer enters
          * the operable part of the drop site for the <code>DropTarget</code>
          * registered with this listener.
          * @param dtde the <code>DropTargetDragEvent</code>
         public void dragEnter(DropTargetDragEvent dtde)
         /** Called while a drag operation is ongoing, when the mouse pointer has
          * exited the operable part of the drop site for the
          * <code>DropTarget</code> registered with this listener.
          * @param dte the <code>DropTargetEvent</code>
         public void dragExit(DropTargetEvent dte)
         /** Called when a drag operation is ongoing, while the mouse pointer is still
          * over the operable part of the drop site for the <code>DropTarget</code>
          * registered with this listener.
          * @param dtde the <code>DropTargetDragEvent</code>
         public void dragOver(DropTargetDragEvent dtde)
         /** Called when the drag operation has terminated with a drop on
          * the operable part of the drop site for the <code>DropTarget</code>
          * registered with this listener.
          * <p>
          * This method is responsible for undertaking
          * the transfer of the data associated with the
          * gesture. The <code>DropTargetDropEvent</code>
          * provides a means to obtain a <code>Transferable</code>
          * object that represents the data object(s) to
          * be transfered.<P>
          * From this method, the <code>DropTargetListener</code>
          * shall accept or reject the drop via the
          * acceptDrop(int dropAction) or rejectDrop() methods of the
          * <code>DropTargetDropEvent</code> parameter.
          * <P>
          * Subsequent to acceptDrop(), but not before,
          * <code>DropTargetDropEvent</code>'s getTransferable()
          * method may be invoked, and data transfer may be
          * performed via the returned <code>Transferable</code>'s
          * getTransferData() method.
          * <P>
          * At the completion of a drop, an implementation
          * of this method is required to signal the success/failure
          * of the drop by passing an appropriate
          * <code>boolean</code> to the <code>DropTargetDropEvent</code>'s
          * dropComplete(boolean success) method.
          * <P>
          * Note: The data transfer should be completed before the call  to the
          * <code>DropTargetDropEvent</code>'s dropComplete(boolean success) method.
          * After that, a call to the getTransferData() method of the
          * <code>Transferable</code> returned by
          * <code>DropTargetDropEvent.getTransferable()</code> is guaranteed to
          * succeed only if the data transfer is local; that is, only if
          * <code>DropTargetDropEvent.isLocalTransfer()</code> returns
          * <code>true</code>. Otherwise, the behavior of the call is
          * implementation-dependent.
          * <P>
          * @param dtde the <code>DropTargetDropEvent</code>
         public void drop(DropTargetDropEvent dtde)
              System.err.println( "CustomTransferHandler::drop" );
              Component c = dtde.getDropTargetContext().getDropTarget().getComponent();
              if ( ! ( c instanceof JComponent ) )
                   dtde.rejectDrop();
                   return;
              JComponent comp = ( JComponent ) c;
              if ( ! ( c instanceof JTable ) || ! ( ( ( JTable ) c ).getModel() instanceof MyTableModel ) )
                   dtde.rejectDrop();
                   return;
              dtde.acceptDrop( TransferHandler.MOVE );
              //     THIS is such a mess -- you can't do the following because
              //     getTransferable() throws an (undocumented) exception - what's that
              //     all about.
    //          Transferable t = dtde.getTransferable();
    //               if ( !t.isDataFlavourSupported( ROW_ARRAY_FLAVOR ) )
    //                    dtde.rejectDrop();
    //                    return false;
    //          TransferHandler handler = comp.getTransferHandler();
    //          if ( null == handler || ! handler.importData( comp, t ) )
    //               dtde.rejectDrop();
    //               return;
              Point p = dtde.getLocation();
              JTable table = ( JTable ) comp;
              rowIndex = table.rowAtPoint( p );
              //     So you have to do this instead and use the data that's been
              //     stored in the data member via import data.  Total mess.
              if ( null == data )
                   dtde.rejectDrop();
                   return;
              MyTableModel model = ( MyTableModel ) table.getModel();
              if ( rowIndex == -1 )
                   model.addRows( data );
              else
                   model.insertRows( rowIndex, data );
              dtde.acceptDrop( TransferHandler.MOVE );
         /** Called if the user has modified
          * the current drop gesture.
          * <P>
          * @param dtde the <code>DropTargetDragEvent</code>
         public void dropActionChanged(DropTargetDragEvent dtde)
    }

    Hi again,
    Well I've tried using the MouseListener / MouseMotionListener approach but it doesn't quite seem to work, although it does get the events correctly. I think the reason is that it doesn't interact correctly with the Java DnD machinery which is something that V.V hinted at. It's something that I may need to look into if / when I have more time available.
    I have to say though that I haven't had any problems with scrollbars - we're making fairly heavy use of large tables and if you drag over a table with a scroll bar and move to the top or bottom then it scrolls as you would expect and allows you to drop the data where you like. For this situation I've used pretty much the same approach as for the toy example above except that I've implemented separate source and destination TransferHandlers (the source table is read-only, and it really doesn't make sense to allow people to drag from the destination table so I've essentially split the functionality of the example handler down the middle).
    I'm not actually particularly in favour of messing too much with the mechanics of DnD, more because of lack of time than anything else. Guess I'll just have to put up with this for the moment. Doesn't help that DnD is so poorly documented by Sun.
    Thanks for all your help.
    Bart

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

Maybe you are looking for