1

I am new in Java and I am currently creating a game with graphics. I have this class that extends from JFrame. In this class, I have many JPanels that needs an image as background. As I know, to be able to paint images in the JPanel, I need to have a separate class that extends from JPanel and that class's paintComponent method will do the work. But I don't want to make separate classes for each JPanel, I have too many of them; and with the fact that I am only concerned with the background. How can I do this? is it with an anonymous inner class? How?

For better understanding I provided some code:

public GUI extends JFrame {
  private JPanel x;
  ...  

  public GUI() {
   x = new JPanel();
   // put an image background to x
  }
krato
  • 1,226
  • 4
  • 14
  • 30
  • Use a JLabel with an icon. There is no reason to use a panel to paint unless you are doing fancy painting like scaling and so on. – camickr Aug 23 '13 at 03:13
  • IMHO, `Anonymous inner classes` won't ease your pain, rather they will work the opposite. It's the same as creating a new class, which provides atleast the functionality of separation of duties. Consider `JLabel` as shown in this [example](http://stackoverflow.com/a/11372350/1057230). Moreover, you can change the `Layout` of the `JLabel` to accommodate more components, as shown in this [example](http://stackoverflow.com/a/10245045/1057230) :-) – nIcE cOw Aug 23 '13 at 03:46
  • just a little out of the track, can you mention the IDE that you are using? – Nitesh Verma Aug 23 '13 at 04:13

3 Answers3

3

You don't have to make another class for it? You could just do:

x = new JPanel(){
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        //draw background image
    }
};
Josh M
  • 11,611
  • 7
  • 39
  • 49
  • Hello, is this what they call anonymous inner classes? – krato Aug 23 '13 at 03:04
  • @krato Well, you are just overriding the method. You could override other methods as well. – Josh M Aug 23 '13 at 03:06
  • @MadProgrammer Yeah I just realized I was missing it aha :P – Josh M Aug 23 '13 at 03:09
  • Not a massive issue as you didn't do anything else in the method, but it helps prevent leading the OP astray ;) – MadProgrammer Aug 23 '13 at 03:09
  • I learned of overriding methods only when you create a new class that extends a parent, can you give me links on how to override upon instantiation(am not sure what to call it); like the one you suggested? I would really like to learn that! :)) – krato Aug 23 '13 at 03:15
3

Why not make a single class that takes a Image??

public class ImagePane extends JPanel {

    private Image image;

    public ImagePane(Image image) {
        this.image = image;
    }

    @Override
    public Dimension getPreferredSize() {
        return image == null ? new Dimension(0, 0) : new Dimension(image.getWidth(this), image.getHeight(this));
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.drawImage(image, 0, 0, this);
        g2d.dispose();
    }
}

You would even provide hints about where it should be painted.

This way, you could simply create an instance when ever you needed it

Updated

The other question is, why?

You could just use a JLabel which will paint the icon for you without any additional work...

See How to use labels for more details...

This is actually a bad idea, as JLabel does NOT use it's child components when calculating it's preferred size, it only uses the size of the image and the text properties when determining it's preferred size, this can result in the component been sized incorrectly

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Why paint an icon at its real size in a JPanel when you can use a JLabel with an Icon? – camickr Aug 23 '13 at 03:14
  • @camickr That's what I thought, but I figured with mention of a game I'd throw it out there... – MadProgrammer Aug 23 '13 at 03:15
  • @camickr as I know, JLabels cannot be containers for other components. I also need to have JButtons in that panel so when I have JLabel on it, I cannot put the JButtons. – krato Aug 23 '13 at 03:18
  • @MadProgrammer BTW, can I put JButtons on JLabels? If so, then I can do that. – krato Aug 23 '13 at 03:23
  • `JLabel` extends from `JComponent`, which extends from `Container`, so yes, you add other components to it, just don't forget to set it's layout manager ;) – MadProgrammer Aug 23 '13 at 03:24
  • *"JLabels cannot be containers for other components"* Actually they can. See [this answer](http://stackoverflow.com/a/18330456/418556) for an example of putting another `JLabel` inside a label that itself has an icon. – Andrew Thompson Aug 23 '13 at 03:24
  • That's really useful! I've been using oracle's tutorials but I never thought that I can do that. – krato Aug 23 '13 at 03:28
  • @krato `can I put JButtons on JLabels?` - See [Background Panel](http://tips4java.wordpress.com/2008/10/12/background-panel/) for for the approach that uses a label and a panel for more complex image painting. – camickr Aug 23 '13 at 03:32
  • Having said that I can use `JLabel` instead, which approach is better then? Using `JPanel` or a `JLabel`? – krato Aug 23 '13 at 03:35
  • It depends what you want to achieve. As camickr has already said. If you're not doing anything to the images (scaling, special painting), then `JLabel` should be just fine... – MadProgrammer Aug 23 '13 at 03:37
  • 2
    `I am new in Java` - for my $0.02 I would suggest using the base classes first and learn the strengths and weaknesses of these classes. As you become more experienced then you can start to customize classes to add extra features that you need. If you spend time rewriting/creating new classes you will never get anything done. In other words get your application working first. Then you can re-evaluate and decide how you might do things better in the future. – camickr Aug 23 '13 at 03:44
1

You can do this in single line:

panelInstance.add(new JLabel(new ImageIcon(ImageIO.read(new File("Image URL")))));

I hope it will work for you.

Vighanesh Gursale
  • 921
  • 5
  • 15
  • 31