How to Create Animated Toggle Buttons in Java Netbeans
In this Java Tutorial we will see How To Create Toggle Buttons with five different styles: Neon, Gradient, Minimal, Cyberpunk, and Neumorphic In Java Using Netbeans.
What We Are Gonna Use In This Project:
- Java Programming Language.- NetBeans Editor.
Project Source Code:
/**
*
* @author 1BestCsharp
*/
public class ModernToggleButtons extends JFrame {
public ModernToggleButtons(){
// Set the title of the window
setTitle("Modern Toggle Buttons");
// Make the application close when the window is closed
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Set the initial size of the window
setSize(500, 600);
// Center the window on the screen
setLocationRelativeTo(null);
// Create the main panel that will hold all components
JPanel mainPanel = new JPanel();
// Set the layout to stack components vertically
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
// Set the background color to dark gray (RGB: 26, 26, 26)
mainPanel.setBackground(new Color(26, 26, 26));
// Add a 20-pixel empty border around all sides of the panel
mainPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
// Add toggle buttons with labels and vertical spacing
mainPanel.add(createTogglePanel("Neon", new NeonToggleButton()));
mainPanel.add(Box.createVerticalStrut(30));
mainPanel.add(createTogglePanel("Gradient", new GradientToggleButton()));
mainPanel.add(Box.createVerticalStrut(30));
mainPanel.add(createTogglePanel("Minimal", new MinimalToggleButton()));
mainPanel.add(Box.createVerticalStrut(30));
mainPanel.add(createTogglePanel("Cyberpunk", new CyberpunkToggleButton()));
mainPanel.add(Box.createVerticalStrut(30));
mainPanel.add(createTogglePanel("Neumorphic", new NeumorphicToggleButton()));
// Add the main panel to the JFrame window
add(mainPanel);
}
// Method that creates a panel containing a label, toggle button, and status label
private JPanel createTogglePanel(String label, JToggleButton toggleButton){
// Create a new panel to hold the components
JPanel panel = new JPanel();
// Use FlowLayout to arrange components horizontally with 20-pixel horizontal gaps
panel.setLayout(new FlowLayout(FlowLayout.CENTER, 20, 0));
// Set the panel's background color to dark gray
panel.setBackground(new Color(26, 26, 26));
// Create a label with the specified text
JLabel nameLabel = new JLabel(label);
// Set the label's text color to white
nameLabel.setForeground(Color.WHITE);
// Set the font to Segoe UI, normal style, 24-point size
nameLabel.setFont(new Font("Segoe UI", Font.PLAIN, 24));
// Set a fixed size for the label
nameLabel.setPreferredSize(new Dimension(150, 30));
// Create a label that will show "ON" or "OFF" status
JLabel statusLabel = new JLabel("OFF");
// Set the status label's text color to white
statusLabel.setForeground(Color.WHITE);
// Set the font to Segoe UI, normal style, 20-point size
statusLabel.setFont(new Font("Segoe UI", Font.PLAIN, 20));
// Set a fixed size for the status label
statusLabel.setPreferredSize(new Dimension(70, 30));
// Check if the toggle button is an instance of our custom BaseToggleButton class
if (toggleButton instanceof BaseToggleButton) {
// Cast the toggle button to BaseToggleButton to access its specific methods
BaseToggleButton baseToggle = (BaseToggleButton) toggleButton;
// Set a callback function that updates the status label when the toggle state changes
baseToggle.setStatusUpdateCallback(isOn -> {
// Update the text to show "ON" or "OFF"
statusLabel.setText(isOn ? "ON" : "OFF");
// Change the text color to green when ON, white when OFF
statusLabel.setForeground(isOn ? new Color(0, 255, 136) : Color.WHITE);
});
}
// Add the components to the panel
panel.add(nameLabel);
panel.add(toggleButton);
panel.add(statusLabel);
return panel;
}
// Abstract base class for all custom toggle buttons
private abstract class BaseToggleButton extends JToggleButton {
// Value between 0.0 (OFF) and 1.0 (ON) for animation progress
protected float animationProgress = 0.0f;
// Timer object to handle the animation
protected Timer animationTimer;
// Duration of the animation in milliseconds
protected final int ANIMATION_DURATION = 200;
// Number of steps in the animation
protected final int ANIMATION_STEPS = 20;
// Callback function that will be called when the toggle state changes
protected Runnable statusUpdateCallback;
public BaseToggleButton(){
// Set the size of the button
setPreferredSize(new Dimension(120, 60));
// Remove the default styling
setBorderPainted(false);
setFocusPainted(false);
setContentAreaFilled(false);
setCursor(new Cursor(Cursor.HAND_CURSOR));
// Add a listener to detect when the button is clicked
addItemListener(e -> {
startAnimation(e.getStateChange() == ItemEvent.SELECTED);
});
}
// Method to set the callback function that updates the status label
public void setStatusUpdateCallback(Runnable callback) {
this.statusUpdateCallback = callback;
}
// Method to start the animation when the button state changes
protected void startAnimation(boolean targetState){
// Stop any existing animation
if (animationTimer != null && animationTimer.isRunning()) {
animationTimer.stop();
}
// Calculate animation parameters
final float targetProgress = targetState ? 1.0f : 0.0f;
final float startProgress = animationProgress;
final float progressStep = (targetProgress - startProgress) / ANIMATION_STEPS;
final int delay = ANIMATION_DURATION / ANIMATION_STEPS;
// Create a new timer for the animation
animationTimer = new Timer(delay, null);
animationTimer.addActionListener(new ActionListener() {
private int currentStep = 0;
@Override
public void actionPerformed(ActionEvent e) {
currentStep++;
if (currentStep <= ANIMATION_STEPS) {
animationProgress = startProgress + (progressStep * currentStep);
repaint();
}
else{
animationProgress = targetProgress;
animationTimer.stop();
if (statusUpdateCallback != null) {
statusUpdateCallback.run(targetState);
}
}
}
});
// Start the animation timer
animationTimer.start();
}
// Interface for the status update callback
public interface Runnable {
void run(boolean isOn);
}
}
// Neon-style toggle button implementation
private class NeonToggleButton extends BaseToggleButton {
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Define colors for OFF and ON states
Color bgOffColor = new Color(51, 51, 51);
Color bgOnColor = new Color(0, 255, 136);
Color currentBgColor = interpolateColor(bgOffColor, bgOnColor, animationProgress);
// Draw the rounded rectangle background
g2.setColor(currentBgColor);
g2.fill(new RoundRectangle2D.Float(0, 0, getWidth(), getHeight(), 60, 60));
// Draw the white circle that moves
g2.setColor(Color.WHITE);
int diameter = getHeight() - 8;
float offX = 4;
float onX = getWidth() - diameter - 4;
float currentX = offX + (onX - offX) * animationProgress;
g2.fillOval(Math.round(currentX), 4, diameter, diameter);
// Add glow effect that increases with animation progress
int alpha = Math.round(50 * animationProgress);
if (alpha > 0) {
g2.setColor(new Color(0, 255, 136, alpha));
g2.setStroke(new BasicStroke(6));
g2.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 60, 60);
}
g2.dispose();
}
}
// Gradient-style toggle button implementation
private class GradientToggleButton extends BaseToggleButton {
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Define colors for OFF and ON states
Color offStartColor = new Color(255, 107, 107);
Color offEndColor = new Color(254, 202, 87);
Color onStartColor = new Color(72, 52, 212);
Color onEndColor = new Color(104, 109, 224);
// Calculate the current colors based on animation progress
Color currentStartColor = interpolateColor(offStartColor, onStartColor, animationProgress);
Color currentEndColor = interpolateColor(offEndColor, onEndColor, animationProgress);
// Create a gradient and apply it
GradientPaint gradient = new GradientPaint(0, 0, currentStartColor,
getWidth(), getHeight(), currentEndColor);
g2.setPaint(gradient);
g2.fill(new RoundRectangle2D.Float(0, 0, getWidth(), getHeight(), 60, 60));
// Draw the white circle that moves
g2.setColor(Color.WHITE);
int diameter = getHeight() - 8;
float offX = 4;
float onX = getWidth() - diameter - 4;
float currentX = offX + (onX - offX) * animationProgress;
g2.fillOval(Math.round(currentX), 4, diameter, diameter);
g2.dispose();
}
}
// Minimal-style toggle button implementation
private class MinimalToggleButton extends BaseToggleButton {
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Define colors for OFF and ON states
Color offColor = Color.WHITE;
Color onColor = new Color(0, 255, 136);
Color currentColor = interpolateColor(offColor, onColor, animationProgress);
// Draw the border of the toggle button
g2.setColor(currentColor);
g2.setStroke(new BasicStroke(3));
g2.draw(new RoundRectangle2D.Float(1, 1, getWidth() - 3, getHeight() - 3, 60, 60));
// Draw the circle that moves
g2.setColor(currentColor);
int diameter = getHeight() - 12;
float offX = 6;
float onX = getWidth() - diameter - 6;
float currentX = offX + (onX - offX) * animationProgress;
g2.fillOval(Math.round(currentX), 6, diameter, diameter);
g2.dispose();
}
}
// Cyberpunk-style toggle button implementation
private class CyberpunkToggleButton extends BaseToggleButton {
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Draw the dark background with less rounded corners
g2.setColor(new Color(45, 52, 54));
g2.fill(new RoundRectangle2D.Float(0, 0, getWidth(), getHeight(), 10, 10));
// Define colors for OFF and ON states
Color offColor = new Color(255, 0, 255); // Magenta
Color onColor = new Color(0, 255, 255); // Cyan
Color currentColor = interpolateColor(offColor, onColor, animationProgress);
// Draw a thin border around the toggle
g2.setColor(currentColor);
g2.setStroke(new BasicStroke(2));
g2.draw(new RoundRectangle2D.Float(1, 1, getWidth() - 3, getHeight() - 3, 10, 10));
// Create a gradient for the slider
GradientPaint gradient = new GradientPaint(0, 0, new Color(255, 0, 255),
getWidth(), getHeight(), new Color(0, 255, 255));
g2.setPaint(gradient);
// Draw the slider as a rounded rectangle
float offX = 4;
float onX = getWidth() - 52;
float currentX = offX + (onX - offX) * animationProgress;
g2.fill(new RoundRectangle2D.Float(currentX, 4, 48, getHeight() - 8, 5, 5));
g2.dispose();
}
}
// Neumorphic-style toggle button implementation
private class NeumorphicToggleButton extends BaseToggleButton {
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Store dimensions
int width = getWidth();
int height = getHeight();
int cornerRadius = 60;
// Define colors for the neumorphic effect
Color baseColor = new Color(26, 26, 26);
Color lightShadow = new Color(40, 40, 40);
Color darkShadow = new Color(10, 10, 10);
// Draw the base shape
g2.setColor(baseColor);
g2.fill(new RoundRectangle2D.Float(0, 0, width, height, cornerRadius, cornerRadius));
// Draw the lighter edge on top-left
g2.setColor(lightShadow);
g2.setStroke(new BasicStroke(2f));
g2.draw(new RoundRectangle2D.Float(1, 1, width-2, height-2, cornerRadius, cornerRadius));
// Draw the darker edge on bottom-right
g2.setColor(darkShadow);
g2.setStroke(new BasicStroke(2f));
g2.draw(new RoundRectangle2D.Float(3, 3, width-6, height-6, cornerRadius, cornerRadius));
// Draw the inner background
g2.setColor(new Color(22, 22, 22));
g2.fill(new RoundRectangle2D.Float(4, 4, width-8, height-8, cornerRadius-8, cornerRadius-8));
// Define colors for OFF and ON states
Color offStartColor = new Color(30, 30, 30);
Color offEndColor = new Color(34, 34, 34);
Color onStartColor = new Color(0, 255, 136);
Color onEndColor = new Color(0, 204, 106);
// Calculate the current colors based on animation progress
Color currentStartColor = interpolateColor(offStartColor, onStartColor, animationProgress);
Color currentEndColor = interpolateColor(offEndColor, onEndColor, animationProgress);
// Create a gradient and apply it
GradientPaint gradient = new GradientPaint(0, 0, currentStartColor,
width, height, currentEndColor);
// Position and draw the toggle circle
g2.setPaint(gradient);
int diameter = height - 16;
float offX = 8;
float onX = width - diameter - 8;
float currentX = offX + (onX - offX) * animationProgress;
// Draw the circle shadow with slight offset
g2.setColor(darkShadow);
g2.fillOval(Math.round(currentX)+2, 6, diameter, diameter);
// Draw the main circle with gradient
g2.setPaint(gradient);
g2.fillOval(Math.round(currentX), 8, diameter, diameter);
// Add highlight to the circle
g2.setColor(new Color(255, 255, 255, 30));
g2.fillArc(Math.round(currentX), 8, diameter, diameter, 45, 180);
g2.dispose();
}
}
// Method to blend between two colors based on a ratio (0.0 to 1.0)
private Color interpolateColor(Color c1, Color c2, float ratio) {
int red = Math.round(c1.getRed() * (1 - ratio) + c2.getRed() * ratio);
int green = Math.round(c1.getGreen() * (1 - ratio) + c2.getGreen() * ratio);
int blue = Math.round(c1.getBlue() * (1 - ratio) + c2.getBlue() * ratio);
return new Color(red, green, blue);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() ->{
try {
// Set the application's look and feel to match the OS
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
// Create and display the frame
new ModernToggleButtons().setVisible(true);
});
}
}
The Final Result:
More Java Projects:
Download Projects Source Code


