2014-03-24 42 views
0

StackOverflow!制作glassPane适合JPanel的尺寸

我正在制作一个项目,关于制作导航系统,我们处于开始阶段,正在绘制地图并自行导航。 我们有一个功能,你应该能够在已经绘制的当前数据的顶部画一个正方形。我想避免重新绘制道路上的所有数据,每个mouseDragged操作事件。要做到这一点,我发现使用玻璃面板是最佳选择。

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

我想以某种方式将玻璃窗放到我的JPanel中,并尝试了几个不同的东西。 我试过的一件事是绘制一个JRootPane而不是JPanel,但这似乎不可能。然后我尝试从我的JPanel(它也有它自己的类)中检索“MyGlassPane”类,并将其称为重绘方法,但这是问题的来源。最近我得到了JPanel本身使用或者是其一部分的JRootPane,然后检索了这个JRootPane的glasspane,但是似乎我的菜单栏添加到JFrame中也是这个JRootPane的一部分,这意味着玻璃窗也覆盖菜单栏。

这里有一些非常简化的代码,它涵盖了这个问题,但不包括鼠标监听和数据绘图方面。然而,它显示出令人讨厌的是矩形正在菜单栏上绘制。

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〜

回答

2

不是asnwer再发表评论,只是猜测基于错误/ uncomplete代码贴在这里

  1. 使用的JLabel代替的JComponent,JComponent中还没有任何布局管理API,这个API肯定的JLabel但它是容器非常简单,就像contianer,是透明的,paintComponent中的任何东西都可以(半透明)

  2. 你的代码不完整为什么有ItemListener,不要把JComponent放到JComponent中作为c或者提到不透明的JLabel是GlassPane的第一种方法,第一代码行应该是paintComponent中的super.paintComponent,dispose()在GlassPane中放置/放置任何东西的所有自定义绘画

  3. JLabel可以有easilly从JPanel复制坐标,使用添加到JPanel的ComponentListener,通过使用Swing Timer从ComponentListener(每个像素一个事件)延迟(350-600)事件,如果调整大小继续调用timer.restart()</EDIT,如果resize结束那么Swing Action/ActionListener将触发放置在GlassPane中的JLabel的setBounds(不管))

  4. 搜索简单的RepaintManager(仅通过覆盖GlassPane中的JLabels边界)在玻璃面板

+0

动画一件事,你看的代码是不是我的项目的一部分,它只是一个很短的例子显示,我的代码上述我的问题...... 1.使用一个JLabel取而代之的是,只有矩形被绘制出来,菜单栏和JLabel隐藏在“GlassPane”下面,因为GlassPane是一个JLabel,它会阻止背后的所有东西,AKA,不透明。 2.请参阅“1.”之前的注释。 3.我不认为你已经读过我的问题,我不完全明白你在说什么/在这里暗示。 4.将得到它。 谢谢你的回复:) – Kirluu

+0

@Kirluu 1.'你看的代码不是我的项目的一部分,'==你的坏,2。'这只是一个很短的例子,显示我在代码上面描述的问题。 ..' ==再次错了,试图猜测,3.点1-3是最低限度的(可能基于这里的一些研究),4.因为GlassPane是一个JLabel使得它阻止它后面的一切== GlassPane的错误用法,5.注意GlassPane只保护MouseEvent,KeyEvent被调度 – mKorbel