为了账号安全,请及时绑定邮箱和手机立即绑定

JFrame 太小,pack() 似乎不起作用

JFrame 太小,pack() 似乎不起作用

幕布斯6054654 2021-10-20 11:11:16
由于某种原因,运行时 JFrame 太小,使用pack();似乎并不能解决问题。有任何想法吗?   public class Window {    public Window(String title, Game game) {        // Creates new JFrame        JFrame frame = new JFrame(title);        // Adds Game to window        frame.add(game);        frame.pack();           // Settings of Window        frame.setResizable(false);        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        frame.setLocationRelativeTo(null);        frame.setVisible(true);    }}青色背景应该是底部和右侧的 64 x 64 边框。绘制的框是正确的,我通过调整窗口大小来检查。但是窗口太小,不适合画布。游戏类:public class Game extends Canvas implements Runnable {private Handler handler;public Game() {    // Create new window    Window window = new Window("Horses Aren't Real", this);    handler = new Handler();    this.addKeyListener(new KeyInput(handler));    handler.addObject(new Daanish(100, 100, ID.Player, handler));}public static void main (String args[]) {    // Creates new game    new Game();}public void draw() {    // Creates a new BufferStrategy    BufferStrategy bs = this.getBufferStrategy();    if (bs == null) {        // This allows the game to preload 3 frames in order to prevent choppy framrate        this.createBufferStrategy(3);        return;    }    // Create Graphics    Graphics g = bs.getDrawGraphics();    g.setColor(Color.cyan);    g.fillRect(0, 0, 1024, 640);    g.setColor(Color.black);    g.fillRect(0, 0, 960, 576);    handler.draw(g);    // Remove frame from queue    g.dispose();    bs.show();}@Overridepublic Dimension getPreferredSize() {    return new Dimension(1024, 640);}}
查看完整描述

2 回答

?
千万里不及你

TA贡献1784条经验 获得超9个赞

所以你遇到了很多问题。首先,窗口的大小还必须考虑框架装饰,这意味着内容的可用空间是窗口的大小减去框架装饰的大小。


直接设置窗口的大小是不明智的。


pack询问框架的内容以获得它的首选大小,并使用它来环绕它的窗口。所以,而不是window size - decorations = content size,你有content size + decorations = window size


来自JavaDocs


使此窗口的大小适合其子组件的首选大小和布局。如果任一维度小于先前调用 setMinimumSize 方法指定的最小尺寸,则生成的窗口宽度和高度将自动放大。


所以,相反,覆盖preferredSize了的Game类并返回你想要的空间大小,可能是类似...


public class Game extends JPanel {

    //...

    @Override

    public Dimension getPreferredSize() {

        return new Dimension(800, 600);

    }

    //...

}

你的下一个问题是,Windowextends from JFrame,但在构造函数中,你正在创建Frame另一个......那么哪个实际上在做什么?


消除混乱。避免从像 那样的顶级容器扩展JFrame,你不会向它添加任何新功能


public class Window {


    public Window(String title, Game game) {


        // Creates new JFrame

        JFrame frame = new JFrame(title);


        // Adds Game to window

        frame.add(game);

        frame.pack();


        // Settings of Window

        frame.setResizable(false);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setLocationRelativeTo(null);

        frame.setVisible(true);


    }


}

更新...

所以,我拿了你的“更新”代码,修改了它,让它运行,运行并且没有任何问题......


import java.awt.Canvas;

import java.awt.Color;

import java.awt.Dimension;

import java.awt.EventQueue;

import java.awt.Graphics;

import java.awt.image.BufferStrategy;

import javax.swing.JFrame;

import javax.swing.UIManager;

import javax.swing.UnsupportedLookAndFeelException;


public class Test {


    public static void main(String[] args) {

        new Test();

    }


    public Test() {

        EventQueue.invokeLater(new Runnable() {

            @Override

            public void run() {

                try {

                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {

                    ex.printStackTrace();

                }


                Game game = new Game();

                Window window = new Window("Help", game);


                game.start();

            }

        });

    }


    public class Window {


        public Window(String title, Game game) {


            // Creates new JFrame

            JFrame frame = new JFrame(title);


            // Adds Game to window

            frame.add(game);

            frame.setResizable(false);

            frame.pack();


            // Settings of Window

            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            frame.setLocationRelativeTo(null);

            frame.setVisible(true);


        }


    }


    public class Game extends Canvas { //implements Runnable {


//      private Handler handler;


        public Game() {

//

//          handler = new Handler();

//          this.addKeyListener(new KeyInput(handler));

//

//          handler.addObject(new Daanish(100, 100, ID.Player, handler));


        }


        public void start() {

            Thread thread = new Thread(new Runnable() {

                @Override

                public void run() {

                    while (true) {

                        draw();

                        try {

                            Thread.sleep(40);

                        } catch (InterruptedException ex) {

                        }

                    }

                }

            });

            thread.start();

        }


        public void draw() {


            // Creates a new BufferStrategy

            BufferStrategy bs = this.getBufferStrategy();


            if (bs == null) {

                // This allows the game to preload 3 frames in order to prevent choppy framrate

                this.createBufferStrategy(3);

                return;

            }


            // Create Graphics

            Graphics g = bs.getDrawGraphics();


            g.setColor(Color.cyan);

            g.fillRect(0, 0, 1024, 640);


            g.setColor(Color.black);

            g.fillRect(0, 0, 960, 576);


//          handler.draw(g);


            // Remove frame from queue

            g.dispose();

            bs.show();


        }


        @Override

        public Dimension getPreferredSize() {

            return new Dimension(1024, 640);

        }


    }


}

但是,我在 MacOS 上运行。setResizable我在 Windows 上遇到过一个鲜为人知的问题,窗口装饰在setResizable被调用时会改变大小。


“基本”解决方案是调用setResziableBEFORE 调用pack,以便在 API 决定如何更新窗口大小之前修改框架装饰。


我原以为这会在以后的 (8+) 版本的 Java 中修复,但由于我不运行 Windows,因此无法进行测试



查看完整回答
反对 回复 2021-10-20
?
桃花长相依

TA贡献1860条经验 获得超8个赞

public class Window extends JFrame {


public Window(final int width, final int height, String title, Game game) {

    super(title);

    // Set dimensions

    Dimension d = new Dimension(width, height);

    game.setPreferredSize(d);


    // Adds Game to window

    add(game);

    // Settings of Window

    setResizable(false);

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    setLocationRelativeTo(null);

    pack();

    setVisible(true);


}


}

使用 pack 时,框架通常会调整为内容大小


查看完整回答
反对 回复 2021-10-20
  • 2 回答
  • 0 关注
  • 274 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信