aspose file tools*
The moose likes Swing / AWT / SWT and the fly likes Is there a way to show an image in a JTable as a thumbnail? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "Is there a way to show an image in a JTable as a thumbnail?" Watch "Is there a way to show an image in a JTable as a thumbnail?" New topic
Author

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

Mike Lipay
Ranch Hand

Joined: Sep 11, 2007
Posts: 171
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
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19722
    
  20

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.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Mike Lipay
Ranch Hand

Joined: Sep 11, 2007
Posts: 171
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

Joined: Sep 11, 2007
Posts: 171
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

Joined: Oct 27, 2005
Posts: 19722
    
  20

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.
Darryl Burke
Bartender

Joined: May 03, 2008
Posts: 4642
    
    5

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.


luck, db
There are no new questions, but there may be new answers.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19722
    
  20

Isn't that the same as option 3 - a custom Icon implementation?
Darryl Burke
Bartender

Joined: May 03, 2008
Posts: 4642
    
    5

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

Joined: Sep 11, 2007
Posts: 171
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

Joined: Oct 27, 2005
Posts: 19722
    
  20

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

Joined: May 03, 2008
Posts: 4642
    
    5

Try using ImageIO#read(URL) instead of Toolkit to load the images.
Mike Lipay
Ranch Hand

Joined: Sep 11, 2007
Posts: 171
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

Joined: Sep 11, 2007
Posts: 171
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

Joined: Oct 27, 2005
Posts: 19722
    
  20

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

Joined: Sep 11, 2007
Posts: 171
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

Joined: Sep 11, 2007
Posts: 171
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.
pete stein
Bartender

Joined: Feb 23, 2007
Posts: 1561
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

Joined: Oct 27, 2005
Posts: 19722
    
  20

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

Joined: Sep 11, 2007
Posts: 171
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

Joined: Sep 11, 2007
Posts: 171
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

Joined: Oct 27, 2005
Posts: 19722
    
  20

It could be a memory problem. Do you see any errors on the console?
Mike Lipay
Ranch Hand

Joined: Sep 11, 2007
Posts: 171
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

Joined: Oct 27, 2005
Posts: 19722
    
  20

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

Joined: Sep 11, 2007
Posts: 171
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

Joined: Oct 27, 2005
Posts: 19722
    
  20

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

Joined: Sep 11, 2007
Posts: 171
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

Joined: Sep 11, 2007
Posts: 171
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

Joined: Sep 11, 2007
Posts: 171
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

Joined: Oct 27, 2005
Posts: 19722
    
  20

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.
 
 
subject: Is there a way to show an image in a JTable as a thumbnail?