我想改变
JButton
渐变颜色,
我发现了这个,http://java2everyone.blogspot.com/2009/01/set-jbutton-gradient-color.html,但我只想更改一个按钮的渐变,而不是所有按钮
您可以重写 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();
}
}
}
比我的答案有一点改进:
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);
}
}
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.0,否则会绘制更多渐变。
由于这是一个多级渐变,因此不能用简单的
GradientPaint
来完成,但可以用LinearGradientPaint
来完成。然而 background
属性只接受 Color
。它甚至不能被欺骗/黑客攻击,因为实际值最终被赋予 Graphics.setColor()
而不是 Graphics2D.setPaint()
(即使 Metal 是基于 Swing 的而不是 AWT)死胡同。 唯一的解决方案似乎完全是 JButton 的子类。
我发现卢卡的回答是最好的。
我刚刚做了一处更改。我添加了一个淡入淡出变量,以便选择如果需要,可以不选择纯白色。
这是总代码:
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);
}
}