的StackOverflow!
我正在开发一个项目,关于制作导航系统,我们正处于起步阶段,正在绘制地图并自行导航。 我们有一个函数,你应该能够在已经绘制的当前数据之上绘制一个正方形。我希望避免每次使用mouseDragged动作事件重新绘制道路的所有数据。为此,我发现使用玻璃窗格是最佳选择。
问题在于玻璃板的尺寸及其读取的坐标。当我点击我们的JPanel上的某个点(我们用它来绘制)时,它知道如何以及在哪里正确放大,但是当我绘制正方形时,它会在我的鼠标位置上方绘制特定数量的像素。这似乎是因为我的玻璃窗格尺寸与我的JPanel尺寸不对应。玻璃窗似乎也覆盖了我的菜单栏,而JPanel本身并没有读取菜单栏上发生的点击。
我想以某种方式为我的JPanel配上玻璃窗,我尝试了一些不同的东西。 我试过的一件事是在JRootPane而不是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玻璃板是我最后的想法......
如果有人有任何见解,请提前致谢!
Kirluu〜
答案 0 :(得分:2)
不是更长的评论,只是基于此处发布的错误/不完整的代码进行猜测
使用JLabel代替JComponent,JComponent没有API中的任何LayoutManager,肯定也是JLabel,但它容器非常简单,就像contianer一样,是透明的,paintComponent中的任何东西都可以(半)透明
您的代码未完成为什么有ItemListener,不要将JComponent作为contianer放入JComponent,改为使用JPanel,或者提到不透明的JLabel是GlassPane的简单方法,第一代码行应该是super.paintComponent在paintComponent中,dispose()所有在GlassPane中放置/放置的任何自定义绘画
JLabel可以轻松地从JPanel复制坐标,使用添加到JPanel的ComponentListener,使用来自ComponentListener的delaing(350-600)事件(每个像素一个事件),使用Swing Timer,EDIT
如果调整大小继续调用timer.restart()</EDIT
,如果调整大小结束,则Swing Action / ActionListener将触发放置在GlassPane中的JLabel(无论如何)的setBounds
在GlassPane中搜索简单的RepaintManager(仅通过覆盖GlassPane中的JLabels边界)动画