gpt4 book ai didi

java - BasicButtonUI 按钮不会重绘

转载 作者:行者123 更新时间:2023-11-29 05:02:07 24 4
gpt4 key购买 nike

我正在试验在 this SO post 上找到的代码关于使用 BasicButtonUI 制作的自定义按钮。我试图让我的自定义按钮在按下时淡出,但由于某种原因我看不到任何结果。我做了一个SSCCE来说明问题:

我在计时器中放了一条打印语句来验证它是否正常工作,让我相信我重绘的方式有问题。

import javax.swing.*;
import javax.swing.plaf.basic.BasicButtonUI;
import java.awt.*;
import java.awt.event.*;

class StyledButtonUI extends BasicButtonUI {

@Override
public void installUI (JComponent c) {
super.installUI(c);
AbstractButton button = (AbstractButton) c;
button.setOpaque(false);
button.setBorder(BorderFactory.createEmptyBorder (5, 15, 5, 15));
}

@Override
public void paint (Graphics g, JComponent c) {
AbstractButton b = (AbstractButton) c;
paintBackground(g, b, b.getModel().isPressed () ? true : false);
super.paint(g, c);
}

private void paintBackground (final Graphics g, final JComponent c, boolean fade) {
final Dimension size = c.getSize();
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

//draws normal button
g.setColor (c.getBackground ());
g.fillRoundRect (0, 0, size.width, size.height - 5, 10, 10);

if (fade) {
Timer timer = new Timer (50, new ActionListener () {
int i = 0;//starting opacity
int limit = 15;//opacity limit

public void actionPerformed (ActionEvent ae) {
if (i <= limit) {
System.out.println ("background color: " + c.getBackground () + " alpha: " + c.getBackground ().getAlpha () + " new fade in color: " + getAlphaColor (c.getBackground (), i) + " fade in alpha: " + i);
g.setColor (getAlphaColor (c.getBackground (), i));
g.fillRoundRect(0, 0, size.width, size.height - 5, 10, 10);
i++;
}
else {
((Timer) ae.getSource ()).stop ();
}
}});

timer.start ();
}
}

private Color getAlphaColor (Color color, int newAlpha) {
return new Color (color.getRed (), color.getGreen (), color.getBlue (), newAlpha);
}

public static void main (String[] args) {
JFrame f = new JFrame("Button UI Test");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

JPanel p = new JPanel();
p.setBackground(Color.WHITE);
f.setContentPane(p);

for (int i = 1; i <= 5; i++) {
final JButton button = new JButton("Button #" + i);

button.setBackground(Color.BLACK);
button.setForeground(Color.WHITE);

button.setUI(new StyledButtonUI());
p.add(button);
}

f.pack();
f.setLocation(500, 500);
f.setVisible(true);
}
}

最佳答案

不确定我是否会为此更改 UI。您绝对不应该在 painting() 方法中启动 Timer。您无法控制 Swing 何时确定组件需要重新绘制。例如,当您将鼠标移到按钮上时,它会重新绘制以实现翻转效果。

这是一个类的例子,当组件获得焦点时,它可以淡化任何组件的背景:

import java.awt.*;
import java.awt.event.*;
import java.util.Hashtable;
import java.util.ArrayList;
import javax.swing.*;

