• Post Reply Bookmark Topic Watch Topic
  • New Topic

Field JTable not editable

 
Daan Heuvelbeuk
Ranch Hand
Posts: 67
MySQL Database Netscape Windows XP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In my application I have a JTable that displays data from the database. The user should only edit the (time spend on a task) fields of the last column of the table:


The data for the table row is stored in a Project object. I retrieve it with a project.getTime(), which returns java.sql.Time. The data on the time spend is converted from Project to row by:

The problem I have with this solution is that I can not edit the Time field. Am I missing something or should I convert the time to a String and write my own Cell renderer?

 
Maneesh Godbole
Bartender
Posts: 11445
18
Android Eclipse IDE Google Web Toolkit Java Mac Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The ability to edit is driven by the model's method isCellEditable(int rowIndex, int columnIndex)
One point to note here is AbstractTableModel returns false where as the default implementation DefaultTableModel returns true! You need to check which model you are using.

Recommended reading for renderer/editor : https://docs.oracle.com/javase/tutorial/uiswing/components/table.html#editrender
 
Daan Heuvelbeuk
Ranch Hand
Posts: 67
MySQL Database Netscape Windows XP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Maneesh Godbole wrote:T
One point to note here is AbstractTableModel returns false where as the default implementation DefaultTableModel returns true! You need to check which model you are using.


Alas, I extend the DefaultTableModel.
 
Maneesh Godbole
Bartender
Posts: 11445
18
Android Eclipse IDE Google Web Toolkit Java Mac Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Daan Heuvelbeuk wrote:
Alas, I extend the DefaultTableModel.

Huh? That means your table is editable. Even if you had extended the abstract model, you can still override this to return true.
 
Daan Heuvelbeuk
Ranch Hand
Posts: 67
MySQL Database Netscape Windows XP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Maneesh Godbole wrote:
Daan Heuvelbeuk wrote:
Alas, I extend the DefaultTableModel.

Huh? That means your table is editable.


Nope. It is not editable. That's the point.

Despite my class extending the DefaultTableModel and I explicitly state that the field is editable, it is not editable.

Some more code from the class:


Some logging:

And although I was clicking in the cell I wanted to change, I could not change it.
 
Maneesh Godbole
Bartender
Posts: 11445
18
Android Eclipse IDE Google Web Toolkit Java Mac Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Daan Heuvelbeuk wrote:
And although I was clicking in the cell I wanted to change, I could not change it.

Ah! But you need to click twice. This is 'as designed' (I suspect the sun engineers wanted to ensure your clicking for row selection was not being confused with the clicking for editing)
You do have the ability to change this. Check out DefaultCellEditor#setClickCountToStart(int clickCount);
 
Daan Heuvelbeuk
Ranch Hand
Posts: 67
MySQL Database Netscape Windows XP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Maneesh Godbole wrote:
Ah! But you need to click twice.


Alas, again. Even after double clicking I was not able to edit the field:


 
Maneesh Godbole
Bartender
Posts: 11445
18
Android Eclipse IDE Google Web Toolkit Java Mac Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Strange!
Please try out this code and let us know if it works for you. Only the date column values should be editable (after 2 clicks)



If it works, you can compare it with your code and see what's different and try to figure out what's going wrong. If nothing else works, please post your SSCCE like I did.
 
Daan Heuvelbeuk
Ranch Hand
Posts: 67
MySQL Database Netscape Windows XP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That worked. However ...


... does not work.

And to thicken the plot, when I changed the code back (by prepending double slashes // before the code, and changing
back to
I was not able to change the 'III' cels. When I copied your copy back and compiled it again, it worked as it shoud.

So what causes the error?
 
Maneesh Godbole
Bartender
Posts: 11445
18
Android Eclipse IDE Google Web Toolkit Java Mac Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Daan Heuvelbeuk wrote:
So what causes the error?

Questions you should be asking yourself
1) What class object does DateFormat.format(date); return?
2) Are you returning the correct class in getColumnClass(int col)
 
Daan Heuvelbeuk
Ranch Hand
Posts: 67
MySQL Database Netscape Windows XP
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Maneesh Godbole wrote:
1) What class object does DateFormat.format(date); return?
2) Are you returning the correct class in getColumnClass(int col)


