更改JButton渐变颜色,但仅针对一个按钮,不是全部

问题描述 投票:0回答:4

我想改变

JButton
渐变颜色, 我发现了这个,http://java2everyone.blogspot.com/2009/01/set-jbutton-gradient-color.html,但我只想更改一个按钮的渐变,而不是所有按钮

java swing gradient background-color jbutton
4个回答
23
投票

您可以重写 JButton 实例的

paintComponent
方法,并使用以下实现 Paint 接口的类之一绘制其 Graphics 对象:


import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public final class JGradientButtonDemo {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                createAndShowGUI();         
            }
        });
    }

    private static void createAndShowGUI() {
        final JFrame frame = new JFrame("Gradient JButton Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new FlowLayout());
        frame.add(JGradientButton.newInstance());
        frame.setSize(new Dimension(300, 150)); // used for demonstration
        //frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    private static class JGradientButton extends JButton {
        private JGradientButton() {
            super("Gradient Button");
            setContentAreaFilled(false);
            setFocusPainted(false); // used for demonstration
        }

        @Override
        protected void paintComponent(Graphics g) {
            final Graphics2D g2 = (Graphics2D) g.create();
            g2.setPaint(new GradientPaint(
                    new Point(0, 0), 
                    Color.WHITE, 
                    new Point(0, getHeight()), 
                    Color.PINK.darker()));
            g2.fillRect(0, 0, getWidth(), getHeight());
            g2.dispose();

            super.paintComponent(g);
        }

        public static JGradientButton newInstance() {
            return new JGradientButton();
        }
    }
}

enter image description here


7
投票

比我的答案有一点改进:

enter image description here

private static final class JGradientButton extends JButton{
    private JGradientButton(String text){
        super(text);
        setContentAreaFilled(false);
    }

    @Override
    protected void paintComponent(Graphics g){
        Graphics2D g2 = (Graphics2D)g.create();
        g2.setPaint(new GradientPaint(
                new Point(0, 0), 
                getBackground(), 
                new Point(0, getHeight()/3), 
                Color.WHITE));
        g2.fillRect(0, 0, getWidth(), getHeight()/3);
        g2.setPaint(new GradientPaint(
                new Point(0, getHeight()/3), 
                Color.WHITE, 
                new Point(0, getHeight()), 
                getBackground()));
        g2.fillRect(0, getHeight()/3, getWidth(), getHeight());
        g2.dispose();

        super.paintComponent(g);
    }
}

2
投票

TL;DR:这不可能直接实现,但可以通过像 Luca 的答案中那样的解决方法来完成,但是他/她的答案使用了不正确的梯度步骤。下面列出了正确的。

它的工作原理

在 Metal LAF 中存在一个硬编码的异常。如果

background
属性是
UIResource
的子类,则它会被忽略*,并且按钮会使用 UI 属性
Button.gradient
中的(也是硬编码的)渐变进行绘制。否则,如果
background
不是
UIResource
,则按原样绘制该背景。

*除非按钮被禁用,在这种情况下没有渐变,并且

UIResource
内的颜色用于背景。


渐变

按照

MetalButtonUI
的逻辑,我发现它使用的渐变来自UI属性
Button.gradient
,其中包含
ArrayList

0 = {Float} 0.3
1 = {Float} 0.0
2 = {ColorUIResource} "[221,232,243]"
3 = {ColorUIResource} "[255,255,255]"
4 = {ColorUIResource} "[184,207,229]"

进一步遵循逻辑,我最终得到了

MetalUtils.GradientPainter.drawVerticalGradient()
。该实现将上述数据解释为*:

  • 从 0% 到 30% 的渐变:颜色 1 到颜色 2
  • 从 30% 到 60% 的渐变:颜色 2 到颜色 1
  • 从 60% 到 100% 的渐变:颜色 1 到颜色 3

*假设第二个浮点数为0.0,否则会绘制更多渐变。

由于这是一个多级渐变,因此不能用简单的

GradientPaint
来完成,但可以用
LinearGradientPaint
来完成。然而
background
属性只接受
Color
。它甚至不能被欺骗/黑客攻击,因为实际值最终被赋予
Graphics.setColor()
而不是
Graphics2D.setPaint()
(即使 Metal 是基于 Swing 的而不是 AWT)死胡同。 唯一的解决方案似乎完全是 JButton 的子类。


0
投票

我发现卢卡的回答是最好的。

我刚刚做了一处更改。我添加了一个淡入淡出变量,以便选择如果需要,可以不选择纯白色。

这是总代码:

 import java.awt.Color;
 import java.awt.GradientPaint;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
 import java.awt.Point;
 import javax.swing.JButton;

 public class GradientButton extends JButton
 {
     private float fade;
     
     public GradientButton(String text)
     {
         super(text);
         setContentAreaFilled(false);
         fade = 1.0f;
     }
     
     public void setFade(float fade)
     {
         if(fade < 0)
             this.fade = 0;
         else if(fade > 1.0f)
             this.fade = 1.0f;
         else
             this.fade = fade;
         
     }
     
     @Override
     protected void paintComponent(Graphics g)
     {
         Color back = getBackground();
         int rb = back.getRed();
         int gb = back.getGreen();
         int bb = back.getBlue();
         
         int rf = (int)((255 - rb) * fade);
         int gf = (int)((255 - gb) * fade);
         int bf = (int)((255 - bb) * fade);
    
         Color fadeColor = new Color(rb + rf, gb + gf, bb + bf);
 
         int y = getInsets().top;
         int h = getHeight() - getInsets().top - getInsets().bottom;
         Graphics2D g2 = (Graphics2D)g.create();
         g2.setPaint(new GradientPaint(
                 new Point(0,y), 
                 getBackground(), 
                 new Point(0, h/3 + y), 
                 fadeColor));
         g2.fillRect(0, y, getWidth(), h/3);
         g2.setPaint(new GradientPaint(
                 new Point(0, h/3 + y), 
                 fadeColor,
                 new Point(0, h + y), 
                 getBackground()));
         g2.fillRect(0, h/3 + y, getWidth(), h);
         g2.dispose();
 
         super.paintComponent(g);
     }
 }
© www.soinside.com 2019 - 2024. All rights reserved.