[英]How to change a JButton color on mouse pressed?
I want to have custom colors according to the mouse events (mouse enter, exit, pressed, etc). 我希望根据鼠标事件(鼠标进入,退出,按下等)获得自定义颜色。 So to accomplish this, I wrote the code bellow.
所以要做到这一点,我写了下面的代码。 It is fine for everything, except on the case of the mouse pressed event, which does nothing.
它对一切都很好,除了鼠标按下事件的情况,什么都不做。 It only works if I override the color in the
UIManager
like this UIManager.put("Button.select", Color.red);
它只有在我覆盖
UIManager
的颜色时才有效,就像这个UIManager.put("Button.select", Color.red);
. 。 Problem with the
UIManager
, is that it will change for all my buttons. UIManager
问题在于它会改变我的所有按钮。
Can anyone tell me what I might be doing wrong or what is the best approach to accomplish what I'm trying to do? 任何人都可以告诉我,我可能做错了什么,或者最好的方法是什么,我想要做什么?
My Code: 我的代码:
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: So, instead of mouse listener, I'm using ChangeListener
and ButtonModel
as suggested by mKorbel. Edit1:所以,我没有使用鼠标监听器,而是按照
ButtonModel
建议使用ChangeListener
和ButtonModel。 With this code I'm still not observing any changes on mouse pressed in the button except when I press and drag outside the button. 使用此代码,我仍然没有观察到按钮上按下鼠标的任何更改,除非我按下并拖动按钮外部。 Any thoughts?
有什么想法吗?
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));
}
}
});
The problem is caused by the fact that a JButton has its content area filled by default and that the Metal L&F will automatically fill it with its internal chosen color when button is pressed. 问题是由于JButton的内容区域默认填充,而金属L&F会在按下按钮时自动用内部选择的颜色填充它。
Best thing to do, is to extend JButton to create your own button, disable content area filled, and paint yourself the background of the button. 最好的办法是扩展JButton以创建自己的按钮,禁用填充的内容区域,并自己绘制按钮的背景。
Here is a small demo for that (not sure it works on other L&F, even pretty sure it does not): 这是一个小的演示(不确定它适用于其他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();
}
});
}
}
never, don't to use MouseListener for JButton 从不,不要将MouseListener用于JButton
use ActionListener or ChangeListener with ButtonModel 将ActionListener或ChangeListener与ButtonModel一起使用
in ButtonModel are implemented 在ButtonModel中实现
1) isPressed
1)
isPressed
2) isArmed
2)
isArmed
3) isRollover
3)
isRollover
4) ei 4)ei
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);
}
}
});
}
}
In my case, I just wanted a simple background and color switch when the user pressed the button. 就我而言,当用户按下按钮时,我只想要一个简单的背景和颜色切换。
Adapted Guillaume Polet's solution: 改编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);
}
}
Could be nothing but could try to instead use: Color.PINK, capital letters? 可能只是可以尝试使用:Color.PINK,大写字母? Any change when doing that?
这样做有什么变化吗?
Also wouldn't the mousepressed & mouseclicked override each other? 也不会鼠标按下并且鼠标点击相互覆盖? mousepressed should react when you press it & clicked when you release the pressing of the mouse
当您按下鼠标时,鼠标按压会发生反应,当您松开按下鼠标时,它会被点击
Instead of setting the color because that appears not to work you could just try setting the background to a stretchable image file and set that as the background. 由于看起来不起作用而不是设置颜色,您可以尝试将背景设置为可伸展的图像文件并将其设置为背景。 Might that work?
可能有用吗?
Try this with what you already have: 尝试使用您已有的:
yourButton.setBorder(null);
yourButton.setContentAreaFilled(false);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.