2014-03-24 88 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