1

我昨天问了一个类似的问题,但是在对我希望完成的事情进行了进一步研究之后,我有理由相信所回答的问题是不充分的,并且本身值得一个新问题,因为昨天的问题将解决一个不同的问题并帮助其他人,但不是我的特定问题问题。在此处链接到上一个问题。

我想要完成的是将 JFrame 的 contentPane 设置为 的大小200,200,但是在绘制两个不同的矩形后,您会注意到明显的差异。请参阅随附的 SSCCE 和随附的图片。

Canvas.getWidth()/getHeight简单地说,我想getContentPane.getWidth()/Height返回我指定的尺寸200,200

参考图片

参考图片

SSCCE 示例

import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class SSCCE extends Canvas implements Runnable {

    private JFrame frame;
    private BufferStrategy bufferStrategy;
    private Graphics2D graphics;
    private boolean running = false;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {             
                SSCCE game = new SSCCE();
                game.setPreferredSize(new Dimension(200,200));
                game.setFocusable(true);
                game.setIgnoreRepaint(true);
                game.frame = new JFrame("SSCCE");
                game.frame.setLayout(new BorderLayout());
                game.frame.getContentPane().setPreferredSize(new Dimension(200,200));
                game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                game.frame.add(game, BorderLayout.CENTER);
                game.frame.pack();
                game.frame.setIgnoreRepaint(true);
                game.frame.setResizable(false);
                game.frame.setLocationRelativeTo(null);
                game.frame.setVisible(true);
                game.start();
            }
        });
    }

    public synchronized void start() {
        this.createBufferStrategy(2);
        bufferStrategy = this.getBufferStrategy();
        graphics = (Graphics2D) bufferStrategy.getDrawGraphics();
        Thread thread = new Thread(this, "main");
        thread.start();
        running = true;
    }

    @Override
    public void run() {
        while (running) {
            graphics = (Graphics2D) bufferStrategy.getDrawGraphics(); 
            graphics.setColor(Color.RED);
            graphics.fillRect(0, 0, 210, 210);
            graphics.setColor(Color.GREEN);
            graphics.fillRect(0, 0, 200, 200);
            graphics.setColor(Color.BLACK);
            graphics.drawString("Specified Width: 200", 0, 10);
            graphics.drawString("Specified Height: 200", 0, 20);
            graphics.drawString("Canvas Width: " + getWidth(), 0, 30);
            graphics.drawString("Canvas Height: " + getHeight(), 0, 40);
            graphics.drawString("Content Pane Width: " + frame.getContentPane().getWidth(), 0, 50);
            graphics.drawString("Content Pane Width: " + frame.getContentPane().getHeight(), 0, 60);
            graphics.drawString("Red Rectangle = 210,200", 0, 70);
            graphics.drawString("Green Retangle = 200,200", 0, 80);
            graphics.dispose();
            bufferStrategy.show();
        }
    }
}
4

1 回答 1

2

据我所知(从示例和其他帖子),问题是框架边框。我能找到的每个示例都将使用一个JWindow或未装饰的框架......

在此处输入图像描述

混合重量和重量轻的组件只会导致流泪,我建议不要Canvas直接在框架中添加。

Swing 本身也是双缓冲的。除非您有特殊问题,否则我建议您尝试在正常的 Swing 管道中进行简单的绘制...

更新

好吧,我有一些坏消息,但我不确定是谁;)

我能够从这里改编这个例子并让它工作......

在此处输入图像描述

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 (Exception ex) {
                }

                Canvas canvas = new Canvas();
                canvas.setPreferredSize(new Dimension(200, 200));

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setIgnoreRepaint(true);
                frame.add(canvas);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                canvas.createBufferStrategy(2);

                Thread t = new Thread(new Painter(canvas));
                t.setDaemon(true);
                t.start();

            }
        });
    }

    public class Painter implements Runnable {

        private Canvas canvas;

        public Painter(Canvas canvas) {
            this.canvas = canvas;
        }

        @Override
        public void run() {
            while (true) {
                BufferStrategy bs = canvas.getBufferStrategy();
                Graphics2D g2d = (Graphics2D) bs.getDrawGraphics();
                g2d.setColor(Color.RED);
                g2d.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());

                int width = canvas.getWidth();
                int height = canvas.getHeight();

                FontMetrics fm = g2d.getFontMetrics();
                g2d.setColor(Color.BLACK);
                g2d.drawString("Size = " + width + "x" + height, 0, fm.getAscent());

                Window w = SwingUtilities.windowForComponent(canvas);
                g2d.drawString("Frame Size = " + w.getWidth() + "x" + w.getHeight(), 0, (fm.getHeight()) + fm.getAscent());

                g2d.dispose();
                bs.show();

                try {
                    Thread.sleep(30);
                } catch (InterruptedException ex) {
                }
            }
        }
    }
}

更多坏消息

在多玩了一些代码之后,我终于可以让你的例子工作了。我只需要删除game.frame.setResizable(false);:P

最后,好消息

先打电话setResizable再打电话包...

于 2013-02-07T02:53:46.640 回答