如何将所有 JButton 的默认鼠标按下背景颜色覆盖为其当前背景颜色的较暗阴影?

Posted

技术标签:

【中文标题】如何将所有 JButton 的默认鼠标按下背景颜色覆盖为其当前背景颜色的较暗阴影?【英文标题】:How can I override the default mousepressed background color of all JButtons into a darker shade of its current background color? 【发布时间】:2020-11-28 12:48:35 【问题描述】:

假设我有十个JButtons,每个都明确设置了自己的背景颜色。 现在,它们都获得了默认的鼠标按下背景颜色,但我如何将其设置为比它们各自的背景颜色更暗的阴影,而不是一一进行呢?

我知道我可以覆盖UIManager 中的颜色:

UIManager.put("Button.select", Color.RED);

我在这里找到How to change a JButton color on mouse pressed?

但这只会将其更改为单一颜色。按下时,我所有的按钮都会变成红色背景。

有没有办法让它像这样:

UIManager.put("Button.select", JButton.getBackground().darker());

我正在尝试学习 java swing,所以请忍受我的无知。

【问题讨论】:

“较深”是基于您开始使用的颜色的主观判断,这就是您必须定义每种背景颜色和每种“较深”颜色的原因。完成此操作后,您可以在示例中编写较暗的方法。 这能回答你的问题吗? How to change a JButton color on mouse pressed? @gthanop 显然不是。这与我在上面提供的链接相同。 【参考方案1】:

一种方法是创建自己的ButtonUI。为避免重新发明***的麻烦,您可以扩展 ButtonUI 的子类。

例如BasicButtonUI 像这样:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.util.Objects;
import java.util.Random;
import javax.swing.AbstractButton;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.BasicButtonUI;

public class MainWithBasicButtonUI 
    
    public static class SelectButtonUI extends BasicButtonUI 
        protected Color selectColor;
        
        public void setSelectColor(final Color selectColor) 
            this.selectColor = Objects.requireNonNull(selectColor);
        
        
        public Color getSelectColor() 
            return selectColor;
        
        
        @Override
        protected void paintButtonPressed(final Graphics g,
                                          final AbstractButton b)
            if (b.isContentAreaFilled()) 
                Dimension size = b.getSize();
                g.setColor(getSelectColor());
                g.fillRect(0, 0, size.width, size.height);
            
        
    
    
    private static void createAndShowGUI() 
        final int rows = 3, cols = 3;
        final Color[] colors = new Color[]Color.RED.brighter(), Color.GREEN.brighter(), Color.CYAN;
        final JPanel buttons = new JPanel(new GridLayout(rows, cols, 2, 2));
        final Random rand = new Random();
        for (int i = 0; i < rows * cols; ++i) 
            final JButton b = new JButton("Button");
            b.setBackground(colors[rand.nextInt(colors.length)]);
            final SelectButtonUI ui = new SelectButtonUI();
            ui.setSelectColor(b.getBackground().darker());
            b.setUI(ui);
            buttons.add(b);
        
        final JFrame frame = new JFrame("App");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(buttons);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    
    
    public static void main(final String[] args) 
        SwingUtilities.invokeLater(MainWithBasicButtonUI::createAndShowGUI);
    

或者,更好的是,MetalButtonUI 像这样:

import java.awt.Color;
import java.awt.GridLayout;
import java.util.Objects;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.plaf.metal.MetalButtonUI;

public class MainWithMetalButtonUI 
    
    public static class SelectButtonUI extends MetalButtonUI 
        public SelectButtonUI() 
            selectColor = super.getSelectColor();
        
        
        public void setSelectColor(final Color selectColor) 
            this.selectColor = Objects.requireNonNull(selectColor);
        
        
        @Override
        protected Color getSelectColor() 
            return selectColor;
        
    
    
    private static void createAndShowGUI() 
        final int rows = 3, cols = 3;
        final Color[] colors = new Color[]Color.RED.brighter(), Color.GREEN.brighter(), Color.CYAN;
        final JPanel buttons = new JPanel(new GridLayout(rows, cols, 2, 2));
        final Random rand = new Random();
        for (int i = 0; i < rows * cols; ++i) 
            final JButton b = new JButton("Button");
            b.setBackground(colors[rand.nextInt(colors.length)]);
            final SelectButtonUI ui = new SelectButtonUI();
            ui.setSelectColor(b.getBackground().darker());
            b.setUI(ui);
            buttons.add(b);
        
        final JFrame frame = new JFrame("App");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(buttons);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    
    
    public static void main(final String[] args) 
        SwingUtilities.invokeLater(MainWithMetalButtonUI::createAndShowGUI);
    

唯一的问题是,你所有的按钮总是看起来像金属 L&F。

【讨论】:

完美!除了MetalButtonUI 解决方案具有focusPainted 但很容易处理之外,无法真正看到两者之间的巨大视觉差异。谢谢。

以上是关于如何将所有 JButton 的默认鼠标按下背景颜色覆盖为其当前背景颜色的较暗阴影?的主要内容,如果未能解决你的问题,请参考以下文章

在 500 毫秒内更改 JButton 颜色

Java JButton 设置文本背景颜色

Eclipse,将鼠标悬停在关键字上时更改弹出文本背景颜色

将鼠标悬停在 li 上时如何更改所有字体颜色

JButton、JTextFeild、JLabel 设置背景颜色不起作用

Android:按下菜单项时的背景颜色