3

以下にリストしたプログラムを実行すると、望ましくない結果が生じる場合があることに気付きました。

編集: わかりやすくするためにコードを簡略化しました。現在のコンポーネント サイズを出力する String を描画しています。Component クラスの getPreferredSize() メソッドをオーバーライドし、幅と高さをそれぞれ 640 x 512 に設定しました。ただし、プログラムを実行した後も、640 x 512 と 650 x 522 という異なる結果が得られます。しかし、ウィンドウのサイズを変更できるようにしたい

import java.awt.*;

import javax.swing.*;

public class DrawTest
{
    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                DrawFrame frame = new DrawFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setResizable(false);
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}


class DrawFrame extends JFrame
{

    private static final long serialVersionUID = 1L;
    public DrawFrame()
    {
        setTitle("DrawTest");
        setLocationByPlatform(true);
        Container contentPane = getContentPane();
        DrawComponent component = new DrawComponent();
        contentPane.add(component);
    }

}

class DrawComponent extends JComponent
{
    private static final long serialVersionUID = 1L;
    public Dimension getPreferredSize() {
        return new Dimension(640, 512);
    }

    public void paintComponent(Graphics g)
    {
        Graphics2D g2 = (Graphics2D) g;         
        String msg = getWidth() + " x " + getHeight();      
        g2.setPaint(Color.BLUE);
        g2.drawString(msg, getWidth()/2, getHeight()/2);
    }
}

4

2 に答える 2

3

の呼び出しは、の後にsetLocationByPlatform()続く必要があります。そうしないと、ジオメトリが間違ってしまいます。サブクラス化する理由がないので、以下の例を省略しました。を使用して、囲んでいるコンテナのサイズが変更されたときにテキストを中央に配置することに注意してください。このアプローチは、レイアウトを学習するのに便利です。pack()setVisible()JFrameDrawFrameFontMetrics

ここに画像の説明を入力してください

import java.awt.*;
import javax.swing.*;

public class DrawTest {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("DrawTest");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new DrawComponent());
                frame.pack();
                frame.setLocationByPlatform(true);
                frame.setVisible(true);
            }
        });
    }
}

class DrawComponent extends JComponent {

    private static final long serialVersionUID = 1L;

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(320, 240);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        String msg = getWidth() + " x " + getHeight();
        g2.setPaint(Color.BLUE);
        int w = (getWidth() - g.getFontMetrics().stringWidth(msg)) / 2;
        g2.drawString(msg, w, getHeight() / 2);
    }
}
于 2012-07-19T19:21:58.277 に答える
3

おそらく、ネイティブ ウィンドウ システムが、フレーム サイズの設定などの要求を無視する可能性があるためです。
setSize() メソッドにも同様の問題があります。

http://docs.oracle.com/javase/7/docs/api/java/awt/Window.html#setSize%28java.awt.Dimension%29

「メソッドはジオメトリ関連のデータを変更します。したがって、ネイティブ ウィンドウ システムはそのような要求を無視するか、要求されたデータを変更して、Window オブジェクトがデスクトップ設定に密接に対応する方法で配置およびサイズ設定されるようにすることができます。」

簡単なテスト、試してください:

public Dimension getPreferredSize() {
    return new Dimension(2000, 1000);
}

同様の設定はおそらく無視されます。

このトピックも確認してください: setSize() は JFrame では機能しません

于 2012-07-19T20:00:55.717 に答える