在Swing中的JLabel上显示按钮 [英] Show button on JLabel in Swing

查看:106
本文介绍了在Swing中的JLabel上显示按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有3个JLabel的GroupLayout的JPanel。我还有一个隐藏的JButton。

我已经将一个MouseListener添加到JPanel,并在mouseEntered中显示该按钮,并分别隐藏mouseExited事件中的按钮。

目前,它们是2个标签之间的按钮空间,并且它们仅使用setVisible()显示或隐藏按钮。当btn可见时,它下面的标签会为按钮留出空间,如果btn被隐藏,它会再次达到其原始大小。



我想要的内容mouseEntered,该按钮应显示在标签本身(让它重叠),我应该可以点击按钮。这一切都应该非常顺利地进行,不会出现屏幕闪烁。同样在mouseExited中,该按钮应该被删除。



我如何实现这一目标?谁能帮我这个。

更新
@Andrew,谢谢我使用JLayeredPane尝试过,它确实有效。虽然该按钮没有设置为可见的错误。这里是我的mouseMoved代码:

  public void mouseMoved(MouseEvent e){
if(e.getComponent()== )(
if(!startCustomBtn.isVisible())
startCustomBtn.setVisible(true);
startCustomBtn.setLocation(e.getX() - 55,e.getY() - 30);
} else {
if(startCustomBtn.isVisible()){
startCustomBtn.setVisible(false);
revalidate();
}
}
}

JPanel的布局:

  private void layeredLayout(){
layeredPane = new JLayeredPane();
layeredPane.addMouseMotionListener(this);

Insets insets = this.getInsets();
Dimension size = rateLabel.getPreferredSize();
rateLabel.setBounds(insets.left + 45,insets.top + 15,size.width,size.height);
size = imageLabel.getPreferredSize();
imageLabel.setBounds(insets.left + 15,insets.top + 40,size.width,size.height);

size = label.getPreferredSize();
label.setBounds(insets.left + 45,insets.top + imageLabel.getWidth()+ 20,size.width,size.height);

size = startCustomBtn.getPreferredSize();
startCustomBtn.setBounds(insets.left + 45,insets.top + 40 + size.height,size.width,size.height);

layeredPane.add(rateLabel,new Integer(0));
layeredPane.add(imageLabel,new Integer(1));
layeredPane.add(label,new Integer(2));

layeredPane.add(startCustomBtn,new Integer(1),0);

setLayout(new BoxLayout(this,BoxLayout.PAGE_AXIS));
add(layeredPane);
}

奇怪 - 我尝试了使用null的FlowLayout,但看不到任何东西。使用BoxLayout进行尝试时,组件出现。

REsult


主屏幕有一个带Gridlayout的JPanel(2,3),并且在每个单元格中添加了JPanel(MyPanel)。当我从1个单元格出来时(即MyPanel),该面板的按钮应该被隐藏,而上述代码没有发生。可能是什么原因?我还添加了revalidate()&也repaint()但没有任何工作。

解决方案


我想要的 - 在mouseEntered中,按钮应该显示在标签上
本身(让它重叠),我应该可以点击
按钮。这一切都应该非常顺利地进行,无需屏幕
闪烁。


由于 JLabel 扩展自 JComponent 您可以添加组件来标记自己,只需要先设置 LayoutManager 即可。这个事实在这个问题中有很好的解释。

示例代码

  import java.awt.BorderLayout中; 
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
导入javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;

