2017-04-18 94 views
0

我試圖使我的JFrame使用下面的代碼在Mac OSX上的我的擴展塢旁邊顯示,但它不起作用。是否有可能讓框架出現在那裏?我正在使用Java。這可以在Mac OSX上實現嗎?

frame.setLocation(5, Toolkit.getDefaultToolkit().getScreenSize().height-45); 

以下是我總是得到:
enter image description here

這裏是我想達到的目標:
enter image description here

回答

1

是的,但你需要利用GraphicsDevice的,GraphicsEnvironmentGraphicsConfiguration APIs

Toolkit#getScreenSize只是臨時T,它返回屏幕的尺寸,但它並沒有包括所有的操作系​​統元素,如碼頭,它佔用額外的空間

Sitting upon the dock

所以,這是一幫庫代碼,設計找到GraphicsDevice特定組件駐留,或者默認GraphicsDevice ...庫中的代碼;)

public static Rectangle getDefaultScreenBounds() { 
    return getScreenBounds(null, true); 
} 

public static Rectangle getScreenBounds(Component comp, boolean acceptDefault) { 
    Rectangle bounds = getScreenBounds(comp); 
    if ((bounds == null || (bounds.x == 0 && bounds.y == 0 && bounds.width == 0 && bounds.height == 0)) && acceptDefault) { 
     GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
     GraphicsDevice gd = ge.getDefaultScreenDevice(); 
     bounds = gd.getDefaultConfiguration().getBounds(); 
    } 
    return bounds; 
} 

public static Rectangle getScreenBounds(Component comp) { 
    Rectangle bounds = new Rectangle(0, 0, 0, 0); 
    GraphicsDevice gd = getGraphicsDevice(comp); 

    if (gd != null) { 
     GraphicsConfiguration gc = gd.getDefaultConfiguration(); 
     bounds = gc.getBounds(); 
    } 
    return bounds; 
} 

public static GraphicsDevice getGraphicsDevice(Component comp) { 
    GraphicsDevice device = null; 
    GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
    GraphicsDevice lstGDs[] = ge.getScreenDevices(); 
    List<GraphicsDevice> lstDevices = new ArrayList<>(lstGDs.length); 
    if (comp != null && comp.isVisible()) { 
     Rectangle parentBounds = comp.getBounds(); 
     /* 
     * If the component is not a window, we need to find its location on the 
     * screen... 
     */ 
     if (!(comp instanceof Window)) { 
      Point p = new Point(0, 0); 
      SwingUtilities.convertPointToScreen(p, comp); 
      parentBounds.setLocation(p); 
     } 

     for (GraphicsDevice gd : lstGDs) { 
      GraphicsConfiguration gc = gd.getDefaultConfiguration(); 
      Rectangle screenBounds = gc.getBounds(); 
      if (screenBounds.intersects(parentBounds)) { 
       lstDevices.add(gd); 
      } 
     } 
     if (lstDevices.size() == 1) { 
      device = lstDevices.get(0); 
     } else { 
      GraphicsDevice gdMost = null; 
      float maxArea = 0; 

      for (GraphicsDevice gd : lstDevices) { 
       GraphicsConfiguration gc = gd.getDefaultConfiguration(); 
       Rectangle bounds = gc.getBounds(); 

       Rectangle2D intBounds = bounds.createIntersection(parentBounds); 
       float perArea = (float) ((intBounds.getWidth() * intBounds.getHeight())/(parentBounds.width * parentBounds.height)); 
       if (perArea > maxArea) { 
        maxArea = perArea; 
        gdMost = gd; 
       } 
      } 
      if (gdMost != null) { 
       device = gdMost; 
      } 
     } 
    } 

    return device; 
} 

而且,這是如何使用它...

package javaapplication1.pkg169; 

import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GraphicsConfiguration; 
import java.awt.GraphicsDevice; 
import java.awt.GraphicsEnvironment; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.awt.Window; 
import java.awt.geom.Rectangle2D; 
import java.util.ArrayList; 
import java.util.List; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

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 (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       Rectangle bounds = getDefaultScreenBounds(); 
       System.out.println(bounds); 
       int x = bounds.x + ((bounds.width - frame.getWidth())/2); 
       frame.setLocation(x, bounds.y + (bounds.height - frame.getHeight())); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     public TestPane() { 
     } 

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

    } 

    public static Rectangle getDefaultScreenBounds() { 
     return getScreenBounds(null, true); 
    } 

    public static Rectangle getScreenBounds(Component comp, boolean acceptDefault) { 
     Rectangle bounds = getScreenBounds(comp); 
     if ((bounds == null || (bounds.x == 0 && bounds.y == 0 && bounds.width == 0 && bounds.height == 0)) && acceptDefault) { 
      GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
      GraphicsDevice gd = ge.getDefaultScreenDevice(); 
      bounds = gd.getDefaultConfiguration().getBounds(); 
     } 
     return bounds; 
    } 

    public static Rectangle getScreenBounds(Component comp) { 
     Rectangle bounds = new Rectangle(0, 0, 0, 0); 
     GraphicsDevice gd = getGraphicsDevice(comp); 

     if (gd != null) { 
      GraphicsConfiguration gc = gd.getDefaultConfiguration(); 
      bounds = gc.getBounds(); 
     } 
     return bounds; 
    } 

    public static GraphicsDevice getGraphicsDevice(Component comp) { 
     GraphicsDevice device = null; 
     GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
     GraphicsDevice lstGDs[] = ge.getScreenDevices(); 
     List<GraphicsDevice> lstDevices = new ArrayList<>(lstGDs.length); 
     if (comp != null && comp.isVisible()) { 
      Rectangle parentBounds = comp.getBounds(); 
      /* 
      * If the component is not a window, we need to find its location on the 
      * screen... 
      */ 
      if (!(comp instanceof Window)) { 
       Point p = new Point(0, 0); 
       SwingUtilities.convertPointToScreen(p, comp); 
       parentBounds.setLocation(p); 
      } 

      for (GraphicsDevice gd : lstGDs) { 
       GraphicsConfiguration gc = gd.getDefaultConfiguration(); 
       Rectangle screenBounds = gc.getBounds(); 
       if (screenBounds.intersects(parentBounds)) { 
        lstDevices.add(gd); 
       } 
      } 
      if (lstDevices.size() == 1) { 
       device = lstDevices.get(0); 
      } else { 
       GraphicsDevice gdMost = null; 
       float maxArea = 0; 

       for (GraphicsDevice gd : lstDevices) { 
        GraphicsConfiguration gc = gd.getDefaultConfiguration(); 
        Rectangle bounds = gc.getBounds(); 

        Rectangle2D intBounds = bounds.createIntersection(parentBounds); 
        float perArea = (float) ((intBounds.getWidth() * intBounds.getHeight())/(parentBounds.width * parentBounds.height)); 
        if (perArea > maxArea) { 
         maxArea = perArea; 
         gdMost = gd; 
        } 
       } 
       if (gdMost != null) { 
        device = gdMost; 
       } 
      } 
     } 

     return device; 
    } 

} 
+0

我看着你的代碼和真相被告知我不太瞭解Graphics Environment,但我確實發現了這一點:1.從我在你添加的圖片中看到的,框架仍然出現在碼頭上方2.如果我改變將框架設置爲「未修飾」,然後框架可以通過設置其位置出現在碼頭的旁邊和後面。那麼,你認爲OSX限制裝飾幀的邊界在碼頭之上嗎?對不起,我很難理解Graphics,因爲我是新手。無論哪種方式你的答案是完整的,並幫助我瞭解了很多,所以我接受它。 – Lae