JTabbedPane:将鼠标侦听器附加到选项卡选择 UI 中不包含选项卡的部分

发布于 2024-07-24 18:24:24 字数 719 浏览 5 评论 0原文

这与此处提出的问题有关: JTabbedPane:选项卡本身之前和之后的组件

我想要附加一个鼠标侦听器,允许拖动构建的类似 google chrome 的框架。 首先,最初的拖动代码相当简单,鼠标拖动代码位于 this Kirill- post 几乎可以直接使用。 仅当用户单击并拖动框架的“标题栏”(即选项卡(粘性标签)所在的区域)时,我才希望出现此行为。 这也很简单 - 只需更改拖动代码以仅接受 JTabbedPane 上部区域(包含选项卡的部分)中的单击。

但是,我想进一步减少可抓取区域,并且只允许在选项卡未占据的区域中单击并拖动框架(粘性标签 - 有人对这个 GUI 元素有更好的名称吗?) - 再次很像Google Chrome(Chrome 还在窗口模式下在选项卡上方添加了一个栏,以便在许多选项卡处于活动状态时更容易抓住框架。但是 Chrome 做得很完美:可以在选项卡式部分中抓取窗口,而不是在选项卡式部分中)有选项卡,甚至在选项卡之间的小 v 中!)

我实际上想做的是能够将鼠标侦听器附加到选项卡 GUI 的背景 - 但如何完成这样的事情呢?

This is in conjunction to the question posed here:
JTabbedPane: Components before and after the tabs themselves

I want to attach a mouse listener that allows for dragging the constructed google chrome-like frame. Starting out, the initial dragging code is rather easy, and the mouse-dragging code at this Kirill-post can be used pretty much directly. I'd only want this behaviour if the user clicks and drags on the "title bar" of the frame, that is, the area where the tabs (the stick-uppers) reside. This is also easy - just change the dragging code to only accept clicks in the upper area of the JTabbedPane, the part that contains the tabs.

However, I want to reduce the grabbable area further, and only allow click-and-drag-frame in the area NOT occupied by the tabs (the stick-uppers - anyone have a better name for this GUI element?) - again quite like Google Chrome (Chrome also adds a bar above the tabs when in windowed mode, to easier get hold of the frame if many tabs are active. But Chrome do this perfect: It is possible to grab the window in the tabbed part that doesn't have tabs, and even in the small v's inbetween the tabs!)

What I'd effectively want to do, is to be able to attach the mouse listeners to the background of the GUI for the tabs - but how to accomplish something like this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

独守阴晴ぅ圆缺 2024-07-31 18:24:24

查看此问题的解决方案后(可拖动选项卡Swing),我发现实际的 TabbedPaneUI 有一些方法可以解决这两个问题:仅在选项卡区域中拖动窗口,这被证明是最难的部分,并且在选项卡本身上方时不拖动。 相关代码如下,在标有“// ::”的两个部分中。 该代码改编自所提到问题的基里尔代码。 除了选项卡位于顶部时之外,该代码不处理其他情况 - 考虑到我想要做什么时,这是有意义的。

        // mouse listener for dragging the host window
        MouseAdapter adapter = new MouseAdapter() {
            int lastX;
            int lastY;

            boolean _dragInitiated;

            @Override
            public void mousePressed(MouseEvent e) {
                TabbedPaneUI ui = _windowTabs.getUI();

                // :: Won't drag if we're positioned above a tab in tab area
                if (ui.tabForCoordinate(_windowTabs, e.getX(), e.getY()) != -1) {
                    _dragInitiated = false;
                    return;
                }

                // :: Won't drag if we're below the tab area
                int maxY = 0;
                for (int i = 0; i < _windowTabs.getTabCount(); i++) {
                    Rectangle bounds = ui.getTabBounds(_windowTabs, i);
                    int y = bounds.y + bounds.height;
                    if (y > maxY) {
                        maxY = y;
                    }
                }
                _dragInitiated = true;
                if (maxY > 0) {
                    if (e.getY() > maxY) {
                        _dragInitiated = false;
                    }
                }

                Point eventLocationOnScreen = e.getLocationOnScreen();
                if (eventLocationOnScreen == null) {
                    Component source = (Component) e.getSource();
                    eventLocationOnScreen = new Point(e.getX() + source.getLocationOnScreen().x, e.getY()
                            + source.getLocationOnScreen().y);
                }

                lastX = eventLocationOnScreen.x;
                lastY = eventLocationOnScreen.y;
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                if (!_dragInitiated) {
                    return;
                }

                Point eventLocationOnScreen = e.getLocationOnScreen();
                if (eventLocationOnScreen == null) {
                    Component source = (Component) e.getSource();
                    eventLocationOnScreen = new Point(e.getX() + source.getLocationOnScreen().x, e.getY()
                            + source.getLocationOnScreen().y);
                }

                int dx = eventLocationOnScreen.x - lastX;
                int dy = eventLocationOnScreen.y - lastY;
                Window win = POTabbedFrame.this;
                Point loc = win.getLocation();
                win.setLocation(loc.x + dx, loc.y + dy);
                lastX = eventLocationOnScreen.x;
                lastY = eventLocationOnScreen.y;
            }
        };
        _windowTabs.addMouseListener(adapter);
        _windowTabs.addMouseMotionListener(adapter);

