2011-09-13 10 views
9

次のSwingコードは、私のマシンや同僚のマシン(すべてのWindows XP &のJava 6)で正常に動作しません。JFrame.setExtendedState(MAXIMIZED_BOTH)は装飾されていないフレームでも動作しますか?

public class Test { 
    public static void main(String[] args) { 
     final JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(800, 600); 
     frame.setLayout(new FlowLayout()); 
     frame.add(new JButton(new AbstractAction("Maximize") { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       frame.setExtendedState((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH ? JFrame.NORMAL : JFrame.MAXIMIZED_BOTH); 
      } 
     })); 
     frame.setUndecorated(true); 
     frame.setVisible(true); 
    } 
} 

これは、ウィンドウを最大化しますが、考慮に入れ、Windowsのタスクを取ることはありません。バー(それは画面いっぱいになります)。 "frame.setUndecorated(true);"をコメントアウトすると、それは正しく動作するようです。

Javadocは、これが機能するはずであることを暗示しているようです。これはJavaのバグですか?特定のリリース、またはWindowsのバージョンに限定されていますか?回避策はありますか?

私はfew workaroundsを見ましたが、それらは不完全なようです。私は自分のフレーム装飾をJavaでコード化する最初の人になることはできません。

EDIT: OpenJDKのをダウンロードしてネイティブコードを掘り後、私は、JavaがWin32関数SetWindowPlacementを呼び出し、右のウィンドウサイズを取得するためにMINMAXINFOを変更するいくつかの条件の下でされることがわかりました。私が見ていたのは、タイトルや枠線のないウィンドウのデフォルトのウィンドウ動作でした(どこにも書かれていませんが)。 JFrame.setMaximizedBounds()を呼び出すと、win32 MINMAXINFO構造体を変更するための境界が提供されることがわかりました。だから私のアクションが実行変更し、私のMaximizedBoundsとしてcamickrによって提案されたウィンドウサイズを使用することによって、私は少し近づくん:

GraphicsConfiguration graphicsConfiguration = frame.getGraphicsConfiguration(); 
frame.setMaximizedBounds(graphicsConfiguration.getBounds()); 
frame.setExtendedState((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH ? JFrame.NORMAL : JFrame.MAXIMIZED_BOTH); 

今最大化ウィンドウはもはやメニューバーが非表示になります。しかし、今、別の問題があります。私はセカンダリモニタから最大化することはできません。フレームが消えるだけです。

この問題を認識しているC++プログラマーを募集して、いくつかのwin32タグを追加しています。

解決策:明らかに自分自身の質問に答えることができないので、ここで解決策を提示します。私は、Sunのクラスを使用していた、と私は、Windows以外のプラットフォーム上でそれをテストしていませんが、これまでのところ、これは複数のモニタ、および複数のタスクバーの設定とうまく動作しているようだ:

GraphicsConfiguration config = frame.getGraphicsConfiguration(); 
Rectangle usableBounds = SunGraphicsEnvironment.getUsableBounds(config.getDevice()); 
frame.setMaximizedBounds(new Rectangle(0, 0, usableBounds.width, usableBounds.height)); 
frame.setExtendedState((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH ? JFrame.NORMAL : JFrame.MAXIMIZED_BOTH); 
+0

このフォーラムにはhttp://download.oracle.com/javase/tutorial/extra/fullscreen/exclusivemode.htmlに関するスレッドがたくさんあります – mKorbel

+0

ありがとうございます、しかし私はフルスクリーンのアプリを作ろうとはしていません。私はおそらく私の目標についてもっとはっきりしていたはずですが、私はオペレーティングシステムのタイトルバーとコントロールを自分のもの(Google Chrome、Microsoft Officeなど)に置き換えようとしています。 Sunは一度これをボックスから外してみようとしていましたが、私は同じ問題を抱えています: 'frame.getRootPane()。setWindowDecorationStyle(JRootPane.FRAME);' –

答えて

4

興味深いです。私はそれを試してみると2つのステップで起こるようです。最初は、タスクバーの上のスペースを埋めるように展開され、その後、分割された後にタスクバーがカバーされます。なぜ私は考えていない。

GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
Rectangle bounds = env.getMaximumWindowBounds(); 
System.out.println("Screen Bounds: " + bounds); 

をあなたはそれを最大限にしたい時に手動でフレームの境界を設定するには:あなたが使用できる回避策についてはとにかく

+0

それは私をもっと近づけるようですが、フレームは、拡張状態を「正常」にリセットする。自分自身のフレームサブクラスを作成し、自分自身の拡張状態と以前の境界を追跡することができますが、オペレーティングシステムはこのシミュレートされた状態を認識せず、微妙な方法で私を裏切ります。さらに、私は、複数のモニタでウィンドウ境界を取得する方法を見つける必要があります。 –

+0

これは、境界を追跡し、自分自身を述べるためのアイデアでした。微妙な問題が何であるかわからないので、私はそれ以上アドバイスを提供することはできません。私はこれまでプレーしていませんが、複数のモニタでは 'GraphicsDevice'クラスを見ることができます。 – camickr

関連する問題