2012-05-03 5 views
3

메뉴를 여는 단추의 y 위치에 따라 JPopupMenu의 위치를 ​​설정하고 싶습니다. 내 코드는 내 첫 번째 모니터에서 제대로 작동하지만 다른 두 번째 모니터에서는 오류가 발생합니다. getLocationOnScreen()은 구성 요소가 표시된 실제 화면이 아니라 기본 화면을 기준으로 위치를 전달하는 문제입니다.현재 모니터에서 구성 요소 위치 가져 오기

내 코드 :

// screenSize represents the size of the screen where the button is 
// currently showing 
final Rectangle screenSize = dateButton.getGraphicsConfiguration().getBounds(); 

final int yScreen = screenSize.height; 
int preferredY; 

// getLocationOnScreen does always give the relative position to the main screen 
if (getLocationOnScreen().y + dateButton.getHeight() + datePopup.getPreferredSize().height > yScreen) { 
    preferredY = -datePopup.getPreferredSize().height; 
} else { 
    preferredY = getPreferredSize().height; 
} 

datePopup.show(DateSpinner.this, 0, preferredY); 

이 어떻게 실제 모니터에 구성 요소의 위치를 ​​얻을 수 있나요?

답변

5

내가 두 번째 화면의 경계를 사용하여이에 대한 해결책을 가지고, 그것은 매우 간단합니다 : 귀하의 답변

public static Point getLocationOnCurrentScreen(final Component c) { 
    final Point relativeLocation = c.getLocationOnScreen(); 

    final Rectangle currentScreenBounds = c.getGraphicsConfiguration().getBounds(); 

    relativeLocation.x -= currentScreenBounds.x; 
    relativeLocation.y -= currentScreenBounds.y; 

    return relativeLocation; 
} 

감사합니다!

+1

보조 모니터가 반대 위치에 있다면 어떻게 될까요? 기본 및 보조 모니터가 변경되면 어떻게됩니까? – Stefan

+0

"+ ="이 아니어야합니까? –

1

일반적으로 "getLocationOnScreen()"을 호출하면 구성 요소 "this"의 위치를 ​​가져옵니다 (코드에서 "this"가 누구인지 이해하지 못합니다).

'button.getLocationOnScreen()'을 사용하여 버튼의 위치를 ​​가져올 수도 있습니다.

+0

버튼이있는 패널 내부라고합니다. – Stephan

1

다음은 요소를 상대적으로 상대적으로 배치하는 방법을 보여주는 작은 스 니펫입니다. 버튼 아래에 팝업 메뉴가 표시되고 왼쪽에는 JDialog가 표시됩니다. 보조 스크린이 메인 스크린의 오른쪽에있는 멀티 스크린 환경에서 테스트했습니다.

또한 getPreferredSize() 대신 getSize(), getWidth() 및 getHeight()를 사용하십시오. getSize(), getWidth 및 getHeight는 컴퍼넌트의 실제의 치수를 돌려주고, getPreferredSize()는 LayoutManager의 컴퍼넌트의 표시 범위로서 사용됩니다.

JPopupMenu.show() 메서드를 사용하는 경우 호출자 구성 요소와 관련된 좌표 및 크기를 사용해야합니다.

import java.awt.Dimension; 
import java.awt.Point; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.ComponentEvent; 
import java.awt.event.ComponentListener; 

import javax.swing.JButton; 
import javax.swing.JDialog; 
import javax.swing.JFrame; 
import javax.swing.JMenuItem; 
import javax.swing.JPopupMenu; 

public class Test2 { 

    public static void main(String[] args) { 

     final JFrame frame = new JFrame(); 
     final JButton button = new JButton("Hello"); 
     button.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       JPopupMenu popupMenu = new JPopupMenu(); 
       popupMenu.add(new JMenuItem("Some test")); 
       System.err.println(button.getLocationOnScreen()); 
       popupMenu.show(button, 0, button.getHeight()); 
       JDialog dialog = new JDialog(frame); 
       dialog.setSize(100, 30); 
       Point locationOnScreen = button.getLocationOnScreen(); 
       locationOnScreen.x += button.getWidth(); 
       dialog.setLocation(locationOnScreen); 
       dialog.setVisible(true); 
      } 
     }); 
     frame.addComponentListener(new ComponentListener() { 

      @Override 
      public void componentShown(ComponentEvent e) { 

      } 

      @Override 
      public void componentResized(ComponentEvent e) { 
       info(button); 
      } 

      private void info(final JButton button) { 
       if (button.isShowing()) { 
        System.err.println(button.getLocationOnScreen()); 
        System.err.println(button.getGraphicsConfiguration().getBounds()); 
       } 
      } 

      @Override 
      public void componentMoved(ComponentEvent e) { 
       info(button); 
      } 

      @Override 
      public void componentHidden(ComponentEvent e) { 

      } 
     }); 
     button.setPreferredSize(new Dimension(200, 60)); 
     frame.add(button); 
     frame.pack(); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.setVisible(true); 
    } 
}