Java - JFrame,JPanel,布局和剪辑

5
我有三个问题/问题。(注意-我没有足够的声望来发布图片,所以我把它们链接起来了。并且我需要混淆它们...)
1)我创建了一个面板,用于保存我的游戏图形(玩家区域)。该面板应为800x800,并裁剪下方和右侧的所有内容。但是,当我将图形面板添加到JFrame时,它不会剪辑。因此,图像在右侧和左侧上方。 这是游戏开始的图片。理想情况下,整个游戏中图形都将始终在此矩形中:
图片#1:http://i.stack.imgur.com/idL8f.png 现在,这是我按播放键启动时发生的情况。
图片#2:http://i.stack.imgur.com/dxtbe.png 如何设置面板/框架,使图形仅占用800x800(如第一张图片),而其他所有内容都被裁剪?
2)我对如何设置JFrame有点困惑。这就是我想要的布局方式:
图片#3:http://i.stack.imgur.com/ZyJS5.png 您将如何布置JFrame /面板?我想到了BorderLayout,但我不确定它是否会奏效。
3)对于这个游戏,扩展JFrame的类也包含main()。这是不好的做法吗?**您是否应该在主类上不扩展JFrame?

已编辑;如果不正确,请恢复。 - trashgod
你是指 裁剪_、_剪裁 还是 _缩放_? - trashgod
@trashgod:我的意思是,我希望游戏包含在其最初的800x800矩形中并显示出来。我不希望面板在x和y方向上显示任何800像素的内容。(因此,溢出的图像仍将超过每个方向的800像素,但不会被显示。) - Dan James
1个回答

4
  1. 获取800x800面板的最简单方法是使用setPreferredSize(),然后pack()包含它的JFrame。方便的是,pack()“使此Window的大小适合其子组件的首选大小和布局。”

2). 请参阅布局管理器的可视化指南以获取布局建议。您可以使用嵌套面板来实现所需的布局。

3). 扩展JFrame没有什么不对,但除非您修改了JFrame的行为,否则没有什么意义。相比之下,JPanel是用于分组组件的方便容器;它被设计为可扩展的。您可以考虑在这个示例中进行检查。

补充:

我不想让面板显示除了x和y方向上的800像素以外的任何东西。

您可以覆盖paintComponent()并复制所需图像的任何部分。在下面的示例中,g.drawImage(img, 0, 0, null)绘制图像的左上角800像素,而g.drawImage(img, 0, 0, getWidth(), getHeight(), null)将图像缩放为面板的大小。请注意,f.setResizable(false)防止更改窗口的大小。

补充:您还可以将源图像的任意部分复制到目标面板的任意区域,如下所示。还考虑覆盖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 https://dev59.com/olDTa4cB1Zd3GeqPNOUB */
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();
            }
        });
    }
}

对于问题#3,修改行为意味着什么?扩展与实例化JFrame是否以任何方式改变了人们允许使用JFrame的方式? - Dan James
@Dan James:根据我对你上面评论的理解,我添加了一个示例。 - trashgod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接