2016-02-16 26 views
0

我正在嘗試爲裝滿文本的幾個JLabel元素創建mouseOver視覺效果。這個想法是當鼠標進入時使每個標籤變暗,然後當鼠標離開它時返回到正常狀態。同樣所有的標籤都放在有背景圖像的面板上。兩個JLabel在鼠標上覆制背景和對象的內容

雖然很簡單,但我遇到了一個我無法克服的令人討厭的行爲。

錯誤1:我第一次將鼠標移動到標籤上時,它顯示了我的主窗口的左上角作爲背景。

問題2:然後,每次將鼠標移動到一個標籤上一次,然後將其移動到第二個標籤上時,第二個將其背景更改爲第一個標籤的「summ背景」(面板圖像+半透明背景) 。在上面看來,即使第一個標籤的文本內容被「複製」到第二個標籤的背景。每次標籤更改時只發生一次:如果將鼠標移到同一標籤上兩次,第二次鼠標懸停事件就會正確繪製。

我已經嘗試使用MouseMotionListener,一個不同的元素(JButton),使用組件修改方法,並試圖重寫繪製方法。沒有結果。

我們已經附上一個GIF動畫顯示所描述的行爲: Two JLabels copying backgrounds and contents from each other

我是比較新的擺動,所以我不熟悉它的注意事項。任何想法可能會導致這種情況?

定義面板類:

public class ImagePanel extends JPanel{ 
    private static final long serialVersionUID = -3995745756635082049L; 

    private Image image = null; 

    public ImagePanel(Image image){ 
     this.image = image; 
    } 

    public void paintComponent(Graphics g){ 
     super.paintComponent(g); 
     if(image != null){ 
      g.drawImage(image, 0, 0, this); 
     } 
    } 
} 

的MouseListener類:

public class MouseHoverPiece implements MouseListener{ 

private static final Cursor CURSOR_HAND = new Cursor(Cursor.HAND_CURSOR); 
private static final Cursor CURSOR_DEFAULT = new Cursor(Cursor.DEFAULT_CURSOR); 
private static final Color HOVER_SHADOW = new Color(40, 80, 60, 50); 

@Override 
public void mouseEntered(MouseEvent e) { 
    JLabel component = (JLabel)e.getComponent(); 
    component.setBackground(HOVER_SHADOW); 
    component.setCursor(CURSOR_HAND); 
    component.setOpaque(true); 
    component.repaint(); 
} 

@Override 
public void mouseExited(MouseEvent e) { 
    JLabel component = (JLabel)e.getComponent(); 
    component.setBackground(null); 
    component.setCursor(CURSOR_DEFAULT); 
    component.setOpaque(false); 
    component.repaint(); 
} 

MainWindow類:

Image background = ResourceLoader.loadImage("board.png"); 
ImagePanel panel = new ImagePanel(background); 
panel.setBounds(10, 55, 480, 480); 
panel.setLayout(null); 
panel_main.add(panel); 

final JLabel lblNewLabel1 = new JLabel("N"); 
lblNewLabel1.setHorizontalAlignment(SwingConstants.CENTER); 
lblNewLabel1.setOpaque(false); 
lblNewLabel1.setBounds(25, 24, 52, 52); 
lblNewLabel1.setFont(lblNewLabel1.getFont().deriveFont(42f)); 
lblNewLabel1.addMouseListener(new MouseHoverPiece()); 
panel.add(lblNewLabel1); 

final JLabel lblNewLabel2 = new JLabel("O"); 
lblNewLabel2.setHorizontalAlignment(SwingConstants.CENTER); 
lblNewLabel2.setOpaque(false); 
lblNewLabel2.setBounds(25+52+2, 24, 52, 52); 
lblNewLabel2.setFont(lblNewLabel2.getFont().deriveFont(42f)); 
lblNewLabel2.addMouseListener(new MouseHoverPiece()); 
panel.add(lblNewLabel2); 
+1

請避免'的setBounds(...)',通常新手代碼的標誌。我猜你的形象是半透明的,是真的? –

+0

我應該用什麼來代替邊界?我只需要將標籤的尺寸強制爲固定的尺寸。面板的圖像和標籤的背景不透明,而我想應用的鼠標懸停背景是50%透明。 – akaine

+1

'我應該用什麼來代替邊界?' - 您使用[佈局管理器](http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html)。 – camickr

回答

2
private static final Color HOVER_SHADOW = new Color(40, 80, 60, 50); 

Swing組件具有透明背景,因爲你破壞了牛逼的問題他繪畫規則說明一個不透明的組件將完全繪製背景。

查看Backgrounds With Transparency瞭解更多信息和解決問題的方法。您可以:

  1. 做標籤上的風俗畫手工繪製背景
  2. 使用包裝部件和具有該組件爲你做的畫。
+0

我在研究我的問題的同時閱讀了上述文章。實際上我基於它的一些代碼。但我認爲我正在着眼於理解這個問題(「規則說明一個不透明的組件將完全描繪背景」)。 – akaine

0

我想我找到了解決方案。兩個bug都消失了。我所做的就是添加父容器的(在我的情況下,面板與板背景)重繪:

@Override 
public void mouseEntered(MouseEvent e) { 
    JLabel component = (JLabel)e.getComponent(); 
    component.setBackground(HOVER_SHADOW); 
    component.setCursor(CURSOR_HAND); 
    component.setOpaque(true); 
    Container container = component.getParent(); 
    component.repaint(); 
    container.repaint(); //fix 
} 

@Override 
public void mouseExited(MouseEvent e) { 
    JLabel component = (JLabel)e.getComponent(); 
    component.setBackground(null); 
    component.setCursor(CURSOR_DEFAULT); 
    component.setOpaque(false); 
    Container container = component.getParent(); 
    component.repaint(); 
    container.repaint(); //fix 
} 

謝謝大家對你的幫助;)

+0

無需在子組件上調用repaint()。當您重新繪製父母時,所有孩子都會重新粉刷。這不是一個真正的解決方案。當您更改組件的屬性時,該組件負責重新繪製自己。您的應用程序代碼不需要知道父級必須先重新繪製。 – camickr

+0

有趣......雖然沒有在父母上調用repaint,但它不起作用。我已經在幾篇文章中看到,由於錯誤的Swing實現,在更改某些特定屬性時需要重繪。我不是在爭論,只是試圖理解正確的做事方式。似乎我對Java的12年經驗在Swing中沒有任何意義...... – akaine

+0

事實上,您將基於alpha的顏色應用於不透明的組件是您的問題的原因,其他任何事情只是可能的破解導致進一步的問題 – MadProgrammer