How to show images in JTable Cell? - java

I am trying to use JTable for showing my personnel list with each picture dedicated to each person. I want to show these images in a JTable cell. I achieved showing images from directory with custom cell renderer. This cell renderer returns the label which has icon via the method new ImageIcon(). Every time scrolling happens in my JTable, I guess this renderer works and creates new images from the directory. So this makes RAM explode and glitches in the images. I read all of the questions related to this problem, however I could not find an efficient way to solve it. An approach to this problem would be much appreciated.
My renderer looks like:
public class ImageCellRenderer extends DefaultTableCellRenderer{
JLabel lbl=new JLabel();
public Component getTableCellRendererComponent(defaultparameters){
ImageIcon imageIcon=new ImageIcon(getClass().getResource("path to directory"+table.getModel().getValueAt(row,column).toString+".jpg"));
"""
Some code to turn image icon to scaled version
"""
lbl.setIcon(imageIcon)
return lbl;
}
}

Use the same ImageIcon, I guess.
Something like:
// Note: Probably don't use `DefaultTableCellRenderer`,
// unless you are using the `JLabel` part of that.
public class ImageCellRenderer extends DefaultTableCellRenderer {
private final JLabel label = new JLabel();
private final Map<String,ImageIcon> images = new HashMap<>();
public Component getTableCellRendererComponent(defaultparameters) {
ImageIcon imageIcon = images.computeIfAbsent(
value.toString(),
// No need to look value up again. Delete this:
//table.getModel().getValueAt(row,column).toString(),
cell -> {
ImageIcon newImage = new ImageIcon(
getClass().getResource("path to directory"+cell+".jpg")
);
"""
Some code to turn image icon to scaled version
"""
return newIcon;
}
);
lbl.setIcon(imageIcon)
return lbl;
}
}
(Whether you want to share the "cache" (leek) between renderers and cache eviction policy is left as an exercise.)

Related

How to create an item for a scrolling list with scened2d

I want to create an "item" template and add them to a ScrollPane
An item should contain an Image, a label and a button
Something like this:
I tried to do this with a table but I can't add a background to a row.
scrollTable.add(itemTest).fill().expandX();
scrollTable.row();
scrollTable.add(itemTest2).fill().expandX();
scrollTable.row();
etc..
What is the best way to create something like the picture?
What's about a class ScrollPaneRow extend Table as template?
public class ScrollPaneRow extends Table {
Label label;
TextButton textButton;
Image image;
public ScrollPaneRow(){
//...
setBackground(Drawable d);
}
}
And then a VerticalGroup which contains the rows:
ScrollPaneRow row = new ScrollPaneRow();
VerticalGroup verticalGroup = new VerticalGroup();
verticalGroup.addActor(row);
And set the VerticalGroup as content of ScrollPane:
ScrollPane scrollPane = new ScrollPane(verticalGroup);

Adding ImageIcon to a JLabel?

Is this the correct way to add an ImageIcon to a JLabel? It doesn't seem to be working when I call the second method.
What type should addCarIcon() be?
//return JLabel that is null
JLabel findEmptySpace()
{
return parkingSpace[emptySpaceNo()];
}
//set icon JLabel
void addCarIcon()
{
ImageIcon carIcon = new ImageIcon("car.png");
findEmptySpace().setIcon(carIcon);
}
//return JLabel that is null
JLabel findEmptySpace()
{
return parkingSpace[emptySpaceNo()];
}
//set icon JLabel
void addCarIcon()
{
// ImageIcon carIcon = new ImageIcon("car.png");
ImageIcon carIcon = new ImageIcon(getClass().getResource("car.png"), null);
findEmptySpace().setIcon(carIcon);
}
I do not reccomend to use ImageIcon(String filename) construction in case of problem, depending on file pakaging. It could work when you run it from IDE, and not work whe you run it from runnable jar.
P.S. Some time ago, I've created IconManager utils to use ico files instead of set of png files. You can test it, maybe it could be useful for you. (This is a link to GitHub: https://github.com/oleg-cherednik/IconManager)

Image in painsComponent only shows tiny left top corner of the full image

