

Javaで、JFrameを使って2Dゲームを作っているのですが、起動すると、画像のようにたまに右端と下に謎の隙間ができてしまいます。

Layoutをいじってみてもあまり効果がありませんでした。

起動する時によって隙間が出来る時と出来ない時があります。この隙間を出てこなくするにはどうしたらよいのでしょうか。知っている方がいらっしゃいましたら是非ご教授ください。  
[![右と下に隙間が出来ている様子](https://i.stack.imgur.com/4Hmwf.png)](https://i.stack.imgur.com/4Hmwf.png)

**追記**

OSはWindows 7  
Javaのバージョンは"1.8.0_91"  
下記のソースコードでも同様の現象がみられました。

[code]

    public class Test extends JFrame{
        private static final long serialVersionUID = 1L;
    
        public Test(){
            Container cnt = getContentPane();
            MainPanel panel = new MainPanel();
            setResizable(false);
            cnt.add(panel);
            pack();
        }
    
        public static void main(String args[]){
            Test test = new Test();
            test.setVisible(true);
            test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }
    }
    
    public class MainPanel extends JPanel{
        private static final long serialVersionUID = 1L;
        private static final int WIDTH = 500;
        private static final int HEIGHT = 500;
    
        public MainPanel(){
            setPreferredSize(new Dimension(WIDTH, HEIGHT));
        }
    
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            g.setColor(Color.blue);
            g.fillRect(0, 0, WIDTH, HEIGHT);
        }
    }
    
[/code]

[![下記ソースコード](https://i.stack.imgur.com/kO0e5.png)](https://i.stack.imgur.com/kO0e5.png)


CC BY-SA 3.0
2016-06-19T13:01:02.357
26866
2016-06-20T12:07:57.210
2016-06-20T11:10:52.620
16887
16887
question
java swing
JFrameアプリケーションに隙間ができる


以下で引用している`Swing`のチュートリアルに記述されているように、イベント・ディスパッチ・スレッド(`EDT`)内で`Swing`オブジェクトのメソッドを呼ぶというルールを無視していると、たまに変な挙動(`JFrame`のサイズが0になったり、表示位置がズレたりなど)をしたり、再現不可なエラーが発生したりします。

[Lesson: Concurrency in Swing (The Java™ Tutorials > Creating a GUI With
JFC/Swing)](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html)

> ### The Event Dispatch Thread
>
> Swing event handling code runs on a special thread known as the event
> dispatch thread. Most code that invokes Swing methods also runs on this
> thread. This is necessary because most Swing object methods are not "thread
> safe": invoking them from multiple threads risks thread interference or
> memory consistency errors. Some Swing component methods are labelled "thread
> safe" in the API specification; these can be safely invoked from any thread.
> All other Swing component methods must be invoked from the event dispatch
> thread. Programs that ignore this rule may function correctly most of the
> time, but are subject to unpredictable errors that are difficult to
> reproduce.

今回の現象もこれが原因の可能性が高そうなので、上記チュートリアルの左にある目次の[Initial
Threads](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html)にあるように、[SwingUtilities#invokeLater(Runnable)](https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/SwingUtilities.html#invokeLater-
java.lang.Runnable-)などで、`JFrame#pack()`や`JFrame#setVisible()`などの`Swing`メソッドを呼ぶタスクをスケジュールし、`EDT`内で実行することで回避できそうな気がします。

[code]

    import java.awt.*;
    import javax.swing.*;
    
    public class Test2 {
      public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
          @Override
          public void run() {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            f.getContentPane().add(new MainPanel());
            f.setResizable(false);
            f.pack();
            f.setVisible(true);
          }
        });
      }
    }
    
    class MainPanel extends JPanel {
      private static final long serialVersionUID = 1L;
      private static final int WIDTH = 500;
      private static final int HEIGHT = 500;
    
      public MainPanel() {
        super();
        //setPreferredSize(new Dimension(WIDTH, HEIGHT));
      }
      @Override
      public Dimension getPreferredSize() {
        return new Dimension(WIDTH, HEIGHT);
      }
      @Override
      public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.blue);
        g.fillRect(0, 0, WIDTH, HEIGHT);
      }
    }
    
[/code]


CC BY-SA 3.0
2016-06-20T12:07:57.210
26894
2016-06-20T12:07:57.210
46
26866
answer