简体   繁体   English

Java - JFrame、JPanel、布局和剪裁

[英]Java - JFrame, JPanel, Layout, and Clipping

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). 1) 我创建了一个面板来保存我的游戏图形(玩家区域)。 The panel is supposed to be 800x800 and clip everything that lies below and to the right.该面板应该是 800x800 并剪辑位于下方和右侧的所有内容。 But when I add the graphics panel to a JFrame, it doesn't clip.但是当我将图形面板添加到 JFrame 时,它​​不会剪辑。 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.stack.imgur.com/idL8f.png图片#1: http : //i.stack.imgur.com/idL8f.png

Now, here's what happens when I press play to start.现在,当我按下播放开始时会发生什么。

Picture #2: http://i.stack.imgur.com/dxtbe.png图片#2: http : //i.stack.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?如何设置面板/框架,以便图形仅占用 800x800(如第一张图片)而其他所有内容都被剪裁?

2) I'm a bit confused about how I can set up the JFrame. 2) 我对如何设置 JFrame 有点困惑。 This is how I want it to be layed out:这是我希望它的布局方式:

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

How would you lay the JFrame/Panels out?你会如何布置 JFrame/Panels? I was thinking BorderLayout, but I'm not certain it would work out.我在考虑 BorderLayout,但我不确定它是否会奏效。

3) For this game, my class that extends JFrame also contains main(). 3) 对于这个游戏,我扩展 JFrame 的类也包含 main()。 Is this bad practice?** Are you supposed to not extend JFrame on the main class?这是不好的做法吗?** 你不应该在主类上扩展 JFrame 吗?

  1. The easiest way to get an 800x800 panel is to use setPreferredSize() and then pack() the JFrame that contains is.获得 800x800 面板的最简单方法是使用setPreferredSize()然后pack()包含的JFrame Conveniently, pack() "Causes this Window to be sized to fit the preferred size and layouts of its subcomponents."方便地, pack() “使这个Window大小适合其子组件的首选大小和布局。”

2). 2)。 See A Visual Guide to Layout Managers for layout suggestions.有关布局建议,请参阅布局管理器可视指南 You can use nested panels to achieve your desired layout.您可以使用嵌套面板来实现所需的布局。

3). 3)。 There's nothing wrong with extending JFrame , but there's little point unless you are modifying the behavior of JFrame .扩展JFrame没有任何问题,但除非您修改JFrame行为,否则没有什么意义。 In contrast, JPanel is a convenient container for grouping components;相比之下, JPanel是一个方便的组件分组容器; 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.除了 x 和 y 方向的 800 像素之外,我不希望面板显示任何内容。

You can override paintComponent() and copy whatever portion of the image is desired.您可以覆盖paintComponent()并复制所需的图像部分。 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.在下面的示例中, g.drawImage(img, 0, 0, null)绘制图像的左上角 800 像素,而g.drawImage(img, 0, 0, getWidth(), getHeight(), null)缩放面板大小的图像。 Note that f.setResizable(false) prevents changing the window's size.请注意, f.setResizable(false)可防止更改窗口的大小。

Addendum: You can also copy arbitrary portions of the source image to arbitrary areas of the the destination panel, as shown below.附录:您还可以将源图像的任意部分复制到目标面板的任意区域,如下所示。 Also consider overriding getPreferredSize() , as suggested here .也可以考虑覆盖getPreferredSize()作为建议在这里

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();
            }
        });
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM