17

我想根据鼠标事件(鼠标进入、退出、按下等)自定义颜色。所以为了做到这一点,我写了下面的代码。一切都很好,除了鼠标按下事件,它什么都不做。只有当我覆盖这样的颜色时它才UIManager有效UIManager.put("Button.select", Color.red);。的问题UIManager是它会改变我所有的按钮。

谁能告诉我我可能做错了什么或者完成我想做的事情的最佳方法是什么?

我的代码:

final JButton btnSave = new JButton("Save");

btnSave.setForeground(new Color(0, 135, 200).brighter());
btnSave.setHorizontalTextPosition(SwingConstants.CENTER);
btnSave.setBorder(null);
btnSave.setBackground(new Color(3, 59, 90));

btnSave.addMouseListener(new MouseListener() {
    @Override
    public void mouseReleased(MouseEvent e) {
        btnSave.setBackground(new Color(3, 59, 90));
    }

    @Override
    public void mousePressed(MouseEvent e) {
        // Not working :(
        btnSave.setBackground(Color.pink);
    }

    @Override
    public void mouseExited(MouseEvent e) {
        btnSave.setBackground(new Color(3, 59, 90));
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        btnSave.setBackground(new Color(3, 59, 90).brighter());
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        btnSave.setBackground(new Color(3, 59, 90).brighter());
    }
});

Edit1:所以,我使用的是 mKorbel 所建议的,而不是鼠标侦听ChangeListenerButtonModel。使用此代码,我仍然没有观察到鼠标在按钮上按下的任何变化,除非我在按钮外按下并拖动。有什么想法吗?

btnSave.getModel().addChangeListener(new ChangeListener() {

    @Override
    public void stateChanged(ChangeEvent e) {
        ButtonModel model = (ButtonModel) e.getSource();

        if (model.isRollover()) {
            btnSave.setBackground(new Color(3, 59, 90).brighter());
        } else if (model.isPressed()) {
            btnSave.setBackground(Color.BLACK);
        } else {
            btnSave.setBackground(new Color(3, 59, 90));
        }
    }
});
4

9 回答 9

27

问题是由于 JButton 默认填充了其内容区域,并且当按下按钮时,Metal L&F 将自动使用其内部选择的颜色填充它。

最好的办法是扩展 JButton 以创建自己的按钮,禁用内容区域填充,并自己绘制按钮的背景。

这是一个小演示(不确定它是否适用于其他 L&F,甚至可以肯定它不适用):

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

public class TestButton {

    class MyButton extends JButton {

        private Color hoverBackgroundColor;
        private Color pressedBackgroundColor;

        public MyButton() {
            this(null);
        }

        public MyButton(String text) {
            super(text);
            super.setContentAreaFilled(false);
        }

        @Override
        protected void paintComponent(Graphics g) {
            if (getModel().isPressed()) {
                g.setColor(pressedBackgroundColor);
            } else if (getModel().isRollover()) {
                g.setColor(hoverBackgroundColor);
            } else {
                g.setColor(getBackground());
            }
            g.fillRect(0, 0, getWidth(), getHeight());
            super.paintComponent(g);
        }

        @Override
        public void setContentAreaFilled(boolean b) {
        }

        public Color getHoverBackgroundColor() {
            return hoverBackgroundColor;
        }

        public void setHoverBackgroundColor(Color hoverBackgroundColor) {
            this.hoverBackgroundColor = hoverBackgroundColor;
        }

        public Color getPressedBackgroundColor() {
            return pressedBackgroundColor;
        }

        public void setPressedBackgroundColor(Color pressedBackgroundColor) {
            this.pressedBackgroundColor = pressedBackgroundColor;
        }
    }

    protected void createAndShowGUI() {
        JFrame frame = new JFrame("Test button");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final MyButton btnSave = new MyButton("Save");
        btnSave.setForeground(new Color(0, 135, 200).brighter());
        btnSave.setHorizontalTextPosition(SwingConstants.CENTER);
        btnSave.setBorder(null);
        btnSave.setBackground(new Color(3, 59, 90));
        btnSave.setHoverBackgroundColor(new Color(3, 59, 90).brighter());
        btnSave.setPressedBackgroundColor(Color.PINK);
        frame.add(btnSave);
        frame.setSize(200, 200);
        frame.setVisible(true);
    }

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

    }

}
于 2013-01-31T14:11:17.190 回答
11
于 2013-01-31T14:05:36.547 回答
5
public class MyCustomButton extends JButton {
    private Color pressedColor = Color.GREEN;
    private Color rolloverColor = Color.RED;
    private Color normalColor = Color.BLUE;

