获取JPopupMenu对象的左上角位置

时间:2011-11-18 13:19:56

标签: java swing jpopupmenu

我有一个JPopupMenu对象。它的行为取决于它的坐标。 如何相对于其父容器获取其位置?

3 个答案:

答案 0 :(得分:0)

MouseListener方法(mouseReleased等)中,您应该会收到一个包含当前位置的MouseEvent对象。如果您不想使用这些值,可以尝试使用Component#getLocation方法,否则使用Component#getLocationOnScreen,但它会返回绝对位置,然后您需要计算相对值。

答案 1 :(得分:0)

有一个解决方案,但不建议这样做,因为如果有一个SecurityManager,它可能会失败(强制该字段可访问):

public static Container getTopParent(@Nonnull Component c) {
    Container lastNotNull = (Container) c;
    Container p = c.getParent();
    if (p != null)
        lastNotNull = p;
    while(p != null) {
        lastNotNull = p;
        p = p.getParent();
    }
    return lastNotNull;
}

public static int getClickedXThatInvokedPopup(@Nonnull ActionEvent ev) {
    try {
        JPopupMenu topParent = (JPopupMenu) getTopParent((Component) ev.getSource());
        java.lang.reflect.Field fieldX = topParent.getClass().getDeclaredField("desiredLocationX");
        fieldX.setAccessible(true);
        int x = (Integer) fieldX.get(topParent);
        Point p = new Point(x, 0);
        SwingUtilities.convertPointFromScreen(p, topParent.getInvoker());
        return p.x;
    } catch(NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
        System.err.println("Cannot get clicked point: " + ex);
        return -1;
    }
}

答案 2 :(得分:0)

由于Component#getLocationComponent#getLocationOnScreen方法都不适合我,并且字段desiredLocationX / desiredLocationY不可访问,因此我对JPopupMenu()进行了如下扩展:< / p>

contextMenu = new JPopupMenu(){
    private Point desiredLocation;

    /**
    * Override Component#getLocation, since it always returns 0,0.
    */
    @Override
    public Point getLocation() {
        return desiredLocation;
    }

    @Override
    public void show(Component invoker, int x, int y) {
        desiredLocation = new Point(x, y);
        super.show(invoker, x, y);
    }
};