Ehm... Now my academic (non) understanding of Java might cause me misunderstanding your question. I'm more of a seat of the pants developer. So your questions might be a tiny bit of a challenge for me. But let my try to answer your questions:
  • What class object does DateFormat.format(date); return?
  • Quoting the JavaDoc: "Gets the time formatter with the given formatting style for the given locale".

  • Are you returning the correct class in getColumnClass(int col)
  • As far as I know I do, as the [tt] getColumnClass(int col)'s returns a DateFormat.class; and when adding the time field to the table a timeFormatter.format(project.getTime() is added, which is of type DateFormat.

    Caveat emptor:
    I get a java.time.sql object from my database. In my logging this comes out as '16:01:39'. Earlier I wrote it as something like project.getTime().toString();. That obviously displayed the time field as String, not as a "Time object". I thought it best to rework the code so the default TableCellRenderer would handle users entering wrong formatted data into the cell. I probably choose the wrong objects to be placed in the cell, resulting in the cell not being editable anymore. But what should I choose to get some TableCellRenderer checking on the entry of my users? Write my own?
     
    Rob Camick
    Ranch Hand
    Posts: 2699
    10
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    You need to understand the difference between "data" and the way the data is displayed (rendered).

    For example you can store an Integer in the TableModel. Assume the value of the Integer is 123456. The data can then be displayed as 1234567, or it can be displayed as 1,234,567 so that it is better formatted.

    Same with a Date. The data is the actual Date, so you display the data as YYYY-MM-DD or DD/MM/YYYY etc.

    In your case the timeFormatter.format(date) returns a String representation of the Date, so the data in the TableModel is a String, not a DateFormat. So if you want to continue along this approach the getColumnClass needs to return a String.class. However, using this approach the user will be able to enter any string into the cell (not just a proper date format.

    So the better approach is to store a Date object in the TableModel and then you need to provide a "renderer" to format the Date for display.

    Table Format Renderer shows how you can create a simple renderer.

    Now when you edit the date you will get the default editor which will simple display a toString() representation of the Date. The user can change the date and the editor will parse the String to recreate a valid Date object.

    If you don't like the way the date is presented in the editor, then you will need to provide a custom editor. Read the Swing tutorial on Editors and Renderers.
     
    Daan Heuvelbeuk
    Ranch Hand
    Posts: 67
    MySQL Database Netscape Windows XP
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Rob Camick wrote:Table Format Renderer shows how you can create a simple renderer.

    <SNIP>

    If you don't like the way the date is presented in the editor, then you will need to provide a custom editor. Read the Swing tutorial on Editors and Renderers.


    Thanks.
     
    Daan Heuvelbeuk
    Ranch Hand
    Posts: 67
    MySQL Database Netscape Windows XP
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I must have the dumbs. I can't get it to work.



    I get the following logging when the JTable is shown on my desktop:


    In lines 27 and 37 I add the objects from my database to the JTable. However, I get an IllegalArgumentException. I tried it with DateFormatter in lines 47 and 55, but got the same result. I think I'm Date/Time challenged
     
    Rob Camick
    Ranch Hand
    Posts: 2699
    10
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Here is the code used to create the image found in the blog link I provided you with showing how to use the custom renderers:

     
    Daan Heuvelbeuk
    Ranch Hand
    Posts: 67
    MySQL Database Netscape Windows XP
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Rob Camick wrote:Here is the code used to create the image found in the blog link I provided you with showing how to use the custom renderers.


    Thanks for the code. It was very enlightening. Eventually I found out I made a mistake. Now the code runs. But still, I can not edit the Date and Time fields. The method isCellEditable(int rowIndex, int columnIndex) now returns true for all columns. And as far as I know that is the only place that decides what cells are editable.
     
    Rob Camick
    Ranch Hand
    Posts: 2699
    10
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Did you run my code? The Date is editable. As I explained you get a toString() representation of the Date to edit.

    You haven't posted your SSCCE demonstrating the problem, so we can't help.
     
    Daan Heuvelbeuk
    Ranch Hand
    Posts: 67
    MySQL Database Netscape Windows XP
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    My code as is:


    And some logging:

    Hope someone seeds what goes wrong.
     
    Daan Heuvelbeuk
    Ranch Hand
    Posts: 67
    MySQL Database Netscape Windows XP
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Rob Camick wrote:You haven't posted your SSCCE demonstrating the problem, so we can't help.


    The following piece of code demonstrates my predicament. The first two columns are not editable:

    I used the following FormatRederer:

     
    Rob Camick
    Ranch Hand
    Posts: 2699
    10
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    You are using an SQL Date, which won't work.

    The default editor needs to be able to take the String entered in the text field and create a new instance of the Object. SQL Date does not support the date format displayed in the editor.

    That is why I stated that if you don't like the way a Date is displayed in the editor, then you need to create a custom editor. I gave you a link to the JTable tutorial.

    If you want the date to be displayed as YYYY-MM-DD then your custom editor needs to take a String of that format and then convert it to a Date object to be stored in the model.

    Here is an example of a format editor to be used with the renderer:

     
    Daan Heuvelbeuk
    Ranch Hand
    Posts: 67
    MySQL Database Netscape Windows XP
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Rob Camick wrote:You are using an SQL Date, which won't work.

    The default editor needs to be able to take the String entered in the text field and create a new instance of the Object. SQL Date does not support the date format displayed in the editor.

    That is why I stated that if you don't like the way a Date is displayed in the editor, then you need to create a custom editor. I gave you a link to the JTable tutorial.

    If you want the date to be displayed as YYYY-MM-DD then your custom editor needs to take a String of that format and then convert it to a Date object to be stored in the model.


    Thanks.

    I changed the formatting of the date field to SimpleDateFormat format = new SimpleDateFormat("H:mm:ss");, as I'm interested in the Time (as duration). The date is set in another part of the program. When set the date will not change. The time (duration) is changeable by the user. Now I only have to translate my java.sql.Time to java.util.Date and visa versa.
     
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!