JFrame与Ubuntu的位置错误(Unity吗?) [英] JFrame wrong location with Ubuntu (Unity ?)

查看:62
本文介绍了JFrame与Ubuntu的位置错误(Unity吗?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Ubuntu似乎存在一个错误(也许只有一个错误). getLocation()getSize()考虑JFrame的修饰,但setLocation()setSize()不考虑.这导致奇怪的行为.例如,如果在显示框架并更改尺寸后使用pack(),框架将下降20个像素...

It seems that there is a bug with Ubuntu (maybe only unity). The decoration of the JFrame is taken into account for getLocation() and getSize(), but not for setLocation() and setSize(). This leads to weird behaviour. For instance, if you use pack() after the frame is displayed and the dimensions changed, the frame will go down 20 pixels...

为了说明一个具体案例,当它变得非常烦人时,我做了一个SSCCE.这是带有基本JPanel的JFrame.如果拖动面板,则JFrame应该会随之移动.

To illustrate a concrete case when it becomes really annoying, I made a SSCCE. It's a JFrame with a basic JPanel. If you drag the panel, the JFrame is supposed to move along.

在Windows下,它可以按预期工作.在Ubuntu下,如果我执行setUndecorated(true),它也可以正常工作,但是如果让装饰生效,JFrame会发疯!

Under Windows, it works as expected. Under Ubuntu, if I do setUndecorated(true) it will also work fine, but if I let the decoration, the JFrame turn crazy !

public class Test {
    private static JFrame mainFrame;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                mainFrame = new JFrame("test");
                mainFrame.setSize(300,20);
                mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                mainFrame.setVisible(true);

                Container pane = mainFrame.getContentPane();
                pane.addMouseMotionListener(new MouseMotionListener() {
                    private int posX = 0, posY = 0;

                    @Override
                    public void mouseDragged(MouseEvent e) {
                        int x = e.getX() - posX + mainFrame.getX();
                        int y = e.getY() - posY + mainFrame.getY();
                        mainFrame.setLocation(x, y);
                    }

                    @Override
                    public void mouseMoved(MouseEvent e) {
                        posX = e.getX();
                        posY = e.getY();
                    }

                });

            }
        });
    }
}

我不知道该如何解决.我怎样才能得到窗户装饰的大小?而且我不知道要关注的是哪个版本的Ubuntu.如果仅仅是Unity问题,我什至不知道如何确定我的用户是否正在使用Unity ...

I don't know how I can fix that. How can I get the size of the windows decoration ? And I have no idea about which versions of Ubuntu are concerned. And if it is only a Unity problem, I don't even know how to find out if my user is using Unity...

有什么解决方法的想法吗?

Any idea for a workaround ?

修改: 好的,MadProgrammer确实提供了更好的代码,但是该错误有时仍会发生.我相应地编辑了MouseListener以跟踪该错误:

Edit : Ok, MadProgrammer did provide a better code, but the bug still occurs sometimes. I edited my MouseListener accordingly to track the bug :

            pane.addMouseMotionListener(new MouseMotionListener() {
                private int posX = 0, posY = 0;

                @Override
                public void mouseDragged(MouseEvent e) {
                    int x = e.getXOnScreen() - posX;
                    int y = e.getYOnScreen() - posY;
                    mainFrame.setLocation(x, y);
                    System.out.println("drag   :  border ignored / border considered : "+(mainFrame.getY()+e.getY())+"   /   "+e.getYOnScreen());
                }

                @Override
                public void mouseMoved(MouseEvent e) {
                    posX = e.getXOnScreen() - mainFrame.getX();
                    posY = e.getYOnScreen() - mainFrame.getY();
                    System.out.println("move  :  border ignored / border considered : "+e.getY()+"   /   "+posY);
                }
            });

每次两个值相同时,表示该错误将在下次单击时发生.否则,值将不同.在其他操作系统上,值始终相同.实际上,它们应该始终相同或相同,或者始终不同.我不明白他们有时是平等的,有时是不同的.

Each time that the 2 values are identical, it means that the bug will occur on the next click. Otherwise, the values are different. On other OS, the values are always the same. Actually, they should be or the same always, or always different. I don't understand how they can be sometimes equal and sometimes different...

推荐答案

我没有Ubuntu可以测试,但是我在MacOS和Windows上都使用了类似的东西

I don't have Ubuntu to test with, but I've used something similar to this on both MacOS and Windows

import java.awt.Container;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Test {

    private static JFrame mainFrame;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                mainFrame = new JFrame("test");
                mainFrame.setSize(300, 100);
                mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                mainFrame.setVisible(true);

                Container pane = mainFrame.getContentPane();
                MouseAdapter ma = new MouseAdapter() {
                    private Point offset;

                    @Override
                    public void mouseDragged(MouseEvent e) {
                        if (offset != null) {
                            Point pos = e.getLocationOnScreen();

                            int x = pos.x - offset.x;
                            int y = pos.y - offset.y;

                            System.out.println(x + "x" + y);

                            SwingUtilities.getWindowAncestor(e.getComponent()).setLocation(x, y);
                        }
                    }

                    @Override
                    public void mousePressed(MouseEvent e) {

                        Point pos = SwingUtilities.getWindowAncestor(e.getComponent()).getLocation();

//                      Point pos = e.getComponent().getLocationOnScreen();
                        offset = new Point(e.getLocationOnScreen());
                        System.out.println(pos + "/" + offset);
                        offset.x -= pos.x;
                        offset.y -= pos.y;

                        System.out.println(offset);
                    }
                };
                pane.addMouseListener(ma);
                pane.addMouseMotionListener(ma);
            }
        });
    }
}

这对装饰和未装饰的窗口均适用,因为它采用了组件位置(在屏幕上)与窗口当前位置之间的差值.拖动后,它会计算到点击点的移动距离,并相应地更新窗口的位置(允许点击的原始偏移量)

This should work for both decorated and undecorated windows, as it takes the difference between the positions of the component (on the screen) and the windows current position. When dragged, it calculates the distance of movement from the click point and updates the window's location accordingly (allowing for the original offset of the click)

这篇关于JFrame与Ubuntu的位置错误(Unity吗?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