繁体   English   中英

在Swing中的JLabel上显示按钮

[英]Show button on JLabel in Swing

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

我已经向JPanel添加了MouseListener,以在mouseEntered中显示按钮,并分别在mouseExited事件中隐藏按钮。

此时,它们是2个标签之间的按钮空间,并且仅使用setVisible()显示或隐藏了按钮。 当btn可见时,其下方的标签会下降,从而为按钮留出空间;如果btn隐藏,则其大小将再次恢复为原始大小。

我想要的-在mouseEntered中,按钮应该显示在标签本身上(让它重叠),并且我应该能够单击该按钮。 所有这些都应该非常平稳地发生,而不会出现屏幕闪烁。 同样,在mouseExited中,应删除按钮。

我该如何实现? 谁能帮我这个。

更新 @Andrew,谢谢我尝试使用JLayeredPane,它确实有效。 虽然该按钮未设置为visible false。 这是我的mouseMoved代码:

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();
        }
    }
}

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时,出现了组件。

结果 在此处输入图片说明

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

我想要的-在mouseEntered中,按钮应该显示在标签本身上(让它重叠),并且我应该能够单击该按钮。 所有这些都应该非常平稳地发生,而不会出现屏幕闪烁。 同样,在mouseExited中,应删除按钮。

随着JLabelJComponent扩展而来,您可以添加组件以标记自身,只需首先设置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;
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();
            }
        });
    }    

}

输出量

在此处输入图片说明

更新资料

正如@nIcEcOw指出的(谢谢!),鼠标事件的过渡会产生烦人的闪烁。 我改进了修复此问题的示例以及另一个未处理的方面,例如“当鼠标从JButton退出时会发生什么?”

这样的问题有点令人沮丧。 几乎有足够的信息来描述您想要的是什么,问题是什么,但不是很清楚。

似乎您希望在鼠标进入面板之前使用label-label-label,然后您希望外观是label-button-label。 很难想象我想要一个UI像这样。

您是否不喜欢按钮的外观,而只希望它出现在面板上? 是否可以更改按钮的外观,使其看起来像您想要的样子,而没有所有带有中间标签和按钮的轨迹?

我不知道为什么要提到一个计时器-您所描述的没有被计时,据我所知。 此外,您应该能够将所需的内容简化为一个可运行的小示例,然后将其发布,以便其他人可以看到您所拥有的内容及其作用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM