2012-08-26 2 views
1

Java에서 시스템 트레이 응용 프로그램을 만들 수 있지만 위치 지정에 문제가 있습니다. 이 프로그램은 단지 몇 개의 입력/출력을 처리 할 필요가 있으므로 쉽게 액세스 할 수 있기를 바랍니다.Java의 시스템 트레이에서 JFrame을 가져 오는 방법

내 질문에 내 응용 프로그램의 시스템 트레이 아이콘을 클릭하면 어떻게 시스템 트레이 위에 우아하게 위치를 설정할 수 있습니까? 요구 사항은 디스플레이 설정 (해상도, 다중 모니터 등) 및 작업 표시 줄 위치에 관계없이이 작업을 수행하는 것입니다. 용지함 가까이에 열지 말고 용지를 놓는 방법이 있습니까?

"네트워크"설정 단추가 Windows에서하는 것과 정확히 일치하게하고 싶습니다. 다음과 유사한 :

Network System Tray Image

이 자바로 가능할까요?

답변

8

불칸 (Vulcan)이 지적한 것처럼 그렇습니다.

또한, 팝업을 배치 할 위치를 (작업 아이콘이 어디에 위치에 관련성) 작업 표시 줄에 있지

Show me the popup

public class TestTrayIcon { 

    protected static final PopupFrame POPUP_FRAME = new PopupFrame(); 

    public static void main(String[] args) { 

     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 

       try { 
        TrayIcon trayIcon = new TrayIcon(ImageIO.read(new File("D:/DevWork/common/icons/iconex_v_bundle_png/iconexperience/v_collections_png/basic_foundation/16x16/plain/about.png"))); 
        trayIcon.addMouseListener(new MouseAdapter() { 
         @Override 
         public void mouseClicked(MouseEvent e) { 

          Point pos = e.getLocationOnScreen(); 
          Rectangle screen = getScreenBoundsAt(pos); 

          if (pos.x + POPUP_FRAME.getWidth() > screen.x + screen.width) { 
           pos.x = screen.x + screen.width - POPUP_FRAME.getWidth(); 
          } 
          if (pos.x < screen.x) { 
           pos.x = screen.x; 
          } 

          if (pos.y + POPUP_FRAME.getHeight() > screen.y + screen.height) { 
           pos.y = screen.y + screen.height - POPUP_FRAME.getHeight(); 
          } 
          if (pos.y < screen.y) { 
           pos.y = screen.y; 
          } 

          POPUP_FRAME.setLocation(pos); 
          POPUP_FRAME.setVisible(true); 

         } 
        }); 
        SystemTray.getSystemTray().add(trayIcon); 
       } catch (Exception ex) { 
        ex.printStackTrace(); 
       } 
      } 
     }); 
    } 

    public static class PopupFrame extends JFrame { 

     public PopupFrame() throws HeadlessException { 
      setLayout(new BorderLayout()); 
      add(new JLabel("Hello world")); 
      pack(); 
     } 
    } 

    public static Rectangle getScreenBoundsAt(Point pos) { 
     GraphicsDevice gd = getGraphicsDeviceAt(pos); 
     Rectangle bounds = null; 

     if (gd != null) { 
      bounds = gd.getDefaultConfiguration().getBounds(); 
      Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(gd.getDefaultConfiguration()); 

      bounds.x += insets.left; 
      bounds.y += insets.top; 
      bounds.width -= (insets.left + insets.right); 
      bounds.height -= (insets.top + insets.bottom); 
     } 
     return bounds; 
    } 

    public static GraphicsDevice getGraphicsDeviceAt(Point pos) { 
     GraphicsDevice device = null; 

     GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
     GraphicsDevice lstGDs[] = ge.getScreenDevices(); 

     ArrayList<GraphicsDevice> lstDevices = new ArrayList<GraphicsDevice>(lstGDs.length); 

     for (GraphicsDevice gd : lstGDs) { 
      GraphicsConfiguration gc = gd.getDefaultConfiguration(); 
      Rectangle screenBounds = gc.getBounds(); 

      if (screenBounds.contains(pos)) { 
       lstDevices.add(gd); 
      } 
     } 

     if (lstDevices.size() == 1) { 
      device = lstDevices.get(0); 
     } 
     return device; 
    } 
} 
+0

멋지고 지능적인 접근법. 훨씬 더 포괄적 인 나의 것보다. 너무 이른 아침에 그렇게하는 것에 대한 명성. +1 – Vulcan

+0

@ Vulcan Shhh, 이전 프로젝트의 코드를 훔쳤습니다.) – MadProgrammer

+0

불행히도 내 대답도 했었습니다 : P 내 응용 프로그램이 클릭하면 창을 팝업하지 않고 오히려 키 콤보를 눌렀을 때 창에 업로드 진행 상황이 표시되는 클립 보드 업로드 응용 프로그램).하지만 나중에 여기에서 지적한 사례를 고려하여 다시 작성하겠습니다. 감사합니다. – Vulcan

4

예, 가능합니다.

화면의 오른쪽 하단을 기준으로 창의 위치를 ​​설정하려면 그래픽 환경의 최대 창 경계를 얻은 다음 간단한 수학을 수행하면됩니다.

Rectangle screen = GraphicsEnvironment.getLocalGraphicsEnvironment() 
     .getMaximumWindowBounds(); 
String os = System.getProperty("os.name"); 
if (os.contains("Windows")) { 
    setLocation(screen.width - windowSize.width - 6, screen.height - windowSize.height - 6); 
} else if (os.contains("Mac")) { 
    setLocation(screen.width - windowSize.width + 6, 6); 
} 

모두 폭의 - 6 높이, 윈도우 작업 표시 줄 사이의 작은 간극을 차지하며 쉽게 맞춤형이다.

그러나이 방법을 사용하면 위쪽 또는 왼쪽에있는 Windows 작업 표시 줄에는 창의 오른쪽/아래쪽에 작업 표시 줄 크기의 간격이 유지됩니다. Java API만으로는 작업 표시 줄 방향을 찾는 것이 불가능하다고 저는 믿습니다.

+2

어떤 경우에 고려하는 것이 매우 가능 화면 하단? – MadProgrammer

+0

@MadProgrammer 매우 적은 비율의 사람이 Windows 작업 표시 줄을 맨 아래가 아닌 다른 위치에 배치합니다. Java API에서 어떤면이 있는지 감지하는 방법이 있는지 확실하지 않습니다. Windows 7 상단의 작업 표시 줄을 사용하면 창 오른쪽 아래에 작업 표시 줄 높이가 창 아래에 표시됩니다. – Vulcan

+0

그 작은 비율에있는 사람을 맞춰보세요.) - 또한 Mac을 할인하고 있습니다.) – MadProgrammer