【问题标题】:Making a glassPane fit with the dimensions of a JPanel使 glassPane 适合 JPanel 的尺寸
【发布时间】:2014-05-01 19:47:28
【问题描述】:

堆栈溢出!

我正在做一个关于制作导航系统的项目,我们正处于开始阶段,绘制地图并自行导航。 我们有一个功能,您应该能够在已经绘制的当前数据之上绘制一个正方形。我想避免在每个 mouseDragged 动作事件中重新绘制道路的所有数据。为此,我发现使用玻璃窗格是最佳选择。

问题在于玻璃板的尺寸和它读取的坐标。当我单击 JPanel 上的某个位置(我们用来绘制)时,它知道如何以及在何处正确放大,但是当我绘制我的正方形时,它会在鼠标位置上方绘制特定数量的像素。这似乎是因为我的玻璃窗格尺寸与我的 JPanel 尺寸不对应。玻璃窗格似乎也覆盖了我的菜单栏,而 JPanel 本身不会读取菜单栏上发生的点击。

我想以某种方式在我的 JPanel 上安装一个玻璃板,并且我尝试了一些不同的方法。 我尝试过的一件事是绘制 JR​​ootPane 而不是 JPanel,但这似乎是不可能的。然后我试图从我的 JPanel(它也有自己的类)中检索“MyGlassPane”类,并将其称为重绘方法,但这就是问题的根源。 最近,我检索了 JPanel 本身使用或属于其中的 JRootPane,然后检索了此 JRootPane 的玻璃窗格,但似乎我添加到 JFrame 的菜单栏也是此 JRootPane 的一部分,这意味着glasspane 也覆盖了菜单栏。

这里有一些非常简化的代码,它涵盖了这个问题,但不包括鼠标侦听和数据绘制方面。然而,它确实显示了在菜单栏顶部绘制矩形很烦人的事实。

import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.*;

public class TestForRootPaneStuff {
    JFrame frame = new JFrame();
    JRootPane root;
    JPanel panel = new JPanel();
    JLabel label = new JLabel("Hello there!");

    public void rootPanePls()
    {
        frame.add(panel);
        panel.add(label);

        root = panel.getRootPane();

        JMenuBar menubar = new JMenuBar();
        JMenu prettyMenu = new JMenu("Pretty");
        menubar.add(prettyMenu);
        frame.setJMenuBar(menubar);

        MyGlassPane gp = new MyGlassPane();
        root.setGlassPane(gp);

        gp.setVisible(true);
        gp.setEnabled(true);
        gp.repaint();


        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(250, 250));

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        TestForRootPaneStuff derp = new TestForRootPaneStuff();
        derp.rootPanePls();
    }

    private class MyGlassPane extends JComponent implements ItemListener
    {
        //React to change button clicks.
        @Override
        public void itemStateChanged(ItemEvent e) {
            setVisible(e.getStateChange() == ItemEvent.SELECTED);
        }

        //Draw the square for zoomToSquare
        @Override
        protected void paintComponent(Graphics g) {
            g.setColor(Color.BLUE);
            g.drawRect(10, 10, 100, 100);
        }
    }
}

这是corresponding screenshot, as a result of running this code.(我不能直接发布图片,因为这里没有活动)

我希望我的解释至少有点道理。我知道我的解释对于实际解决问题可能有点过于深入,但我觉得有必要让你们更多地了解我的情况,以及我需要解决方案的原因.

TL;DR: 我需要一种方法来使 glassPane(从某处检索/设置)完全适合特定 JPanel 的尺寸,以便我可以为 JPanel 和 glasspane 接收相同的鼠标事件坐标。有关问题的可视化,请参见上面的代码。 有没有聪明的方法来解决这个问题?设置 RootPane 玻璃窗格是我的最终想法...

提前感谢,如果有人有任何见解可以带来!

基鲁~

【问题讨论】:

    标签: java swing paintcomponent jcomponent glasspane


    【解决方案1】:

    不是更长的评论,只是根据此处发布的错误/不完整代码进行猜测

    1. 使用 JLabel 代替 JComponent,JComponent 在 API 中没有任何 LayoutManager,当然 JLabel 也是,但它是一个非常简单的容器,就像 contianer,是透明的,paintComponent 中的任何东西都可以(半)透明

    2. 1234563 , dispose() 任何放置/放置在 GlassPane 中的所有自定义绘画
    3. JLabel 可以轻松地从 JPanel 复制坐标,使用添加到 JPanel 的 ComponentListener,通过使用 Swing Timer,EDIT 从 ComponentListener 延迟 (350-600) 事件(每一个像素一个事件),如果调整大小继续调用 timer.restart() </EDIT,如果调整大小结束,则 Swing Action/ActionListener 将为放置在 GlassPane 中的 JLabel(无论什么)触发 setBounds

    4. 为 GlassPane 中的动画搜索简单的 RepaintManager(仅通过覆盖 GlassPane 中的 JLabels 边界)

    【讨论】:

    • 一方面,您查看的代码不是我项目的一部分,它只是一个非常简短的示例,显示我在代码上方描述的问题... 1. 使用 JLabel 代替,使以便只绘制矩形,菜单栏和 JLabel 隐藏在“GlassPane”下,因为 GlassPane 是 JLabel 使它阻挡了它后面的所有东西,AKA,不透明。 2. 参考“1”前的注释。 3. 我认为你没有读过我的问题是什么,我也不完全理解你在这里所说/建议的内容。 4.会得到它。谢谢你的回复:)
    • @Kirluu 1.he code you looked at is not part of my project, == 你的坏,2.it's just a very short example displaying my problem which I described above the code... == 又是错误的,很容易猜测,3. 点 1-3 大约是最低的(可能基于一些在这里研究),4. because the GlassPane being a JLabel makes it block everything behind it == GlassPane 的错误使用,5. 注意 GlassPane 只保护 MouseEvents,KeyEvents 被调度
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-22
    • 2020-11-24
    • 1970-01-01
    • 2013-02-24
    • 1970-01-01
    • 1970-01-01
    • 2017-05-21
    相关资源
    最近更新 更多