Card Slider in Java Swing

How to Create a Card Slider in Java Netbeans

How to Create a Card Slider in Java Netbeans



In this Java Tutorial we will see How To Create a card slider with smooth animations, drag interactions, mouse wheel navigation, dynamic scaling, and glassmorphism design elements In Java Using Netbeans.

What We Are Gonna Use In This Project:

- Java Programming Language.
- NetBeans Editor.





Project Source Code:


/**
 *
 * @author 1BestCsharp
 * 
 */
public class CardSlider extends JPanel  {
    
    // Card display and animation constants
    private static final int CARD_WIDTH = 320;
    private static final int CARD_HEIGHT = 420;
    private static final int CARD_SPACING = 30;
    private static final int ANIMATION_DURATION = 250;
    
    // Color palette for modern, clean design
    private static final Color BACKGROUND_COLOR = new Color(245, 247, 250);
    private static final Color SPECIAL_COLOR = new Color(88, 86, 214);
    private static final Color CARD_BACKGROUND = new Color(255, 255, 255, 240);
    private static final Color TEXT_COLOR = new Color(30, 30, 30);
    private static final Color CARD_BORDER = new Color(255, 255, 255, 100);
            
    // State tracking variables for card slider
    private final List<Card> cards = new ArrayList<>();
    private int currentIndex = 0;
    private Timer animationTimer;
    private long animationStartTime;
    private double slideOffset = 0;
    private double targetOffset = 0;
    private double startOffset = 0;
    
    // UI components for navigation
    private JButton prevButton;
    private JButton nextButton;
    private CardIndicator indicator;
    
    // Drag interaction variables
    private boolean isDragging = false;
    private Point dragStart;
    private double startDragOffset;
    
    public CardSlider(){
        
        setBackground(BACKGROUND_COLOR);
        setLayout(null);
        
        setupNavigationButtons();
        setupMouseInteraction();
        setupAnimationTimer();
        setupCardIndicator();
        
    }
    
    
    // Create dots at bottom to show current card position
    private void setupCardIndicator(){
        indicator = new CardIndicator();
        add(indicator);
    }
    
