Reputation: 804
I'm making an application where you can change your background to any picture or just leave the default one. It consists of a ImagePanel
class that overides its paintComponent to set a imageicon as its background.
GUISettings
class for the user to choose an image from a FileChooser with a filter and then pass the file.getPath() string to the ImagePanel
class and revalidate that gui, but no background is changed, not even the debug prints that I have in ImagePanel
show on console.The following is the code (simplified):
The ImagePanel
class:
public class ImagePanel extends JPanel{
private String defaultbg = "Icons/background.jpg";
private String path = "";
private BufferedImage img;
private GridBagConstraints gbc = new GridBagConstraints();
public ImageIcon bgicon;
private Image bg;
public static boolean defaultbgset = true;
public ImagePanel(){
if(defaultbgset){
path = defaultbg;
System.out.println("path in default = " + path);
} else {
if(GUISettings.getPath() != null){
path = GUISettings.getPath();
System.out.println("path in userBG = " + path);
}
}
bgicon = new ImageIcon(getClass().getResource(path));
bg = (new ImageIcon(bgicon.getImage().getScaledInstance(1024, 800, java.awt.Image.SCALE_SMOOTH))).getImage();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bg, 0, 0, getWidth(), getHeight(), this);
}
public ImageIcon getDrawBoardBackground(){
return bgicon;
}
public void setPath(String p){
this.path = p;
}
public void resetPath(){
this.path = defaultbg;
}
}
Now the GUISettings
class:
public class GUISettings extends JPanel implements ActionListener{
private TitledBorder title = BorderFactory.createTitledBorder("User Interface Settings");
private JLabel lbackground, userbg;
private JTextField bgpath;
private GridBagConstraints gbc = new GridBagConstraints();
public static JRadioButton default_bg, user_bg;
private JButton browse;
public static File file;
private JLabel userfile = new JLabel("Not chosen.");
public static String userBgPath = null;
public GUISettings(){
//this.setLayout(new GridBagLayout());
Dimension size = getPreferredSize();
size.setSize(200,150); //w, h
this.setPreferredSize(size);
this.setBorder(title);
JPanel toppane = new JPanel();
toppane.setLayout(new GridBagLayout());
(..)
browse = new JButton("Choose file");
browse.setActionCommand("browse");
browse.addActionListener(this);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.insets = new Insets(0,0,0,0);
toppane.add(browse,gbc);
gbc.gridx = 2;
gbc.gridy = 2;
gbc.insets = new Insets(0,5,0,0);
toppane.add(userfile,gbc);
add(toppane, BorderLayout.NORTH);
JPanel midpane = new JPanel();
midpane.setLayout(new GridBagLayout());
add(midpane, BorderLayout.CENTER);
(..)
}
@Override
public void actionPerformed(ActionEvent e) {
if("browse".equalsIgnoreCase(e.getActionCommand())){
final JFileChooser fc = new JFileChooser();
fc.setFileFilter(new ExtensionFileFilter());
int returnVal = fc.showOpenDialog(fc);
if (returnVal == JFileChooser.APPROVE_OPTION) {
file = fc.getSelectedFile();
//This is where a real application would open the file.
userfile.setText(file.getName());
userBgPath = file.getPath();
// THIS IS WHERE I UPDATE PATH etc.
MainFrame.bg.setPath(userBgPath);
MainFrame.bg.defaultbgset = false; // set to user
MainFrame.bg.repaint();
MainFrame.bg.revalidate();
user_bg.setSelected(true);
System.out.println("File: " + file.getName() + ".");
} else {
MainFrame.bg.defaultbgset = true;
MainFrame.bg.resetPath();
MainFrame.bg.repaint();
MainFrame.bg.revalidate();
default_bg.setSelected(true);
}
} // end of if
}
public static String getPath(){
return userBgPath;
}
}
Upvotes: 1
Views: 1257
Reputation: 13066
@Override
public void paintComponent(Graphics g) {
g.drawImage(bg, 0, 0, getWidth(), getHeight(), this);
}
This should be written as:
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(bg, 0, 0, getWidth(), getHeight(), this);
}
And whenever you are changing the image of ImagePanel by any means , you must call repaint()
method of ImagePanel
object (say imagepanel).. using
imagePanel.repaint()
.
UPDATE
In my opinion you should have a method in ImagePanel
class where you set the image and repaint the JPanel
itself over there like:
public void setImage(Image bg)
{
this.bg = bg;
repaint();
}
This will save you from calling the repaint()
method of ImagePanel
objects explicitly where it is being used..
Upvotes: 4
Reputation: 324088
then pass the file.getPath() string to the ImagePanel class
Passing the path doesn't do anything. You actually need to read the image when the path changes. So in your set path method I would guess you need to add code like:
bgicon = new ImageIcon(getClass().getResource(path));
bg = (new ImageIcon(bgicon.getImage().getScaledInstance(1024, 800, java.awt.Image.SCALE_SMOOTH))).getImage();
repaint();
The class should be responsible for repainting itself.
Upvotes: 4