Java swing custom ripple button:

To create this button, we extended the JButton class and overrode the paintComponent method to draw a rounded rectangle with a white ripple effect when the button is clicked. We also added a mouse listener to start and stop the ripple effect thread when the button is pressed and released respectively.

In the paintComponent method, we first cast the Graphics object to Graphics2D and set the rendering hint to antialiasing to create smooth edges. Then we draw the background of the button with the fillRoundRect method, using the current dimensions of the button and a border radius of 15 pixels.

If the ripple effect is currently active (i.e. the rippleRadius is less than the width of the button), we draw an oval with a white semi-transparent color to create the ripple effect. The position and size of the oval are determined by the current rippleX, rippleY, and rippleRadius values.

Overall, this custom button provides a unique and visually appealing way to interact with Java Swing GUIs.



import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;

public class RippleButton extends JButton{
    
    private volatile int rippleX;
    private volatile int rippleY;
    private volatile int rippleRadius;
    private Thread rippleThread;

    public RippleButton() {
        setOpaque(false);
        setFocusPainted(false);
        setContentAreaFilled(false);
        addMouseListener(new MouseAdapter(){
            @Override
            public void mousePressed(MouseEvent e) {
                
                rippleThread = new Thread(){
                    @Override
                    public void run() {
                        rippleX = e.getX();
                        rippleY = e.getY();
                        rippleRadius = 0;
                        while(rippleRadius< getWidth()){
                            rippleRadius+= 4;
                            try {
                                Thread.sleep(5);
                            } catch (InterruptedException ex) {
                                Logger.getLogger(RippleButton.class.getName()).log(Level.SEVERE, null, ex);
                            }
                            repaint();
                        }
                    }
                  
                };
                rippleThread.start();
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                
                repaint();
                rippleRadius = 0;
            }
            
            
        });
    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setColor(getBackground());
        g2.fillRoundRect(0, 0, getWidth(), getHeight(), 15, 15);
        if(rippleRadius < getWidth()){
            g2.setColor(new Color(255,255,255,100));
            g2.fillOval(rippleX - rippleRadius, rippleY - rippleRadius, rippleRadius*2, rippleRadius*2);
        }
        super.paintComponent(g); 
    }
    

}