public class Demo {

private void initGUI(){

final JButton button = new JButton(Hello!);
button.setVisible(false);

final JLabel testLabel = new JLabel(Welcome!);
testLabel.setPreferredSize(new Dimension(200,30));
testLabel.setBorder(new LineBorder(Color.GRAY,1));
testLabel.setLayout(new BorderLayout());
testLabel.add(button,BorderLayout.EAST);

button.addMouseListener(new MouseAdapter(){
@Override
public void mouseExited(MouseEvent e){
Point mousePosition = MouseInfo.getPointerInfo()。getLocation );
if(testLabel.contains(mousePosition)){
testLabel.dispatchEvent(new MouseEvent(testLabel,MouseEvent.MOUSE_ENTERED,System.currentTimeMillis(),0,mousePosition.x,mousePosition.y,0 ,false));
} else {
testLabel.dispatchEvent(new MouseEvent(testLabel,MouseEvent.MOUSE_EXITED,System.currentTimeMillis(),0,mousePosition.x,mousePosition.y,0,false)) ;
}
}

});

button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
JOptionPane.showMessageDialog(null,按钮被按下!);
点mousePosition = MouseInfo.getPointerInfo()。getLocation();
testLabel.dispatchEvent(new MouseEvent(testLabel,MouseEvent.MOUSE_EXITED,System.currentTimeMillis(),0,mousePosition.x, mousePosition.y,0,false));
}
});

testLabel.addMouseListener(new MouseAdapter(){
@Override
public void mouseEntered(MouseEvent e){
JLabel label =(JLabel)e.getSource() ;
label.setText(Here is the Button!);
button.setVisible(true);
}

@Override
public void mouseExited(MouseEvent e){
Point point = e.getPoint();
point.setLocation(point.x - button.getX(),point.y - button.getY()); //使点相对于按钮的位置
if(!button.contains(point)){
JLabel label =(JLabel)e.getSource();
label.setText(The button );
button.setVisible(false);
}
}
});

JPanel content = new JPanel(new FlowLayout());
content.setPreferredSize(new Dimension(300,100));
content.add(testLabel);

JFrame frame = new JFrame(Demo);
frame.setContentPane(content);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);


$ b public static void main(String [] args){
SwingUtilities.invokeLater(new Runnable(){
@Override
public void run(){
new Demo()。initGUI();
}
});
}

}

输出




$ b

更新



