2016-01-20 89 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(...)方法。