Reputation: 650
In addition to my question How can I more quickly render my array?, I made the following class to make a JFrame
:
package myprojects;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
class BackgroundImageJFrame extends JFrame {
public BackgroundImageJFrame(BufferedImage img) {
setTitle("Background Color for JFrame");
int h = img.getHeight();
int w = img.getWidth();
setSize(w, h);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
setLayout(new BorderLayout());
setContentPane(new JLabel(new ImageIcon(img)));
setLayout(new FlowLayout());
// Just for refresh :) Not optional!
setSize(w-1, h-1);
setSize(w, h);
}
}
which I call with new BackgroundImageJFrame(img);
. As I want to refresh the contents of this JFrame
, this doesn't work optimally, since this creates a new JFrame
everytime.
How could I alter this to just have the JFrame
refreshed?
Upvotes: 1
Views: 822
Reputation: 32343
You can pretty simply do this by storing the JLabel
control, and then setting the image with a method. Make sure you set the image on the Event Dispatch Thread!
I have revised the code to do this in a more stable way based on @MadProgrammer's excellent comments.
Brief summary of the issues addressed between this and the previous version:
contentPane
to be a JLabel
, as it makes it more difficult to add other controls later and doesn't have a layout manager. I've added a JPanel
in between, and given it BorderLayout
.EventQueue.invokeLater
as I do here in main before calling setBackgroundImage()
.setSize
and setPreferredSize
on the JLabel so that the layout managers can properly choose good sizes for the controls, and so that frame.pack
works as expected.initComponents
method, outside of the constructor, to make the code easier to follow and to make it easy to add more constructors later if necessary.Here's the code:
public class NonogramSolutionJFrame extends JFrame {
private final JLabel label;
private final JPanel panel;
public NonogramSolutionJFrame(BufferedImage img) {
panel = new JPanel();
label = new JLabel();
initComponents(img);
}
private final void initComponents(BufferedImage img) {
setTitle("Background Color for JFrame");
setBackgroundImage(img);
setContentPane(panel);
panel.setLayout(new BorderLayout());
panel.add(label, BorderLayout.CENTER);
setLocationRelativeTo(null);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void setBackgroundImage(final BufferedImage img) {
label.setIcon(new ImageIcon(img));
label.setPreferredSize(new Dimension(img.getWidth(), img.getHeight()));
}
public static void main(String... args) throws Exception {
BufferedImage img = ImageIO.read(NonogramSolutionJFrame.class.getResource("/nonogram.png"));
NonogramSolutionJFrame frame = new NonogramSolutionJFrame(img);
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
frame.setVisible(true);
}
});
}
}
Using the image from your other answer, this code produces the following (on Linux):
Upvotes: 2