    // Set up mouse interactions like dragging and scrolling
    private void setupMouseInteraction(){
        
        MouseAdapter mouseHandler = new MouseAdapter() {
            
            @Override
            public void mousePressed(MouseEvent e){
                // Record where drag started
                dragStart = e.getPoint();
                startDragOffset = slideOffset;
                isDragging = true;
            }
            
            @Override
            public void mouseReleased(MouseEvent e){
                
                if(isDragging){
                    
                    isDragging = false;
                    double dragDistance = e.getX() - dragStart.x;
                    
                    // Determine if drag should change card
                    if(Math.abs(dragDistance) > CARD_WIDTH / 3){
                        
                        if(dragDistance > 0 && currentIndex > 0){
                            currentIndex --; // Move to previous card
                        }
                        
                        else if(dragDistance < 0 && currentIndex < cards.size() - 1){
                            currentIndex ++; // Move to next card
                        }
                        
                    }
                    
                    startSlideAnimation();
                    
                }
                
            }

            @Override
            public void mouseDragged(MouseEvent e){
                
                if(isDragging){
                    // Update slider position based on drag
                    double dragDistance = e.getX() - dragStart.x;
                    slideOffset = startDragOffset + dragDistance;
                    repaint();
                }

            }
            
            @Override
            public void mouseWheelMoved(MouseWheelEvent e){
                // Allow mouse wheel to navigate cards
                if(e.getWheelRotation() > 0){ nextCard(); }
                
                else{ previousCard(); }
                
            }

        };
        
        // Register mouse listeners for interaction
        addMouseListener(mouseHandler);
        addMouseMotionListener(mouseHandler);
        addMouseWheelListener(mouseHandler);
        
    }
    
    
    // Create smooth animation timer for card transitions
    private void setupAnimationTimer(){
        
        animationTimer = new Timer(16, e -> {
            
            long elapsed = System.currentTimeMillis() - animationStartTime;
            float progress = Math.min(1f, (float) elapsed / ANIMATION_DURATION);
            
            // Advanced easing function for more natural animation
            progress = (float) (progress < 0.5 ? 4 * progress * progress * progress : 
                                            1 - Math.pow(-2 * progress +2, 3));
            
            // Interpolate between start and target offsets
            slideOffset = startOffset + (targetOffset - startOffset) * progress;
            
            // Stop animation when complete
            if(progress >= 1){
                startOffset = targetOffset;
                ((Timer) e.getSource()).stop();
            }
            
            repaint();
            
        });
        
    }
    
    
    
    
     // Add navigation buttons
    private void setupNavigationButtons(){
        prevButton = createNavigationButton("‹");
        nextButton = createNavigationButton("›");
        
        prevButton.addActionListener(e -> previousCard());
        nextButton.addActionListener(e -> nextCard());
        
        add(prevButton);
        add(nextButton);
    }
    
    
    // Create and design navigation button
    private JButton createNavigationButton(String text){
        
        JButton button = new JButton(text){
            
            @Override
            protected void paintComponent(Graphics g){
                Graphics2D g2d = (Graphics2D)g.create();
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
                
                // Create circular button shape
                Area circle = new Area(new Ellipse2D.Double(0,0, getWidth(), getHeight()));
                // Background with transparency
                g2d.setColor(new Color(255, 255, 255, 80));
                g2d.fill(circle);
                // Dynamic button color based on interaction state
                Color buttonColor = getModel().isPressed() ? SPECIAL_COLOR.darker() : SPECIAL_COLOR;
                
                g2d.setColor(buttonColor);
                g2d.fill(circle);
                
                // Add subtle border
                g2d.setColor(CARD_BORDER);
                g2d.setStroke(new BasicStroke(2.0f));
                g2d.draw(circle);
                
                // Add text with shadow effect
                g2d.setColor(new Color(0,0,0,50));
                g2d.setFont(new Font("Arial", Font.BOLD, 18));
                FontMetrics fm = g2d.getFontMetrics();
                int x = (getWidth() - fm.stringWidth(text)) / 2;
                int y = (getHeight() + fm.getAscent() - fm.getDescent()) / 2;
                g2d.drawString(text, x + 1, y + 1);
                
                g2d.setColor(Color.WHITE);
                g2d.drawString(text, x, y);
                g2d.dispose();
                
            }
            
        };
        
        // Button styling
        button.setPreferredSize(new Dimension(50, 50));
        button.setBorderPainted(false);
        button.setContentAreaFilled(false);
        button.setFocusPainted(false);
        button.setCursor(new Cursor(Cursor.HAND_CURSOR));
        
        return button;

    }
    
    
    
    // Inner class representing an individual card
    private class Card{
        
        private String title;
        private String description;
        private Color cardColor;
        
        public Card(String title, String description, Color cardColor){
            this.title = title;
            this.description = description;
            this.cardColor = cardColor;
        }
        
