マウスイベント(マウスの入力、終了、押されたなど)に応じてカスタムカラーが必要です。そのため、これを実現するために、以下のコードを作成しました。何もしないマウスプレスイベントの場合を除いて、すべてに問題ありません。このUIManager.put("Button.select", Color.red);
のようにUIManager
の色をオーバーライドした場合にのみ機能します。 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());
}
});
編集1:だから、マウスリスナーの代わりに、mKorbelが示唆するようにChangeListener
とButtonModel
を使用しています。このコードでは、ボタンの外側を押してドラッグする場合を除いて、ボタンで押したマウスの変更はまだ観察されていません。何かご意見は?
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));
}
}
});
この問題は、デフォルトで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();
}
});
}
}
決して MouseListener を JButton に使用しないでください
ActionListener または ChangeListener with ButtonModel を使用します
in ButtonModel が実装されています
1)isPressed
2)isArmed
3)isRollover
4)e.i.
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);
}
}
});
}
}
私の場合、ユーザーがボタンを押したときのシンプルな背景と色の切り替えが必要でした。
適応したギヨーム・ポレットのソリューション:
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);
}
}