代码之家  ›  专栏  ›  技术社区  ›  andrbrue

WindowsLookAndFeel有关按钮颜色的意外行为

  •  0
  • andrbrue  · 技术社区  · 7 年前

    使用由选择的WindowsLookAndFeel

    UIManager.getSystemLookAndFeelClassName()
    

    由于我在windows上工作,因此会导致意外行为。按钮的背景色会更改。有时在我当前的项目中没有,但我无法发现差异。

    行为错误的按钮:

    https://i.stack.imgur.com/d5OUk.png

    具有默认外观的按钮:

    https://i.stack.imgur.com/AMoHv.png

    我将给出一个产生意外行为的工作示例:

    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 回复  |  直到 4 年前
        1
  •  2
  •   andrbrue    7 年前

    经过几个小时的研究,我找到了一个解决办法。甲骨文表示,即使我不理解LAF为何如此不宽容,也希望看到这种行为。解决方案是向按钮的构造函数添加以下行:

    setContentAreaFilled(false);
    setOpaque(true);
    

    第一行禁用绘制背景,第二行重新启用背景,但缺少LAF更改外观的部分。