• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Paul Clapham
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Roland Mueller
  • Piet Souris
Bartenders:

Is there a way to show an image in a JTable as a thumbnail?

 
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
As one column in my JTable I want to display an image in thumbnail size, the intent is for the viewer to click on the image which will then open a full-size view. I don't want to create two images (thumbnail and full size), is it possible to tell the JTable to reduce the size of the image to, say, 50x50?

Here is the table entry as it currently exists:



Thanks,

Mike
 
Sheriff
Posts: 22862
132
Eclipse IDE Spring TypeScript Quarkus Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Check out how TableCellRenderers work. By default, for Icon, it returns a JLabel that contains the image. I'm sure you can use that to your advantage.
 
Mike Lipay
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rob Prime wrote:Check out how TableCellRenderers work. By default, for Icon, it returns a JLabel that contains the image. I'm sure you can use that to your advantage.



If I knew how to resize and image, it might. I have been looking at the renderers and haven't seen anything about sizing an image.
 
Mike Lipay
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Lipay wrote:

Rob Prime wrote:Check out how TableCellRenderers work. By default, for Icon, it returns a JLabel that contains the image. I'm sure you can use that to your advantage.



If I knew how to resize and image, it might. I have been looking at the renderers and haven't seen anything about sizing an image.




I think I need to find a new forum, one made for beginners. I work 90% in the mainframe arena, just dabbling with Java, which makes Java a bit harder to pick up. Sun's java docs are cryptic to me, so I need more help than just "read the tablecellrenderer docs". You guys are good, but too far above to provide the kind of help I need.
 
Rob Spoor
Sheriff
Posts: 22862
132
Eclipse IDE Spring TypeScript Quarkus Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
We try to let you find the answers yourself first, nudging you a bit in the right direction. So here's another nudge: Graphics.drawImage is overloaded to take a width and height. You now have several options:

1) create a BufferedImage:

2) Sub class a JLabel and override its paintComponent to draw the image. It's a bit unconventional though.

3) create your own implementation of Icon which you then add to the table. Your TableModel must return Icon.class for the column. This icon implementation is quite easy:
- getIconWidth() and getIconHeight() return the thumbnail size
- paintIcon paints the image with the custom size on the Graphics object.


Personally, I'd go for option 1. The scaling may take a long time, and if you use options 2 or 3 you may end up performing the same scaling operation over and over, each time the cells are repainted.
 
Bartender
Posts: 5167
11
Netbeans IDE Opera Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rob Prime wrote:
2) Sub class a JLabel and override its paintComponent to draw the image. It's a bit unconventional though.


Bit of a nitpick, but if you're going to override paintComponent there's really no point in extending JLabel, might as well extend JPanel or JComponent.

A fourth approach could be to create a ThumbnailIcon class. Code typed here, may have typos or other bugs ;)

Instead of the ImageIcons, the ThumbnailIcons could be pre-constructed and cached in the TableModel. Returning Icon.class from getColumnClass() would use the default Icon renderer to display them, no need of a custom renderer.
 
Rob Spoor
Sheriff
Posts: 22862
132
Eclipse IDE Spring TypeScript Quarkus Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Isn't that the same as option 3 - a custom Icon implementation?
 
Darryl Burke
Bartender
Posts: 5167
11
Netbeans IDE Opera Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rob Prime wrote:Isn't that the same as option 3 - a custom Icon implementation?


I'm really sorry, Rob, I don't know how I missed reading your response thoroughly
 
Mike Lipay
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Worked (50%)

I'm not sure why the second image shows up blank (first image shows up fine), can someone try this and see whether there is something wrong with the image?






 
Rob Spoor
Sheriff
Posts: 22862
132
Eclipse IDE Spring TypeScript Quarkus Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Not with this little information. You should post an SSCCE that includes at least the following:
- the creation of the table model
- the creation of the JTable and its renderers / editors
- a main method
 
Darryl Burke
Bartender
Posts: 5167
11
Netbeans IDE Opera Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Try using ImageIO#read(URL) instead of Toolkit to load the images.
 
Mike Lipay
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Darryl Burke wrote:Try using ImageIO#read(URL) instead of Toolkit to load the images.



That can't be done inside the table, it requires IOException to be caught.
 
Mike Lipay
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rob Prime wrote:Not with this little information. You should post an SSCCE that includes at least the following:
- the creation of the table model
- the creation of the JTable and its renderers / editors
- a main method



Sorry, never sure how much is too much, and how little is too little. I think the problem with the image is that there is too much white space, and the routine that is creating the thumbnail is not as good at rendering as Mac and Win when they create the icon image in the folders.

I guess another method, if possible, is to access the desktop's icon for the file, but I don't know if there is a way to do that.

Here is the code for the ThumbnailIcon class (as posted above)




And the code for the Service class:

 
Rob Spoor
Sheriff
Posts: 22862
132
Eclipse IDE Spring TypeScript Quarkus Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That's not an SSCCE. There is now too much code; I don't need all those labels, the dialog, etc. And there is no main method like I asked you.

I've copied / pasted bits and pieces and have come up with the following SSCCE, containing only the table model and the thumbnail icon. As a comparison, my code is 96 lines with both classes and import statements. Your code has over twice as much.
I see two images just as I expected. I did change the name of the file to remove the space and dashes, as these were not in the file when I saved it from this thread. If I change the name in the code so it doesn't match anymore then I see a blank cell like you described. So my guess is that your physical file name and the file name in the code don't match.
 
