1

I am trying to paint an image onto a panel, that is contained by a frame.

Let us say I have a 320 x 480 image. When i try to create a frame with size 320x480 and add the panel into it, I encounter a problem.

In different operating systems, the JFrame of 320x480 is of different sizes due to title bar. Thus my correct fit image in windows XP will not be properly painted in Windows8 or Ubuntu.

A grey patch is visible because the image was not properly placed. I tried overriding paint method and using ImageIcon.

Please do offer a solution.

TIA

Code Snippet

CLASS PA CONTENTS
setPreferredSize(new Dimension(500,500));
.
.
JLabel image= new JLabel();
ImageIcon background = new ImageIcon(getClass().getClassLoader().getResource("Flower.jpg"));
image.setBounds(0, 0, 500, 500);
image.setIcon(background);
this.add(image);    //where "this" is extending from JPanel

CLASS PB CONTENTS
frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
inserting(frame.getContentPane());

frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setResizable(false);

private void inserting(Container pane)
{
cardPanel=new JPanel();
            CardLayout cards=new CardLayout();
cardPanel.setLayout(cards);

PA home= new PA();
cardPanel.add(home,"homeScreen");

    pane.add(cardPanel);
}
user2756339
  • 685
  • 1
  • 10
  • 17
  • To get better help sooner, please provide a [SSCCE](http://sscce.org) – Jonathan Drapeau Oct 09 '13 at 12:08
  • 2
    Have you tried calling [`pack()`](http://docs.oracle.com/javase/7/docs/api/java/awt/Window.html#pack%28%29) on your JFrame instead of setting its size explicitly? – VGR Oct 09 '13 at 12:14
  • Yes I have used pack, because I specified size of the containing panel expicitly. Is that the problem ? (Code added) – user2756339 Oct 09 '13 at 12:37
  • Obviously it is. That's why `pack` method is important. And don't call `setBounds` for the love of god. – Branislav Lazic Oct 09 '13 at 12:40
  • 1
    Please have a look at this [related example](http://stackoverflow.com/a/11372350/1057230). Hope it helps :-) – nIcE cOw Oct 09 '13 at 15:26
  • 1
    @nIcEcOw I hope you had posted this as the answer. :) The overriding of the getPreferredSize was exactly what I lacked. Thanx a ton ! – user2756339 Oct 10 '13 at 06:16
  • @user2756339 : Glad the example did helped you in that direction, though __brano88's__ answer very much describes that direction, I just gave, a working example on that lines. For the rest You're MOST WELCOME and KEEP SMILING :-) – nIcE cOw Oct 10 '13 at 06:29

2 Answers2

4

Don't call setSize at all, call pack (as VGR stated in his comment). pack will size your JFrame based on size's of component's within it, and gaps between those component's.

Now.. issue you will encounter is that your JFrame will be small at startup. So override getPreferredSize method for your JPanel to return dimensions of your image:

public void getPreferredSize() {
    return new Dimension(image.getWidth(), image.getHeight());
}

Now your image will fit perfectly and your application will be fully OS independent. And also, do not override paint method. Instead, override paintComponent. Here is a small demo I made in cases like yours:

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;


public class Drawing {
    JFrame frame = new JFrame();

    public Drawing() {
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(new Panel());
        frame.pack();
        frame.setVisible(true);

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Drawing();
            }
        });
    }

    class Panel extends JPanel {
        BufferedImage image = null;

        Panel() {
            try {
                image = ImageIO.read(new File("path-to-your-image"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(image, 0, 0, this);
        }

        @Override
        public Dimension getPreferredSize() {
            // Panel will be sizes based on dimensions of image
            return new Dimension(image.getWidth(), image.getHeight());
        }
    }
}
Branislav Lazic
  • 14,388
  • 8
  • 60
  • 85
1

It seems to be the layout problem. The most obvious solution is to wrap you image panel into another container with proper layout, so your panel will always have the same size.

ferrerverck
  • 618
  • 3
  • 9
  • 17