JPanel background image not getting changed - java

I am using following class for adding background image to JPanel.
http://www.java2s.com/Code/Java/Swing-JFC/Panelwithbackgroundimage.htm
But when the application is executing and image is changed the new updated image is not shown on screen.
Image image = new ImageIcon(path + item.getItemID() + ".png").getImage();
panel = new ImagePanel(image);
variable path is static path outside workspace.

If you "update JPanel with new JPanel" you are not "updating", you are creating a new JPanel.
Example, we have a green JPanel called "panelTest":
panelTest = new JPanel();
panelTest.setBackground(Color.green);
add(panelTest);
And now we have a button that will change the JPanel background color from green to red, but in a wrong way:
JButton btnTest = new JButton("Test");
btnTest.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
panelTest = new JPanel(); //woops, now we have 2 panels...
panelTest.setBackground(Color.red);
}
});
Note that panelTest was a pointer to a green panel, and now it is pointing to a new JPanel with a red background. This new JPanel has not been added to any container, thus it will not be shown. And the old green panel will stay visible.
The best way to update the image is creating a method inside ImagePanel like:
public void setImage( Image image ) {
this.img = image;
this.repaint();
}
This way you don't have to create a new ImagePanel just for changing the background.

Related

Unable to add contents over my background image in java

I am creating a profile page. At the left, I have added a jlabel containing a background image to my jpanel. Now over this panel, I want to add another jlabel for the icon. However, it is not showing up. Please help me.
P.s: This is only part of the code
public CustomerProfile()
{
super("Customer Profile");
setLayout(new BorderLayout());
//PROFILE DETAILS JPANEL
jpProfile = new JPanel();
add(jpProfile, BorderLayout.WEST);
//BACKGROUND IMAGE OF THE PROFILE JPANEL
ImageIcon background_img = new ImageIcon("background.jpg");
Image img = background_img.getImage();
Image tempImg = img.getScaledInstance(350, 600, Image.SCALE_SMOOTH);
background_img = new ImageIcon(tempImg);
background = new JLabel("",background_img,JLabel.CENTER);
jpProfile.add(background);
//PROFILE ICON
ImageIcon profImg = new ImageIcon("female.png");
jlProfileIcon = new JLabel();
jlProfileIcon.setIcon(profImg);
//ADDING PROFILE ICON TO JPANEL
jpProfileIcon = new JPanel();
jpProfileIcon.add(jlProfileIcon);
//jpProfile.setOpaque(false);
//jpProfileIcon.setOpaque(false);
jpProfileIcon.add(jlProfileIcon);
background.add(jpProfileIcon);
}
By default only a JPanel uses a layout manager.
The JLabel does not use a layout manager so the size/location of any component added to the label is not changed. The default size of a component is (0, 0) so there is nothing to paint.
Try:
background = new JLabel("",background_img,JLabel.CENTER);
background.setLayout( new BorderLayout() ); // added
…
background.add(jlProfileIcon);
The following code is not needed:
//jpProfileIcon = new JPanel();
//jpProfileIcon.add(jlProfileIcon);
That is you don't need to create a JPanel, just to add the label to it.
A better option is to paint the background image onto a panel and then you can just add your label normally to the panel. See: Background Panel for a class that implements this functionality.

Images not visible in JList

