Reputation: 55
I'm building a simple GUI with swing and I've run into a problem that I can't figure out the reason for. The creation of a buffered image stops the rest of my code from doing anything.
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.BorderFactory;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Main extends JPanel{
BufferedImage img;
int number;
public static void main(String[] args) {
JFrame frame = new JFrame("Some practice");
frame.setSize(200,200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
Main doStuff = new Main();
JButton myButton = new JButton("Button");
JPanel controls = new JPanel();
controls.setBorder(BorderFactory.createTitledBorder(
"Small Panel"));
controls.add(myButton);
frame.add("South", controls);
frame.add(doStuff);
}
public Main () {
super.setBorder(BorderFactory.createTitledBorder("Big Panel!"));
// This method seems to shut down my GUI
importImage();
}
private void importImage() {
try {
img = ImageIO.read(new File("res/strawberry.jpg"));
} catch (IOException e) {
System.out.println("Image exception");
}
}
}
If I have my importImage
function in the constructor of Main
then the GUI doesn't show. Try commenting out the line doStuff();
and you will see two bordered panels show up.
What I want to know is what property of Java or Swing am I not seeing that's causing me this mix-up? Thanks
Upvotes: 1
Views: 56
Reputation: 201487
Move frame.setVisible(true);
to the end of main()
.
public static void main(String[] args) {
JFrame frame = new JFrame("Some practice");
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// frame.setVisible(true);
Main doStuff = new Main();
JButton myButton = new JButton("Button");
JPanel controls = new JPanel();
controls.setBorder(BorderFactory.createTitledBorder("Small Panel"));
controls.add(myButton);
frame.add("South", controls);
frame.add(doStuff); // <-- you are still adding things.
frame.setVisible(true);
}
Edit
But, you seem to want an ImagePanel
like
/**
* From: http://www.java2s.com/Code/Java/Swing-JFC/Panelwithbackgroundimage.htm
*/
class ImagePanel extends JPanel {
private Image img;
public ImagePanel(String img) {
this(new ImageIcon(img).getImage());
}
public ImagePanel(Image img) {
this.img = img;
Dimension size = new Dimension(img.getWidth(null),
img.getHeight(null));
setPreferredSize(size);
setMinimumSize(size);
setMaximumSize(size);
setSize(size);
setLayout(null);
}
public void paintComponent(Graphics g) {
g.drawImage(img, 0, 0, null);
}
}
And then change the constructor to use add(ImagePanel)
like,
String imgPath = "res/strawberry.jpg";
add(new ImagePanel(imgPath));
Finally, you should be doing things in a new Thread
context and I added an ActionListener
to Main
so you can click the button. Putting it all together
public class Main extends JPanel implements ActionListener {
BufferedImage img;
int number;
public static void main(String[] args) {
JFrame frame = new JFrame("Some practice");
Runnable doRun = new Runnable() {
@Override
public void run() {
frame.setSize(200, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Main doStuff = new Main();
JButton myButton = new JButton("Button");
myButton.addActionListener(doStuff);
JPanel controls = new JPanel();
controls.setBorder(BorderFactory
.createTitledBorder("Small Panel"));
controls.add(myButton);
frame.add("South", controls);
frame.add(doStuff);
frame.setVisible(true);
}
};
SwingUtilities.invokeLater(doRun);
}
public Main() {
super.setBorder(BorderFactory.createTitledBorder("Big Panel!"));
final String imgPath = "res/strawberry.jpg";
// This method seems to shut down my GUI
add(new ImagePanel(imgPath));
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(e);
}
}
Upvotes: 2