Don't want cells in a JTable to receive focus

In a class that extends JTable, I am creating a table that uses a DefaultTableModel.  I need this table to be dynamic so I can load files and add records that are stored in those files and then allow the user to add records at runtime (all of this works).  My question is...how can I get the cells to not receive focus?  What I'm trying to do is receive a double click action.  The double click works, but ONLY if you double click on the "cell separators" - because when you double click on a cell, the first click gives focus to the cell so a double click on a cell isn't possible.

Below is the code I am currently using (again, this works fine, but double clicking doesn't work too well):
-----------------------------------------
setPreferredScrollableViewportSize(new Dimension(750, 550));
setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
setRowSelectionAllowed(true);

dtm = new DefaultTableModel(columnNames, 0);

TableSorter sorter = new TableSorter(dtm);
sorter.addMouseListenerToHeaderInTable(this);

//addMouseListener(this);
addMouseListener(new MouseAdapter() {
     public void mouseClicked(MouseEvent e) {
          if (e.getClickCount() == 2) {
               System.out.println("double click");
          }
     }
} );

setModel(sorter);
-----------------------------------------

I found that I could use an AbstractTableModel to do what I want - but then it doesn't look like an ATM can give a dynamic table.

Thanks!

Chris

p.s. - sorry about the points - this is all i have left!  If this turns out to be kinda difficult, I will give you more points when I get some :)
ctjoumasAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

OviCommented:
Try this (you will need to images: file.gif and folder.gif in the same directory as your classes):

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.Vector;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;

public class FileSystemView extends JFrame {
  private SystemView table;

  public FileSystemView() {
    getContentPane().setLayout(new BorderLayout());
    setSize(400, 300);
    setLocation(300, 100);
    table = new SystemView();
    getContentPane().add(new JScrollPane(table), BorderLayout.CENTER);
    setVisible(true);
  }

  class SystemView extends JTable {
    SystemViewModel model;

    public SystemView() {
      model = new SystemViewModel();
      setAutoCreateColumnsFromModel(false);
      loadDirectory("c:");
      setModel(model);
      createColumns();
      setGridColor(Color.white);
      setForeground(Color.black);
      setBackground(Color.white);
      setSelectionBackground(Color.black);
      setSelectionForeground(Color.white);
      addMouseListener(new TableMouseAdapter(this, model));
    }

    protected void loadDirectory(String dir) {
      Vector v = new Vector();
      File f = new File(dir);
      File[] files = f.listFiles();
      for(int i = 0; i < files.length; i++) {
        FileElement fe = new FileElement();
        fe.setFile(files[i]);
        v.addElement(fe);
      }
      model.addData(v);
    }

    protected void loadDirectory(File f) {
      Vector v = new Vector();
      File[] files = f.listFiles();
      for(int i = 0; i < files.length; i++) {
        FileElement fe = new FileElement();
        fe.setFile(files[i]);
        v.addElement(fe);
      }
      model.addData(v);
    }

    protected void createColumns() {
      for(int i = 0; i<model.cols.length; i++) {
        DefaultTableCellRenderer renderer = new FileRenderer();
        renderer.setHorizontalAlignment(model.cols[i].alignment);
        TableColumn column = new TableColumn(i, model.cols[i].width, renderer, null);
        setFont(new Font ("MicrosoftSanSerif", Font.PLAIN, 12));
        addColumn(column);
      }
    }
  }

  class TableMouseAdapter extends MouseAdapter {
    SystemView table;
    SystemViewModel model;
    public TableMouseAdapter(SystemView t, SystemViewModel m){table = t;model = m;}
    public void mouseClicked(MouseEvent e) {// simple update the path
      if(e.getClickCount()==2) {//execute the LS (or the program in the next future)
        int row = table.getSelectedRow();
        File file = model.getFileAt(row);
        if(file.isDirectory())
          table.loadDirectory(file);
        return;
      }
    }
  }

  class SystemViewModel extends AbstractTableModel {
    protected ColumnDescriptor cols[] =  {
      new ColumnDescriptor("Name", 40, JLabel.LEFT),
      new ColumnDescriptor("Size", 50, JLabel.LEFT),
    };
    protected Vector fileObjects;

    public SystemViewModel() {
      fileObjects = new Vector();
    }