I'm writing a little photo application (asked some questions before) and I have one problem which I cannot resolve. The idea is that there are two sections: the upper one is for an overview (using thumbnails) and the lower one shows the selected image in it's full size. I cannot use ImageIO (required by my lecturer).
I'm using a JList for the overview but most images are not visible. I chose a folder with about 20 images and only 2 show up. And one of them isn't even centered.
For some reason, if I delete those lines:
thumbnaillist.setFixedCellWidth(thumbW);
thumbnaillist.setFixedCellHeight(thumbH);
One image shows up that wasn't visible before, but now the other two disappear.
This is my code:
public class PVE extends JFrame {
private JFileChooser fileChoose;
//MenuBar
private JMenuBar menubar;
private JMenu file;
private JMenuItem openFolder;
private JMenuItem exit;
//Thumbnails
private JList thumbnaillist;
private DefaultListModel<ImageIcon> listmodel;
private JScrollPane tscroll;
private ImageIcon thumbs;
private int thumbW = 100;
private int thumbH = 100;
//for full size view
private JPanel imgview;
public PVE() {
setLayout(new BorderLayout());
//MenuBar
menubar = new JMenuBar();
file = new JMenu("File");
openFolder = new JMenuItem("Open folder...");
exit = new JMenuItem("Quit");
file.add(openFolder);
file.addSeparator();
file.add(exit);
menubar.add(file);
setJMenuBar(menubar);
fileChoose = new JFileChooser();
openFolder.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
fileChoose.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fileChoose.showOpenDialog(null);
File chosenDir = fileChoose.getSelectedFile();
loadToThumbView(chosenDir);
}
});
//Thumbnail view
listmodel = new DefaultListModel();
thumbnaillist = new JList(listmodel);
thumbnaillist.setLayoutOrientation(JList.HORIZONTAL_WRAP);
thumbnaillist.setFixedCellWidth(thumbW);
thumbnaillist.setFixedCellHeight(thumbH);
thumbnaillist.setVisibleRowCount(1);
tscroll = new JScrollPane(thumbnaillist, JScrollPane.VERTICAL_SCROLLBAR_NEVER,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
tscroll.setPreferredSize(new Dimension(0, 100));
add(tscroll, "North");
//for full size view
imgview = new JPanel();
imgview.setBackground(Color.decode("#f7f7f7"));
add(imgview, "Center");
setTitle("Photo Viewer");
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
SwingUtilities.updateComponentTreeUI(this);
} catch (Exception e) {
}
setSize(700, 700);
setLocation(200, 200);
setVisible(true);
}
public void loadToThumbView(File folder) {
listmodel.removeAllElements();
File[] imgpaths = folder.listFiles();
for (int j = 0; j < imgpaths.length; j++) {
listmodel.addElement(resizeToThumbnail(new ImageIcon(imgpaths[j].toString())));
}
}
public ImageIcon resizeToThumbnail(ImageIcon icon) {
Image img = icon.getImage();
BufferedImage bf = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics g = bf.createGraphics();
g.drawImage(img, 0, 0, thumbW, thumbH, null);
ImageIcon kB = new ImageIcon(bf);
return kB;
}
public static void main(String argv[]) {
PVE pv = new PVE();
}
}
Your problem is because of the way you're scaling your images.
I'm not exactly sure why but I guess it has something to do with the BufferedImage#createGraphics() call and that I was able to reproduce the problem with .jpg images while .png files were correctly painted.
However if you scale your images instead of converting them to a BufferedImage and getting a new ImageIcon from it, you get the correct output:
public ImageIcon resizeToThumbnail(ImageIcon icon) {
Image img = icon.getImage();
Image scaled = img.getScaledInstance(thumbW, thumbH, Image.SCALE_SMOOTH);
return new ImageIcon(scaled);
}
This is the folder I used to test:
And the outputs with your code and mine:
Important notes
And as as a recommendation don't make a window that big if all you're using is that little bar above. If you're adding something else below, then it's ok but for now it's not that "user friendly" (IMHO). Instead of JFrame#setSize() you could try using JFrame#pack() method so your frame resizes to it's preferred size.
Some other things I noted in your program:
You're not placing it inside the Event Dispatch Thread (EDT) which is dangerous since your application won't be Thread safe that way. You can change that if you change your main method as follows:
public static void main(String argS[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
PVE pv = new PVE();
}
});
}
You're setting the JScrollPane preferred size, instead you should override its getPreferredSize() method, see Should I avoid the use of setPreferred|Maximum|MinimumSize methods in Java Swing? (YES)
You're extending JFrame, you should instead create an instance of it unless you're overriding one of its methods (and you're not, so don't do it) or you have any good reason to do it. If you need to extend a Container you should extend JPanel instead, as JFrame is a rigid container which cannot be placed inside another one. See this question and this one.
I think I'm not missing anything, and hope this helps
Your “scaled” images are actually images which are the same size as the original image, but are blank except for a scaled version drawn in the upper left corner. That upper left corner is clipped out of view in each rendered cell (at least for the somewhat large images I tested with).
The scaled image needs to be created with the thumbnail size, not the size of the original image. Meaning, change this:
BufferedImage bf = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
to this:
BufferedImage bf = new BufferedImage(thumbW, thumbH, BufferedImage.TYPE_INT_ARGB);

