Search code examples
javaswingjbuttoncustom-componentgraphics2d

Need help to create a custom button in swing


I am trying to create a button which looks as shown below and continuously fades in and fades out .It looks like :-

enter image description here

Now i have done till the looks with gradient paint but what should i do to make the button text appear.Inspite of calling 'super(s)' it doesn't appear as i have painted it with GradientPaint.What should i do make the text appear over paint.My code is shown below :-

import java.awt.AlphaComposite;
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 javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;


public class Fader extends JFrame{
Fader()
{
    super("A fading button");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLayout(new FlowLayout());
    setSize(400,400);

    add(new CustomButton("Submit"));
    setVisible(true);
}
public static void main(String args[])
{
SwingUtilities.invokeLater(new Runnable(){public void run(){new Fader();}});
}
}

class CustomButton extends JButton
{
public CustomButton(String s) {
    super(s);
    // TODO Auto-generated constructor stub
}
public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    Graphics2D g2=(Graphics2D)g.create();
    GradientPaint gp=new GradientPaint(0, 0, Color.RED, 200, 100, Color.YELLOW);
    g2.setPaint(gp);
    g2.fillRect(0, 0, getWidth(), getHeight());
}
public Dimension getPreferredSize()
{
    return new Dimension(200,100);
}
}

Secondly,an advice to implement the fade in and out effect is also requested.


Solution

  • You can use this option, that paints a transparent color gradient on a component:

    @Override
    public void paintComponent(Graphics g){
        super.paintComponent( g );
    
        Graphics2D g2=(Graphics2D)g.create();
        int h = getHeight();
        int w = getWidth();
    
        g2.setComposite(AlphaComposite.getInstance(
                AlphaComposite.SRC_OVER, .5f));
        g2.setPaint(new GradientPaint(0, 0, Color.yellow, 0, h, Color.red));
        g2.fillRect(0, 0, w, h);
    
        g2.dispose();
    }
    

    enter image description here

    Other pretty good example with fading in (as requested). I used RadialGradientPaint. You can play with AlphaComposite

    g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .4f));
    

    where 4f represent transparent level 40%

    @Override
    public void paintComponent(Graphics g){
        super.paintComponent( g );
    
        Graphics2D g2=(Graphics2D)g.create();
        int h = getHeight();
        int w = getWidth();
    
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f));
    
    
        Point2D center = new Point2D.Float(100, 50);
        float radius = 150;
        float[] dist = {0.0f, 1.0f};
    
        Color[] colors = {Color.yellow, Color.red};
        RadialGradientPaint p = new RadialGradientPaint(center, radius, dist, colors);
        g2.setPaint(p);     
    
        g2.fillRect(0, 0, w, h);
    
        g2.dispose();       
    
    }
    

    enter image description here

    Finally we can play with alpha dynamically. Her is the full code. I created simple thread that change me alpha from 0 to 9 and vise versa. Here we go:

    public class Fader extends JFrame{
    private static final long serialVersionUID = 1L;
    static JButton button;
    
    public static float mTransparent = .0f;
    
    Fader(){
        super("A fading button");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new FlowLayout());
        setSize(400,400);
    
        JButton button = new CustomButton("Submit");
    
        add(button);
        setVisible(true);
    
        Blink blink = new Blink(this);
        blink.start();
    }
    
    public static void main(String args[]){
        SwingUtilities.invokeLater(new Runnable(){public void run(){new Fader();}});
    }
    
    public static float getTransparentLevel() {
        return mTransparent;
    }
    
    public  void setTransparentLevel(float newVal) {
        mTransparent = newVal;
    
        if(button != null){
            button.repaint();
    
        }
        repaint();
    
    
    }
    }
    
    
    class Blink extends Thread{
    
    Fader fader;
    
    public Blink(Fader fader) {
        this.fader = fader;
    }
    
    @Override
    public void run(){
    
        while(true){        
    
            if(Fader.getTransparentLevel() == 0.0f){                
                //increase to 1f
                for(int i=1; i<10; i++){
                    fader.setTransparentLevel((float)i/10);
    
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }               
            }
            else if(Fader.getTransparentLevel() == 0.9f){
                //increase to 1f
                for(int i=10; i>=0; i--){
                    fader.setTransparentLevel((float)i/10);
    
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }       
        }       
    }
    }
    
    
    class CustomButton extends JButton {
    
    private static final long serialVersionUID = 1L;
    public CustomButton(String s) {
        super(s);       
    }
    
    @Override
    public void paintComponent(Graphics g){
        super.paintComponent( g );
    
        Graphics2D g2=(Graphics2D)g.create();
        int h = getHeight();
        int w = getWidth();
    
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, Fader.getTransparentLevel()));
    
    
        Point2D center = new Point2D.Float(100, 50);
        float radius = 150;
        float[] dist = {0.0f, 1.0f};
    
        Color[] colors = {Color.yellow, Color.red};
        RadialGradientPaint p = new RadialGradientPaint(center, radius, dist, colors);
        g2.setPaint(p);     
        g2.fillRect(0, 0, w, h);
        g2.dispose();       
    
    }
    
    public Dimension getPreferredSize(){
        return new Dimension(200,100);
    }
    }
    

    It blinks with sleep 300 ms from .0 to .9 of transparent and back from .9 to .0:

    enter image description here --> enter image description here