        // Render the card with modern visual effects
        public void draw(Graphics2D g2d, int x, int y, float scale, float alpha){
            
            AffineTransform transform = g2d.getTransform();
            
            // Apply scaling transformation
            g2d.translate(x + CARD_WIDTH / 2, y + CARD_HEIGHT / 2);
            g2d.scale(scale, scale);
            g2d.translate(-CARD_WIDTH / 2 , -CARD_HEIGHT / 2);
            
            // Create layered shadow effect
            for(int i = 0; i < 3; i++){
                g2d.setColor(new Color(0,0,0,10 - i *3));
                g2d.fillRoundRect(5 + i, 5 + i, CARD_WIDTH, CARD_HEIGHT, 25, 25);
            }
            
            // Apply transparency and background
            g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
            g2d.setColor(CARD_BACKGROUND);
            g2d.fillRoundRect(0, 0, CARD_WIDTH, CARD_HEIGHT, 25, 25);
            
            // Add subtle border
            g2d.setColor(CARD_BORDER);
            g2d.setStroke(new BasicStroke(1.5f));
            g2d.drawRoundRect(0, 0, CARD_WIDTH, CARD_HEIGHT, 25, 25);
            
             // Create gradient accent bar at top of card
             GradientPaint gradient = new GradientPaint(0, 0, cardColor, CARD_WIDTH, 0,
                                new Color(cardColor.getRed(), cardColor.getGreen(), cardColor.getBlue(), 60)
             );
             g2d.setPaint(gradient);
             g2d.fillRoundRect(0, 0, CARD_WIDTH, 6, 6, 6);
             
             // Draw card content
             g2d.setColor(TEXT_COLOR);
             g2d.setFont(new Font("Arial", Font.BOLD, 26));
             //g2d.drawString(title, 25, 60);
             drawWrappedText(g2d, title, 25, 60, CARD_WIDTH - 50);
             
             g2d.setFont(new Font("Arial", Font.PLAIN, 16));
             //g2d.drawString(description, 25, 110);
             drawWrappedText(g2d, description, 25, 110, CARD_WIDTH - 50);
             
            g2d.setTransform(transform);
            
        }
        
        
        // Method to wrap text within card bounds
        private void drawWrappedText(Graphics2D g2d, String text, int x, int y, int width){
            
            FontMetrics fm = g2d.getFontMetrics();
            String[] words = text.split("\\s+");
            StringBuilder line = new StringBuilder();
            
            for(String word: words){
                if(fm.stringWidth(line + " " + word) < width){
                    
                    if(line.length() > 0) line.append(" ");
                    line.append(word);
                    
                }
                else{
                    g2d.drawString(line.toString(), x, y);
                    y += fm.getHeight();
                    line = new StringBuilder(word);
                }
            }
            
            if(line.length() > 0){
                g2d.drawString(line.toString(), x, y);
            }
            
        }
  
    }
    
    
    
    
    // Inner class to create card position indicator dots
    private class CardIndicator extends JComponent{
        
        private static final int DOT_SIZE = 10;
        private static final int DOT_SPACING = 10;
        
        @Override
        protected void paintComponent(Graphics g){
            
            Graphics2D g2d = (Graphics2D)g.create();
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            
            // Calculate total width of indicator
            int totalWidth = cards.size() * (DOT_SIZE + DOT_SPACING) - DOT_SPACING;
            int startX = (getWidth() - totalWidth) / 2;
            
            // Draw dots for each card
            for(int i = 0; i < cards.size(); i++){
                
                if(i == currentIndex){
                    // Active dot with gradient
                    GradientPaint gradient = new GradientPaint(
                            startX + i * (DOT_SIZE + DOT_SPACING), 0, SPECIAL_COLOR,
                            startX + i * (DOT_SIZE + DOT_SPACING) + DOT_SIZE, 0, SPECIAL_COLOR.brighter()
                    );
                    
                    g2d.setPaint(gradient);
                    g2d.fillOval(startX + i * (DOT_SIZE + DOT_SPACING), 0, DOT_SIZE, DOT_SIZE);
                    
                }
                
                else{
                    // Inactive dot
                    g2d.setColor(new Color(SPECIAL_COLOR.getRed(), SPECIAL_COLOR.getGreen(), SPECIAL_COLOR.getBlue(), 100));
                    g2d.fillOval(startX + i * (DOT_SIZE + DOT_SPACING), 0, DOT_SIZE - 1, DOT_SIZE - 1);
                }
                
            }
            
            g2d.dispose();
            
        }
        
        // Calculate preferred size for indicator
        @Override
        public Dimension getPreferredSize(){
            return new Dimension(cards.size() * (DOT_SIZE + DOT_SPACING) - DOT_SPACING, DOT_SIZE);
        }
        
        
    }
    
    
    
    // Add a new card to the slider
    public void addCard(String title, String description, Color color){
        cards.add(new Card(title, description, color));
        indicator.repaint();
        revalidate();
        repaint();
    }
    
    
    // Navigate to previous card
    private void previousCard(){
        if(currentIndex > 0 && !animationTimer.isRunning()){
            currentIndex--;
            startSlideAnimation();
        }
    }
    
