2011-09-13 51 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中編寫自己的框架裝飾的人。

編輯:下載OpenJDK的,並通過本機代碼挖後,我發現,Java正在調用Win32函數SetWindowPlacement和改變MINMAXINFO一定條件下可以得到正確的窗口大小。我認爲我所看到的是沒有標題或邊框的窗口的默認窗口行爲(儘管我無法在任何地方找到它)。我發現調用JFrame.setMaximizedBounds()提供了用來改變win32 MINMAXINFO結構的邊界。因此,通過改變我的行爲,並進行使用camickr作爲我MaximizedBounds建議的窗口大小,我有點接近:

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

現在最大化窗口不再隱藏菜單欄。但是..現在我有另一個問題。我無法從輔助監視器最大化。框架剛剛消失。

我添加了一些win32標籤,希望得到一個C++程序員認識到這個問題。

SOLUTION:我顯然不能回答我自己的問題,所以我只是把我的解決方案放在這裏。我不得不使用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

有趣。當我嘗試它時,它似乎分兩步發生。首先展開以填充任務欄上方的空間,然後在一秒之後它覆蓋任務欄。我不知道爲什麼。

反正的解決方法,你可以使用:

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

手動設置幀的邊界,當你想最大化。

+0

這似乎讓我更接近,但設置的邊界幀將擴展狀態重置爲「正常」。我可以創建自己的框架子類並跟蹤自己的擴展狀態和以前的界限,但操作系統並不知道這種模擬狀態,並會以微妙的小方式背叛我。另外,我需要找到一些方法來獲取多個監視器上的窗口邊界。 –

+0

這是追蹤界限和陳述自己的想法。我不知道這些微妙的問題可能是什麼,我不能在那裏提供更多的建議。我從來沒有玩過它,但對於多個顯示器,你可以看看'GraphicsDevice'類。 – camickr