[英]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中,应删除按钮。
随着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;
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.