views:

111

answers:

1

I have three questions/problems. (NOTE - I don't have enough reputation to post pics, so I linked them. And I needed to obfuscate them...)

1) I created a panel that holds my game graphics (the player area). The panel is supposed to be 800x800 and clip everything that lies below and to the right. But when I add the graphics panel to a JFrame, it doesn't clip. So images go over on the right and left. This is a picture of how to game starts. Ideally, the graphics would start in this rectangle the whole time:

Picture #1: http://i.imgur.com/idL8f.png

Now, here's what happens when I press play to start.

Picture #2: http://i.imgur.com/dxtbe.png

How can I set the panel/frame so that the graphics only occupy 800x800 (like the first picture) and everything else is clipped?

2) I'm a bit confused about how I can set up the JFrame. This is how I want it to be layed out:

Picture #3: http://i.imgur.com/ZyJS5.png

How would you lay the JFrame/Panels out? I was thinking BorderLayout, but I'm not certain it would work out.

3) For this game, my class that extends JFrame also contains main(). Is this bad practice?** Are you supposed to not extend JFrame on the main class?

+2  A: 

1) The easiest way to get an 800x800 panel is to use setPreferredSize() and then pack() the JFrame that contains is. Conveniently, pack() "Causes this Window to be sized to fit the preferred size and layouts of its subcomponents."

2). See A Visual Guide to Layout Managers for layout suggestions. You can use nested panels to achieve your desired layout.

3). There's nothing wrong with extending JFrame, but there's little point unless you are modifying the behavior of JFrame. In contrast, JPanel is a convenient container for grouping components; it was designed to be extended. You might examine this example in that regard.

Addendum:

I don't want the panel to show anything but the 800 pixels in the x and y direction.

You can override paintComponent() and copy whatever portion of the image is desired. In the example below, g.drawImage(img, 0, 0, null) draws the top-left 800 pixels of the image, while g.drawImage(img, 0, 0, getWidth(), getHeight(), null) scales the image the panel's size. Note that f.setResizable(false) prevents changing the window's size.

Addendum: You can also copy arbitrary portions of the source image to arbitrary areas of the the destination panel, as shown below.

import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; import javax.swing.JFrame; import javax.swing.JPanel;

/** @see http://stackoverflow.com/q/3851847 */
public class MyPanel extends JPanel {

    private BufferedImage img;

    public MyPanel() {
        this.setPreferredSize(new Dimension(800, 800));
        try {
            img = ImageIO.read(new File("../scratch/image.png"));
        } catch (IOException ex) {
            ex.printStackTrace(System.err);
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
//        g.drawImage(img, 0, 0, 800, 800, null);
//        g.drawImage(img, 0, 0, getWidth(), getHeight(), null);
        g.drawImage(img, 0, 0, 800, 800, 0, 0, 800, 800, this);
    }

    private void display() {
        JFrame f = new JFrame("MyPanel");
//        f.setResizable(false);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new MyPanel().display();
            }
        });
    }
}
trashgod
@trashgod: For #3, what would modifying behavior entail? Does extending vs. instantiating JFrame change how one is allowed to use the JFrame in any way?
Dan James
@Dan James: See also http://forums.sun.com/thread.jspa?threadID=5384235
trashgod
@Dan James: I've added an example based on my understanding of your comment above.
trashgod