How can I place JButton over a JLabel with image?

I use NetBeans IDE to create an application using java. I want to include a JButton over a JLabel with image. Actually when I add JButton over the JLabel it would inserted but it will transparent and the name and the button didn't display. It seems the button to be added under the JLabel. How can I overcome this problem?
there are two ways
put image to JPanel by override paintComponent (standard way)
JLabel haven't any LayoutManager in API, you have to set LayoutManager, then JLabel will be container
ImageIcon img = null;
class Panel extends JPanel{
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img == null){
img = new ImageIcon("d:\\picture.jpg");
g.drawImage(img.getImage(), 0, 0, null);
}
}
}
//in the constructor
JButton button = new JButton( "OK");
Panel panel = new Panel();
panel.add(button);
add(panel);

Image button created from JLabel is not working

I'm trying to make a buttom from an image on the JFrame using the ImageIcon and the addMouseListener that will replace the current image with another image by clicking it.
static JPanel jp = new JPanel();
final JLabel jl = new JLabel();
final JFrame jf = new JFrame();
ImageIcon image = new ImageIcon("image1.jpg");
jl.setIcon(image);
jp.add(jl);
jf.add(jp);
jf.validate();
JLabel button = new JLabel(image);
button.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
jl.setIcon( null );
ImageIcon image = new ImageIcon("image2.jpg");
jl.setIcon(image);
}
});
The GUI is displayed with image1.jpg, but the button does not work at all and I can't even test whether the replacement from image1 to image2 works. GUI will not do anything even if I attempt to click the image1.jpg displayed on the window.
Edit: Adjusted JLabel varaible to be final for now. Other similar questions intimate that this method should be working but I can't figure out what is wrong with the code.
Not really sure ActionListener works with JLabel either.
No you can't add an ActionListener to a JLabel. An easier approach is to make a JButton look like a JLabel, then you can add the ActionListener to the button:
JButton button = new JButton(...);
button.setBorderPainted(false);
button.setContentAreaFilled(false);
button.addActionListener(...);
but the button does not work at all
A mouse click is generated when a mousePressed and mouseReleased is received for the same mouse point. So if you move the mouse slightly the event will not get generated. Instead listen for the mousePressed() event.

set transparent panel on top of canvas

I have a canvas and I want when mouse entered it, some transparent Jpanel containing some components displayed on top of my canvas. I used JlayeredPane for this; but as you see in following example when I want to display transparent panel on top of canvas, by adding it to jLayeredPane on upper layer, It's background is shown as color of the panel that is under canvas.
public class NewClass {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(200 , 200);
JLayeredPane layeredPane = new JLayeredPane();
frame.setContentPane(layeredPane);
JPanel canvasPanel = new JPanel();
canvasPanel.setLayout(new GridLayout());
canvasPanel.setBackground(Color.RED);
Canvas canvas = new Canvas();
canvas.setBackground(Color.BLACK);
canvasPanel.add(canvas);
layeredPane.add(canvasPanel , JLayeredPane.PALETTE_LAYER);
canvasPanel.setSize(200 , 200);
JPanel transparentPanel = new JPanel();
transparentPanel.setSize(100 , 100);
transparentPanel .setOpaque(false);
transparentPanel.add(new JButton("button"));
layeredPane.add(transparentPanel , JLayeredPane.DRAG_LAYER);
frame.setVisible(true);
}
}
how can I show transparent panel on canvas such that, It's background seems as canvas?
I don't understand the problem, when I ran the code as is it resulted in the button on top of a red square on a black background
If not working for you, try setting the transparentPanel background color to red (same as canvasPanel)
Although this probably wouldn't work for non solid backgrouds

Categories