gpt4 book ai didi

java - 使 glassPane 适合 JPanel 的尺寸

转载 作者:行者123 更新时间:2023-12-02 06:01:51 25 4
gpt4 key购买 nike

堆栈溢出!

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

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

我想以某种方式将玻璃板安装到我的 JPanel 上,并且我尝试了一些不同的方法。我尝试过的一件事是在 JRootPane 而不是 JPanel 上绘图,但这似乎不可能。然后我尝试从我的 JPanel(它也有自己的类)中检索“MyGlassPane”类,并调用它的重绘方法,但这就是问题的根源。最近,我检索了 JPanel 本身使用或属于其一部分的 JRootPane,然后检索了此 JRootPane 的玻璃 Pane ,但似乎添加到 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. (由于此处缺乏 Activity ,我无法发布直接图像)

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

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

如果有人有任何见解,请提前致谢!

基鲁~

最佳答案

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

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

  2. 你的代码不完整为什么有ItemListener,不要将JComponents作为容器放入JComponent,而是使用JPanel,或者提到不透明的JLabel是GlassPane最简单的方法,第一个代码行应该是paintComponent中的super.paintComponent , dispose() 对 GlassPane 中放置/放置的任何内容进行所有自定义绘制

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

  4. 在 GlassPane 中搜索简单的 RepaintManager(只需覆盖 GlassPane 中的 JLabels 边界)以实现动画

关于java - 使 glassPane 适合 JPanel 的尺寸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22609655/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com