Articles Projects Tips Downloads Contacts About
 

Slider to rotate content of Container.

If a Container with CardLayout contains multiple components and we want to add a bit more dynamic. To show next or previous component we move the old component out and replace it with a new one. Depending on next/previous we continuously shift the component to the left/right. A simplest example of such a slider is image gallery component. User clicks on the "Next" or "Previous" button to get another image. Old image moves and a new one appears.

To implement such a slider component to rotate content I use something like the simple JSLSlider class.

That's the component's screenshot:

The source code of the component and a small test app is below. Or you can download a jar demo app with sources inside from here.

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
public class JSLSlider extends JPanel {

    JPanel pnlMain=new JPanel(new SliderCardLayout());
    
    JButton btnNext=new JButton(">");
    JButton btnPrevious=new JButton("<");
    
    public JSLSlider() {
        setLayout(new BorderLayout());
 
        add(pnlMain, BorderLayout.CENTER);
        add(btnNext, BorderLayout.EAST);
        add(btnPrevious, BorderLayout.WEST);
 
        btnNext.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                next();
            }
        });
        btnPrevious.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                previous();
            }
        });
 
    }
 
    public void previous() {
        SliderCardLayout cl=(SliderCardLayout)pnlMain.getLayout();
        Component currentComp=cl.getCurrentComponent(pnlMain);
        Component previousComp=cl.getPreviousComponent(pnlMain);
        Rectangle b=currentComp.getBounds();
        previousComp.setVisible(true);
        SliderListener sl=new SliderListener(10, currentComp, previousComp, false);
        Timer t=new Timer(40,sl);
        sl.timer=t;
        t.start();
    }
 
    public void next() {
        SliderCardLayout cl=(SliderCardLayout)pnlMain.getLayout();
        Component currentComp=cl.getCurrentComponent(pnlMain);
        Component nextComp=cl.getNextComponent(pnlMain);
        Rectangle b=currentComp.getBounds();
        nextComp.setVisible(true);
        SliderListener sl=new SliderListener(10, currentComp, nextComp, true);
        Timer t=new Timer(40,sl);
        sl.timer=t;
        t.start();
    }
 
    public void addSliderComponent(JComponent c) {
        pnlMain.add(c,""+getComponentCount());
    }
 
    public void refresh() {
        revalidate();
        repaint();
    }
 
    public class SliderListener implements ActionListener {
        Component c1;
        Component c2;
        int steps;
        int step=0;
        Timer timer;
        boolean isNext;
 
        public SliderListener(int steps, Component c1, Component c2, boolean isNext) {
            this.steps=steps;
            this.c1=c1;
            this.c2=c2;
            this.isNext=isNext;
        }
 
        public void actionPerformed(ActionEvent e) {
            Rectangle bounds=c1.getBounds();
            int shift=bounds.width/steps;
            if (!isNext) {
                c1.setLocation(bounds.x-shift, bounds.y);
                c2.setLocation(bounds.x-shift+bounds.width, bounds.y);
            }
            else {
                c1.setLocation(bounds.x+shift, bounds.y);
                c2.setLocation(bounds.x+shift-bounds.width, bounds.y);
            }
            pnlMain.repaint();
            step++;
            if (step==steps) {
                timer.stop();
                c2.setVisible(false);
                CardLayout cl=(CardLayout)pnlMain.getLayout();
                if (isNext) {
                    cl.next(pnlMain);
                }
                else {
                    cl.previous(pnlMain);
                }
            }
        }
    } 
}

import java.awt.*;
 
public class SliderCardLayout extends CardLayout{
    public Component getCurrentComponent(Container parent) {
        int n = parent.getComponentCount();
        for (int i = 0 ; i < n ; i++) {
            Component comp = parent.getComponent(i);
            if (comp.isVisible()) {
                return comp;
            }
        }
        return null;
    }
 
    public Component getNextComponent(Container parent) {
        int n = parent.getComponentCount();
        for (int i = 0 ; i < n ; i++) {
            Component comp = parent.getComponent(i);
            if (comp.isVisible()) {
                int currentCard = (i + 1) % n;
                comp = parent.getComponent(currentCard);
                return comp;
            }
        }

        return null;
    }
    
    public Component getPreviousComponent(Container parent) {
        int n = parent.getComponentCount();
        for (int i = 0 ; i < n ; i++) {
            Component comp = parent.getComponent(i);
            if (comp.isVisible()) {
                int currentCard = ((i > 0) ? i-1 : n-1);
                comp = parent.getComponent(currentCard);
                return comp;
            }

        }
        return null;
    }
}

import javax.swing.*;
 
public class TestApp {
    public static void main(String[] args) {
        JFrame f=new JFrame("Test slider component app");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
        f.getContentPane().add(initSlider());
        f.pack();
        f.setState(JFrame.MAXIMIZED_BOTH);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
 
    public static JComponent initSlider() {
        JSLSlider slider=new JSLSlider();
        slider.addSliderComponent(new JButton("JButton instance - component 1"));
        slider.addSliderComponent(new JLabel("Long text JLabel instance - component 2"));
        slider.addSliderComponent(new JTextField("JTextField instance - component 3"));
        slider.refresh();
        
        return slider;
    }

}