【问题标题】:Java - JFrame, JPanel, Layout, and ClippingJava - JFrame、JPanel、布局和剪辑
【发布时间】:2011-04-20 14:13:48
【问题描述】:

我有三个问题/问题。 (注意 - 我没有足够的声誉来发布照片,所以我将它们链接起来。我需要混淆它们......)

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/Panel?我在考虑 BorderLayout,但我不确定它会成功。

3) 对于这个游戏,我扩展 JFrame 的类也包含 main()。这是不好的做法吗?** 你不应该在主类上扩展 JFrame 吗?

【问题讨论】:

  • 已编辑;如果不正确,请恢复。
  • 你的意思是clippingcropping还是scaling
  • @trashgod:我的意思是,我希望将游戏包含在其中并显示它最初所在的 800x800 矩形。我不希望面板通过 x 和 y 中的 800 像素显示任何内容方向。 (所以溢出的图像仍然会在每个方向超过 800,但不会显示。)

标签: java swing layout jframe jpanel


【解决方案1】:
  1. 获得 800x800 面板的最简单方法是使用 setPreferredSize(),然后使用 pack() 包含的 JFrame。方便的是,pack() “导致此 Window 的大小适合其子组件的首选大小和布局。”

2)。有关布局建议,请参阅 A Visual Guide to Layout Managers。您可以使用嵌套面板来实现所需的布局。

3)。扩展JFrame 并没有错误,但除非你修改JFrame行为,否则没有什么意义。相比之下,JPanel 是一个方便的组件分组容器; 设计是为了扩展。你可以在这方面检查这个example

附录:

我不希望面板只显示 x 和 y 方向上的 800 像素。

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

附录:您还可以将源图像的任意部分复制到 目标面板,如下所示。还可以考虑覆盖getPreferredSize(),正如建议的here

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

【讨论】:

  • 对于#3,修改行为需要什么?扩展与实例化 JFrame 是否会改变允许以任何方式使用 JFrame 的方式?
  • @Dan James:根据我对您上述评论的理解,我添加了一个示例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-24
  • 2011-05-25
  • 2012-09-24
  • 2012-01-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多