    public void addData(Vector v) {
      fileObjects.removeAllElements();
      for(int i = 0; i<v.size(); i++) {
        fileObjects.addElement(v.elementAt(i));
      }
      updateObjects();
    }
    public File getFileAt(int row) {return(((FileElement)fileObjects.elementAt(row)).file);}
    protected void updateObjects() {fireTableDataChanged();}
    public int getColumnCount() {return(cols.length);}
    public int getRowCount() {return(fileObjects.size());}
    public String getColumnName(int c) {return(cols[c].name);}

    public Object getValueAt(int row, int col) {
      if(getRowCount() <= 0)
        return "";
      if(row<0||row>=getRowCount())
        return "";
      Object o = fileObjects.elementAt(row);
      if(o instanceof FileElement) {
        FileElement fd = (FileElement) o;
        switch(col) {
          case 0: return fd.getName();
          case 1: return new Long(fd.getSize());
        }
      }
      return "";
    }

    class ColumnDescriptor {
      public String name;public int width;public int alignment;
      public ColumnDescriptor(String n, int w, int a) {name = n;width = w;alignment = a;}
    }
  }

  class FileUI {
    public ImageIcon icon = null;private String fileName;
    public FileUI(ImageIcon img, String fn) {icon = img;fileName = fn;}
    public String getFileName() {return(fileName);}
    public String toString() {return(fileName);}
  }

  public class FileElement {
    private File file;
    private long size;
    private FileUI name = null;

    public FileElement() {}

    public void setFile(File f) {
      ImageIcon icon = null;
      file = f;
      if(f.isDirectory())
        icon = new ImageIcon(FileSystemView.this.getClass().getResource("folder.gif"));
      else
        icon = new ImageIcon(FileSystemView.this.getClass().getResource("file.gif"));
      name = new FileUI(icon, f.getName());
      long size = f.length();
    }

    public long getSize() {return(size);}
    public FileUI getName() {return (name);}
    public boolean isDirectory() {return(file.isDirectory());}
  }

  public class FileRenderer extends DefaultTableCellRenderer {
    public void setValue(Object cell) {
      setFont(new Font ("MicrosoftSanSerif", Font.PLAIN, 12));
      if(cell instanceof FileUI) {
        FileUI fui = (FileUI)cell;
        setIcon(fui.icon);
        setText(fui.getFileName());
        setToolTipText(fui.getFileName());
      }
      else {
        super.setValue(cell);
        setToolTipText(cell.toString());
      }
    }
  }
  public static void main(String[] args) {FileSystemView t = new FileSystemView();}
}
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ctjoumasAuthor Commented:
Hmm... basically, the SystemViewModel that you have is what I want.  I don't really need any of the other things.  My program already saves and loads info to and from a file...  and I can add and delete records.  I'm trying to mess with the SystemViewModel and integrate it into my program....all I need is to change my DefaultTableModel to the AbstractTableModel so that I can't "select" a cell.

I will be trying to fix this - but you seem to be a lot more knowledgable about Java than me, so if you can possibly help me with just the SystemViewModel and make this a lot less confusing for me, I thank you very much :)  So, I guess i just need the SystemViewModel to add, delete, and retrieve records for me.  I think I am close - it is just adding blank records (and about 8 of them) right now!

Thanks,

Chris
0
ctjoumasAuthor Commented:
One question i have is - im not so sure what the fileObjects vector is doing.  Is this vector being "put" to the table?  If so...how is it doing this?  So, if I have 7 fields (or columns) in one record and I want to add this record - how can I add this to the table?

Thanks,

Chris
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

ctjoumasAuthor Commented:
One question i have is - im not so sure what the fileObjects vector is doing.  Is this vector being "put" to the table?  If so...how is it doing this?  So, if I have 7 fields (or columns) in one record and I want to add this record - how can I add this to the table?

Thanks,

Chris
0
ctjoumasAuthor Commented:
One question i have is - im not so sure what the fileObjects vector is doing.  Is this vector being "put" to the table?  If so...how is it doing this?  So, if I have 7 fields (or columns) in one record and I want to add this record - how can I add this to the table?

Thanks,

