Swing Jbutton:仅在悬停时显示边框和背景

时间:2013-07-15 15:45:51

标签: java swing hover jbutton

我想在自定义的Swing.JButton中添加一个悬停效果,类似于Chrome浏览器上的图标:

在悬停之前>>

enter image description here

悬停>>

之后

enter image description here

我可以在创建按钮时将其设置为“之前”状态,但是当它悬停时我无法创建“边框+凸起背景”。当我尝试将边框重新添加到按钮时,我在插入重新绘制新边框后获得了移动效果。

这是我目前的代码:

public class MyButton extends JButton implements MouseListener {

public MyButton(String iconPath, String toolTip) {
    super(new ImageIcon(TipButton.class.getResource(iconPath)));
    addMouseListener(this);
    setBorder(null);
    setBorderPainted(false);
    setFocusPainted(false);
    setOpaque(false);
    setContentAreaFilled(false);
    setToolTipText(toolTip);
}

public MyButton(String iconPath, String name, String toolTip) {
    this(observers, iconPath, toolTip);
    setText(name);
}

@Override
public void mouseClicked(MouseEvent e) {}

@Override
public void mousePressed(MouseEvent e) {}

@Override
public void mouseReleased(MouseEvent e) {}

@Override
public void mouseEntered(MouseEvent e) {
    if (e.getSource() != this) return;

    setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
}

@Override
public void mouseExited(MouseEvent e) {
    if (e.getSource() != this) return;

    setBorder(null);
}

}

我想主要的逻辑应该是mouseEntered / mouseExited方法,但我不知道如何获得想要的效果。有什么想法吗?

4 个答案:

答案 0 :(得分:5)

我想我找到了解决方案。使用具有相同大小(插图)的凸起边框的EmptyBorder可以解决问题。代码:

public class SwingUtils {

public static JButton createMyButton (String iconPath, String toolTip) {
    final JButton b = new JButton (new ImageIcon(SwingUtils.class.getResource(iconPath)));
    final Border raisedBevelBorder = BorderFactory.createRaisedBevelBorder();
    final Insets insets = raisedBevelBorder.getBorderInsets(b);
    final EmptyBorder emptyBorder = new EmptyBorder(insets);
    b.setBorder(emptyBorder);
    b.setFocusPainted(false);
    b.setOpaque(false);
    b.setContentAreaFilled(false);
    b.setToolTipText(toolTip);
    b.getModel().addChangeListener(new ChangeListener() {
        @Override
        public void stateChanged(ChangeEvent e) {
            ButtonModel model = (ButtonModel) e.getSource();
            if (model.isRollover()) {
                b.setBorder(raisedBevelBorder);
            } else {
                b.setBorder(emptyBorder);
            }
        }
    });
    return b;
}

}

注意:正如mKorbel所说,它将使用ChangeListener和在工厂方法中创建的按钮而不是子类JButton。

答案 1 :(得分:2)

为每个州使用不同的图像。您可以为选定,禁用选定,禁用,按下,翻转,rolloverEnabled,rolloverSelected设置不同的图标。更多信息here

答案 2 :(得分:1)

在java 7中有一个BevelBorder类,它看起来就像你要找的那样。你可能会感兴趣的两种方法是

    paintRaisedBevel(Component c, Graphics g, int x, int y, int width, int height)

    paintLoweredBevel(Component c, Graphics g, int x, int y, int width, int height)

以下是该课程的文档:http://docs.oracle.com/javase/7/docs/api/javax/swing/border/BevelBorder.html

答案 3 :(得分:1)