在Swing中的JLabel上显示按钮 [英] Show button on JLabel in Swing
问题描述
我有一个带有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屋!