WindowsLookAndFeel неожиданное поведение в отношении окраски кнопок
Используя WindowsLookAndFeel, который выбирается
UIManager.getSystemLookAndFeelClassName()
так как я работаю на Windows приводит к неожиданному поведению. Цвет фона кнопок меняется. Иногда они не в моем текущем проекте, но я не могу определить разницу.
Кнопки с неправильным поведением:
Кнопки со стандартным LookAndFeel:
Я приведу рабочий пример, приводящий к неожиданному поведению:
import javax.swing.UIManager;
public class Context {
public static void main(String[] args) throws Exception {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
new VocableEditor();
}
}
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class VocableEditor extends JFrame implements WindowListener, ActionListener {
private static final long serialVersionUID = -6209345602005762300L;
private Button b_save, b_discard;
private GridBagLayout layout;
public VocableEditor() {
setTitle("vocableEditorTitle");
setSize(600, 400);
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
addWindowListener(this);
layout = new GridBagLayout();
setLayout(layout);
GridBagConstraints c = new GridBagConstraints();
c.gridwidth = 1;
c.gridheight = 1;
b_discard = new Button("discardAndLeave");
b_discard.addActionListener(this);
c.gridwidth = 1;
c.gridx = 2;
add(b_discard, c);
b_save = new Button("saveAndExit");
b_save.addActionListener(this);
c.gridx = 3;
add(b_save, c);
setVisible(true);
}
public void end(boolean save) {
System.out.println(save);
dispose();
}
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
}
@Override
public void windowClosed(WindowEvent e) {
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == b_save) {
end(true);
} else if (e.getSource() == b_discard) {
end(false);
}
}
}
import java.awt.Color;
import javax.swing.JButton;
public class Button extends JButton {
private static final Color BACKGROUND_COLOR = new Color(60, 90, 180);
public Button(String name) {
super(name);
setBackground(BACKGROUND_COLOR);
setForeground(Color.WHITE);
}
}
1 ответ
Решение
После нескольких часов исследований я нашел решение. Oracle говорит, что показанное поведение желательно, даже если я не могу понять, почему LAF должен быть таким прозрачным. Решение заключается в добавлении следующих строк в конструктор кнопки:
setContentAreaFilled(false);
setOpaque(true);
Первая строка отключает рисование фона, а вторая включает его снова, но пропускает часть, в которой LAF меняет внешний вид.