3

JPopupMenuメニューを開くボタンのy位置に応じて位置を設定したい。私のコードは最初のモニターでは正常に機能しますが、高さが異なる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);

実際のモニターでコンポーネントの場所を取得するにはどうすればよいですか?

4

3 に答える 3

6

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;
}

回答ありがとうございます。

于 2012-05-03T10:03:34.940 に答える
1

通常、「getLocationOnScreen()」を呼び出すと、コンポーネント「this」の場所が取得されます (コードからは、「this」が誰なのかよくわかりません)。

おそらく、「button.getLocationOnScreen()」を使用してボタンの位置を取得しようとすることができます。

于 2012-05-03T09:47:28.247 に答える
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);
    }
}
于 2012-05-03T10:02:44.117 に答える