2012-05-03 18 views
3

メニューを開くボタンの位置に応じて、JPopupMenuの位置を設定します。私のコードは最初のモニターで正常に動作しますが、別の高さを持つ2番目のモニターでは失敗します。 問題は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

私は2番目の画面の境界を使用して、このためのソリューションを持って、それは非常に簡単です:あなたの答えのための

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()はコンポーネントが望むものへの唯一の目安です。

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); 
    } 
} 
関連する問題