After looking at the solutions for this question (draggable tabs in Swing), I found that the actual TabbedPaneUI has some methods that can fix both problems: Only drag window in tab area, which turned out to be the hardest part, and not drag when above the tabs themselves. The relevant code follows, in the two sections marked with "// ::". The code is adapted from the question-mentioned Kirill-code. The code doesn't handle other cases than when the tabs are at top - which makes sense when considering what I want to do.

        // mouse listener for dragging the host window
        MouseAdapter adapter = new MouseAdapter() {
            int lastX;
            int lastY;

            boolean _dragInitiated;

            @Override
            public void mousePressed(MouseEvent e) {
                TabbedPaneUI ui = _windowTabs.getUI();

                // :: Won't drag if we're positioned above a tab in tab area
                if (ui.tabForCoordinate(_windowTabs, e.getX(), e.getY()) != -1) {
                    _dragInitiated = false;
                    return;
                }

                // :: Won't drag if we're below the tab area
                int maxY = 0;
                for (int i = 0; i < _windowTabs.getTabCount(); i++) {
                    Rectangle bounds = ui.getTabBounds(_windowTabs, i);
                    int y = bounds.y + bounds.height;
                    if (y > maxY) {
                        maxY = y;
                    }
                }
                _dragInitiated = true;
                if (maxY > 0) {
                    if (e.getY() > maxY) {
                        _dragInitiated = false;
                    }
                }

                Point eventLocationOnScreen = e.getLocationOnScreen();
                if (eventLocationOnScreen == null) {
                    Component source = (Component) e.getSource();
                    eventLocationOnScreen = new Point(e.getX() + source.getLocationOnScreen().x, e.getY()
                            + source.getLocationOnScreen().y);
                }

                lastX = eventLocationOnScreen.x;
                lastY = eventLocationOnScreen.y;
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                if (!_dragInitiated) {
                    return;
                }

                Point eventLocationOnScreen = e.getLocationOnScreen();
                if (eventLocationOnScreen == null) {
                    Component source = (Component) e.getSource();
                    eventLocationOnScreen = new Point(e.getX() + source.getLocationOnScreen().x, e.getY()
                            + source.getLocationOnScreen().y);
                }

                int dx = eventLocationOnScreen.x - lastX;
                int dy = eventLocationOnScreen.y - lastY;
                Window win = POTabbedFrame.this;
                Point loc = win.getLocation();
                win.setLocation(loc.x + dx, loc.y + dy);
                lastX = eventLocationOnScreen.x;
                lastY = eventLocationOnScreen.y;
            }
        };
        _windowTabs.addMouseListener(adapter);
        _windowTabs.addMouseMotionListener(adapter);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文