Chris
0
ctjoumasAuthor Commented:
oops..sorry about the multiple posts!
0
ctjoumasAuthor Commented:
OK...  I have gotten it to add the correct amount of rows now... basically,  the addData function looks like:

public void addData(Vector v) {
    table.add(v.toArray());
    fireTableRowsInserted(table.size(), table.size()+1);
}

where table is my table vector - it contains all of the data that the table shows.  So, my thinking is, that the vector v that is sent to addData contains the customer record (a vector of size 7...which contains the 7 elements of each of the 7 columns I have) and this is added to my table vector...and when I fireTableRowsInserted, this vector v should now show up as a new row in the table.

However, this doesn't happen.  A new row appears, but it is empty.  I don't get any errors or anything..

Chris
0
ctjoumasAuthor Commented:
For the most part - what you gave me helped...it is doing what I want it to do.  But, when I add a row, no data gets added - just a blank row is added.  Is there some way I need to "link" my data vector into my table model?  I think I'm missing something simple.

Thanks,

Chris
0
OviCommented:
Sorry for absence!
0
OviCommented:
try with fireTableDataChanged() instead of rowsAdded. Follow my source code and see if it works. There is a method call on every model metod which modify the internal data, called updateObjects(). Focus on that one.
0
ctjoumasAuthor Commented:
I have already tried fireTableDataChanged() :)  Here is the code I am working with right now (i've left out unimportant methods and library imports...):

----------------------------
public class RecordsTable extends JTable {

  /**
   * Handle to the parent application object.
   */  
  private HelpDesk helpDeskObj;

  private RecordsViewModel rvm = null;

  public RecordsTable(HelpDesk helpDesk) {

    dtm = new RecordsViewModel();

    addMouseListener(new MouseAdapter() {
      public void mouseClicked(MouseEvent e) {
        if (e.getClickCount() == 2) {
       System.out.println("double click");
     }
      }
    });

    setModel(rvm);
  }

  // this gets called from another class, which
  // passes in a vector that holds the customer data
  public void addRow(Vector record) {
    rvm.addData(record);
  }
}


class RecordsViewModel extends AbstractTableModel {

  protected ColumnDescriptor cols[] =  {
    new ColumnDescriptor("FirstName", 40, JLabel.LEFT),
    new ColumnDescriptor("LastName", 50, JLabel.LEFT),
    new ColumnDescriptor("Phone", 50, JLabel.LEFT),
    new ColumnDescriptor("City", 50, JLabel.LEFT),
    new ColumnDescriptor("State", 50, JLabel.LEFT),
    new ColumnDescriptor("Street", 50, JLabel.LEFT),
    new ColumnDescriptor("Notes", 50, JLabel.LEFT),
    new ColumnDescriptor("WorkOrder", 50, JLabel.LEFT),
  };

  private Vector table;

  public RecordsViewModel() {
    table = new Vector();
  }  

  public void addData(Vector v) {
    table.addElement(v);
    fireTableDataChanged();
  }

  class ColumnDescriptor {
    public String name;
    public int width;
    public int alignment;

    public ColumnDescriptor(String n, int w, int a) {
      name = n;
      width = w;
      alignment = a;
    }
  }
}
----------------------------


Thanks,

Chris
0
ctjoumasAuthor Commented:
Sorry, the line:
dtm = new RecordsViewModel();

is:
rvm = new RecordsViewModel();

Just letting you know that that isn't hte problem :)

Thanks,

Chris
0
OviCommented:
I see that uou are holding a Vector of vectors structure into your model. In my original code there was a dedicated object to actually represent a row in the table/model, called FileElement. Check your getValueAt(int row, int col) method in your model.
0
ctjoumasAuthor Commented:
Ah...ok - that was my problem.  I didn't know that getValueAt gets called when displaying (or adding) a record.  I need to read up somewhere (Hopefully Java's API has explanations) on how all this works together!

Thanks!!

Chris
0
OviCommented:
Yes, the methods are called

Eg: getValueAt() request the value of a particular cell
getColumnName() should return the column name stored by your collumns array
getColumnCount should return columns.length
getRowCount should return table.size()
... and so on ...
0
ctjoumasAuthor Commented:
Gotcha..  thank you very much and sorry I didn't have any more points to give you!
0
OviCommented:
no problem, sorry for late feedback :-)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.