2016-01-20 128 views
0

我創建了一個簡單的程序,當鼠標在JLabel上時顯示一個JFram窗口。這似乎很好地工作,直到你通過鼠標在JLabel的很多次:JComponents開始變得破碎像這樣的畫面:JComponent和mouseListener非常奇怪的行爲

enter image description here

JComponents開始出現在任何地方,而且應該要顯示的JLabel,有一個「奇怪的粗體」字體。我認爲這可能發生,因爲程序永遠不會「退出」小窗口,所以內存永遠不會被釋放?!我可能也是錯的......但我當然不知道爲什麼會發生這種情況!

import java.awt.GridLayout; 
import java.awt.Point; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 

public class finestra implements MouseListener{ 

    private JFrame finestra = new JFrame(); 
    private JFrame pagina = new JFrame(); 
    private JButton submit1 = new JButton("press"); 
    private JTextField text = new JTextField(); 
    finestra(){ 

     pagina.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     pagina.setSize(500, 500); 

     JPanel cont = new JPanel(); 
     cont.setLayout(new GridLayout(3,4)); 

      JLabel label = new JLabel(); 
      label.setText("ON MOUSEROVER THIS"); 
       cont.add(label); 
      label.addMouseListener(this); 

     cont.add(submit1); 
     cont.add(text); 
     pagina.add(cont); 
     pagina.setVisible(true); 

     finestra.setUndecorated(true); 
    } 

    @Override 
    public void mouseClicked(MouseEvent arg0) {} 

    @Override 
    public void mouseEntered(MouseEvent event) { 
     if(event.getSource() instanceof JLabel){ 
      JLabel event_casted = (JLabel)event.getSource(); 

      if(event_casted.getText().equals("ON MOUSEROVER THIS")){ 
       Point punto = event.getLocationOnScreen(); 
       punto.setLocation(punto.getX()+20, punto.getY()+20); 

       JLabel littlelabel = new JLabel(); 

       littlelabel.setText("your mouse is on the jlabel"); 
       finestra.add(littlelabel); 
       finestra.setLocation(punto); 
       finestra.setSize(100,100); 
       finestra.setVisible(true); 
      } 
     } 
    } 

    @Override 
    public void mouseExited(MouseEvent event) { 
     if(event.getSource() instanceof JLabel){ 
      JLabel event_casted = (JLabel)event.getSource(); 
       if(event_casted.getText().equals("ON MOUSEROVER THIS")){ 
        finestra.setVisible(false); 
       } 
     } 
    } 

    @Override 
    public void mousePressed(MouseEvent event) { 

    } 

    @Override 
    public void mouseReleased(MouseEvent arg0) {} 

    public static void main(String[] args0){ 
     new finestra(); 
    }; 

} 

回答

3

OK,我真的不知道爲什麼你的代碼行爲不端,因爲它不是行爲不端,對我來說既是顯示在這裏考慮使用一個工具提示此功能,否則無模式未修飾的JDialog :

import java.awt.Color; 
import java.awt.GridLayout; 
import java.awt.Point; 
import java.awt.Dialog.ModalityType; 
import java.awt.Window; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 

import javax.swing.*; 
import javax.swing.border.Border; 

public class Finestra2 extends JPanel { 
    private static final int EB = 20; 
    private JLabel dialogLabel = new JLabel("Dialog hover label"); 
    private JLabel toolTipLabel = new JLabel("Tooltip hover label"); 

    public Finestra2() { 
     // tool tip text will appear if the mouse hovers over component 
     toolTipLabel.setToolTipText("This is tooltipLabel's text"); 
     dialogLabel.addMouseListener(new DialogLabelMouseListener()); 

     // a one column grid with a variable number of rows 
     setLayout(new GridLayout(0, 1)); 

     addWithBorder(dialogLabel); 
     add(new JButton("Some Button")); // just a component to show possible visual misbehaviors 
     add(new JLabel("Do nothing label")); // ditto 
     addWithBorder(toolTipLabel); 
     add(new JButton("Some Button")); 
     add(new JLabel("Do nothing label")); 

     setBorder(BorderFactory.createEmptyBorder(EB, EB, EB, EB)); 
    } 

    // put a border around our labels of interest 
    private void addWithBorder(JComponent component) { 
     Border innerBorder = BorderFactory.createEmptyBorder(EB, EB, EB, EB); 
     Border outerBorder = BorderFactory.createLineBorder(Color.BLACK); 
     Border compoundBorder = BorderFactory.createCompoundBorder(outerBorder, innerBorder); 
     component.setBorder(compoundBorder); 
     add(component); 
    } 

    private class DialogLabelMouseListener extends MouseAdapter { 
     private JDialog hoverDialog; 

     @Override 
     public void mouseEntered(MouseEvent e) { 
      // only create the dialog once in a lazy fashion 
      if (hoverDialog == null) { 
       Window win = SwingUtilities.getWindowAncestor(Finestra2.this); 
       hoverDialog = new JDialog(win, "", ModalityType.MODELESS); 
       JLabel label = new JLabel("Dialog label hover window"); 
       hoverDialog.add(label); 
       hoverDialog.setUndecorated(true); 
       hoverDialog.pack(); 
      } 
      Point punto = e.getLocationOnScreen(); 
      punto.setLocation(punto.getX() + 20, punto.getY() + 20); 
      hoverDialog.setLocation(punto); 
      hoverDialog.setVisible(true); 
     } 

     @Override 
     public void mouseExited(MouseEvent e) { 
      if (hoverDialog != null) { 
       hoverDialog.setVisible(false); 
      } 
     } 
    } 

    private static void createAndShowGui() { 
     Finestra2 mainPanel = new Finestra2(); 

     JFrame frame = new JFrame("Finestra2"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> { 
      createAndShowGui(); 
     }); 
    } 
} 
+0

好,解決了JComponents無意義出現的問題。但是這個「奇怪的粗體」字體呢? –

+0

@ElMapoMapo:請忽略此答案 - 這是錯誤的。讓我看看發生了什麼。 –

+0

@ElMapoMapo:請參閱編輯回答。 –

2

首先,學習並使用標準的命名約定:

  1. 類名應以大寫字符(Finestra)開始。另外,具有相同的類和變量名稱是非常令人困惑的。

  2. 變量名的第二個字應當上套管(littleLabel)

https://en.wikipedia.org/wiki/Naming_convention_(programming)#Java

JLabel的是應該被顯示,有一個 「奇怪粗體」 字型。

這是因爲您不斷創建新的JLabel並將其添加到框架中。所以每個標籤都被繪製,看起來像粗體文本。不知道爲什麼每個標籤都沒有完全重疊在一起。可能與抗鋸齒有關,指出每個位置的黑色像素。

創建框架並將其添加到框架時創建標籤。然後你只需在你的監聽器中調用setText(...)方法。