public class Fader
{
// background color when component has focus
private Color fadeColor;

// steps to fade from original background to fade background
private int steps;

// apply transition colors at this time interval
private int interval;

// store transition colors from orginal background to fade background
private Hashtable backgroundColors = new Hashtable();

/*
* Fade from a background color to the specified color using
* the default of 10 steps at a 50 millisecond interval.
*
* @param fadeColor the temporary background color
*/
public Fader(Color fadeColor)
{
this(fadeColor, 10, 50);
}

/*
* Fade from a background color to the specified color in the
* specified number of steps at the default 5 millisecond interval.
*
* @param fadeColor the temporary background color
* @param steps the number of steps to fade in the color
*/
public Fader(Color fadeColor, int steps)
{
this(fadeColor, steps, 50);
}

/*
* Fade from a background color to the specified color in the
* specified number of steps at the specified time interval.
*
* @param fadeColor the temporary background color
* @param steps the number of steps to fade in the color
* @param intevral the interval to apply color fading
*/
public Fader(Color fadeColor, int steps, int interval)
{
this.fadeColor = fadeColor;
this.steps = steps;
this.interval = interval;
}

/*
* Add a component to this fader.
*
* The fade color will be applied when the component gains focus.
* The background color will be restored when the component loses focus.
*
* @param component apply fading to this component
*/
public Fader add(JComponent component)
{
// Get colors to be used for fading

ArrayList colors = getColors( component.getBackground() );

// FaderTimer will apply colors to the component

new FaderTimer( colors, component, interval );

return this;
}

/*
** Get the colors used to fade this background
*/
private ArrayList getColors(Color background)
{
// Check if the color ArrayList already exists

Object o = backgroundColors.get( background );

if (o != null)
{
return (ArrayList)o;
}

// Doesn't exist, create fader colors for this background

ArrayList colors = new ArrayList( steps + 1 );
colors.add( background );

int rDelta = ( background.getRed() - fadeColor.getRed() ) / steps;
int gDelta = ( background.getGreen() - fadeColor.getGreen() ) / steps;
int bDelta = ( background.getBlue() - fadeColor.getBlue() ) / steps;

for (int i = 1; i < steps; i++)
{
int rValue = background.getRed() - (i * rDelta);
int gValue = background.getGreen() - (i * gDelta);
int bValue = background.getBlue() - (i * bDelta);

colors.add( new Color(rValue, gValue, bValue) );
}

colors.add( fadeColor );
backgroundColors.put(background, colors);

return colors;
}

class FaderTimer implements FocusListener, ActionListener
{
private ArrayList colors;
private JComponent component;
private Timer timer;
private int alpha;
private int increment;

FaderTimer(ArrayList colors, JComponent component, int interval)
{
this.colors = colors;
this.component = component;
component.addFocusListener( this );
timer = new Timer(interval, this);
}

public void focusGained(FocusEvent e)
{
alpha = 0;
increment = 1;
timer.start();
}

public void focusLost(FocusEvent e)
{
alpha = steps;
increment = -1;
timer.start();
}

public void actionPerformed(ActionEvent e)
{
alpha += increment;

component.setBackground( (Color)colors.get(alpha) );

if (alpha == steps || alpha == 0)
timer.stop();
}
}

public static void main(String[] args)
{
// Create test components

JComponent textField1 = new JTextField(10);
textField1.setBackground( Color.YELLOW );
JComponent textField3 = new JTextField(10);
JComponent textField4 = new JTextField(10);
JComponent button = new JButton("Start");
JComponent checkBox = new JCheckBox("Check Box");

JFrame frame = new JFrame("Fading Background");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.getContentPane().add(textField1, BorderLayout.NORTH );
frame.getContentPane().add(button, BorderLayout.SOUTH );
frame.getContentPane().add(textField3, BorderLayout.WEST );
frame.getContentPane().add(textField4, BorderLayout.EAST );
frame.getContentPane().add(checkBox);

// Gradual Fading (using defaults)

// Fader fader = new Fader( new Color(155, 255, 155) );
Fader fader = new Fader( new Color(155, 255, 155), 10, 50 );
fader.add( textField1 );
fader.add( textField3 );
fader.add( checkBox );

// Instant Fading

fader = new Fader( new Color(255, 155, 155), 1, 1 );
fader.add( textField4 );
fader.add( button );

frame.pack();
frame.setVisible( true );
}
}

您需要自定义它以支持在 mousePressed 上淡入淡出。

关于java - BasicButtonUI 按钮不会重绘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31764608/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com