    public MyCustomButton (String text) {
        super(text);
        setBorderPainted(false);
        setFocusPainted(false);

        setContentAreaFilled(false);
        setOpaque(true);

        setBackground(normalColor);
        setForeground(Color.WHITE);
        setFont(new Font("Tahoma", Font.BOLD, 12));
        setText(text);

        addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent evt) {
                if (getModel().isPressed()) {
                    setBackground(pressedColor);
                } else if (getModel().isRollover()) {
                    setBackground(rolloverColor);
                } else {
                    setBackground(normalColor);
                }
            }
        });
    }
}
于 2014-05-30T16:07:20.053 回答
1

用你已经拥有的东西试试这个:

yourButton.setBorder(null);
yourButton.setContentAreaFilled(false);
于 2017-10-23T18:05:02.220 回答
1

就我而言,当用户按下按钮时,我只想要一个简单的背景和颜色切换。

改编 Guillaume Polet 的解决方案:

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;

import javax.swing.ButtonModel;
import javax.swing.JButton;

@SuppressWarnings("serial")
class Button extends JButton {

    private Color pressedForeground = Color.BLACK;
    private Color pressedBackground = Color.WHITE;

    Button() {
        this(null);
    }

    Button(String text) {
        super(text);
        super.setContentAreaFilled(false);
        setForeground(Color.WHITE);
        setBackground(Color.BLACK);
        setFocusPainted(false);
        setBorderPainted(false);
        setFont(new Font("arial", Font.PLAIN, 16));
    }

    @Override
    public void paint(Graphics g) {
        Color oldFg = getForeground();
        Color newFg = oldFg;
        ButtonModel mod = getModel();

        if (mod.isPressed()) {
            newFg = pressedForeground;
            g.setColor(pressedBackground);
        } else {
            g.setColor(getBackground());
        }

        g.fillRect(0, 0, getWidth(), getHeight());
        setForeground(newFg);
        super.paintComponent(g);
        setForeground(oldFg);
    }
}
于 2018-11-04T18:19:25.557 回答
0

可能什么都没有,但可以尝试改用:Color.PINK,大写字母?这样做时有什么变化吗?

mousepressed 和 mouseclicked 也不会相互覆盖吗?mousepressed 应该在您按下它时做出反应并在您释放鼠标时单击它

于 2013-01-31T13:46:58.807 回答
0

而不是设置颜色,因为这似乎不起作用,您可以尝试将背景设置为可拉伸的图像文件并将其设置为背景。那行得通吗?

于 2013-08-23T11:50:21.037 回答
0

这对我有用!试试这个兄弟...

final JButton btnSave = new JButton("Save");

btnSave.setForeground(new Color(0, 135, 200).brighter());
btnSave.setHorizontalTextPosition(SwingConstants.CENTER);
btnSave.setBorder(null);

UIManager.put("Button.select", new Color(3, 59, 90)); //<--- Added ---
//btnSave.setBackground(new Color(3, 59, 90));

btnSave.addMouseListener(new MouseListener() {
    @Override
    public void mouseReleased(MouseEvent e) {
        UIManager.put("Button.select", new Color(3, 59, 90)); //<--- Added ---
        //btnSave.setBackground(new Color(3, 59, 90));
    }

    @Override
    public void mousePressed(MouseEvent e) {
        // it's working :)
        UIManager.put("Button.select", Color.pink); //<--- Added ---
        //btnSave.setBackground(Color.pink);
    }

    @Override
    public void mouseExited(MouseEvent e) {
        btnSave.setBackground(new Color(3, 59, 90));
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        btnSave.setBackground(new Color(3, 59, 90).brighter());
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        btnSave.setBackground(new Color(3, 59, 90).brighter());
    }
});    
于 2021-05-06T06:21:07.620 回答
0

初始化按钮

JButton button = new JButton();

然后,在鼠标按下时执行:

button.setContentAreaFilled(false);
button.setOpaque(true);
button.setBackground(/*Insert Color Here*/);

在鼠标释放时:

button.setContentAreaFilled(true);
button.setBackground(/*Reset Color Here*/);
于 2021-09-15T00:08:21.797 回答