1

私は昨日同様の質問をしましたが、私が達成したいことについてさらに調査した後、昨日の質問は別の問題を解決し、他の人を助けるが、私の特定のものではないため、回答された質問は不十分であり、それ自体で新しい質問に値すると信じる理由があります問題。前の質問へのリンクはこちら

私が達成しようとしているのは、JFrame の contentPane を のサイズに設定することですが200,200、2 つの異なる長方形を描画すると、明らかな違いに気付くでしょう。付属の SSCCE と添付の写真を参照してください。

簡単に言えば、指定されたサイズを返品したいCanvas.getWidth()/getHeightと思います。getContentPane.getWidth()/Height200,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 に答える