正如@nIcEcOw指出的那样(谢谢!鼠标事件过渡。我改进了解决这个问题的例子,以及另一个未处理的方面,比如鼠标从 JButton >退出时会发生什么?


I have a JPanel with GroupLayout with 3 JLabels in it. I also have a hidden JButton in it.

I have added a MouseListener to JPanel showing the button in mouseEntered and hide the button in mouseExited events respectively.

At this time, their is space for button between 2 labels and their only the button is shown or hidden using setVisible(). When the btn is visible, the labels below it goes down making space for button and if the btn is hidden it again comes to its original size.

What I want - in mouseEntered, the button should show on the label itself (let it be overlap) and I should be able to click on the button. This all should happen very smoothly without screen flickering. Similarly in mouseExited, the button should be removed.

How do I achieve this ? Can anyone help me with this.

UPDATE @Andrew, Thanks I tried with JLayeredPane and it does work. Though the button is not set to visible false. Here's my mouseMoved code :

public void mouseMoved(MouseEvent e) {
    if (e.getComponent() == layeredPane) {
        if (! startCustomBtn.isVisible())
            startCustomBtn.setVisible(true);
        startCustomBtn.setLocation(e.getX()-55, e.getY()-30);       
    } else {
        if (startCustomBtn.isVisible()) {
            startCustomBtn.setVisible(false);
            revalidate();
        }
    }
}

Layout of the JPanel :

private void layeredLayout() {
    layeredPane = new JLayeredPane();
    layeredPane.addMouseMotionListener(this);

    Insets insets = this.getInsets();
    Dimension size = rateLabel.getPreferredSize();
    rateLabel.setBounds(insets.left + 45, insets.top + 15, size.width, size.height);
    size = imageLabel.getPreferredSize();
    imageLabel.setBounds(insets.left + 15, insets.top + 40, size.width, size.height);

    size = label.getPreferredSize();
    label.setBounds(insets.left + 45, insets.top + imageLabel.getWidth() + 20 , size.width, size.height);

    size = startCustomBtn.getPreferredSize();
    startCustomBtn.setBounds(insets.left + 45, insets.top + 40 + size.height, size.width, size.height);

    layeredPane.add(rateLabel, new Integer(0));
    layeredPane.add(imageLabel, new Integer(1));
    layeredPane.add(label, new Integer(2));

    layeredPane.add(startCustomBtn, new Integer(1), 0);

    setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
    add(layeredPane);
}

Strange - I tried the layout with null, FlowLayout, but couldn't see anything. When tried with BoxLayout, components showed up.

REsult :

Main screen has a JPanel with Gridlayout(2, 3) and in each cell this JPanel (MyPanel) is added. When I come out from 1 cell (i.e. MyPanel) the button of that panel should be hidden which is not happening with the above code. What can be the reason ? I also added revalidate() & also repaint() but nothing works. ????

解决方案

What I want - in mouseEntered, the button should show on the label itself (let it be overlap) and I should be able to click on the button. This all should happen very smoothly without screen flickering. Similarly in mouseExited, the button should be removed.

As JLabel extends from JComponent you can add componentes to label itself, just need to set a LayoutManager first. This fact is well explained in this question.

Sample Code

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;

public class Demo {

   private void initGUI(){

       final JButton button = new JButton("Hello!");
       button.setVisible(false);

       final JLabel testLabel = new JLabel("Welcome!");
       testLabel.setPreferredSize(new Dimension(200, 30));
       testLabel.setBorder(new LineBorder(Color.GRAY, 1));
       testLabel.setLayout(new BorderLayout());
       testLabel.add(button, BorderLayout.EAST);

       button.addMouseListener(new MouseAdapter() {
           @Override
           public void mouseExited(MouseEvent e) {
               Point mousePosition = MouseInfo.getPointerInfo().getLocation();
               if(testLabel.contains(mousePosition)){
                   testLabel.dispatchEvent(new MouseEvent(testLabel, MouseEvent.MOUSE_ENTERED, System.currentTimeMillis(), 0, mousePosition.x, mousePosition.y, 0, false));
               } else {
                   testLabel.dispatchEvent(new MouseEvent(testLabel, MouseEvent.MOUSE_EXITED, System.currentTimeMillis(), 0, mousePosition.x, mousePosition.y, 0, false));
               }
           }

       });

       button.addActionListener(new ActionListener() {
           @Override
           public void actionPerformed(ActionEvent e) {
               JOptionPane.showMessageDialog(null, "The button was pressed!");
               Point mousePosition = MouseInfo.getPointerInfo().getLocation();
               testLabel.dispatchEvent(new MouseEvent(testLabel, MouseEvent.MOUSE_EXITED, System.currentTimeMillis(), 0, mousePosition.x, mousePosition.y, 0, false));
           }
       });

       testLabel.addMouseListener(new MouseAdapter(){
           @Override
           public void mouseEntered(MouseEvent e) {
               JLabel label = (JLabel) e.getSource();
               label.setText("Here is the Button!");
               button.setVisible(true);
           }

           @Override
           public void mouseExited(MouseEvent e) {
               Point point = e.getPoint();
               point.setLocation(point.x - button.getX(), point.y - button.getY()); //make the point relative to the button's location
               if(!button.contains(point)) {
                   JLabel label = (JLabel) e.getSource();
                   label.setText("The button is gone!");
                   button.setVisible(false);
               }
           }
       }); 

       JPanel content = new JPanel(new FlowLayout());
       content.setPreferredSize(new Dimension(300,100));
       content.add(testLabel);

       JFrame frame = new JFrame("Demo");
       frame.setContentPane(content);
       frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
       frame.pack();
       frame.setLocationRelativeTo(null);
       frame.setVisible(true);

   }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Demo().initGUI();
            }
        });
    }    

}

Output

Update

As @nIcEcOw pointed out (thanks!), there's an annoying flickering generated by mouse events' transition. I improved the example fixing this and another untreated aspects like "what happens when mouse exits from JButton?"

这篇关于在Swing中的JLabel上显示按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