Mike Lipay
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rob Prime wrote:That's not an SSCCE. There is now too much code; I don't need all those labels, the dialog, etc. And there is no main method like I asked you.



Sorry, will try to do better.

Rob Prime wrote:I see two images just as I expected. I did change the name of the file to remove the space and dashes, as these were not in the file when I saved it from this thread. If I change the name in the code so it doesn't match anymore then I see a blank cell like you described. So my guess is that your physical file name and the file name in the code don't match.



Not in my case, here is what I have:




 
Mike Lipay
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Rob,

I took your code, compiled and executed it, and the image shows. There must be something different between your code and mine that makes mine not work.
 
Bartender
Posts: 1561
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Lipay wrote:

Darryl Burke wrote:Try using ImageIO#read(URL) instead of Toolkit to load the images.



That can't be done inside the table, it requires IOException to be caught.



I don't understand what you're saying here. What does catching an IOException have to do with whether or not to use Darryl's (excellent) suggestion?
 
Rob Spoor
Sheriff
Posts: 22862
132
Eclipse IDE Spring TypeScript Quarkus Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Mike Lipay wrote:Rob,

I took your code, compiled and executed it, and the image shows. There must be something different between your code and mine that makes mine not work.


Then look for the differences. Most of all, check the return value of your table model's getValueAt method.Just before returning something print out what you're going to return.

If that works out OK print out the image's real size in the ThumbnailIcon. Make sure that the width and height are not -1 (meaning an invalid image, at least at the time. It could be still loading). Component implements ImageObserver so if you do it in the paintIcon method that would be easiest.
 
Mike Lipay
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rob Prime wrote:

Mike Lipay wrote:Rob,

I took your code, compiled and executed it, and the image shows. There must be something different between your code and mine that makes mine not work.


Then look for the differences. Most of all, check the return value of your table model's getValueAt method.Just before returning something print out what you're going to return.

If that works out OK print out the image's real size in the ThumbnailIcon. Make sure that the width and height are not -1 (meaning an invalid image, at least at the time. It could be still loading). Component implements ImageObserver so if you do it in the paintIcon method that would be easiest.




Odd, I brought this into work to work on it during breaks. When I run your code under Win-XP I don't see the image.
 
Mike Lipay
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok, I think I found the problem (at least on the WinXP system), but I'm not sure of the solution - it seems to be the size of the image. The original size is 2550 x 3317; I cut the size in half, just on a hunch, and it worked. Going on this I restored the image and progressively reduced the size until it worked, turns out the magic number is 60%, which brings the image down to 1530 x 1991.

Any idea what's going on, and if there is a way around it. I cannot control the size of an image someone else creates.
 
Rob Spoor
Sheriff
Posts: 22862
132
Eclipse IDE Spring TypeScript Quarkus Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It could be a memory problem. Do you see any errors on the console?
 
Mike Lipay
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rob Prime wrote:It could be a memory problem. Do you see any errors on the console?



No, everything looks like it worked, the image just doesn't appear. In fact, I don't think it's being generated. If I click on the cell containing the first image (NoDoc.png) I can see the outline of the image inside of the selection background color; if I click on the cell with no image the entire cell is in background color.
 
Rob Spoor
Sheriff
Posts: 22862
132
Eclipse IDE Spring TypeScript Quarkus Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Then I suggest you follow my previous suggestions - check out what is returned from getValueAt, what size the image has when painting, etc.
 
Mike Lipay
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Rob Prime wrote:Then I suggest you follow my previous suggestions - check out what is returned from getValueAt, what size the image has when painting, etc.



I put the display into the ThumbnailIcon class (paint method) since I couldn't figure out how to put it into the getValueAt method.

H:50 W:50
H:50 W:50

 
Rob Spoor
Sheriff
Posts: 22862
132
Eclipse IDE Spring TypeScript Quarkus Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Don't print the width and height you want it to get - print the actual width and height from the image.
 
Mike Lipay
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok, I think I have what you asked for, here are the sizes: H:2106 W:1548

Here is the code (in case I guessed wrong):

 
Mike Lipay
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok, I have some more information. Running the script multiple times returns different values for h & w, sometimes one or the other will have a -1. I'm guessing that the image is not finished resizing when the paint is called. If you agree, any idea how to get the draw to wait, or to insert a delay before drawImage is called?
 
Mike Lipay
Ranch Hand
Posts: 171
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok, I added this right before the drawImage and the thumbnail was created



Question is, is there a better way to wait for the resize operation to complete? I would imagine that the delay would vary depending on the speed of the J-engine, and the size of the original image.
 
Rob Spoor
Sheriff
Posts: 22862
132
Eclipse IDE Spring TypeScript Quarkus Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
There are a few ways of ensuring the images are loaded:

- use ImageIO.read as Darryl suggested. Don't worry about the IOException, you can catch it if you initialize the table in a static initializer block

- use ImageIcon like you originally did, then retrieve its image using getImage().

- use a MediaTracker. This is actually what ImageIcon does internally.
 
Consider Paul's rocket mass heater.
reply
    Bookmark Topic Watch Topic
  • New Topic