I have a program that should load 2 panels next to each other. On one I show a grid of 10x10 images using an array of panels:
private JPanel imagePanels[][] = new JPanel[10][10];
Then I load a custom panel with the image like this:
imagePanels[i][j] = new ImagePanel("http://i.stack.imgur.com/W3RMa.jpg",Color.WHITE);
This is the Image I tried to load (32x32 pixels):
ImagePanel:
public class ImagePanel extends JPanel{
private BufferedImage image;
public ImagePanel(String path,Color background){ //TODO!!:set background color
try{
URL url = new URL(path);
image = = ImageIO.read(url);
}catch(IOException ex){
System.out.println("Image Not Found");
}
}
#Override
protected void paintComponent(Graphics g){
super.paintComponents(g);
g.drawImage(image,0,0,null);
}
}
This works and the panel shows the 32x32 pixel image that I passed it. Now I want to display another image inside another panel. I decided to use the ImagePanel class as a GoTo class for loading images on panels throughout the program. So I made another class for the second panel:
public class LeftPlayerPanel extends JPanel{
private JPanel PlayerPicturePanel = new ImagePanel("http://i.stack.imgur.com/sjfvC.jpg",Color.GRAY);
public LeftPlayerPanel(Player thisPlayer){
this.add(PlayerPicturePanel);
//TODO!!:Display Player Stats
}
}
This is the image that I tried to load this time (128x128 pixels):
The program however looks like this:
As you can see the right side works fine showing the entire image 100 times.(don't worry about the red dot. that's what it's supposed to do) but on the left of the program the image only shows up partially (a little bit of the left top corner.)
Can there be a problem in my layout? Do I have to make another class for each image? Or for each image size? is this happening because I use a SplitPane?
Here is the class that displays the stuff:
public class test {
private static Positition p;
public static void main(String[] v){
Field f = new Field(2, 100);
p = f.getRandomFieldPosition();
printPosition(p);
JPanel panel = new FieldPanel(p);
JPanel player = new LeftPlayerPanel(null);// add player later
JFrame f1 = new TestFrame("TESTFRAME");
panel.setPreferredSize(new Dimension(326,309));
player.setPreferredSize(new Dimension(135,309));
JSplitPane splitpane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,player,panel);
JPanel content = new JPanel();
content.setLayout(new BorderLayout());
content.add(splitpane,BorderLayout.CENTER);
f1.setContentPane(content);
f1.setPreferredSize(new Dimension(326+135,309));
f1.pack();
f1.show();
}
}
ps. I'm still working on the exact sizing of the program and the size of each panel. I know that the way it's displayed now it's not going to fit but I also tried sliding the SplitPane to the right to make the panel bigger.
EDIT: I made a version that has all the important stuff in one file but I can't test it because i'm on a proxy and it won't load the images here. (I think I got the url right.)
URL for the LeftPlayerPanel: http://i.stack.imgur.com/sjfvC.jpg
URL for the LoadSquare method: http://i.stack.imgur.com/W3RMa.jpg

How to paint an Image that from a JFileChooser?

I want the user to be able to click a button and choose and image which'll be displayed on the screen.
This is the code I wrote. It doesn't seem to work:
uploadBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int retVal = fc.showOpenDialog(EditImage.this);
if(retVal == JFileChooser.APPROVE_OPTION){
File file = fc.getSelectedFile();
try{
Image img = ImageIO.read(file);
if(img==null){
//TODO: THE FILE IS NOT AN IMAGE. ERROR
}
ImageIcon ic = new ImageIcon(img);
JLabel imageLabel = new JLabel(ic);
imagePreview.add(imageLabel);
}
catch(IOException ex){
//TODO: THE FILE COULD NOT BE OPENED.
}
}
}
});
imagePreview is a JPanel that I've got somewhere on the screen.
What am I doing wrong?
agree with other answers here is required to call container.revalidate() and (there is an Image, then to required) container.repaint()
but this logics is wrong, you couldn't, why to add/remove JComponent for showing another Image, there no reason for, you can to switch betweens ImageIcons in JLabel - JLabel.setIcon(file)
and there is another issue, Images can increasing used JVM memory, you have to call Icon/ImageIcon.flush() before is added to JLabel.setIcon(a few times mentioned here)
Is imagePreview already visible when you add the JLabel to it? If so, you can't just add components to a visible container; you have to revalidate it.
call imagePreview.revalidate(); imagePreview.repaint() after imagePreview.add(imageLabel);, that needed if you add components to visible container.

Transparent Background in Java SWT Label

Is there anyway in Java SWT that I can place a label on top of another label and then have the label on top to have a transparent background?
I am doing this in a class that extends Composite as I want to create a custom SWT "fancy button" out of 2 labels. So the label below will be the lable that consist of only an image while the one on top will be the label with the text of the "fancy button". But the label on top has to have a transparent background so as to not cover the image below it.
Currently, the label on top is covering the label below.
Any idea how I could do this?
Thanks!
Instead you could try doing the following to get the same result.
Create a label
Assign an image to the label using a shell
Then use "setText()" to write something on the label.
The Text will appear above the image. You will be able to see the image.
( Showing only relavent code )
Example of Label with text/image.
Image image = new Image(display, "c:\\picture.jpeg");
Shell shell = new Shell(SWT.NO_TRIM);
shell.setBounds(10,10,200,200);
shell.setBackgroundImage(image);
shell.setBackgroundMode(SWT.INHERIT_DEFAULT);
Label label = new Label(shell, SWT.NONE);
label.setText("LAbel text here. ");
Since you want to make buttons.
You can use the same logic, using the "Button" api as well.
You can create a button with an image and then set any text above it.
( Showing only relavent code )
Example of Button
Button button = new Button(shell, SWT.PUSH);
button.setImage(image);
button.setText("Click Me");
I hope this is what you are trying to do.
instead of doing
drawString("text", x, y)
do
drawString("text", x, y, true)
it will make the background transparent, as per the documentation
Writing a text (as label) without background seems to be simple possible only in a Canvas using the GC class for the paint routine. I have written an inheritance of Canvas for that:
public class SwtTransparentLabel extends Canvas {
String text = "";
Font font = null;
public SwtTransparentLabel(Composite parent, int style) {
super(parent, style | SWT.TRANSPARENT);
addPaintListener(paintListener);
}
public void setText (String string) {
text = string;
}
public void setFont (Font font) {
this.font = font;
}
/**The listener for paint events. It is called whenever the window is shown newly. It does the work for graphic output. */
protected PaintListener paintListener = new PaintListener() {
#Override public void paintControl(PaintEvent e) {
GC gc = e.gc;
if(font !=null){ gc.setFont(font); }
//no: gc.setAlpha(100); //... experience, not necessary
gc.drawString(text, 0, 0, true);
}
};
}
That works similar as org.eclipse.swt.widgets.Label.
I am yet trying to improve the solution (setAlignment is missing). You may visit results on www.vishia.org/Java

Categories

Resources