   // Navigate to next card
    private void nextCard(){
        if(currentIndex < cards.size() - 1 && !animationTimer.isRunning()){
            currentIndex++;
            startSlideAnimation();
        }
    }
    
    
    
    
    // Start smooth sliding animation between cards
    private void startSlideAnimation(){
        startOffset = slideOffset;
        targetOffset = -currentIndex * (CARD_WIDTH + CARD_SPACING);
        animationStartTime = System.currentTimeMillis();
        animationTimer.restart();
    }
    
    
    
    // Custom painting method to render cards with visual effects
    @Override
    protected void paintComponent(Graphics g){
        
        super.paintComponent(g);
        
        // Enable high-quality rendering
        Graphics2D g2d = (Graphics2D)g.create();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                                            RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                                            RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        
        
        // Calculate center position for cards
        int centerX = (getWidth() - CARD_WIDTH) / 2;
        int centerY = (getHeight() - CARD_HEIGHT) / 2;
        
        // Render cards with parallax and scale effects
        for(int i = 0; i < cards.size(); i++){
            Card card = cards.get(i);
            int x = centerX + (int) (i * (CARD_WIDTH + CARD_SPACING) + slideOffset);
            
            // Only draw cards that are visible
            if(x + CARD_WIDTH >= 0 && x <= getWidth()){
                // Calculate scale and transparency based on distance from center
                float distance = Math.abs(x - centerX);
                float scale = Math.max(0.85f, 1f - distance / (getWidth() * 0.8f));
                float alpha = Math.max(0.6f, 1f - distance / (getWidth() * 0.8f));
                
                card.draw(g2d, x, centerY, scale, alpha);
                
            }
        
        }
        
        g2d.dispose();
        
        
    }
    
    
    // Set preferred size for the slider
    @Override
    public Dimension getPreferredSize(){
        return new Dimension(900, 600);
    }
    
    
    
    // Manually layout components
    @Override
    public void doLayout(){
        
        super.doLayout();
        
        // Position navigation buttons
        if(prevButton != null && nextButton != null){
            Dimension buttonSize = prevButton.getPreferredSize();
            int y = (getHeight() - buttonSize.height) / 2;
            
            prevButton.setBounds(25, y, buttonSize.width, buttonSize.height);
            nextButton.setBounds(getWidth() - buttonSize.width - 25, y, buttonSize.width, buttonSize.height);
        }
        
        // Position indicator dots
        if(indicator != null){
            Dimension indSize = indicator.getPreferredSize();
            indicator.setBounds((getWidth() - indSize.width) / 2, getHeight() - indSize.height - 25,
                    indSize.width, indSize.height);
        }
        
    }
    
    
    
    
    
    public static void main(String[] args) {
        
        JFrame frame = new JFrame("Card Slider");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        
        CardSlider slider = new CardSlider();
            // Add sample cards with different themes
            slider.addCard("Material Design", 
                         "Sleek and modern interface with glass morphism effects and smooth animations.",
                         new Color(103, 58, 183)); // Deep purple
            
            slider.addCard("Smart Interactions", 
                         "Intuitive mouse and wheel controls with responsive feedback and natural gestures.",
                         new Color(0, 150, 136)); // Teal
            
            slider.addCard("Visual Effects", 
                         "Beautiful transitions, parallax scrolling, and dynamic scaling effects.",
                         new Color(233, 30, 99)); // Pink
            
            slider.addCard("Customizable Theme", 
                         "Easy to customize with gradients, shadows, and modern color schemes.",
                         new Color(33, 150, 243)); // Blue
            
            slider.addCard("Responsive Layout", 
                         "Automatically adapts to different screen sizes with fluid animations.",
                         new Color(139, 195, 74)); // Light Green
        
        frame.add(slider);
        //slider.repaint();
        
        frame.setSize(1000, 600);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

    }

}


The Final Result:

Card Slider in Java Swing

Create Card Slider in Java Swing

Create Card Slider in Java

Create Card Slider in Java Netbeans


if you want the source code click on the download button below




disclaimer: you will get the source code and to make it work in your machine is your responsibility and to debug any error/exception is your responsibility this project is for the students who want to see an example and read the code not to get and run.






Share this

Related Posts

Latest
Previous
Next Post »