# Java Swing : The Ultimate Guide!!



## JGuru (Sep 25, 2014)

*Java Swing  : The Ultimate Guide*

All the programs are entirely written by me. It's much better than the code found in most of Swing books!!
These demos showcase how Swing can be effectively used.

JFC is short for Java Foundation Classes, which encompass a group of features for building graphical user interfaces (GUIs) and adding rich graphics functionality and interactivity to Java applications.

The Swing API is powerful, flexible — and immense. The Swing API has 18 public packages:

javax.accessibility 	
javax.swing.plaf 	
javax.swing.text
javax.swing 	
javax.swing.plaf.basic 	
javax.swing.text.html
javax.swing.border 	
javax.swing.plaf.metal 	
javax.swing.text.html.parser
javax.swing.colorchooser 	
javax.swing.plaf.multi 	
javax.swing.text.rtf
javax.swing.event 	
javax.swing.plaf.synth 	
javax.swing.tree
javax.swing.filechooser 	
javax.swing.table 	
javax.swing.undo

Fortunately, most programs use only a small subset of the API. This guide sorts out the API for you, giving you examples of common code and pointing you to methods and classes you're likely to need. Most of the code in this trail uses only one or two Swing packages:

    javax.swing
    javax.swing.event (not always required)

To run the following programs create a directory called 'JSession' & place all the programs in that directory.
Also create a directory called 'Images' under the JSession directory & place the JPG, PNG, GIF, BMP pictures (a minimum of 10, a maximum of 20).
We need icons & Images to run the following programs. You can also use an IDE like NetBeans, IDEA, or JDeveloper to run this programs.

*JButton*

Ordinary buttons — JButton objects — have just a bit more functionality than the AbstractButton class provides: You can make a JButton be the default button.
When the size of the button component is larger than its contents, the label and icon are always kept together.
you can place the label/icon pair in one of nine possible locations. How you implement event handling depends on the type of button you use and how you use it. 
Generally, you implement an action listener, which is notified every time the user clicks the button.


```
// Place the contents in the nw corner
    button.setVerticalAlignment(SwingConstants.TOP);
    button.setHorizontalAlignment(SwingConstants.LEFT);
    
    // Place the contents centered at the top
    button.setVerticalAlignment(SwingConstants.TOP);
    button.setHorizontalAlignment(SwingConstants.CENTER);
    
    // Place the contents in the ne corner
    button.setVerticalAlignment(SwingConstants.BOTTOM);
    button.setHorizontalAlignment(SwingConstants.RIGHT);
    
    // Place the contents in the sw corner
    button.setVerticalAlignment(SwingConstants.BOTTOM);
    button.setHorizontalAlignment(SwingConstants.LEFT);
    
    // Place the contents centered at the bottom
    button.setVerticalAlignment(SwingConstants.BOTTOM);
    button.setHorizontalAlignment(SwingConstants.CENTER);
    
    // Place the contents in the se corner
    button.setVerticalAlignment(SwingConstants.BOTTOM);
    button.setHorizontalAlignment(SwingConstants.RIGHT);
    
    // Place the contents vertically centered on the left
    button.setVerticalAlignment(SwingConstants.CENTER);
    button.setHorizontalAlignment(SwingConstants.LEFT);
    
    // Place the contents directly in the center
    button.setVerticalAlignment(SwingConstants.CENTER);
    button.setHorizontalAlignment(SwingConstants.CENTER);
    
    // Place the contents vertically centered on the right
    button.setVerticalAlignment(SwingConstants.CENTER);
    button.setHorizontalAlignment(SwingConstants.RIGHT);
```

We create an array of Color buttons & add them to the bottom. Clicking on them changes the JLabel color!.
Clicking on the Image button brings a JFrame with Megan Fox Image. Hovering the Mouse over the button shows
the tooltip.


ButtonDemo.java 


```
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.RescaleOp;
import java.io.File;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 7/19/14
 * Time: 3:28 PM
 * To change this template use File | Settings | File Templates.
 */
public class ButtonDemo extends JFrame {

    private JButton imageButton, ok, cancel;
    private JButton []colorButton;
    private Color []color ={Color.blue, Color.cyan, Color.green, Color.magenta, Color.orange, Color.pink, Color.red, Color.black, Color.gray, Color.yellow};
    private String []tipName = {"Blue", "Cyan", "Green", "Magenta", "Orange", "Pink", "Red", "Black", "Gray", "Yellow"};
    private Image image;
    private JLabel label;
    private JViewport viewport;
    private JFrame frame;
    private JFrame myFrame;
    private JButton disButton;

    public ButtonDemo() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
            System.err.println("Can't set the System look'n feel!!");
        }
        myFrame = this;
        label = new JLabel("Button Demo", JLabel.CENTER);
        label.setFont(new Font("Serif", Font.BOLD, 28));
        JScrollPane scrollPane = new JScrollPane(label);
        viewport = scrollPane.getViewport();
        final Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        ok = new JButton("OK");
        ok.setToolTipText("I'm OK!!");
        cancel = new JButton("Cancel");
        cancel.setToolTipText("I'm zapped!!");
        disButton = new JButton("Disabled");
        disButton.setEnabled(false);
        // Get the Image
        image = getImage("Images/Megan Fox1.jpg");
        final Image bigImage = image;
        frame = new JFrame("Image Viewer");
        //Create a smaller Image
        if(image != null) {
            image = image.getScaledInstance(60, 45, Image.SCALE_SMOOTH);
            imageButton = new JButton(new ImageIcon(darken(image)));
            // Show the normal image when the Mouse moves over it
            imageButton.setRolloverIcon(new ImageIcon(image));
            // When the Mouse is pressed display brighter image
            imageButton.setPressedIcon(new ImageIcon(brighten(image)));
            imageButton.setToolTipText("Hai I'm Megan Fox, Click Me!!");
            // Add a action listener
            imageButton.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    frame.add(new JScrollPane(new JLabel(new ImageIcon(bigImage))));
                    frame.setSize(scrDim.width / 2, scrDim.height / 2);
                    frame.setLocation(myFrame.getX() + myFrame.getWidth(), myFrame.getY());
                    frame.setVisible(true);
                    frame.validate();
                    frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
                }
            });
        }
        else
        {
            imageButton = new JButton("No Image!!");
        }

        JPanel top = new JPanel(new FlowLayout(FlowLayout.CENTER));
        top.add(imageButton);
        top.add(ok);
        top.add(cancel);
        top.add(disButton);
        add(top, BorderLayout.NORTH);
        add(scrollPane, BorderLayout.CENTER);
        JPanel bottom = new JPanel(new FlowLayout(FlowLayout.CENTER));

        //Create an array of Color buttons
        colorButton = new JButton[color.length];
        for (int i = 0; i < color.length; i++) {
            colorButton[i] = new JButton();
            colorButton[i].setIcon(new ColorIcon(color[i]));
            colorButton[i].addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent ae) {
                    Object source = ae.getSource();
                    for (int j = 0; j < color.length; j++) {
                        if(source == colorButton[j]) {
                            viewport.setBackground(color[j]);
                        }
                    }
                }
            });
            colorButton[i].setToolTipText(tipName[i]);
            colorButton[i].setPreferredSize(new Dimension(40, 20));
            colorButton[i].setBorder(new BevelBorder(BevelBorder.LOWERED));
            bottom.add(colorButton[i]);
        }
        bottom.setBorder(new TitledBorder(new EtchedBorder(), "Colors"));
        add(bottom, BorderLayout.SOUTH);
        setSize(scrDim.width/2, scrDim.height/2);
        setTitle("ButtonDemo");
        setVisible(true);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    // Darken the Image
    public Image darken(Image image) {
        if (image != null) {
            // Darken the image by 50%
            float scaleFactor = 0.5f;
            RescaleOp op = new RescaleOp(scaleFactor, 0, null);
            return op.filter(toBufferedImage(image), null);
        }
        return null;
    }

    // Brighten the Image
    public BufferedImage brighten(Image image) {
        if (image != null) {
            // Brighten the image by 30%
            float scaleFactor = 1.3f;
            RescaleOp op = new RescaleOp(scaleFactor, 0, null);
            return op.filter(toBufferedImage(image), null);
        }
        return null;
    }

    // Convert the Image to BufferedImage
    public BufferedImage toBufferedImage(Image image) {
        if (image != null) {
            BufferedImage buffImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
            Graphics g = buffImage.getGraphics();
            g.drawImage(image, 0, 0, null);
            g.dispose();
            return buffImage;
        }
        return null;
    }

    public Image getImage(String fileName) {
        try
        {
            return ImageIO.read(new File(fileName));
        }  catch (IOException ioe) {
            System.err.println("Error loading Image: " + fileName + "!!");
        }
        return null;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ButtonDemo();
            }
        });
    }

    // Inner class ColorIcon
    private class ColorIcon implements Icon {

        Color myColor;

        public ColorIcon(Color color) {
            myColor = color;
        }

        @Override
        public int getIconWidth() {
            return 40;
        }

        @Override
        public int getIconHeight() {
            return 20;
        }

        @Override
        public void paintIcon(Component c, Graphics g, int x, int y) {
            g.setColor(myColor);
            g.fillRect(x, y, getIconWidth(), getIconHeight());
        }
    }
}
```

*s3.postimg.org/mn1hv94zj/Button_Demo.jpg

The following programs loads all the Images in the 'Images' directory & shows the Image preview using an array of buttons,
added to JPanel.


```
/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 9/14/14
 * Time: 10:18 PM
 * To change this template use File | Settings | File Templates.
 */
// ThumbnailButtons.java
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import static java.lang.System.out;

// All the Image buttons are loaded with a graphic icon and then the Image preview is added later

public class ThumbnailButtons extends JFrame implements Runnable {

    private int iconWidth = 140;
    private int iconHeight = 110;
    private ImageIcon picIcon = new ImageIcon("Icons/image_64x64.png");
    private int columns = 8;
    private int rows;
    private Dimension scrDim;
    private String path = "Images/";
    private File directory = new File(path);
    private JLabel statusBar = new JLabel("Ready");

    @Override
    public void run() {
        loadImages();
    }

    public void loadImages() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
            // Do nothing
        }
        scrDim = Toolkit.getDefaultToolkit().getScreenSize();

        String[] name = directory.list(new FilenameFilter() {
            String[] readFormat = ImageIO.getReaderFormatNames();

            @Override
            public boolean accept(File dir, String name) {
                name = name.toLowerCase();
                for (int i = 0; i < readFormat.length; i++) {
                    if (name.endsWith(readFormat[i])) {
                        return true;
                    }
                }
                return false;
            }
        });
        int MAX = name.length;
        rows = MAX / columns;

        //Create that many Buttons
        JButton[] button = new JButton[MAX];
        JPanel panel = new JPanel(new GridLayout(rows, columns));
        long before = System.currentTimeMillis();
        String imageFormat = "";
        // Load all the buttons with the default pic Icon first
        for (int i = 0; i < MAX; i++) {
            if (picIcon != null) {
                button[i] = new JButton(picIcon);
            } else {
                button[i] = new JButton(name[i]);
            }
            imageFormat = name[i];
            imageFormat = imageFormat.substring(imageFormat.lastIndexOf(".") + 1);
            button[i].setPreferredSize(new Dimension(iconWidth, iconHeight));
            if (imageFormat.startsWith("j") || imageFormat.startsWith("J")) {
                imageFormat = "JPEG - JIFF Format";
            } else if (imageFormat.startsWith("p")) {
                imageFormat = "Portable Network Graphics";
            } else if (imageFormat.startsWith("bmp")) {
                imageFormat = "Bit Map Picture";
            } else if (imageFormat.startsWith("gif")) {
                imageFormat = "Graphics Interchange Format";
            } else {
                imageFormat = imageFormat.toUpperCase() + " Image Format";
            }
            // Set the button multiline tooltip
            button[i].setToolTipText("<html>" + name[i] + "<br> " + imageFormat + " </html>");
            //Add the buttons to the Panel
            panel.add(button[i]);
            panel.validate();
        }
        add(new JScrollPane(panel), BorderLayout.CENTER);
        add(statusBar, BorderLayout.SOUTH);
        //Set the Frame's properties
        setSize((iconWidth * columns) + iconWidth + 90, scrDim.height);
        setTitle("ThumbnailButtons");
        setVisible(true);
        validate();
        Image image;
        out.println("Fetching the Images, Please wait...");
        // Now update the Image preview to all the buttons
        try {
            for (int i = 0; i < MAX; i++) {
                image = getImage(path + name[i]);
                // Update the Button's icon with the preview Image
                button[i].setIcon(new ThumbnailIcon(image));
                button[i].setText("");
                // Update the button state
                button[i].validate();
                // Make the button visible by scrolling if it's not already
                button[i].scrollRectToVisible(new Rectangle(iconWidth, iconHeight));
            }
        } catch (OutOfMemoryError ome) {
            JOptionPane.showMessageDialog(null, "Oops, the JVM is running short of Heap memory!!", "Error", JOptionPane.ERROR_MESSAGE);
            System.exit(-1);
        }

        long after = System.currentTimeMillis();
        double time = (after - before) / 1000;
        statusBar.setText("Total time taken in seconds : " + time);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    // Faster way of loading Images
    public Image getImage(String fileName) {
        if (fileName.endsWith("jpg") || fileName.endsWith("jpeg") || fileName.endsWith("png")) {
            return new ImageIcon(fileName).getImage();
        }
        try {
            return ImageIO.read(new File(fileName));
        } catch (IOException ioe) {
            System.err.println("Error loading Image!!");
        }
        return null;
    }

    /**
     * [MENTION=9956]PARAM[/MENTION] args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Thread(new ThumbnailButtons()).start();
            }
        });
    }

    // To show a preview Image icon
    private class ThumbnailIcon implements Icon {

        private final int MAX_WIDTH = 120;
        private final int MAX_HEIGHT = 90;
        private Image thumb = null;
        private int height, width;
        private double aspect;

        public ThumbnailIcon(Image image) {
            if (image != null) {
                thumb = image;
                height = thumb.getHeight(null);
                width = thumb.getWidth(null);
                aspect = ((double) width / (double) height);
            }
        }

        @Override
        public int getIconHeight() {
            return MAX_HEIGHT;
        }

        @Override
        public int getIconWidth() {
            return MAX_WIDTH;
        }

        @Override
        public void paintIcon(Component c, Graphics g, int x, int y) {
            Graphics2D g2d = (Graphics2D) g;
            // Set RenderingHints properties - Speed
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_SPEED);
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);

            width = getWidth();
            height = getHeight();
            int topBorder = (MAX_HEIGHT - height) / 2;
            int leftBorder = (MAX_WIDTH - width) / 2;
            if (thumb != null) {
                // Scale the Image on the fly
                g2d.drawImage(thumb, 10, 10, getIconWidth(), getIconHeight(), c);
            }
        }
    }
}
```

*s30.postimg.org/dkefxi6x9/Thumbnail_Buttons.jpg

*JCheckBox*

The JCheckBox class provides support for check box buttons. You can also put check boxes in menus, using the JCheckBoxMenuItem class. Because JCheckBox and JCheckBoxMenuItem
inherit from AbstractButton, Swing check boxes have all the usual button characteristics,
Check boxes are similar to radio buttons but their selection model is different, by convention. Any number of check boxes in a group — none, some, or all — can be selected. A group of radio buttons, on the other hand, can have only one button selected.
A check box generates one item event and one action event per click. Usually, you listen only for item events, since they let you determine whether the click selected or deselected the check box.

The following demo shows a group of checkboxes , selecting them shows the Image. You can select more than one.

CheckBoxDemo.java


```
/**
 * Created with IntelliJ IDEA.
 * User: JGuru
 * Date: 7/31/14
 * Time: 5:10 PM
 * To change this template use File | Settings | File Templates.
 */

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;

public class CheckBoxDemo extends JPanel {

    private String []imgName;
    private String path = "Images/";
    //Images cache
    private Image []image;
    private ArrayList <Integer>list = new ArrayList<>();
    private int MAX;
    private boolean isShown = false;
    private int imageWidth = 150 * 2;
    private int imageHeight = 120 * 2;
    private int xValue = 150;

    public CheckBoxDemo() {
        super(new BorderLayout());
        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }  catch (Exception e) {
            // Do nothing
        }

        File directory = new File(path);
        if(!directory.exists()) {
            System.err.println("The specified directory doesn't exist!!");
            System.exit(-1);
        }
        //Filter out the Images
        imgName = new File(path).list(new FilenameFilter() {

            String []readFormat = ImageIO.getReaderFormatNames();
            @Override
            public boolean accept(File dir, String name) {
                for (int i = 0; i < readFormat.length; i++) {
                    if(name.endsWith(readFormat[i]))
                        return true;
                }
                return false;
            }
        });
        MAX = imgName.length;
        if(MAX == 0) {
            System.err.println("The Oops No Images found!!");
            System.exit(-1);
        }
        //Maximum of 10 items
        if(MAX > 10) {
            MAX = 10;
        }
        final JCheckBox []checkBox = new JCheckBox[MAX];
        image = new Image[MAX];
        //Put the check boxes in a column in a panel.
        JPanel checkBoxPanel = new JPanel(new GridLayout(0, 1));
        for (int i = 0; i < MAX; i++) {
            checkBox[i] = new JCheckBox(imgName[i].substring(0, imgName[i].lastIndexOf(".")));
            //Cache the Images
            image[i] = getImage(path + imgName[i]);
            checkBox[i].setActionCommand(imgName[i]);
            checkBoxPanel.add(checkBox[i]);
            checkBox[i].addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    isShown = true;
                    for (int j = 0; j < MAX ; j++) {
                        if(checkBox[j].isSelected())  {

                            if(!list.contains(new Integer(j))) {
                              try
                               {
                                  list.add(new Integer(j), j);
                                  repaint();
                               } catch (Exception ex) {

                              }
                            }
                        }
                        else
                        {
                            try
                            {
                                list.remove(new Integer(j));
                                repaint();
                            }  catch (Exception ex) {

                            }
                        }
                    }
                }
            });
        }
        // Select the 1st item programmatically
        checkBox[0].setSelected(true);

        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        setPreferredSize(new Dimension(scrDim.width/2 + 150, scrDim.height));
        add(checkBoxPanel, BorderLayout.LINE_START);
        setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        // Get the Graphics
        Graphics2D g2d = (Graphics2D) g;
        // Best appearance at the cost of performance
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        int width = getWidth() - 150;
        int height = getHeight();
        int nImages = width/imageWidth;

        if(!isShown) {
            //Show the 1st Image
            g2d.drawImage(image[0], width/4 + 50, height/10 - 50, this);
        }
        else {
            int x = xValue, y = -xValue;
            for (int i = 0; i < list.size() ; i++) {
                if(list.size() == 1) {
                    g2d.drawImage(image[list.get(i)], width/4 + 50, height/10 - 50, width, height, this);
                }
                else
                {
                    x += imageWidth;
                    if(i % nImages == 0) {
                        x = xValue;
                        y += imageHeight;
                    }
                    g2d.drawImage(image[list.get(i)], x, y, imageWidth, imageHeight, this);
                }
            }
        }
    }

    /** Returns an Image, or null if the path was invalid. */
    public Image getImage(String path) {
        try
        {
            return ImageIO.read(new File(path));
        }  catch (IOException ioe) {
            System.err.println("Error loading Image : " + path);
        }
        return null;
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("CheckBoxDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        JComponent newContentPane = new CheckBoxDemo();
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
       //creating and showing this application's GUI.
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
```

*s22.postimg.org/94az6ff6l/Check_Box_Demo.jpg

*JRadioButton*

Radio buttons are groups of buttons in which, by convention, only one button at a time can be selected. The Swing release supports radio buttons with the JRadioButton 
and ButtonGroup classes. To put a radio button in a menu, use the JRadioButtonMenuItem class.
Each time the user clicks a radio button (even if it was already selected), the button fires an action event. One or two item events also occur — one from the button that was just selected, and another from the button that lost the selection (if any). Usually, you handle radio button clicks using an action listener.
For each group of radio buttons, you need to create a ButtonGroup instance and add each radio button to it. The ButtonGroup takes care of unselecting the previously selected button when the user selects another button in the group.

You should generally initialize a group of radio buttons so that one is selected. However, the API doesn't enforce this rule — a group of radio buttons can have no initial selection. Once the user has made a selection, exactly one button is selected from then on.
The following demo shows a group of RadioButtons, select any of them displays the Image.


```
/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 7/31/14
 * Time: 5:10 PM
 * To change this template use File | Settings | File Templates.
 */

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;

public class RadioButtonDemo extends JPanel {

    private JLabel picture;
    private String []imgName;
    private String path = "Images/";

    public RadioButtonDemo() {
        super(new BorderLayout());
        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }  catch (Exception e) {
             // Do nothing
        }

        File directory = new File(path);
        if(!directory.exists()) {
            System.err.println("The specified directory doesn't exist!!");
            System.exit(-1);
        }
        //Filter out the Images
        imgName = new File(path).list(new FilenameFilter() {

            String []readFormat = ImageIO.getReaderFormatNames();
            @Override
            public boolean accept(File dir, String name) {
                for (int i = 0; i < readFormat.length; i++) {
                    if(name.endsWith(readFormat[i]))
                        return true;
                }
                return false;
            }
        });
        int MAX = imgName.length;
        if(MAX == 0) {
            System.err.println("The Oops No Images found!!");
            System.exit(-1);
        }
        //Maximum of 10 items
        if(MAX > 10) {
            MAX = 10;
        }
        JRadioButton []radioButton = new JRadioButton[MAX];
        //Group the radio buttons.
        ButtonGroup group = new ButtonGroup();
        //Put the radio buttons in a column in a panel.
        JPanel radioPanel = new JPanel(new GridLayout(0, 1));
        for (int i = 0; i < radioButton.length; i++) {
            radioButton[i] = new JRadioButton(imgName[i].substring(0, imgName[i].lastIndexOf(".")));
            radioButton[i].setActionCommand(imgName[i]);
            radioPanel.add(radioButton[i]);
            radioButton[i].addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    picture.setIcon(createImageIcon(path + e.getActionCommand()));
                }
            });
            group.add(radioButton[i]);
        }
        // Select the 1st item programmatically
        radioButton[0].setSelected(true);
        //Set up the picture label.
        picture = new JLabel(createImageIcon(path + imgName[0]));

        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        setPreferredSize(new Dimension(scrDim.width/2, scrDim.height));
        add(radioPanel, BorderLayout.LINE_START);
        add(new JScrollPane(picture), BorderLayout.CENTER);
        setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
    }

    /** Returns an ImageIcon, or null if the path was invalid. */
    protected static ImageIcon createImageIcon(String path) {
        try
        {
            return new ImageIcon(ImageIO.read(new File(path)));
        }  catch (IOException ioe) {
             System.err.println("Error loading Image : " + path);
        }
        return null;
    }

    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("RadioButtonDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //Create and set up the content pane.
        JComponent newContentPane = new RadioButtonDemo();
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);

        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
```

*s27.postimg.org/4i2rzgovj/Radio_Button_Demo.jpg

*JComboBox*

A JComboBox, which lets the user choose one of several choices, can have two very different forms. The default form is the uneditable combo box, which features a button and a drop-down list of values. 
The second form, called the editable combo box, features a text field with a small button abutting it. The user can type a value in the text field or click the button to display a drop-down list.

As a ListCellRenderer, ComboBoxRenderer implements a method called getListCellRendererComponent, which returns a component whose paintComponent method is used to display the combo box and each of
its items. The easiest way to display an image and an icon is to use a label. So ComboBoxRenderer is a subclass of label and returns itself. The implementation of getListCellRendererComponent 
configures the renderer to display the currently selected icon and its description.

These arguments are passed to getListCellRendererComponent:

    JList list — a list object used behind the scenes to display the items. The example uses this object's colors to set up foreground and background colors.
    Object value — the object to render. An Integer in this example.
    int index — the index of the object to render.
    boolean isSelected — indicates whether the object to render is selected. Used by the example to determine which colors to use.
    boolean cellHasFocus — indicates whether the object to render has the focus.

A combo box uses a renderer to display each item in its menu. If the combo box is uneditable, it also uses the renderer to display the currently selected item. An editable combo box, on the other hand, uses an editor to display the selected item. A renderer for a combo box must implement the ListCellRenderer interface. A combo box's editor must implement ComboBoxEditor. This section shows how to provide a custom renderer for an uneditable combo box.

The default renderer knows how to render strings and icons. If you put other objects in a combo box, the default renderer calls the toString method to provide a string to display. You can customize the way a combo box renders itself and its items by implementing your own ListCellRenderer.

Combo boxes also generate item events, which are fired when any of the items' selection state changes. Only one item at a time can be selected in a combo box, so when the user makes a new selection the previously selected item becomes unselected. Thus two item events are fired each time the user selects a different item from the menu. If the user chooses the same item, no item events are fired. Use addItemListener to register an item listener on a combo box.

The following demo shows a JComboBox with preview Image. We create an array of ImageIcons for showing the preview Image.
It uses a ComboBoxRenderer to show the preview Images.

ComboBoxDemo.java 


```
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.*;
import javax.swing.*;

public class ComboBoxDemo extends JPanel {

    private ImageIcon[] images;
    private String[] imgStrings;
    private String path = "Images/";
    private static JLabel label;

    public ComboBoxDemo() {
        super(new BorderLayout());
        File directory = new File(path);
        if (!directory.exists()) {
            System.out.println("The specified directory doesn't exist!!");
            System.exit(-1);
        }
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
            System.err.println("Error loading look'n feel!!");
        }
        label = new JLabel();
        label.setHorizontalAlignment(SwingConstants.CENTER);
        label.setVerticalAlignment(SwingConstants.CENTER);
        // Filter out JPG Images
        imgStrings = directory.list(new FilenameFilter() {

            @Override
            public boolean accept(File dir, String name) {
                name = name.toLowerCase();
                if (name.endsWith("jpg")) {
                    return true;
                }
                return false;
            }
        });
        String str;
        // Remove the file extension
        for (int i = 0; i < imgStrings.length; i++) {
            str = imgStrings[i];
            str = str.substring(0, str.lastIndexOf("."));
            imgStrings[i] = str;
        }
        //Load the pet images and create an array of indexes.
        images = new ImageIcon[imgStrings.length];
        Integer[] intArray = new Integer[imgStrings.length];
        for (int i = 0; i < imgStrings.length; i++) {
            intArray[i] = new Integer(i);
            images[i] = createImageIcon(path + imgStrings[i] + ".jpg", true);
            if (images[i] != null) {
                images[i].setDescription(imgStrings[i]);
            }
        }

        //Create the combo box.
        final JComboBox<Integer> comboBox = new JComboBox<>(intArray);
        comboBox.addItemListener(new ItemListener() {

            @Override
            public void itemStateChanged(ItemEvent e) {
                int index = comboBox.getSelectedIndex();
                label.setIcon(createImageIcon(path + imgStrings[index] + ".jpg", false));
            }
        });
        //Display the first image
        label.setIcon(createImageIcon(path + imgStrings[0] + ".jpg", false));

        comboBox.setRenderer(new ComboBoxRenderer());
        comboBox.setMaximumRowCount(5);

        //Lay out the demo.
        add(comboBox, BorderLayout.PAGE_START);
        setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
    }

    /**
     * Returns an ImageIcon, or null if the path was invalid.
     *
     * [MENTION=9956]PARAM[/MENTION] path
     * [MENTION=9956]PARAM[/MENTION] resize
     * @return ImageIcon
     */
    protected static ImageIcon createImageIcon(String path, boolean resize) {
        java.net.URL imgURL = ComboBoxDemo.class.getResource(path);
        if (imgURL != null) {
            Image image = new ImageIcon(imgURL).getImage();
            if (resize) {
                //Scale down the Image
                image = image.getScaledInstance(60, 45, Image.SCALE_SMOOTH);
                return new ImageIcon(image);
            } else {
                return new ImageIcon(image);
            }

        } else {
            System.err.println("Couldn't find file: " + path);
            return null;
        }
    }

    /**
     * Create the GUI and show it. For thread safety, this method should be
     * invoked from the event-dispatching thread.
     */
    private static void createAndShowGUI() {
        //Create and set up the window.
        JFrame frame = new JFrame("ComboBoxDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new ComboBoxDemo();
        panel.setOpaque(false);
        JPanel top = new JPanel(new FlowLayout(FlowLayout.CENTER));
        top.add(new JLabel("Choose Image : "));
        top.add(panel);
        //frame.setContentPane(top);
        frame.add(top, BorderLayout.NORTH);
        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        label.setPreferredSize(new Dimension(scrDim.width / 2, scrDim.height - 150));
        frame.add(new JScrollPane(label), BorderLayout.CENTER);
        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application's GUI.
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                createAndShowGUI();
            }
        });
    }

    // Inner class ComboBoxRenderer to render Image preview
    class ComboBoxRenderer extends JLabel implements ListCellRenderer<Object> {

        private Font uhOhFont;

        public ComboBoxRenderer() {
            setOpaque(true);
            setHorizontalAlignment(CENTER);
            setVerticalAlignment(CENTER);
            setPreferredSize(new Dimension(280, 110));
        }

        /*
         * This method finds the image and text corresponding
         * to the selected value and returns the label, set up
         * to display the text and image.
         */
        @Override
        public Component getListCellRendererComponent(
                JList<?> list,
                Object value,
                int index,
                boolean isSelected,
                boolean cellHasFocus) {
            //Get the selected index. (The index param isn't
            //always valid, so just use the value.)
            int selectedIndex = ((Integer) value).intValue();

            if (isSelected) {
                setBackground(list.getSelectionBackground());
                setForeground(list.getSelectionForeground());
            } else {
                setBackground(list.getBackground());
                setForeground(list.getForeground());
            }

            //Set the icon and text.  If icon was null, say so.
            ImageIcon icon = images[selectedIndex];
            String pet = imgStrings[selectedIndex];
            setIcon(icon);
            if (icon != null) {
                setText("  " + pet);
                setFont(list.getFont());
            } else {
                setUhOhText(pet + " (no image available)",
                        list.getFont());
            }

            return this;
        }

        //Set the font and text when no image was found.
        protected void setUhOhText(String uhOhText, Font normalFont) {
            if (uhOhFont == null) { //lazily create this font
                uhOhFont = normalFont.deriveFont(Font.ITALIC);
            }
            setFont(uhOhFont);
            setText(uhOhText);
        }
    }
}
```

*s1.postimg.org/45imte7ij/Combo_Box_Demo.jpg

*JColorChooser*

Use the JColorChooser class to enable users to choose from a palette of colors. A color chooser is a component that you can place anywhere within your program GUI.
The JColorChooser API also makes it easy to bring up a dialog (modal or not) that contains a color chooser.
A color chooser uses an instance of ColorSelectionModel to contain and manage the current selection. The color selection model fires a change event whenever the 
user changes the color in the color chooser.

The following program shows a random Image. Clicking on the 'Choose' button brings a ColorChooser dialog.
If you select a particular color then the JLabel's background changes correspondingly!!


```
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.io.File;
import java.io.FilenameFilter;
import javax.imageio.ImageIO;
import java.io.IOException;

public class ColorChooserDemo2 extends JFrame {

    private JLabel label = new JLabel();
    private String []imgName;
    private String path = "Images/";
    private File directory = new File(path);
    private JButton button = new JButton("Choose");
    private JViewport viewport;

    public ColorChooserDemo2() {
        //Set look 'n feel
        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }  catch (Exception e) {
            // Do nothing
        }
        button.updateUI();
        if(!directory.exists()) {
            System.out.println("The specified directory doesn't exist!!");
            System.exit(-1);
        }
        imgName = directory.list(new FilenameFilter() {
            String []readFormat = ImageIO.getReaderFormatNames();
            @Override
            public boolean accept(File dir, String name) {
                for (int i = 0; i < readFormat.length; i++) {
                     if(name.endsWith(readFormat[i]))
                         return true;
                }
                return false;
            }
        });

        int rand = (int) (imgName.length * Math.random());
        label.setIcon(new ImageIcon(getImage(path + imgName[rand])));
        final JScrollPane scrollPane = new JScrollPane(label);
        viewport = scrollPane.getViewport();
        button.setPreferredSize(new Dimension(150, 32));
        add(scrollPane);
        JPanel bottom = new JPanel(new FlowLayout(FlowLayout.CENTER));
        bottom.add(button);

        add(bottom, BorderLayout.SOUTH);

        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Color newColor = JColorChooser.showDialog(
                        ColorChooserDemo2.this,
                        "Choose Background Color",
                         viewport.getBackground());
                if(newColor != null)
                {
                    viewport.setBackground(newColor);
                    button.setIcon(new ImageIcon(createIcon(newColor)));
                }
            }
        });
        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        setSize(scrDim.width/2, scrDim.height);
        setTitle("ColorChooserDemo2");
        setVisible(true);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    public BufferedImage createIcon(Color color) {
        BufferedImage buffImage = new BufferedImage(16*3, 16, BufferedImage.TYPE_INT_RGB);
        Graphics gr = buffImage.getGraphics();
        gr.setColor(color);
        gr.fillRect(0, 0, 16 * 3, 16);
        gr.dispose();
        return buffImage;
    }

    public Image getImage(String fileName) {
        try
        {
            return ImageIO.read(new File(fileName));
        }  catch (IOException ioe) {
            System.err.println("Error loading Image : " + fileName + "!!");
        }
        return null;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ColorChooserDemo2();
            }
        });
    }

}
```

*s28.postimg.org/abjky2wsp/Color_Chooser_Demo.jpg

*JEditorPane*

Two Swing classes support styled text: JEditorPane and its subclass JTextPane. The JEditorPane class is the foundation for Swing's styled text components and provides a mechanism through 
which you can add support for custom text formats. If you want unstyled text, use a text area instead.
Editor panes, by default, know how to read, write, and edit plain, HTML, and RTF text. Text panes inherit this capability but impose certain limitations. A text pane insists that its 
document implement the StyledDocument interface. HTMLDocument and RTFDocument are both StyledDocuments so HTML and RTF work as expected within a text pane. If you load a text pane with plain text though, the text pane's document is not a PlainDocument as you might expect, but a DefaultStyledDocument.

EditorPaneDemo2.java - Highlights Java keywords in a document.


```
import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.net.URL;
import java.util.HashMap;

// Highlights the Java keywords of the Java Code
public class EditorPaneDemo2 extends JFrame {

    private String sourceCode = "";

    public EditorPaneDemo2(String fileName) {
        try {
            for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | UnsupportedLookAndFeelException e) {
            // Do nothing
        }
        //Load the file from the disk
        loadSourceCode(fileName);
        JEditorPane editor = new JEditorPane();
        editor.setFont(new Font("Serif", Font.BOLD, 14));
        editor.setContentType("text/html");
        editor.setText(getSourceCode());
        add(new JScrollPane(editor));
        setTitle("EditorPaneDemo2");
        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        setSize(scrDim.width / 2, scrDim.height);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public String getSourceCode() {
        return sourceCode;
    }

    public void loadSourceCode(String file) {
        sourceCode = "<html><body bgcolor=\"#ffffff\"><pre><b>";
        InputStream is;
        InputStreamReader isr;
        CodeViewer cv = new CodeViewer();
        URL url;
        String filename = "";
        try {
            FileReader fileReader = new FileReader(file);
            try (BufferedReader reader = new BufferedReader(fileReader)) {

                // Read one line at a time, htmlize using super-spiffy
                
                String line = reader.readLine();
                while (line != null) {
                    sourceCode += cv.syntaxHighlight(line) + " \n ";
                    line = reader.readLine();
                }
            }
            sourceCode += "</b></pre></body></html>";
        } catch (IOException ex) {
            sourceCode = "Could not load file: " + file + "!!";
            System.exit(-1);
        }
    }

    public static void main(final String[] args) {
        if(args.length > 0) {
            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {
                    new EditorPaneDemo2(args[0]);
                }
            });
        }
        else
        {
            System.out.println("java EditorPaneDemo2 <filename.java>");
        }
    }
}

/**
 * A class that syntax highlights Java code by turning it into html.
 *
 * <p>
 * A
 * <code>CodeViewer</code> object is created and then keeps state as lines are
 * passed in. Each line passed in as java text, is returned as syntax
 * highlighted html text.
 *
 * <p>
 * Users of the class can set how the java code will be highlighted with setter
 * methods.
 *
 * <p>
 * Only valid java lines should be passed in since the object maintains state
 * and may not handle illegal code gracefully.
 *
 * <p>
 * The actual system is implemented as a series of filters that deal with
 * specific portions of the java code. The filters are as follows:
 *
 * <pre>
 *  htmlFilter
 *     |__
 *        multiLineCommentFilter
 *           |___
 *                inlineCommentFilter
 *                   |___
 *                        stringFilter
 *                           |__
 *                               keywordFilter
 * </pre>
 *
 * @version 1.5 12/03/01
 * @author Bill Lynch, Matt Tucker, CoolServlets.com
 */
class CodeViewer {

    private static HashMap<Object, Object> reservedWords = new HashMap<>();
    private boolean inMultiLineComment = false;
    private String backgroundColor = "#ffffff";
    private String commentStart = "</font><font size=3 color=\"#006400\"><i>";
    private String commentEnd = "</font></i><font size=3 color=black>";
    private String stringStart = "</font><font size=3 color=\"#800080\">";
    private String stringEnd = "</font><font size=3 color=black>";
    private String reservedWordStart = "</font><font size=3 color=\"#0000cc\">";
    private String reservedWordEnd = "</font><font size=3 color=black>";

    static {
        loadHash();
    }

    public CodeViewer() {
    }

    public void setCommentStart(String commentStart) {
        this.commentStart = commentStart;
    }

    public void setCommentEnd(String commentEnd) {
        this.commentEnd = commentEnd;
    }

    public void setStringStart(String stringStart) {
        this.stringStart = stringStart;
    }

    public void setStringEnd(String stringEnd) {
        this.stringEnd = stringEnd;
    }

    public void setReservedWordStart(String reservedWordStart) {
        this.reservedWordStart = reservedWordStart;
    }

    public void setReservedWordEnd(String reservedWordEnd) {
        this.reservedWordEnd = reservedWordEnd;
    }

    public String getCommentStart() {
        return commentStart;
    }

    public String getCommentEnd() {
        return commentEnd;
    }

    public String getStringStart() {
        return stringStart;
    }

    public String getStringEnd() {
        return stringEnd;
    }

    public String getReservedWordStart() {
        return reservedWordStart;
    }

    public String getReservedWordEnd() {
        return reservedWordEnd;
    }

    /**
     * Passes off each line to the first filter.
     *
     * [MENTION=9956]PARAM[/MENTION] line The line of Java code to be highlighted.
     */
    public String syntaxHighlight(String line) {
        return htmlFilter(line);
    }

    /*
     * Filter html tags into more benign text.
     */
    private String htmlFilter(String line) {
        if (line == null || line.equals("")) {
            return "";
        }

        // replace ampersands with HTML escape sequence for ampersand;
        line = replace(line, "&", "&");

        // replace the \\ with HTML escape sequences. fixes a problem when
        // backslashes preceed quotes.
        line = replace(line, "\\\\", "\\");

        // replace \" sequences with HTML escape sequences;
        line = replace(line, "" + (char) 92 + (char) 34, "\&#34");

        // replace less-than signs which might be confused
        // by HTML as tag angle-brackets;
        line = replace(line, "<", "<");
        // replace greater-than signs which might be confused
        // by HTML as tag angle-brackets;
        line = replace(line, ">", ">");

        return multiLineCommentFilter(line);
    }

    /*
     * Filter out multiLine comments. State is kept with a private boolean
     * variable.
     */
    private String multiLineCommentFilter(String line) {
        if (line == null || line.equals("")) {
            return "";
        }
        StringBuilder buf = new StringBuilder();
        int index;
        //First, check for the end of a multi-line comment.
        if (inMultiLineComment && (index = line.indexOf("*/")) > -1 && !isInsideString(line, index)) {
            inMultiLineComment = false;
            buf.append(line.substring(0, index));
            buf.append("*/").append(commentEnd);
            if (line.length() > index + 2) {
                buf.append(inlineCommentFilter(line.substring(index + 2)));
            }
            return buf.toString();
        } //If there was no end detected and we're currently in a multi-line
        //comment, we don't want to do anymore work, so return line.
        else if (inMultiLineComment) {
            return line;
        } //We're not currently in a comment, so check to see if the start
        //of a multi-line comment is in this line.
        else if ((index = line.indexOf("/*")) > -1 && !isInsideString(line, index)) {
            inMultiLineComment = true;
            //Return result of other filters + everything after the start
            //of the multiline comment. We need to pass the through the
            //to the multiLineComment filter again in case the comment ends
            //on the same line.
            buf.append(inlineCommentFilter(line.substring(0, index)));
            buf.append(commentStart).append("/*");
            buf.append(multiLineCommentFilter(line.substring(index + 2)));
            return buf.toString();
        } //Otherwise, no useful multi-line comment information was found so
        //pass the line down to the next filter for processesing.
        else {
            return inlineCommentFilter(line);
        }
    }

    /*
     * Filter inline comments from a line and formats them properly.
     */
    private String inlineCommentFilter(String line) {
        if (line == null || line.equals("")) {
            return "";
        }
        StringBuilder buf = new StringBuilder();
        int index;
        if ((index = line.indexOf("//")) > -1 && !isInsideString(line, index)) {
            buf.append(stringFilter(line.substring(0, index)));
            buf.append(commentStart);
            buf.append(line.substring(index));
            buf.append(commentEnd);
        } else {
            buf.append(stringFilter(line));
        }
        return buf.toString();
    }

    /*
     * Filters strings from a line of text and formats them properly.
     */
    private String stringFilter(String line) {
        if (line == null || line.equals("")) {
            return "";
        }
        StringBuilder buf = new StringBuilder();
        if (line.indexOf("\"") <= -1) {
            return keywordFilter(line);
        }
        int start = 0;
        int startStringIndex = -1;
        int endStringIndex = -1;
        int tempIndex;
        //Keep moving through String characters until we want to stop...
        while ((tempIndex = line.indexOf("\"")) > -1) {
            //We found the beginning of a string
            if (startStringIndex == -1) {
                startStringIndex = 0;
                buf.append(stringFilter(line.substring(start, tempIndex)));
                buf.append(stringStart).append("\"");
                line = line.substring(tempIndex + 1);
            } //Must be at the end
            else {
                startStringIndex = -1;
                endStringIndex = tempIndex;
                buf.append(line.substring(0, endStringIndex + 1));
                buf.append(stringEnd);
                line = line.substring(endStringIndex + 1);
            }
        }

        buf.append(keywordFilter(line));

        return buf.toString();
    }

    /*
     * Filters keywords from a line of text and formats them properly.
     */
    private String keywordFilter(String line) {
        if (line == null || line.equals("")) {
            return "";
        }
        StringBuilder buf = new StringBuilder();
        HashMap<String, String> usedReservedWords = new HashMap<>();
        int i = 0, startAt = 0;
        char ch;
        StringBuilder temp = new StringBuilder();
        while (i < line.length()) {
            temp.setLength(0);
            ch = line.charAt(i);
            startAt = i;
            // 65-90, uppercase letters
            // 97-122, lowercase letters
            while (i < line.length() && ((ch >= 65 && ch <= 90)
                    || (ch >= 97 && ch <= 122))) {
                temp.append(ch);
                i++;
                if (i < line.length()) {
                    ch = line.charAt(i);
                }
            }
            String tempString = temp.toString();
            if (reservedWords.containsKey(tempString) && !usedReservedWords.containsKey(tempString)) {
                usedReservedWords.put(tempString, tempString);
                line = replace(line, tempString, (reservedWordStart + tempString + reservedWordEnd));
                i += (reservedWordStart.length() + reservedWordEnd.length());
            } else {
                i++;
            }
        }
        buf.append(line);
        return buf.toString();
    }

    /*
     * All important replace method. Replaces all occurences of oldString in
     * line with newString.
     */
    private String replace(String line, String oldString, String newString) {
        int i = 0;
        while ((i = line.indexOf(oldString, i)) >= 0) {
            line = (new StringBuffer().append(line.substring(0, i)).append(newString).append(line.substring(i + oldString.length()))).toString();
            i += newString.length();
        }
        return line;
    }

    /*
     * Checks to see if some position in a line is between String start and
     * ending characters. Not yet used in code or fully working :)
     */
    private boolean isInsideString(String line, int position) {
        if (line.indexOf("\"") < 0) {
            return false;
        }
        int index;
        String left = line.substring(0, position);
        String right = line.substring(position);
        int leftCount = 0;
        int rightCount = 0;
        while ((index = left.indexOf("\"")) > -1) {
            leftCount++;
            left = left.substring(index + 1);
        }
        while ((index = right.indexOf("\"")) > -1) {
            rightCount++;
            right = right.substring(index + 1);
        }
        if (rightCount % 2 != 0 && leftCount % 2 != 0) {
            return true;
        } else {
            return false;
        }
    }

    /*
     * Load Hashtable (or HashMap) with Java reserved words.
     */
    private static void loadHash() {
        reservedWords.put("abstract", "abstract");
        reservedWords.put("do", "do");
        reservedWords.put("inner", "inner");
        reservedWords.put("public", "public");
        reservedWords.put("var", "var");
        reservedWords.put("boolean", "boolean");
        reservedWords.put("continue", "continue");
        reservedWords.put("int", "int");
        reservedWords.put("return", "return");
        reservedWords.put("void", "void");
        reservedWords.put("break", "break");
        reservedWords.put("else", "else");
        reservedWords.put("interface", "interface");
        reservedWords.put("short", "short");
        reservedWords.put("volatile", "volatile");
        reservedWords.put("byvalue", "byvalue");
        reservedWords.put("extends", "extends");
        reservedWords.put("long", "long");
        reservedWords.put("static", "static");
        reservedWords.put("while", "while");
        reservedWords.put("case", "case");
        reservedWords.put("final", "final");
        reservedWords.put("naive", "naive");
        reservedWords.put("super", "super");
        reservedWords.put("transient", "transient");
        reservedWords.put("cast", "cast");
        reservedWords.put("float", "float");
        reservedWords.put("new", "new");
        reservedWords.put("rest", "rest");
        reservedWords.put("catch", "catch");
        reservedWords.put("for", "for");
        reservedWords.put("null", "null");
        reservedWords.put("synchronized", "synchronized");
        reservedWords.put("char", "char");
        reservedWords.put("finally", "finally");
        reservedWords.put("operator", "operator");
        reservedWords.put("this", "this");
        reservedWords.put("class", "class");
        reservedWords.put("generic", "generic");
        reservedWords.put("outer", "outer");
        reservedWords.put("switch", "switch");
        reservedWords.put("const", "const");
        reservedWords.put("goto", "goto");
        reservedWords.put("package", "package");
        reservedWords.put("throw", "throw");
        reservedWords.put("double", "double");
        reservedWords.put("if", "if");
        reservedWords.put("private", "private");
        reservedWords.put("true", "true");
        reservedWords.put("default", "default");
        reservedWords.put("import", "import");
        reservedWords.put("protected", "protected");
        reservedWords.put("try", "try");
    }
}
```

*s21.postimg.org/v4hobu76b/Editor_Pane_Demo2.jpg

*JTextPane*

TextPaneDemo.java 


```
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Sowndar
 */
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.text.*;

public class TextPaneDemo extends JFrame {

    private JTextPane textPane;

    public TextPaneDemo() {

        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
            System.err.println("Error loading look'n feel!!");
        }
        //See the StyleConstants class for more attributes.
        try {

            StyleContext sc = new StyleContext();
            DefaultStyledDocument doc = new DefaultStyledDocument(sc);

            textPane = new JTextPane(doc);
            // Create a style object and then set the style attributes

            Style style7 = doc.addStyle("StyleName7", null);
            StyleConstants.setBold(style7, true);
            StyleConstants.setFontSize(style7, 28);
            StyleConstants.setForeground(style7, Color.orange.darker().darker());

            doc.insertString(doc.getLength(), " \n\nBigger Bolder Text : ", style7);

            Style style = doc.addStyle("StyleName", null);

            // Italic
            StyleConstants.setItalic(style, true);

            // Bold
            StyleConstants.setBold(style, true);

            // Font family
            StyleConstants.setFontFamily(style, "SansSerif");

            // Font size
            StyleConstants.setFontSize(style, 32);

            doc.insertString(doc.getLength(), "Hello TextPane!!", style);

            // Create a style object and then set the style attributes
            Style style2 = doc.addStyle("StyleName2", null);
            StyleConstants.setBold(style2, true);
            StyleConstants.setFontSize(style2, 28);
            StyleConstants.setForeground(style2, Color.red);

            doc.insertString(doc.getLength(), "\n\n Subscript: H", style2);
            // Subscript
            StyleConstants.setSubscript(style2, true);
            // Append to document
            doc.insertString(doc.getLength(), "2", style2);
            StyleConstants.setSubscript(style2, false);
            doc.insertString(doc.getLength(), "O", style2);

            // Create a style object and then set the style attributes
            Style style3 = doc.addStyle("StyleName3", null);
            StyleConstants.setBold(style3, true);
            StyleConstants.setFontSize(style3, 28);
            StyleConstants.setForeground(style3, Color.blue);

            doc.insertString(doc.getLength(), "\n Superscript:  E = Mc", style3);
            StyleConstants.setSuperscript(style3, true);
            doc.insertString(doc.getLength(), "2", style3);

            // Create a style object and then set the style attributes
            Style style4 = doc.addStyle("StyleName4", null);
            StyleConstants.setBold(style4, true);
            StyleConstants.setFontSize(style4, 28);
            StyleConstants.setForeground(style4, Color.black);
            StyleConstants.setStrikeThrough(style4, true);

            Style style5 = doc.addStyle("StyleName5", null);
            StyleConstants.setBold(style5, true);
            StyleConstants.setFontSize(style5, 28);
            StyleConstants.setForeground(style5, Color.green.darker().darker());

            doc.insertString(doc.getLength(), "\n\nStrikeThrough : ", style5);
            doc.insertString(doc.getLength(), "StrikeThrough\n\n", style4);

            Style style6 = doc.addStyle("StyleName6", null);

            Image image = null;

            // Load the Image from the disk
            image = getImage("Images/Aishwarya.jpg");
            if (image != null) {
                image = resize(image);
                // The image must first be wrapped in a style
                StyleConstants.setIcon(style6, new ImageIcon(image));
            }


            Style style8 = doc.addStyle("StyleName7", null);
            StyleConstants.setBold(style8, true);
            StyleConstants.setFontSize(style8, 28);
            StyleConstants.setForeground(style8, Color.orange.darker().darker());
            doc.insertString(doc.getLength(), "\n\nImage : ", style8);
            // Insert the image at the end of the text
            doc.insertString(doc.getLength(), "Image", style6);

            Style style9 = doc.addStyle("StyleName", null);
            StyleConstants.setBold(style9, true);
            StyleConstants.setFontSize(style9, 28);
            StyleConstants.setForeground(style9, Color.orange.darker().darker());
            StyleConstants.setBackground(style9, Color.blue);
            StyleConstants.setForeground(style9, Color.yellow);

            Style style10 = doc.addStyle("StyleName", null);
            StyleConstants.setBold(style10, true);
            StyleConstants.setFontSize(style10, 28);
            StyleConstants.setForeground(style10, Color.magenta);

            doc.insertString(doc.getLength(), "\n\nBackground & Foreground : ", style10);

            doc.insertString(doc.getLength(), "JTextPane Rocks!!", style9);

            Style style11 = doc.addStyle("StyleName11", null);
            StyleConstants.setBold(style11, true);
            StyleConstants.setFontSize(style11, 28);
            StyleConstants.setForeground(style11, Color.cyan.darker());

            doc.insertString(doc.getLength(), "\n\nUnderLine : ", style11);

            Style style12 = doc.addStyle("StyleName12", null);
            StyleConstants.setBold(style12, true);
            StyleConstants.setFontSize(style12, 28);
            StyleConstants.setForeground(style12, Color.pink);
            StyleConstants.setUnderline(style12, true);
            StyleConstants.setAlignment(style12, StyleConstants.ALIGN_CENTER);

            doc.insertString(doc.getLength(), "Java is Cool!! : ", style12);

            // Create one of each type of tab stop
            java.util.List<TabStop> list = new ArrayList<>();

            // Create a right-aligned tab stop at 200 pixels from the left margin
            float pos = 200;
            int align = TabStop.ALIGN_RIGHT;
            int leader = TabStop.LEAD_NONE;
            TabStop tstop = new TabStop(pos, align, leader);
            list.add(tstop);

            // Create a center-aligned tab stop at 300 pixels from the left margin
            pos = 300;
            align = TabStop.ALIGN_CENTER;
            leader = TabStop.LEAD_NONE;
            tstop = new TabStop(pos, align, leader);
            list.add(tstop);

            // Create a tab set from the tab stops
            TabStop[] tstops = list.toArray(new TabStop[0]);
            TabSet tabs = new TabSet(tstops);

            // Add the tab set to the logical style;
            // the logical style is inherited by all paragraphs
            Style style13 = textPane.getLogicalStyle();
            StyleConstants.setTabSet(style13, tabs);
            textPane.setLogicalStyle(style13);

            doc.insertString(doc.getLength(), "\n\nTab Stop", style13);
            StyleContext styles = new StyleContext();

            Style def = styles.getStyle(StyleContext.DEFAULT_STYLE);

            Style heading = styles.addStyle("heading", def);
            StyleConstants.setFontFamily(heading, "SansSerif");
            StyleConstants.setBold(heading, true);
            StyleConstants.setAlignment(heading, StyleConstants.ALIGN_JUSTIFIED);
            StyleConstants.setSpaceAbove(heading, 10);
            StyleConstants.setSpaceBelow(heading, 10);
            StyleConstants.setFontSize(heading, 18);

            doc.insertString(doc.getLength(), "\n\nHai!! ", heading);

        } catch (BadLocationException e) {
        }
        add(new JScrollPane(textPane), BorderLayout.CENTER);
        setTitle("TextPaneDemo");
        setSize(750, 650);
        setLocationRelativeTo(this);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public BufferedImage getImage(String fileName) {
        try {
            return ImageIO.read(new File(fileName));
        } catch (IOException ioe) {
            System.err.println("Error loading Image!!");
        }
        return null;
    }

    public Image resize(Image image) {
        if (image != null) {
            int imgWidth = image.getWidth(null);
            int imgHeight = image.getHeight(null);
            int maxWidth, maxHeight;
            double aspect = ((double) imgWidth) / ((double) imgHeight);

            if (aspect > 1.3333) {
                // Fix the width as maxWidth, calculate the maxHeight
                maxWidth = 70;
                maxHeight = (int) (((double) maxWidth) / aspect);
            } else {
                // Fix the height as iconHeight, calculate the maxWidth for this
                maxHeight = 65;
                maxWidth = (int) (((double) maxHeight) * aspect);
            }
            return image.getScaledInstance(maxWidth, maxHeight, Image.SCALE_SMOOTH);
        }
        return null;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TextPaneDemo();
            }
        });
    }
}
```

Here is another demo that highlights the Java keywords in a document. This is what an IDE like NetBeans, IDEA, JDeveloper does!!
The program parses a document & highlights the Java keywords in them.


```
/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 7/31/14
 * Time: 1:42 PM
 * To change this template use File | Settings | File Templates.
 */
import javax.swing.*;
import javax.swing.text.*;
import java.awt.*;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;

public class TextPaneDemo2 extends JFrame {
    private static final String STYLE_KEYWORD = "keyword";
    private static final String STYLE_LITERAL = "literal";
    private static final String STYLE_TYPE    = "type";
    private static final String STYLE_COMMENT = "comment";
    private static final String STYLE_STRING  = "string";

    private HashMap <Object, Object>stylesMap;
    private JTextPane textPane;
    private Document document;
    private HashMap <Object, Object>tokens;

    public TextPaneDemo2(String fileName) {
        super("TextPaneDemo2");
        try
        {
             UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            // Do nothing
        }
        initTokens();
        initAttributeSets();
        initUI();

        try {
            loadFile(fileName);
        } catch (IOException e) {

        }

        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        setSize(scrDim.width/2, scrDim.height);
        setVisible(true);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    private void loadFile(String fileName) throws IOException {
        File file = new File(fileName);
        if(!file.exists()) {
            System.err.println("The specified file doesn't exist!!");
            System.exit(-1);
        }
        FileReader in = new FileReader(file);

        int c = -1;
        boolean startWord = true;
        StringBuffer segment = new StringBuffer();

        while ((c = in.read()) != -1) {
            if (startWord) {
                if (Character.isJavaIdentifierStart(c)) {
                    segment.append((char) c);
                    startWord = false;
                } else if (c == '/') {
                    StringBuffer comment = new StringBuffer();
                    comment.append('/');

                    c = in.read();
                    comment.append((char) c);
                    if (c == '/') {
                        do {
                            c = in.read();
                            if (c != -1) {
                                if (c == '#') {
                                    StringBuffer image = new StringBuffer();
                                    do {
                                        c = in.read();
                                        if (c != '#') {
                                            image.append((char) c);
                                        }
                                    } while (c != '#');
                                    try {
                                        document.insertString(document.getLength(), comment.toString(), (AttributeSet) stylesMap.get(STYLE_COMMENT));
                                    } catch (BadLocationException e) { }
                                    comment = new StringBuffer();
                                    Icon imageIcon = new ImageIcon(image.toString());
                                    SimpleAttributeSet set = new SimpleAttributeSet();
                                    StyleConstants.setIcon(set, imageIcon);
                                    try {
                                        document.insertString(document.getLength(), " ", set);
                                    } catch (BadLocationException e) { }
                                } else {
                                    comment.append((char) c);
                                }
                            }
                        } while (c != -1 && c != '\n');
                    } else if (c == '*') {
                        boolean seenStar = false;
                        do {
                            c = in.read();
                            if (c == '*') {
                                seenStar = true;
                            } else if (c != '/') {
                                seenStar = false;
                            }
                            comment.append((char) c);
                        } while (!(seenStar && c == '/'));
                    }

                    try {
                        document.insertString(document.getLength(), comment.toString(), (AttributeSet) stylesMap.get(STYLE_COMMENT));
                    } catch (BadLocationException e) { }
                } else if (c == '"') {
                    StringBuffer string = new StringBuffer();
                    string.append('"');
                    boolean noEscape = true;
                    do {
                        c = in.read();
                        string.append((char) c);
                        noEscape = (c != '\\');
                    } while (!(noEscape && c == '"'));
                    try {
                        document.insertString(document.getLength(), string.toString(), (AttributeSet) stylesMap.get(STYLE_STRING));
                    } catch (BadLocationException e) { }
                } else {
                    try {
                        document.insertString(document.getLength(), String.valueOf((char) c), null);
                    } catch (BadLocationException e) { }
                }
            } else {
                if (Character.isJavaIdentifierPart(c)) {
                    segment.append((char) c);
                } else {
                    try {
                        String fragment = segment.toString();
                        document.insertString(document.getLength(), fragment, getStyle(fragment));
                        document.insertString(document.getLength(), String.valueOf((char) c), null);
                    } catch (BadLocationException e) { }

                    segment = new StringBuffer();
                    startWord = true;
                }
            }
        }
        in.close();
    }

    private SimpleAttributeSet getStyle(String word) {
        Object key = tokens.get(word);
        if (key != null) {
            return (SimpleAttributeSet) stylesMap.get(key);
        }
        return null;
    }

    private void initTokens() {
        tokens = new HashMap<>();
        tokens.put("package", STYLE_KEYWORD);
        tokens.put("import", STYLE_KEYWORD);
        tokens.put("byte", STYLE_TYPE);
        tokens.put("char", STYLE_TYPE);
        tokens.put("short", STYLE_TYPE);
        tokens.put("int", STYLE_TYPE);
        tokens.put("long", STYLE_TYPE);
        tokens.put("float", STYLE_TYPE);
        tokens.put("double", STYLE_TYPE);
        tokens.put("boolean", STYLE_TYPE);
        tokens.put("void", STYLE_TYPE);
        tokens.put("String", STYLE_TYPE);
        tokens.put("enum", STYLE_KEYWORD);
        tokens.put("class", STYLE_KEYWORD);
        tokens.put("interface", STYLE_KEYWORD);
        tokens.put("abstract", STYLE_KEYWORD);
        tokens.put("assert", STYLE_KEYWORD);
        tokens.put("final", STYLE_KEYWORD);
        tokens.put("strictfp", STYLE_KEYWORD);
        tokens.put("private", STYLE_KEYWORD);
        tokens.put("protected", STYLE_KEYWORD);
        tokens.put("public", STYLE_KEYWORD);
        tokens.put("static", STYLE_KEYWORD);
        tokens.put("synchronized", STYLE_KEYWORD);
        tokens.put("native", STYLE_KEYWORD);
        tokens.put("volatile", STYLE_KEYWORD);
        tokens.put("transient", STYLE_KEYWORD);
        tokens.put("break", STYLE_KEYWORD);
        tokens.put("case", STYLE_KEYWORD);
        tokens.put("continue", STYLE_KEYWORD);
        tokens.put("default", STYLE_KEYWORD);
        tokens.put("do", STYLE_KEYWORD);
        tokens.put("else", STYLE_KEYWORD);
        tokens.put("for", STYLE_KEYWORD);
        tokens.put("if", STYLE_KEYWORD);
        tokens.put("instanceof", STYLE_KEYWORD);
        tokens.put("new", STYLE_KEYWORD);
        tokens.put("return", STYLE_KEYWORD);
        tokens.put("switch", STYLE_KEYWORD);
        tokens.put("while", STYLE_KEYWORD);
        tokens.put("throw", STYLE_KEYWORD);
        tokens.put("try", STYLE_KEYWORD);
        tokens.put("catch", STYLE_KEYWORD);
        tokens.put("extends", STYLE_KEYWORD);
        tokens.put("finally", STYLE_KEYWORD);
        tokens.put("implements", STYLE_KEYWORD);
        tokens.put("throws", STYLE_KEYWORD);
        tokens.put("this", STYLE_LITERAL);
        tokens.put("null", STYLE_LITERAL);
        tokens.put("super", STYLE_LITERAL);
        tokens.put("true", STYLE_LITERAL);
        tokens.put("false", STYLE_LITERAL);
    }

    private void initUI() {
        textPane = new JTextPane();
        textPane.setPreferredSize(new Dimension(640, 480));
        textPane.setFont(new Font("Monospaced", Font.PLAIN, 12));
        document = textPane.getDocument();

        getContentPane().add(BorderLayout.CENTER, new JScrollPane(textPane));
    }

    private void initAttributeSets() {
        stylesMap = new HashMap<>();
        stylesMap.put(STYLE_KEYWORD, createAttributeSet(Color.magenta.darker().darker(), true, false));
        stylesMap.put(STYLE_LITERAL, createAttributeSet(new Color(101, 0, 153), true, false));
        stylesMap.put(STYLE_TYPE, createAttributeSet(Color.blue, false, false));
        stylesMap.put(STYLE_COMMENT, createAttributeSet(new Color(14, 153, 11), false, true));
        stylesMap.put(STYLE_STRING,  createAttributeSet(new Color(14, 16, 255), false, false));
    }

    private SimpleAttributeSet createAttributeSet(Color color, boolean bold, boolean italic) {
        SimpleAttributeSet style = new SimpleAttributeSet();
        style.addAttribute(StyleConstants.Foreground, color);
        StyleConstants.setBold(style, bold);
        StyleConstants.setItalic(style, italic);
        return style;
    }

    public static void main(final String[] args) {
        if (args.length > 0) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new TextPaneDemo2(args[0]);
                }
            });
        }
        else {
            System.out.println("Usage: java TextPaneDemo2 <filename.java>");
        }

    }
}
```

*s15.postimg.org/6kdtxisgn/Text_Pane_Demo2.jpg

*JInternalFrame*

With the JInternalFrame class you can display a JFrame-like window within another window. Usually, you add internal frames to a desktop pane. The desktop pane, in turn, might be used as the content pane of a JFrame.
The desktop pane is an instance of JDesktopPane, which is a subclass of JLayeredPane that has added API for managing multiple overlapping internal frames.
Internal frames are not windows or top-level containers, however, which makes them different from frames. For example, you must add an internal frame to a container (usually a JDesktopPane); an internal frame cannot
be the root of a containment hierarchy. Also, internal frames do not generate window events. Instead, the user actions that would cause a frame to fire window events cause an internal frame to fire internal frame events.

Because internal frames are implemented with platform-independent code, they add some features that frames cannot give you. One such feature is that internal frames give you more control over their state and capabilities 
than frames do. You can programatically iconify or maximize an internal frame. You can also specify what icon goes in the internal frame's title bar. You can even specify whether the internal frame has the window 
decorations to support resizing, iconifying, closing, and maximizing.
The following program shows an InternaFrame. From the menu File -> Open. Select a Image(s). The Images are displayed in an InternalFrame.
You can select more than one Image by pressing & holding the SHIFT key & selecting the Images.


```
/**
 * Created with IntelliJ IDEA.
 * User: JGuru
 * Date: 7/23/14
 * Time: 11:04 AM
 * To change this template use File | Settings | File Templates.
 */
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
import javax.swing.plaf.basic.BasicFileChooserUI;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Sowndar
 */

public class InternalFrameDemo extends JFrame implements ActionListener {

    private String path = "Images/";
    private JDesktopPane desktopPane;
    private JMenu menu = new JMenu("File", true);
    private JMenuItem open = new JMenuItem("Open");
    private JMenuItem cascade = new JMenuItem("Cascade");
    private JMenuItem tile = new JMenuItem("Tile");
    private JMenuItem exit = new JMenuItem("Exit");
    private JMenuBar mBar = new JMenuBar();
    private JFileChooser fChooser = new JFileChooser(path);
    private JLabel previewLabel = new JLabel();
    private File file;
    private int X = 10, Y = 10;
    private String[] readFormat = ImageIO.getReaderFormatNames();
    private Image image;
    //Cache the Internal frames
    private ArrayList <JInternalFrame>cache = new ArrayList<>();
    private JLabel statusBar = new JLabel("Ready");
    // The gap between internal frames when cascading effect is applied
    private int FRAME_OFFSET = 20;

    public void updateUI() {
        menu.updateUI();
        open.updateUI();
        exit.updateUI();
        mBar.updateUI();
        cascade.updateUI();
        tile.updateUI();
        fChooser.updateUI();
        previewLabel.updateUI();
    }

    public void setEnabled(boolean condition) {
        cascade.setEnabled(condition);
        tile.setEnabled(condition);
    }

    public InternalFrameDemo() {

        try {
            for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | UnsupportedLookAndFeelException e) {
            // Do nothing
        }
        updateUI();
        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        //Initial condition of the Components
        setEnabled(false);
        desktopPane = new JDesktopPane();
        desktopPane.setBackground(getBackground());
        desktopPane.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);

        open.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_DOWN_MASK));
        exit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, KeyEvent.CTRL_DOWN_MASK));
        menu.add(open);
        menu.add(cascade);
        menu.add(tile);
        menu.add(exit);
        mBar.add(menu);

        setJMenuBar(mBar);
        // Add action listener
        open.addActionListener(this);
        cascade.addActionListener(this);
        tile.addActionListener(this);
        exit.addActionListener(this);
        previewLabel.setPreferredSize(new Dimension(250, 150));
        previewLabel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
        previewLabel.setHorizontalAlignment(SwingConstants.CENTER);
        previewLabel.setVerticalAlignment(SwingConstants.CENTER);
        // Show Image preview
        fChooser.setAccessory(previewLabel);
        fChooser.setPreferredSize(new Dimension(650, 400));
        fChooser.setAcceptAllFileFilterUsed(false);
        //Only one file can be selected at a time
        fChooser.setMultiSelectionEnabled(true);
        fChooser.setDragEnabled(true);
        // Set a File filter
        fChooser.addChoosableFileFilter(new javax.swing.filechooser.FileFilter() {

            @Override
            public boolean accept(File f) {
                String name = f.getName();
                for (int i = 0; i < readFormat.length; i++) {
                    if (f.isDirectory() || name.endsWith(readFormat[i])) {
                        return true;
                    }
                }
                return false;
            }

            @Override
            public String getDescription() {
                return "Image Filter";
            }
        });

        fChooser.addPropertyChangeListener(new PropertyChangeListener() {

            @Override
            public void propertyChange(final PropertyChangeEvent evt) {
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        boolean update = false;
                        String prop = evt.getPropertyName();

                        //If the directory changed, don't show an image.
                        if (JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals(prop)) {
                            file = null;
                            update = true;

                            //If a file became selected, find out which one.
                        } else if (JFileChooser.SELECTED_FILE_CHANGED_PROPERTY.equals(prop)) {
                            file = (File) evt.getNewValue();
                            update = true;
                        }

                        if (update) {
                            if (file != null) {
                                //Show the Image preview
                                previewLabel.setIcon(null);
                                previewLabel.setText("Processing, Please wait...");
                                image = getImage(file.toString());
                                previewLabel.setIcon(new ImageIcon(setImage(image)));
                                previewLabel.setText("");
                            } else {
                                image = null;
                                previewLabel.setIcon(null);
                                previewLabel.setText("");
                            }
                        }
                    }
                }).start();
            }
        });
        add(desktopPane, BorderLayout.CENTER);
        add(statusBar, BorderLayout.SOUTH);
        desktopPane.setVisible(true);
        setSize(scrDim.width / 2 + 150, scrDim.height);
        setTitle("InternalFrameDemo");
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        Object source = ae.getSource();
        if (source == open) {
            // Open the file
            //Don't show any preview until the user selects an Image
            previewLabel.setIcon(null);
            fChooser.setSelectedFile(null);
            BasicFileChooserUI ui = (BasicFileChooserUI) fChooser.getUI();
            ui.setFileName("");
            int returnVal = fChooser.showOpenDialog(null);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        // Get the selected files
                        //You can select more than one file by pressing & holding the SHIFT key & selecting as many as you like!!
                        File []file = fChooser.getSelectedFiles();
                        if (file != null) {
                            for (int i = 0; i < file.length; i++) {
                                getInternalFrame(file[i]);
                            }
                            //Enable the Components
                            setEnabled(true);
                        }
                    }
                }).start();
            }
        }
        else if(source == cascade) {
            cascade();
        }
        else if(source == tile) {
            tileHorizontal();
        }
        else
        {
            System.exit(0);
        }
    }

    /* Cascade the internal frames */
    public void cascade() {
        int x = 0;
        int y = 0;
        JInternalFrame allFrames[] = desktopPane.getAllFrames();
        int frameHeight = (desktopPane.getBounds().height - 5) - allFrames.length * FRAME_OFFSET;
        int frameWidth = (desktopPane.getBounds().width - 5) - allFrames.length * FRAME_OFFSET;
        for (int i = allFrames.length - 1; i >= 0; i--) {
            allFrames[i].setSize(frameWidth, frameHeight);
            allFrames[i].setLocation(x, y);
            x = x + FRAME_OFFSET;
            y = y + FRAME_OFFSET;
        }
    }

    /**
     * Tile all internal frames horizontally
     */
    public void tileHorizontal() {
        JInternalFrame allFrames[] = desktopPane.getAllFrames();
        int frameHeight = desktopPane.getBounds().height / allFrames.length;
        int frameWidth = desktopPane.getBounds().width / allFrames.length;
        int wholeHeight = desktopPane.getBounds().height;
        int x = 0, y = 0;
        for (int i = 0; i < allFrames.length; i++) {
            allFrames[i].setSize(frameWidth, wholeHeight);
            allFrames[i].setLocation(x, 0);
            x = x + frameWidth;
            y = y + frameHeight;
        }
    }

    // Create an Internal Frame, add it to DesktopPane
    public void getInternalFrame(final File file) {

            final JInternalFrame iFrame = new JInternalFrame(file.getName(), true, true, true, true);
            //Cache the internal frames
            cache.add(iFrame);
            JLabel label = new JLabel();
            // Get the Image
            image = getImage(file.toString());
            if (image != null) {

                label.setIcon(new ImageIcon(image));
                iFrame.add(new JScrollPane(label));
                iFrame.setSize(650, 600);
                iFrame.setFrameIcon(getIcon(image));
                // Make it the current selected frame
                try {
                    iFrame.setSelected(true);
                } catch (PropertyVetoException pve) {
                }
                X += 25;
                Y += 35;
                iFrame.setLocation(X, Y);
                iFrame.setDefaultCloseOperation(JInternalFrame.DISPOSE_ON_CLOSE);
                iFrame.setVisible(true);

                desktopPane.add(iFrame);
                // Move the frame to the front
                iFrame.moveToFront();

                iFrame.addInternalFrameListener(new InternalFrameAdapter() {

                    @Override //Invoked when an internal frame is activated.
                    public void internalFrameActivated(InternalFrameEvent ie) {

                        for (int i = 0; i < cache.size(); i++) {
                            if(ie.getSource() == cache.get(i)) {
                                statusBar.setText("You selected iFrame : " + i + " [" + ((JInternalFrame)ie.getSource()).getTitle() + "]");
                            }
                        }
                    }
                    @Override    // Invoked when an internal frame is in the process of being closed
                    public void internalFrameClosing(InternalFrameEvent ie) {
                        statusBar.setText("" + ((JInternalFrame)ie.getSource()).getTitle() + " is being closed!!");
                    }

                    @Override   // Invoked when an internal frame has been closed
                    public void internalFrameClosed(InternalFrameEvent ie) {
                         statusBar.setText("" + ((JInternalFrame)ie.getSource()).getTitle() + " is closed!!");
                    }

                    @Override  // Invoked when an internal frame is iconified.
                    public void internalFrameIconified(InternalFrameEvent ie) {
                        statusBar.setText("" + ((JInternalFrame)ie.getSource()).getTitle() + " is iconified!!");
                    }

                    @Override // Invoked when an internal frame is de-iconified.
                    public void internalFrameDeiconified(InternalFrameEvent ie) {
                        statusBar.setText("" + ((JInternalFrame)ie.getSource()).getTitle() + " is de-iconified!!");
                    }
                });
            }
    }

    public ImageIcon getIcon(Image image) {
        if (image != null) {
            return new ImageIcon(image.getScaledInstance(32, 32, Image.SCALE_SMOOTH));
        }
        return null;
    }

    public Image setImage(Image image) {
        if (image != null) {
            int imgWidth = image.getWidth(null);
            int imgHeight = image.getHeight(null);
            double aspect = ((double) imgWidth) / ((double) imgHeight);
            int maxWidth, maxHeight;

            // If aspect ratio exceeds 1.3333
            if (aspect > 1.3333) {
                // Fix the width as maxWidth, calculate the maxHeight
                maxWidth = 260;
                maxHeight = (int) (((double) maxWidth) / aspect);
            } else {
                // Fix the height as iconHeight, calculate the maxWidth for this
                maxHeight = 240;
                maxWidth = (int) (((double) maxHeight) * aspect);
            }
            return image.getScaledInstance(maxWidth, maxHeight, Image.SCALE_SMOOTH);
        }
        return null;
    }

    //Get the Image from the disk
    public Image getImage(String fileName) {
        if(fileName.endsWith("jpg")|| fileName.endsWith("png")) {
            return new ImageIcon(fileName).getImage();
        }
        try {
            return ImageIO.read(new File(fileName));
        } catch (IOException ioe) {
            System.err.println("Error loading Image : " + fileName);
        }
        return null;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new InternalFrameDemo();
            }
        });
    }
}
```

*s13.postimg.org/8obbcyd03/Internal_Frame_Demo.jpg

*JLabel*

With the JLabel class, you can display unselectable text and images. If you need to create a component that displays a string, an image, or both, you can do so by using or extending JLabel.
If the component is interactive and has a certain state, use a button instead of a label.

The demo scrolls a Label using a custom Popup menu. It's a preview scroller!!


```
/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 8/7/14
 * Time: 2:38 PM
 * To change this template use File | Settings | File Templates.
 */

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class PreviewScroller extends JFrame {

    private Image image;

    public PreviewScroller(String title, Image userImage) {
        super(title);
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | UnsupportedLookAndFeelException e) {
            // Do nothing
        }
        image = userImage;
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        JScrollPane imagePane = new JScrollPane(
                new JLabel(new ImageIcon(image)));

        PreviewCorner pCorner = new PreviewCorner(
                imagePane,  createIcon(), true, JScrollPane.LOWER_RIGHT_CORNER);
        imagePane.setCorner(JScrollPane.LOWER_RIGHT_CORNER, pCorner);

        add(imagePane);
        setSize(700, 500);
        setVisible(true);
        // Click the Preview button programmatically
        pCorner.doClick();
    }

    //Create an Icon
    public ImageIcon createIcon() {
        BufferedImage buff = new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB);
        Graphics gr = buff.getGraphics();
        gr.setColor(Color.blue);
        int num = 4;
        gr.fillRect(0, 0, num * num, num * num);
        gr.setColor(Color.yellow);
        gr.fillArc(num, num, (num * num) - (num * 2), (num * num) - (num * 2), 0, 360);
        gr.dispose();
        return new ImageIcon(buff);
    }

    public static BufferedImage getImage(String fileName) {
        try {
            return ImageIO.read(new File(fileName));
        } catch (IOException ioe) {
            System.err.println("Error loading Image!!");
            System.exit(-1);
        }
        return null;
    }

    public static void main(final String[] args) throws IOException {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                if (args.length != 1) {
                    System.err.println("Usage: java SampleApp <ImageFilePath>");
                    System.exit(-1);
                }
                Image myImage = getImage(args[0]);
                new PreviewScroller("Preview Scroller", myImage);
            }
        });
    }
}


/**
 * This is a button which is designed to be the corner component of a
 * <code>JScrollPane</code>. It triggers a popup menu which holds a scaled image
 * of the component contained inside the
 * <code>JScrollPane</code>.
 */
class PreviewCorner extends JButton implements ActionListener {

    private String corner;
    private PreviewPopup previewPopup;

    /**
     * [MENTION=9956]PARAM[/MENTION] scrollPane the <code>JScrollPane</code> to preview
     * [MENTION=9956]PARAM[/MENTION] zoomIcon the icon to use for the button
     * [MENTION=9956]PARAM[/MENTION] doCloseAfterClick When <code>true</code> the preview popup menu is
     * closed on mouse click.
     * [MENTION=9956]PARAM[/MENTION] corner Supposed to be one of the four corners of a
     * <code>JScrollPane</code>, like
     * <code>JScrollPane.LOWER_RIGHT_CORNER</code> for example, which should
     * match the position of the corner component of the scroll pane. Note: If
     * this parameter is not set correctly,
     * <code>JScrollPane.UPPER_LEFT_CORNER</code> will be used instead.
     */
    public PreviewCorner(
            JScrollPane scrollPane,
            ImageIcon zoomIcon,
            boolean doCloseAfterClick,
            String corner) {

        super(zoomIcon);
        this.corner = corner;

        // Creates the popup menu, containing the scaled image of the component.
        previewPopup = new PreviewPopup(scrollPane, doCloseAfterClick);

        setToolTipText("View a miniature of scrollpane content and navigate");

        // The action listener is used to trigger the popup menu.
        addActionListener(this);

    }

    public PreviewCorner(
            JScrollPane scrollPane,
            ImageIcon zoomIcon,
            String corner) {

        this(scrollPane, zoomIcon, false, corner);

    }

    @Override
    public void actionPerformed(ActionEvent e) {

        previewPopup.showUpInCorner(this, corner);
    }

}

class PreviewPopup extends JPopupMenu implements MouseListener, MouseMotionListener {

    private JScrollPane scrollPane;
    private JViewport viewPort;
    private JLabel zoomWindow; // the JLabel containing the scaled image
    private JLabel cursorLabel; // the JLabel mimicking the fake rectangle cursor

    // This component will hold both JLabels zoomWindow and cursorLabel,
    // the latter on top of the other.
    private JLayeredPane layeredPane;
    private int iconWidth;
    private int iconHeight;
    private boolean doCloseAfterClick;
    int ratio;
    // DELTA is the space between the scroll pane and the preview popup menu.
    private static int DELTA = 5;
    // SCALEFACTOR is the scale factor between the previewed component
    // and the viewport.
    private static int SCALEFACTOR = 4;
    private JLabel label;
    int vpWidth, vpHeight;

    public PreviewPopup(JScrollPane scroller, boolean doClick) {

        this.setBorder(BorderFactory.createEtchedBorder());

        doCloseAfterClick = doClick;
        scrollPane = scroller;
        viewPort = scrollPane.getViewport();

        zoomWindow = new JLabel();
        cursorLabel = createCursor();

        layeredPane = new JLayeredPane();

        layeredPane.add(zoomWindow, new Integer(0));
        layeredPane.add(cursorLabel, new Integer(1));

        // Creates a blank transparent cursor to be used as the cursor of
        // the popup menu.
        BufferedImage bim
                = new BufferedImage(1, 1, BufferedImage.TYPE_4BYTE_ABGR);
        setCursor(
                getToolkit().createCustomCursor(bim, (new Point(0, 0)), "HiddenM"));

        this.add(layeredPane);

        // Adds the mouse input listeners to the layeredPane to scroll the
        // viewport and to move the fake cursor (cursorLabel).
        layeredPane.addMouseListener(this);
        layeredPane.addMouseMotionListener(this);
    }

    /**
     * By default, the right corner of a popup menu is positionned at the right
     * of a mouse click. What we want is to have the preview popup menu
     * positionned <i>inside</i> the scroll pane, near the corner component. The
     * purpose of this method is to display the scaled image of the component of
     * the scroll pane, and to calculate the correct position of the preview
     * popup menu.
     */
    public void showUpInCorner(Component c, String corner) {

        if (viewPort.getComponentCount() == 0) {
            return;
        }
        // Get the Component this viewport holds
        label = (JLabel) viewPort.getComponent(0);
        vpWidth = viewPort.getWidth();
        vpHeight = viewPort.getHeight();
        if (vpWidth < (vpHeight * SCALEFACTOR)) {
            ratio
                    = label.getWidth()
                    / (vpWidth / SCALEFACTOR);
        } else {
            ratio
                    = label.getHeight()
                    / (vpHeight / SCALEFACTOR);
        }

        int zoomWidth = label.getWidth() / ratio;
        int zoomHeight = label.getHeight() / ratio;
        Image capture = captureComponentViewAsBufferedImage(label);
        // Scale the Image smoothly
        Image componentImage = capture.getScaledInstance(zoomWidth, zoomHeight, Image.SCALE_SMOOTH);

        // Converts the Image to an ImageIcon to be used with a JLabel.
        ImageIcon componentIcon = new ImageIcon(componentImage);

        iconWidth = componentIcon.getIconWidth();
        iconHeight = componentIcon.getIconHeight();

        zoomWindow.setIcon(componentIcon);

        zoomWindow.setBounds(0, 0, iconWidth, iconHeight);

        int cursorWidth = vpWidth / ratio;

        int cursorHeight = vpHeight / ratio;

        cursorLabel.setBounds(0, 0, cursorWidth, cursorHeight);

        layeredPane.setPreferredSize(new Dimension(iconWidth, iconHeight));

        int dx = componentIcon.getIconWidth() + DELTA;
        int dy = componentIcon.getIconHeight() + DELTA;

        if (corner == JScrollPane.UPPER_LEFT_CORNER); else if (corner == JScrollPane.UPPER_RIGHT_CORNER) {
            dx = -dx;
        } else if (corner == JScrollPane.LOWER_RIGHT_CORNER) {
            dx = -dx;
            dy = -dy;
        } else if (corner == JScrollPane.LOWER_LEFT_CORNER) {
            dy = -dy;
        }
        // Shows the popup menu at the right place (Right side bottom corner).
        this.show(c, dx, dy);
    }

    // Create a fake Cursor
    public JLabel createCursor() {
        JLabel label2 = new JLabel();
        label2.setBorder(BorderFactory.createLineBorder(Color.green, 1));
        label2.setVisible(false);
        return label2;
    }

    @Override
    public void mouseClicked(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // When the mouse enters the preview popup menu, set the visibility
        // of the fake cursor to true.
        cursorLabel.setVisible(true);
    }

    @Override
    public void mouseExited(MouseEvent e) {
        // When the mouse exits the preview popup menu, set the visibility
        // of the fake cursor to false.
        cursorLabel.setVisible(false);
    }

    @Override
    public void mousePressed(MouseEvent e) {
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        // When the mouse is released, set the visibility of the preview
        // popup menu to false only if doCloseAfterClick is set to true.
        if (doCloseAfterClick) {
            this.setVisible(false);
            cursorLabel.setVisible(false);
        }
    }

    public void scrollMe(MouseEvent e) {
        moveCursor(e.getX(), e.getY());
        scrollViewPort();
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        scrollMe(e);
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        scrollMe(e);
    }

    /**
     * Centers the fake cursor (cursorLabel) position on the coordinates
     * specified in the parameters.
     */
    private void moveCursor(int x, int y) {
        int dx = x - cursorLabel.getWidth() / 2;
        int dy = y - cursorLabel.getHeight() / 2;
        cursorLabel.setLocation(dx, dy);
    }

    /**
     * Scrolls the viewport according to the fake cursor position in the preview
     * popup menu.
     */
    private void scrollViewPort() {
        Point cursorLocation = cursorLabel.getLocation();
        int dx = (int) Math.max(cursorLocation.getX(), 0);
        int dy = (int) Math.max(cursorLocation.getY(), 0);

        dx = dx * ratio;
        dy = dy * ratio;
        // Scroll the label Component
        label.scrollRectToVisible(new Rectangle(dx, dy, vpWidth, vpHeight));
    }

    /**
     * takes a java component and generates an image out of it.
     *
     * [MENTION=9956]PARAM[/MENTION] c the component for which image needs to be generated
     * @return the generated image
     */
    public static BufferedImage captureComponentViewAsBufferedImage(Component c) {
        if (c != null) {
            Dimension size = c.getSize();
            BufferedImage buffImage = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);
            Graphics buffGr = buffImage.createGraphics();
            c.paint(buffGr);
            return buffImage;
        }
        return null;
    }
}
```

*s22.postimg.org/s7d6vp0nx/Preview_Scroller.jpg

Here is what the code does: 

The main class is PreviewScroller that displays the Image using a Label.
The class PreviewPopup shows a preview Image using a JLayeredPane.
The method scrollViewPort() actually scrolls the label!!
You need to move the cursor on the preview Image(PreviewPopup) to actually make the Label scroll.
This what a application like PhotoShop or GIMP does!!

*JLayeredPane*

A layered pane is a Swing container that provides a third dimension for positioning components: depth, also known as Z order. 
When adding a component to a layered pane, you specify its depth as an integer. The higher the number, closer the component is 
to the "top" position within the container. If components overlap, the "closer" components are drawn on top of components at a
lower depth. The relationship between components at the same depth is determined by their positions within the depth.

Swing provides two layered pane classes. The first, JLayeredPane, is the class that root panes use and is the class used by 
the example in this section. The second, JDesktopPane, is a JLayeredPane subclass that is specialized for the task of holding internal frames.

The following program loads the Images & shows them using a JlayeredPane in a cascading fashion.


```
/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 8/1/14
 * Time: 2:21 PM
 * To change this template use File | Settings | File Templates.
 */
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Sowndar
 */
public final class LayeredPaneDemo2 extends JFrame {

    private JLabel[] label;
    private JLayeredPane layeredPane = new JLayeredPane();
    private Image image;
    private Dimension scrDim;
    private String path = "Images/";
    private File directory = new File(path);
    private String name[];
    private int MAX;
    private int imgWidth, imgHeight;
    private int X = -30, Y = 50;
    private String fileName;
    private Image[] imageFile;

    public LayeredPaneDemo2() {
        scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        // Filter only the Images
        name = directory.list(new FilenameFilter() {

            String []readFormat = ImageIO.getReaderFormatNames();
            public boolean accept(File dir, String name) {
                for (int i = 0; i < readFormat.length; i++) {
                    if(name.endsWith(readFormat[i]))
                        return true;
                }
                return false;
            }
        });
        MAX = name.length;
        // Limit to a maximum of 10 Images
        if(MAX > 10) {
            MAX = 10;
        }
        label = new JLabel[MAX];
        imageFile = new Image[MAX];
        for (int i = 0; i < label.length; i++) {
            label[i] = new JLabel();
            // This is the background
            if (i == 0) {
                // The bigLabel starts at 0, 0
                image = getImage(path + name[i]);
                imgWidth = image.getWidth(null);
                imgHeight = image.getHeight(null);
                label[i].setBounds(new Rectangle(0, 0, imgWidth, imgHeight));
                label[i].setIcon(new ImageIcon(image));
                label[i].setPreferredSize(new Dimension(imgWidth, imgHeight));
            } else {
                image = getImage(path + name[i]);
                image = scaleImage(image);
                // Cache the Images
                imageFile[i] = image;
                imgWidth = image.getWidth(null);
                imgHeight = image.getHeight(null);
                label[i].setBounds(X, Y, imgWidth, imgHeight);
                label[i].setIcon(new ImageIcon(image));
            }
            label[i].setVerticalAlignment(SwingConstants.TOP);
            label[i].setHorizontalAlignment(SwingConstants.LEFT);
            // Extract only the name without the file extension
            fileName = name[i];
            fileName = fileName.substring(0, fileName.lastIndexOf("."));
            label[i].setToolTipText(fileName);
            layeredPane.add(label[i], new Integer(i));
            X += 75;
            Y += 75;
        }

        add(layeredPane, BorderLayout.CENTER);

        setSize(label[0].getWidth() + 15, label[0].getHeight() + 40);
        setTitle("LayeredPaneDemo2");
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public Image getImage(String fileName) {
        try {
            return ImageIO.read(new File(fileName));
        } catch (IOException ioe) {
            System.err.println("Error loading Image : " + fileName + " !!");
        }
        return null;
    }

    public Image scaleImage(Image image) {
        if (image != null) {
            int imgWidth2 = image.getWidth(null);
            int imgHeight2 = image.getHeight(null);
            double aspect = ((double) imgWidth2) / ((double) imgHeight2);
            int maxWidth = 0, maxHeight = 0;

            if (imgHeight2 < imgWidth2) {
                // Fix the height , calculate the maxWidth for this
                maxHeight = 200;
                maxWidth = (int) (((double) maxHeight) * aspect);
            } else {

                // Fix the width as maxWidth, calculate the maxHeight
                maxWidth = 150;
                maxHeight = (int) (((double) maxWidth) / aspect);
            }
            return image.getScaledInstance(maxWidth, maxHeight, Image.SCALE_SMOOTH);
        }
        return null;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                new LayeredPaneDemo2();
            }
        });
    }
}
```

*s17.postimg.org/fx4b77gyj/Layered_Pane_Demo.jpg

*JList*

A JList presents the user with a group of items, displayed in one or more columns, to choose from. Lists can have many items, so they are often put in scroll panes.
Other JList constructors let you initialize a list from a Vector or from an object that adheres to the ListModel interface. If you initialize a list with an array or vector, the constructor implicitly creates a default list model. The default list model is immutable — you cannot add, remove, or replace items in the list. To create a list whose items can be changed individually, set the list's model to an instance of a mutable list model class, such as an instance of DefaultListModel. You can set a list's model when you create the list or by calling the setModel method.
The call to setSelectionMode specifies how many items the user can select, and whether they must be contiguous; the next section tells you more about selection modes.

The call to setLayoutOrientation lets the list display its data in multiple columns. The value JList.HORIZONTAL_WRAP specifies that the list should display its items from left
to right before wrapping to a new row. Another possible value is JList.VERTICAL_WRAP, which specifies that the data be displayed 
from top to bottom (as usual) before wrapping to a new column. 

The following program loads all the Images, shows the JList. Selecting an item displays it. 
You can select more than one item by pressing & holding the SHIFT key.


```
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 8/1/14
 * Time: 2:28 PM
 * To change this template use File | Settings | File Templates.
 */
public class ListDemo extends JFrame {

    private String path = "Images/";
    private String []imgName;
    private JList <String>list = new JList<>();
    private int MAX;
    //Cache the Images
    private Image []image;

    public ListDemo() {
        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            // Do nothing
        }
        list.updateUI();
        File directory = new File(path);
        if(!directory.exists()) {
            System.err.println("The specified directory doesn't exist!!");
            System.exit(-1);
        }
        // Filter out the Images
        imgName = directory.list(new FilenameFilter() {
            String []readFormat = ImageIO.getReaderFormatNames();
            @Override
            public boolean accept(File dir, String name) {
                for (int i = 0; i < readFormat.length; i++) {
                    if(name.endsWith(readFormat[i]))
                        return true;
                }
                return false;
            }
        });
        MAX = imgName.length;
        image = new Image[MAX];
        if(MAX == 0) {
            System.err.println("OOps , No Images found!!");
            System.exit(-1);
        }
        if(MAX > 20) {
            MAX = 20;
        }

        list.setListData(imgName);
        list.setCellRenderer(new ImagePreviewRenderer());
        final JTabbedPane tabbedPane = new JTabbedPane();
        final JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(list), tabbedPane);
        splitPane.setDividerLocation(350);
        splitPane.setOneTouchExpandable(true);
        list.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                //For Thread-safety issues call it from the Event-dispatch Thread!
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        new SwingWorker<Void, Void>() {
                            @Override
                            protected Void doInBackground() throws Exception {
                                //Remove all the previously added Components
                                tabbedPane.removeAll();
                                int index[] = list.getSelectedIndices();
                                int SIZE = index.length;
                                String fileName = "";
                                for (int i = 0; i < SIZE; i++) {
                                    fileName = imgName[index[i]];
                                    // Add the Component to the TabbedPane
                                    tabbedPane.addTab(fileName.substring(0, fileName.lastIndexOf(".")), new JScrollPane(new JLabel(new ImageIcon(getImage(path + fileName)))));
                                    // Select it programmatically
                                    tabbedPane.setSelectedIndex(i);
                                }
                                return null;
                            }
                        }.execute();
                    }
                });
            }
        });

        add(splitPane);
        setTitle("ListDemo");
        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        setSize(scrDim.width/2 + 150, scrDim.height);
        setVisible(true);
        //Start loading the Images in a separate Thread in the background
        start();
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    public void loadImages() {

        setCursor(new Cursor(Cursor.WAIT_CURSOR));
        for (int i = 0; i < MAX; i++) {
            image[i] = getImage(path + imgName[i]);
            //Create preview Images
            image[i] = image[i].getScaledInstance(64, 64, Image.SCALE_DEFAULT);
            list.repaint();
        }
        //Beep!!
        Toolkit.getDefaultToolkit().beep();
        setCursor(new Cursor(Cursor.DEFAULT_CURSOR));

    }

    public void start() {
        new SwingWorker<Void, Void>() {
            @Override
            protected Void doInBackground() throws Exception {
                loadImages();
                return null;
            }
        }.execute();
    }

    //Load Images quickly
    public Image getImage(String fileName) {
        if(fileName.endsWith("jpg")|| fileName.endsWith("png")) {
            return new ImageIcon(fileName).getImage();
        }
        try
        {
            return ImageIO.read(new File(fileName));
        }  catch (IOException ioe) {
            System.err.println("Error loading Image : " + fileName);
        }
        return null;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ListDemo();
            }
        });
    }

    //  Inner class  for Image preview for the List
    class ImagePreviewRenderer extends JLabel implements ListCellRenderer<Object> {

        Dimension dim = new Dimension(210, 74);

        ImagePreviewRenderer() {
            setOpaque(true);
        }

        @Override
        public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            //  If this is the selection value request from a combo box
            //  then find out the current selected index from the list.
            if (index == -1) {
                int selected = list.getSelectedIndex();
                if (selected == -1) {
                    return this;
                } else {
                    index = selected;
                }
            }
            setText(value.toString());
            try {
                if (image[index] != null) {
                    setIcon(new ImageIcon(image[index]));
                 }

            } catch (Exception e) {
            }
            setPreferredSize(dim);
            setFont(list.getFont());
            if (isSelected) {
                setBackground(list.getSelectionBackground());
                setForeground(list.getSelectionForeground());
            } else {
                setBackground(list.getBackground());
                setForeground(list.getForeground());
            }
            return this;
        }
    }
}
```

*s28.postimg.org/yd5mqvukp/List_Demo.jpg

*JProgressBar*

Sometimes a task running within a program might take a while to complete. A user-friendly program provides some indication to the user that the task is occurring,
how long the task might take, and how much work has already been done. One way of indicating work, and perhaps the amount of progress, is to use an animated image.
Sometimes you can't immediately determine the length of a long-running task, or the task might stay stuck at the same state of completion for a long time. You can show work 
without measurable progress by putting the progress bar in indeterminate mode. A progress bar in indeterminate mode displays animation to indicate that work is occurring. 
As soon as the progress bar can display more meaningful information, you should switch it back into its default, determinate mode.

The following demo shows the Images loading progress using a ProgressBar.

ProgressBarDemo.java


```
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 7/24/14
 * Time: 1:27 PM
 * To change this template use File | Settings | File Templates.
 */
public class ProgressBarDemo extends JFrame implements Runnable {

    private String path = "Images/";
    private JLabel label = new JLabel();
    private JProgressBar progressBar = new JProgressBar(0, 100);
    private String []imgName;
    private JPanel bottom = new JPanel();
    private Thread thread = null;
    private int MAX;

    public ProgressBarDemo() {
        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }  catch (Exception e) {
            // Do nothing
        }
        label.setHorizontalAlignment(SwingConstants.CENTER);
        label.setVerticalAlignment(SwingConstants.CENTER);
        progressBar.updateUI();
        progressBar.setPreferredSize(new Dimension(250, 32));
        //Filter out the Images
        File directory = new File(path);
        if(!directory.exists()) {
            System.out.println("The specified directory doesn't exist!!");
            System.exit(-1);
        }
        imgName = directory.list(new FilenameFilter() {
            String []readFormat = ImageIO.getReaderFormatNames();
            @Override
            public boolean accept(File dir, String name) {
                for (int i = 0; i < readFormat.length; i++) {
                    if(name.endsWith(readFormat[i]))
                        return true;
                }
                return false;
            }
        });
        MAX = imgName.length;
        if(MAX == 0) {
            System.out.println("No Images found!!! , Exiting!!!");
            System.exit(-1);
        }
        else
        {
            bottom.setLayout(new FlowLayout(FlowLayout.CENTER));
            bottom.add(new JLabel("Loading Images, Please wait..."));
            bottom.add(progressBar);

            add(label, BorderLayout.CENTER);

            add(bottom, BorderLayout.SOUTH);
            setSize(Toolkit.getDefaultToolkit().getScreenSize());
            setTitle("ProgressBarDemo");
            setVisible(true);
            start();
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        }
    }

    public Image getImage(String fileName) {
        try
        {
            return ImageIO.read(new File(fileName));
        }  catch (IOException ioe) {
            System.err.println("Error loading Image : " + fileName);
        }
        return null;
    }

    public void loadImages() {
        int count = 0;
        setCursor(new Cursor(Cursor.WAIT_CURSOR));
        for (int i = 0; i < MAX; i++) {
            count =  (i*100)/(MAX -1);
            progressBar.setValue(count);
            label.setIcon(new ImageIcon(getImage(path + imgName[i])));
        }
        setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
        remove(bottom);
        validate();
    }

    public void start() {
        if(thread == null) {
            thread = new Thread(this);
            thread.setPriority(Thread.MAX_PRIORITY);
            thread.start();
        }
    }

    @Override
    public void run() {
        loadImages();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ProgressBarDemo();
            }
        });
    }
}
```

*s29.postimg.org/z6dn5v643/Progress_Bar_Demo.jpg

*ProgressMonitor*

Now let's rewrite ProgressBarDemo to use a progress monitor instead of a progress bar.
By default, a progress monitor waits a minium of 500 milliseconds before deciding whether to pop up the dialog.
It also waits for the progress to become more than the minimum value. If it calculates that the task will take more 
than 2000 milliseconds to complete, the progress dialog appears. To adjust the minimum waiting period, invoke setMillisToDecidedToPopup.
To adjust the minimum progress time required for a dialog to appear, invoke setMillisToPopup.


```
/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 7/24/14
 * Time: 2:34 PM
 * To change this template use File | Settings | File Templates.
 */
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 7/24/14
 * Time: 1:27 PM
 * To change this template use File | Settings | File Templates.
 */
public class ProgressMonitorDemo extends JFrame implements Runnable {

    private String path = "Images/";
    private JLabel label = new JLabel();
    private ProgressMonitor progressMonitor = new ProgressMonitor(null, "Loading Images, Please wait...", "", 0, 100);
    private String []imgName;
    private Thread thread = null;
    private int MAX;

    public ProgressMonitorDemo() {
        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }  catch (Exception e) {
            // Do nothing
        }
        label.setHorizontalAlignment(SwingConstants.CENTER);
        label.setVerticalAlignment(SwingConstants.CENTER);

        //Filter out the Images
        File directory = new File(path);
        if(!directory.exists()) {
            System.out.println("The specified directory doesn't exist!!");
            System.exit(-1);
        }
        imgName = directory.list(new FilenameFilter() {
            String []readFormat = ImageIO.getReaderFormatNames();
            @Override
            public boolean accept(File dir, String name) {
                for (int i = 0; i < readFormat.length; i++) {
                    if(name.endsWith(readFormat[i]))
                        return true;
                }
                return false;
            }
        });
        MAX = imgName.length;
        if(MAX == 0) {
            System.out.println("No Images found!!! , Exiting!!!");
            System.exit(-1);
        }
        else
        {
            add(label, BorderLayout.CENTER);
            setSize(Toolkit.getDefaultToolkit().getScreenSize());
            setTitle("ProgressMonitorDemo");
            setVisible(true);
            start();
            setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        }
    }

    public Image getImage(String fileName) {
        try
        {
            return ImageIO.read(new File(fileName));
        }  catch (IOException ioe) {
            System.err.println("Error loading Image : " + fileName);
        }
        return null;
    }

    public void loadImages() {
        int count = 0;
        setCursor(new Cursor(Cursor.WAIT_CURSOR));
        for (int i = 0; i < MAX; i++) {
            count =  (i*100)/(MAX -1);
            progressMonitor.setProgress(count);
            progressMonitor.setNote("" + count + "% done");
            //Display the Image
            label.setIcon(new ImageIcon(getImage(path + imgName[i])));
        }
        //Beep!!
        Toolkit.getDefaultToolkit().beep();
        setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
    }

    public void start() {
        if(thread == null) {
            thread = new Thread(this);
            thread.setPriority(Thread.MAX_PRIORITY);
            thread.start();
        }
    }

    @Override
    public void run() {
        loadImages();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ProgressMonitorDemo();
            }
        });
    }
}
```

*s29.postimg.org/582vnla5v/Progress_Monitor_Demo.jpg

*JSlider*

A JSlider component is intended to let the user easily enter a numeric value bounded by a minimum and maximum value. 
If space is limited, a spinner is a possible alternative to a slider.
By default, spacing for major and minor tick marks is zero. To see tick marks, you must explicitly set the spacing 
for either major or minor tick marks (or both) to a non-zero value and call the setPaintTicks(true) method. However,
you also need labels for your tick marks. To display standard, numeric labels at major tick mark locations, set the 
major tick spacing, then call the setPaintLabels(true) method.
When you move the slider's knob, the stateChanged method of the slider's ChangeListener is called.

In the following demo we use a Slider to rotate an Image clockwise!!.


```
/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 8/2/14
 * Time: 2:15 PM
 * To change this template use File | Settings | File Templates.
 */

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Sowndar
 */
public class SliderDemo extends JPanel {

    private BufferedImage buffImage;
    private String path = "Images/";
    private Font font = new Font("Serif", Font.BOLD, 20);
    private int imgWidth, imgHeight;
    private JSlider slider;
    private int value = 0;
    private static JPanel bottom;
    private final Dimension scrDim;
    private String fileName;
    private String []imgName;
    private int MAX;

    public SliderDemo() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
            System.err.println("Error loading System look'n feel!!");
        }
        File directory = new File(path);
        if(!directory.exists()) {
            System.err.println("The specified directory doesn't exist!!");
            System.exit(-1);
        }
        imgName = directory.list(new FilenameFilter() {
            String[] readFormat = ImageIO.getReaderFormatNames();

            @Override
            public boolean accept(File dir, String name) {
                for (int i = 0; i < readFormat.length; i++) {
                    if (name.endsWith(readFormat[i])) {
                        return true;
                    }
                }
                return false;
            }
        });
        MAX = imgName.length;
        if(MAX == 0) {
            System.err.println("OOps, No Images found!!");
            System.exit(-1);
        }
        bottom = new JPanel(new FlowLayout(FlowLayout.CENTER));
        int rand = (int) (MAX * Math.random());
        buffImage = getImage(path + imgName[rand]);
        slider = new JSlider(JSlider.HORIZONTAL, 0, 360, 0);
        slider.setMajorTickSpacing(25);
        slider.setMinorTickSpacing(5);
        slider.setPaintTicks(true);
        slider.setPaintLabels(true);
        slider.setPreferredSize(new Dimension(450, 45));
        slider.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                value = slider.getValue();
                repaint();
            }
        });

        bottom.add(new JLabel("Degrees : "));
        bottom.add(slider);
        setBackground(Color.green.darker());

        scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        if (buffImage != null) {
            imgWidth = buffImage.getWidth();
            imgHeight = buffImage.getHeight();
            // Resize bigger Images
            if (imgWidth > scrDim.width / 2 || imgHeight > scrDim.height) {

                buffImage = toBufferedImage(resizeImage(buffImage));
            }
        } else {
            System.exit(-1);
        }
        setPreferredSize(new Dimension(imgWidth + 450, scrDim.height - 100));
    }

    public Image resizeImage(Image image) {
        if (image != null) {

            double aspect = ((double) imgWidth) / ((double) imgHeight);
            int maxWidth, maxHeight;
            // If aspect ratio exceeds 1.3333
            if (aspect > 1.3333) {
                // Fix the width as maxWidth, calculate the maxHeight
                maxWidth = scrDim.width / 2;
                maxHeight = (int) (((double) maxWidth) / aspect);
            } else {
                // Fix the height as iconHeight, calculate the maxWidth for this
                maxHeight = scrDim.height - 50;
                maxWidth = (int) (((double) maxHeight) * aspect);
            }
            imgWidth = maxWidth;
            imgHeight = maxHeight;
            return image.getScaledInstance(maxWidth, maxHeight, Image.SCALE_SMOOTH);
        }
        return null;
    }

    public BufferedImage toBufferedImage(Image image) {
        if (image != null) {
            BufferedImage buff = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
            Graphics2D g2 = buff.createGraphics();
            g2.drawImage(image, 0, 0, null);
            g2.dispose();
            return buff;
        }
        return null;
    }

    public BufferedImage getImage(String fileName) {
        try {
            return ImageIO.read(new File(fileName));
        } catch (IOException ioe) {
            System.err.println("Error loading Image!!");
            System.exit(-1);
        }
        return null;
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);

        g2d.setFont(font);
        g2d.setColor(Color.black);

        AffineTransform tx = new AffineTransform();
        // Set the angle to rotate
        // + degrees means clockwise, - degrees means anti-clockwise
        tx.rotate(Math.toRadians(value), imgWidth / 2, imgHeight / 2);

        AffineTransformOp transformOp = new AffineTransformOp(tx, AffineTransformOp.TYPE_BICUBIC);
        // Transforms the source BufferedImage
        // Center the Image on the screen
        int X = (getWidth() - imgWidth) / 2;
        int Y = (getHeight() - imgHeight) / 2;

        // Draw the transformed Image
        g2d.drawImage(transformOp.filter(buffImage, null), X, Y, this);
        g2d.setColor(Color.yellow);
        g2d.drawString("Rotate : " + value + " degrees", 15, 15);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("SliderDemo");
                frame.add(new SliderDemo());
                frame.add(bottom, BorderLayout.SOUTH);
                frame.pack();
                frame.setVisible(true);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            }
        });
    }
}
```

*s28.postimg.org/cveccyyyx/Slider_Demo.jpg

[img=*s17.postimg.org/60vf27b8b/Slider_Demo.jpg]

Write a program to zoom the Image using the Slider :
[img=*s2.postimg.org/g1azq70dx/Zooming_Slider.jpg]

The following program shows how you can use a Slider to control the speed (frames/sec) of the animation.
You can move the slider to 'Slow', "Slightly Fast', or 'Normal'. Watch as the frame drops/increases.


```
/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 8/2/14 Time: 2:51 PM To
 *
 * change this template use File | Settings | File Templates.
 */

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Hashtable;

public class SliderDemo2 extends JFrame implements Runnable {

    private String path = "resources/";
    // Initial Frame no.
    private int frameNumber = -1;
    private JLabel label = new JLabel();
    // Size of the Image displayed
    private Dimension dim = new Dimension(352 * 2, 288 * 2);
    private Image image = null;
    // Total no of frames
    private int totalFrames = 0;
    // 32 for BMP, 22 for PNG format
    private int sleepTime = 34;
    private int min = 0, max = 100, value = sleepTime;
    private JSlider slider = new JSlider(min, max, value);
    private boolean frozen = false;
    private File file = new File(path);
    private String[] readFormat = ImageIO.getReaderFormatNames();
    private Thread thread = null;
    // For example if your filename is SM1.jpg, then filePrefix is 'SM'
    private String filePrefix = "SM";
    // Extension is the file extension jpg, bmp, png, gif etc.,
    private String fileExtension = "jpg";

    public String[] getImages(String path) {
        String name[] = new File(path).list(new FilenameFilter() {

            @Override
            public boolean accept(File dir, String name) {
                for (String readFormat1 : readFormat) {
                    if (name.endsWith(readFormat1)) {
                        return true;
                    }
                }
                return false;
            }
        });
        totalFrames = name.length - 1;
        return name;
    }

    public SliderDemo2() {
        if (!file.exists()) {
            System.out.println("The specified path : " + path + " doesn't exist!!!");
            System.exit(1);
        }
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | UnsupportedLookAndFeelException e) {
            // Do nothing
        }
        slider.updateUI();
        label.setHorizontalAlignment(SwingConstants.CENTER);
        label.setVerticalAlignment(SwingConstants.CENTER);
        getImages(path);
        add(label, BorderLayout.CENTER);

        add(slider, BorderLayout.EAST);
        slider.setMajorTickSpacing(10);
        slider.setMinorTickSpacing(10);

        slider.setPaintTicks(true);
        slider.setOrientation(JSlider.VERTICAL);
        slider.setToolTipText("" + value + " fps");
        //Create the label table.

        Hashtable<Integer, JLabel> labelTable = new Hashtable<>();

        labelTable.put(new Integer(sleepTime + 40), new JLabel("Slower"));

        labelTable.put(new Integer(sleepTime + 20), new JLabel("Slow"));

        labelTable.put(new Integer(sleepTime), new JLabel("Normal"));

        labelTable.put(new Integer(sleepTime - 20), new JLabel("Slightly Fast"));

        labelTable.put(new Integer(sleepTime - 40), new JLabel("Moderate Fast"));

        labelTable.put(new Integer(sleepTime - 60), new JLabel("Very Fast"));

        slider.setPaintLabels(true);
        slider.setLabelTable(labelTable);
        slider.addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                sleepTime = slider.getValue();
                slider.setToolTipText("" + sleepTime + " fps");
            }
        });
        // Start the Thread
        start();
        //Frame's properties
        setTitle("SliderDemo - Animation");
        setSize(dim.width + 40, dim.height);
        setLocationRelativeTo(null);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public void start() {
        if (thread == null) {
            thread = new Thread(this);
            thread.start();
        }
    }

    @Override
    public void run() {
        while (true) // put it in infinite loop
        {
            if (frameNumber == totalFrames) {
                // We have reached the end, start from the beginning again
                frameNumber = 0;
            }
            frameNumber++;
            // totalFrames - > 100
            // currentFrame -> (currentFrame*100)/totalFrames
            setTitle("SliderDemo2 - Animation " + (frameNumber * 100) / totalFrames + "% Done");
            String str = path + filePrefix + frameNumber + "." + fileExtension;
            image = getImage(str);
            if (image != null) {
                image.setAccelerationPriority(0.9f);
                label.setIcon(new ImageIcon(image.getScaledInstance(dim.width, dim.height, Image.SCALE_DEFAULT)));
                sleep(sleepTime);
            }
        }
    }

    public Image getImage(String fileName) {
        try {
            return ImageIO.read(new File(fileName));
        } catch (IOException ioe) {
            System.err.println("Error loading Image : " + fileName);
        }
        return null;
    }

    public void print(String msg) {
        System.out.println(msg);
    }

    public void sleep(long ms) {   //     millis - the length of time to sleep in milliseconds.
        //nanos - 0-999999 additional nanoseconds to sleep.
        // sleep(millis, nanos)
        // This synchronizes the Audio with the Video
        try {
            Thread.sleep(ms, 700);
        } catch (InterruptedException ie) {
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new SliderDemo2();
            }
        });
    }
}
```

*s21.postimg.org/l992pe7kj/Slider_Demo2.jpg

*JSplitPane*

A JSplitPane displays two components, either side by side or one on top of the other. By dragging the divider that
appears between the components, the user can specify how much of the split pane's total area goes to each component.
You can divide screen space among three or more components by putting split panes inside of split panes.

In the following demo we load two random Images & show them using a SplitPane.
By the way, the splitpane can also be nested!!


```
/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 8/2/14
 * Time: 2:23 PM
 * To change this template use File | Settings | File Templates.
 */
// Split Pane demo

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.EtchedBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;

class SplitPaneDemo extends JFrame {

    private JSplitPane splitPane = null;
    private JLabel label1 = null;
    private JLabel label2 = null;
    private Dimension scrDim;
    private String path = "Images/";
    private String []imgName;
    private int MAX;

    // SplitPane Constructor
    SplitPaneDemo(String fName) {
        super(fName);
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | UnsupportedLookAndFeelException e) {
            System.err.println("Error loading System look'n feel!!");
        }
        File directory = new File(path);
        if(!directory.exists()) {
            System.out.println("The specified directory doesn't exist!!");
            System.exit(-1);
        }
        //Filter out the Images
        imgName = directory.list(new FilenameFilter() {
            String []readFormat = ImageIO.getReaderFormatNames();
            @Override
            public boolean accept(File dir, String name) {
                for (int i = 0; i < readFormat.length; i++) {
                    if(name.endsWith(readFormat[i]))
                        return true;
                }
                return false;
            }
        });
        MAX = imgName.length;
        if(MAX == 0) {
            System.out.println("No Images found!!! , Exiting!!!");
            System.exit(-1);
        }

        label1 = new JLabel();
        //Get a random number
        int rand = getRandom();
        label1.setIcon(new ImageIcon(getImage(path + imgName[rand])));
        label1.setMinimumSize(new Dimension(20, 20));

        label2 = new JLabel();
        int rand2 = getRandom();
        if(rand2 == rand) {
            rand2 = getRandom();
        }
        label2.setIcon(new ImageIcon(getImage(path + imgName[rand2])));
        label2.setMinimumSize(new Dimension(20, 20));

        splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, label1, label2);
        splitPane.setContinuousLayout(true);
        splitPane.setOneTouchExpandable(true);
        splitPane.setResizeWeight(1);
        splitPane.setDividerSize(7);
        scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        splitPane.setDividerLocation(scrDim.width / 2);

        add(splitPane, BorderLayout.CENTER);
        setBackground(Color.black);
        add(createSplitPaneControls(), BorderLayout.SOUTH);
        setSize(Toolkit.getDefaultToolkit().getScreenSize());
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    public BufferedImage getImage(String fileName) {
        try {
            return ImageIO.read(new File(fileName));
        } catch (IOException ioe) {
            System.err.println("Error loading Image!!");
        }
        return null;
    }

    public int getRandom() {
        return (int) (MAX * Math.random());
    }

    // Creates controls to alter the JSplitPane.
    protected JPanel createSplitPaneControls() {
        JPanel wrapper = new JPanel();
        ButtonGroup group = new ButtonGroup();
        JRadioButton button;
        Box buttonWrapper = new Box(BoxLayout.X_AXIS);
        wrapper.setLayout(new GridLayout(0, 1));
        wrapper.setBorder(new EtchedBorder());

        // Create a radio button to vertically split the split pane.
        button = new JRadioButton("Vertically Split");
        button.setMnemonic('V');
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
                splitPane.setDividerLocation(scrDim.height / 2);
            }
        });
        group.add(button);
        buttonWrapper.add(button);

        // Create a radio button the horizontally split the split pane.
        button = new JRadioButton("Horizontally Split");
        button.setMnemonic('H');
        button.setSelected(true);
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                splitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
                splitPane.setDividerLocation(scrDim.width / 2);
            }
        });
        group.add(button);
        buttonWrapper.add(button);

        // Create a check box as to whether or not the split pane continually lays out the component when dragging.
        JCheckBox checkBox = new JCheckBox("Continous Layout");
        checkBox.setMnemonic('C');
        checkBox.setSelected(true);

        checkBox.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                splitPane.setContinuousLayout(
                        ((JCheckBox) e.getSource()).isSelected());
            }
        });
        buttonWrapper.add(checkBox);

        // Create a check box as to whether or not the split pane divider contains the oneTouchExpandable buttons.
        checkBox = new JCheckBox("One-Touch expandable");
        checkBox.setMnemonic('O');
        checkBox.setSelected(true);

        checkBox.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                splitPane.setOneTouchExpandable(
                        ((JCheckBox) e.getSource()).isSelected());
            }
        });
        buttonWrapper.add(checkBox);
        wrapper.add(buttonWrapper);
        return wrapper;
    }

    public static void main(String[] arg) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new SplitPaneDemo("SplitPaneDemo");
            }
        });
    }
}
```

*s27.postimg.org/pt196h4vj/Split_Pane_Demo.jpg

You can also nest a SplitPane *s29.postimg.org/6yw26ugtv/Split_Pane_Demo2.jpg


*JTabbedPane*

With the JTabbedPane class, you can have several components, such as panels, share the same space. The user chooses which 
component to view by selecting the tab corresponding to the desired component. If you want similar functionality without the 
tab interface, you can use a card layout instead of a tabbed pane.

In this demo we load the Images, show them in tabs, also we show the animated Images moving in different directions.


```
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Random;

/**
 * JTabbedPane Demo
 *
 * @version 1.11 11/17/05
 * @author JGuru
 */
public class TabbedPaneDemo extends JPanel implements ActionListener {

    private final HeadSpin spin;
    private final JTabbedPane tabbedpane;
    private final ButtonGroup group;
    private final JRadioButton top;
    private final JRadioButton bottom;
    private final JRadioButton left;
    private final JRadioButton right;
    private static Dimension scrDim;
    private int maxWidth, maxHeight;
    private int MAX;
    private String path = "Images/";
    private String[] imgName;
    private ImageIcon[] icon;

    /**
     * TabbedPaneDemo Constructor
     */
    public TabbedPaneDemo() {

        File directory = new File(path);
        if(!directory.exists()) {
            System.err.println("The specified directory doesn't exist!!");
            System.exit(-1);
        }
        try {
            for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | UnsupportedLookAndFeelException e) {
            // Do nothing
        }
        scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        imgName = new File(path).list(new FilenameFilter() {
            String[] readFormat = ImageIO.getReaderFormatNames();

            @Override
            public boolean accept(File dir, String name) {
                for (int i = 0; i < readFormat.length; i++) {
                    if (name.endsWith(readFormat[i])) {
                        return true;
                    }
                }
                return false;
            }
        });
        MAX = imgName.length;

        if(MAX == 0) {
            System.err.println("Sorry , No Images found!!");
            System.exit(-1);
        }
        //Limit the maximum Images to 14
        if(MAX > 14) {
            MAX = 14;
        }
        setLayout(new BorderLayout());
        // create tab position controls
        JPanel tabControls = new JPanel();
        tabControls.add(new JLabel("Tab Placement"));
        top = (JRadioButton) tabControls.add(new JRadioButton("Top"));
        left = (JRadioButton) tabControls.add(new JRadioButton("Left"));
        bottom = (JRadioButton) tabControls.add(new JRadioButton("Bottom"));
        right = (JRadioButton) tabControls.add(new JRadioButton("Right"));
        add(tabControls, BorderLayout.NORTH);

        group = new ButtonGroup();
        group.add(top);
        group.add(bottom);
        group.add(left);
        group.add(right);

        top.setSelected(true);

        top.addActionListener(this);
        bottom.addActionListener(this);
        left.addActionListener(this);
        right.addActionListener(this);

        // create tab
        tabbedpane = new JTabbedPane();
        add(tabbedpane, BorderLayout.CENTER);

        String name = "";

        JLabel pix;
        icon = new ImageIcon[MAX];
        String tooltip = "";
        // Load all the Images
        for (int i = 0; i < MAX; i++) {
            name = imgName[i];
            icon[i] = createImageIcon(path + name, name);
            pix = new JLabel(icon[i]);
            tooltip = name.substring(name.lastIndexOf(".")+1).toUpperCase() + " Image";
            tabbedpane.addTab(name.substring(0, name.lastIndexOf(".")), getIcon(icon[i]), new JScrollPane(pix), tooltip);
        }
        name = "<html><font color=blue><bold><center>Bouncing Images!</center></bold></font></html>";
        spin = new HeadSpin();
        tabbedpane.add(name, spin);

        tabbedpane.getModel().addChangeListener(
                new ChangeListener() {
                    @Override
                    public void stateChanged(ChangeEvent e) {
                        SingleSelectionModel model = (SingleSelectionModel) e.getSource();
                        if (model.getSelectedIndex() == tabbedpane.getTabCount() - 1) {
                            spin.go();
                        }
                    }
                }
        );
    }

    public ImageIcon getIcon(ImageIcon icon) {

        if (icon != null) {
            return new ImageIcon(icon.getImage().getScaledInstance(32, 32, Image.SCALE_SMOOTH));
        }
        return null;
    }

    public ImageIcon createImageIcon(String filename, String description) {
        if (filename.endsWith("jpg") || filename.endsWith("png")) {
            return new ImageIcon(filename, description);
        }
        try {
            return new ImageIcon(ImageIO.read(new File(filename)));
        } catch (IOException ioe) {
        }
        return null;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();
        if (source == top) {
            tabbedpane.setTabPlacement(JTabbedPane.TOP);
        } else if (source == left) {
            tabbedpane.setTabPlacement(JTabbedPane.LEFT);
        } else if (source == bottom) {
            tabbedpane.setTabPlacement(JTabbedPane.BOTTOM);
        } else if (source == right) {
            tabbedpane.setTabPlacement(JTabbedPane.RIGHT);
        }
    }

    private class HeadSpin extends JComponent implements ActionListener {

        private Timer animator;
        private final int numImages = MAX;
        private final double[] x = new double[numImages];
        private final double[] y = new double[numImages];
        private final int[] xh = new int[numImages];
        private final int[] yh = new int[numImages];
        private final double[] scale = new double[numImages];
        private final Random rand = new Random();

        public HeadSpin() {
            setBackground(Color.black);
        }

        public void go() {
            animator = new Timer(22 + 22 + 22, this);
            animator.start();
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.setColor(getBackground());
            g.fillRect(0, 0, getWidth(), getHeight());

            for (int i = 0; i < numImages; i++) {
                if (x[i] > 3 * i) {
                    nudge(i);
                    squish(g, icon[i], xh[i], yh[i], scale[i]);
                } else {
                    x[i] += .05;
                    y[i] += .05;
                }
            }
        }

        public void nudge(int i) {
            x[i] += (double) rand.nextInt(1000) / 8756;
            y[i] += (double) rand.nextInt(1000) / 5432;
            int tmpScale = (int) (Math.abs(Math.sin(x[i])) * 10);
            scale[i] = (double) tmpScale / 10;
            int nudgeX = (int) (((double) getWidth() / 2) * .8);
            int nudgeY = (int) (((double) getHeight() / 2) * .60);
            xh[i] = (int) (Math.sin(x[i]) * nudgeX) + nudgeX;
            yh[i] = (int) (Math.sin(y[i]) * nudgeY) + nudgeY;
        }

        public void squish(Graphics g, ImageIcon icon, int x, int y, double scale) {
            if (isVisible()) {
                g.drawImage(icon.getImage(), x, y,
                        (int) (icon.getIconWidth() * scale),
                        (int) (icon.getIconHeight() * scale),
                        this);
            }
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            if (isVisible()) {
                repaint();
            } else {
                animator.stop();
            }
        }
    }

    /**
     * main method allows us to run as a standalone demo.
     *
     * [MENTION=9956]PARAM[/MENTION] args
     */
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("TabbedPaneDemo");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TabbedPaneDemo());
                frame.setSize(new Dimension(scrDim.width / 2 + 190, scrDim.height));
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}
```

*s21.postimg.org/o1b6icgk3/Tabbed_Pane_Demo.jpg


*JTextArea*

The JTextArea class provides a component that displays multiple lines of text and optionally allows the user to edit the text.
If you need to obtain only one line of input from the user, you should use a text field. If you want the text area to display 
its text using multiple fonts or other styles, you should use an editor pane or text pane.
Text areas are editable by default. The code setEditable(false) makes the text area uneditable. It is still selectable and the 
user can copy data from it, but the user cannot change the text area's contents directly.
You can customize text areas in several ways. For example, although a given text area can display text in only one font and color,
you can set which font and color it uses. This customization option can be performed on any component. You can also determine how the 
text area wraps lines and the number of characters per tab. Finally, you can use the methods that the JTextArea class inherits from the
JTextComponent class to set properties such as the caret, support for dragging, or color selection.

The following demo shows a text editor that can open, save, print a text document.


```
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import javax.swing.plaf.basic.BasicFileChooserUI;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.print.PrinterException;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 8/1/14
 * Time: 10:07 PM
 * To change this template use File | Settings | File Templates.
 */
public class TextAreaDemo extends JFrame implements ActionListener {

    private JMenuBar mBar = new JMenuBar();
    private JMenuItem open = new JMenuItem("Open", new ImageIcon("Icons/open.gif"));
    private JMenuItem save = new JMenuItem("Save", new ImageIcon("Icons/save.gif"));
    private JMenuItem saveAs = new JMenuItem("Save As", new ImageIcon("Icons/save As.png"));
    private JMenuItem print = new JMenuItem("Print", new ImageIcon("Icons/print.gif"));
    private JMenuItem exit = new JMenuItem("Exit", new ImageIcon("Icons/Close.png"));
    private JMenu menu = new JMenu("File");
    private JFileChooser fileChooser = new JFileChooser(".");
    private JTextArea textArea = new JTextArea();
    private String []textFiles = {"c", "cpp", "java", "html", "xml", "bat", "txt"};
    private String fileName;

    public void updateUI() {
        fileChooser.updateUI();
        mBar.updateUI();
        open.updateUI();
        save.updateUI();
        saveAs.updateUI();
        print.updateUI();
        menu.updateUI();
        exit.updateUI();
    }

    public TextAreaDemo() {
        // Set the look'n feel
        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            // Do nothing
        }
        updateUI();
        textArea.setFont(new Font("Serif", Font.BOLD, 14));
        //Add the menuitems to the Menu
        menu.add(open);
        menu.add(save);
        menu.add(saveAs);
        menu.add(print);
        menu.add(exit);
        mBar.add(menu);
        setJMenuBar(mBar);

        fileChooser.setAcceptAllFileFilterUsed(false);
        //Set the filter
        fileChooser.addChoosableFileFilter(new FileFilter() {
            @Override
            public boolean accept(File f) {
                for (int i = 0; i < textFiles.length; i++) {
                    if(f.isDirectory() || f.getName().endsWith(textFiles[i]))
                        return true;
                }
                return false;
            }

            @Override
            public String getDescription() {
                return "Text Files";
            }
        });

        //Add the action listener
        open.addActionListener(this);
        save.addActionListener(this);
        saveAs.addActionListener(this);
        print.addActionListener(this);
        exit.addActionListener(this);
        add(new JScrollPane(textArea));
        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        setSize(scrDim.width/2, scrDim.height);
        setTitle("TextAreaDemo");
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TextAreaDemo();
            }
        });
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        Object source = ae.getSource();
        if(source == open) {
            openFile();
        }
        else if(source == save) {
            saveFile();
        }
        else if(source == saveAs) {
            saveAs();
        }
        else if(source == print) {
            try {
                textArea.print();
            } catch (PrinterException e) {
                JOptionPane.showMessageDialog(null, "Oops, Can't print!!", "Error", JOptionPane.ERROR_MESSAGE);
            }
        }
        else
        {
            System.exit(0);
        }
    }

    public String getFileName(String fullPath) {
        String fSeparator = System.getProperty("file.separator");
        String fName = fullPath;
        int sIndex = fName.lastIndexOf(fSeparator);
        if (sIndex != -1) {
            fName = fName.substring(sIndex + 1);
            return fName;
        }
        return null;
    }

    // Save the file under a different name
    private void saveAs() {

        // Show a File save dialog
        fileChooser.setDialogTitle("Save As");
        int result = fileChooser.showSaveDialog(null);
        if (result != 0) {
            return;
        }
        File file = fileChooser.getSelectedFile();
        if (file == null) {
            return;
        }
        fileName = file.toString();
        BasicFileChooserUI ui = (BasicFileChooserUI) fileChooser.getUI();
        ui.setFileName(getFileName(fileName));
        if (file.exists()) {
            // Dialog, Want to overwrite ?, Yes, NO option
            final JOptionPane optionPane = new JOptionPane(
                    "Do you want to overwrite " + getFileName(fileName) + " ?",
                    JOptionPane.QUESTION_MESSAGE,
                    JOptionPane.YES_NO_OPTION);

            final JDialog dialog = new JDialog(new Frame(), "Confirm", true);
            dialog.setContentPane(optionPane);
            dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);

            optionPane.addPropertyChangeListener(new PropertyChangeListener() {

                @Override
                public void propertyChange(PropertyChangeEvent e) {
                    String prop = e.getPropertyName();

                    if (dialog.isVisible() && (e.getSource() == optionPane) && (prop.equals(JOptionPane.VALUE_PROPERTY))) {
                        //If you were going to check something
                        //before closing the window, you'd do
                        //it here.
                        dialog.setVisible(false);
                    }
                }
            });
            dialog.pack();
            dialog.setLocationRelativeTo(null);
            dialog.setVisible(true);

            int value = ((Integer) optionPane.getValue()).intValue();
            if (value == JOptionPane.YES_OPTION) {
                saveFile();
            } else if (value == JOptionPane.NO_OPTION) {
                // Show saveAs dialog , for entering a new name
                saveAs();
            }

        } else {
            // Now save the file
            saveFile();
        }
    }

    //Save the file to the disk
    private void saveFile() {
        //
        if (fileName == null) {
            return;
        }

        FileWriter writer = null;
        try {
            writer = new FileWriter(fileName);
            textArea.write(writer);
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(TextAreaDemo.this,
                    "File Not Saved", "ERROR", JOptionPane.ERROR_MESSAGE);
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException x) {
                }
            }
        }
    }
    // Open the file using the FileChooser
    private void openFile() {
        fileChooser.setDialogTitle("Open");

        int result = fileChooser.showOpenDialog(null);
        if (result != 0) {
            return;
        }
        File file = fileChooser.getSelectedFile();
        if (file == null) {
            return;
        } else {
            fileName = file.toString();
            if (fileName == null) {
                return;
            }
            else
            {
                FileReader reader = null;

                try {
                    reader = new FileReader(fileName);
                    textArea.read(reader, null);

                } catch (IOException ex) {
                    JOptionPane.showMessageDialog(TextAreaDemo.this,
                            "File Not Found", "ERROR", JOptionPane.ERROR_MESSAGE);
                } finally {
                    if (reader != null) {
                        try {
                            reader.close();
                        } catch (IOException x) {
                        }
                    }
                }
            }
        }
    }
}
```

*s17.postimg.org/6wmukjel7/Text_Area_Demo.jpg

*JTextField*

A text field is a basic text control that enables the user to type a small amount of text. When the user indicates that text entry 
is complete (usually by pressing Enter), the text field fires an action event.

The following program shows how to implement a incremental search (searches a Document until EOF).
Clicking on the search button looks for the next occurrence of a word, highlights the word (if found).


```
/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 8/2/14
 * Time: 12:28 PM
 * To change this template use File | Settings | File Templates.
 */

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/*
 * The program continues to search (incremental search) the text entered by the user
 * if the user the user presses the enter key, it searches the next
 * occurence of the input text.
 * This program uses Regular expression for pattern matching
 * NOTE: This program doesn't look for exact match, rather half-match
 * If you search for "me", it will find -  moment, some, seemed, time, disappointment, underneath etc.,
 */
public class TextFieldDemo extends JFrame implements DocumentListener, ActionListener {

    private JTextComponent content;
    private Matcher matcher;
    private JLabel statusBar;
    private String searchWord = "";
    private JPanel top = new JPanel(new FlowLayout(FlowLayout.CENTER));
    private JTextField search_field;
    private JButton search;
    private JTextArea textArea;
    private Font font = new Font("Serif", Font.BOLD, 14);

    public TextFieldDemo() {
        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            // Do nothing
        }
        textArea = new JTextArea(10, 20);
        textArea.setFont(font);
        textArea.setBackground(Color.black);
        textArea.setForeground(Color.green);
        textArea.setSelectionColor(Color.red);
        content = textArea;
        statusBar = new JLabel("Ready", JLabel.LEFT);
        statusBar.setFont(font);
        search_field = new JTextField(20);
        search_field.setFont(font);
        search = new JButton("Search", new ImageIcon("resources/find.png"));
        search.setPreferredSize(new Dimension(100, 30));
        search.addActionListener(this);
        // Get the file
        getFile("resources/content.txt");
        JScrollPane scroll = new JScrollPane(textArea);
        JLabel label = new JLabel("Enter Search String : ");
        label.setFont(font);
        top.add(label);
        top.add(search_field);
        top.add(search);
        search_field.getDocument().addDocumentListener(this);
        search_field.addActionListener(this);
        // Add the Components
        add("North", top);
        add("Center", scroll);
        add("South", statusBar);
        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        setSize(scrDim.width / 2, scrDim.height / 2 + 150);
        setLocationRelativeTo(null);
        setTitle("TextFieldDemo");
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public void getFile(String fileName) {
        // Read from the File
        File file = new File(fileName);
        FileReader reader = null;
        try {
            reader = new FileReader(file);
            textArea.read(reader, null);
        } catch (IOException ex) {
            System.err.println("The specified file doesn't exist!!");
            System.exit(-1);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException x) {
                }
            }
        }
    }

    /* DocumentListener implementation */
    @Override
    public void insertUpdate(DocumentEvent evt) {
        runNewSearch(evt.getDocument());
    }

    @Override
    public void removeUpdate(DocumentEvent evt) {
        runNewSearch(evt.getDocument());
    }

    @Override
    public void changedUpdate(DocumentEvent evt) {
        runNewSearch(evt.getDocument());
    }

    /* ActionListener implementation */
    @Override
    public void actionPerformed(ActionEvent evt) {

        continueSearch();
    }

    private void runNewSearch(Document query_doc) {
        try {
            String query = query_doc.getText(0, query_doc.getLength());
            searchWord = query;
            Pattern pattern = Pattern.compile(query);
            Document content_doc = content.getDocument();
            String body = content_doc.getText(0, content_doc.getLength());
            matcher = pattern.matcher(body);
            continueSearch();
        } catch (BadLocationException ex) {
            print("Exception: " + ex);
        }
    }

    private void continueSearch() {
        if (matcher != null) {
            if (matcher.find()) {
                content.getCaret().setDot(matcher.start());
                // Update the statusbar also
                statusBar.setText("Found \"" + searchWord + "\" at " + matcher.start());
                content.getCaret().moveDot(matcher.end());
                content.getCaret().setSelectionVisible(true);
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                new TextFieldDemo();
            }
        });
    }

    public static void print(String str) {
        System.out.println(str);
    }
}
```

*s11.postimg.org/s8l0m4o6n/Text_Field_Demo.jpg

Here is the text for content.txt 


```
ALICE'S ADVENTURES IN WONDERLAND
by Lewis Carroll

CHAPTER I
DOWN THE RABBIT-HOLE
ALICE was beginning to get very tired of sitting by her sister on the bank and of having nothing to do: once or twice she had peeped into the book her sister was reading, but it had no pictures or conversations in it, "and what is the use of a book," thought Alice, "without pictures or conversations?"

So she was considering, in her own mind (as well as she could, for the hot day made her feel very sleepy and stupid), whether the pleasure of making a daisy-chain would be worth the trouble of getting up and picking the daisies, when suddenly a White Rabbit with pink eyes ran close by her.

There was nothing so very remarkable in that; nor did Alice think it so very much out of the way to hear the Rabbit say to itself "Oh dear! Oh dear! I shall be too late!" (when she thought it over afterwards it occurred to her that she ought to have wondered at this, but at the time it all seemed quite natural); but, when the Rabbit actually took a watch out of its waistcoat-pocket, and looked at it, and then hurried on, Alice started to her feet, for it flashed across her mind that she had never before seen a rabbit with either a waistcoat-pocket, or a watch to take out of it, and burning with curiosity, she ran across the field after it, and was just in time to see it pop down a large rabbit-hole under the hedge.

In another moment down went Alice after it, never once considering how in the world she was to get out again.

The rabbit-hole went straight on like a tunnel for some way, and then dipped suddenly down, so suddenly that Alice had not a moment to think about stopping herself before she found herself falling down what seemed to be a very deep well.

Either the well was very deep, or she fell very slowly, for she had plenty of time as she went down to look about her, and to wonder what was going to happen next. First, she tried to look down and make out what she was coming to, but it was too dark to see anything: then she looked at the sides of the well, and noticed that they were filled with cupboards and book-shelves: here and there she saw maps and pictures hung upon pegs. She took down ajar from one of the shelves as she passed: it was labeled "ORANGE MARMALADE" but to her great disappointment it was empty: she did not like to drop the jar, for fear of killing somebody underneath, so managed to put it into one of the cupboards as she fell past it.

"Well!" thought Alice to herself "After such a fall as this, I shall think nothing of tumbling down-stairs! How brave they'll all think me at home! Why, I wouldn't say anything about it, even if I fell off the top of the house!" (which was very likely true.)

Down, down, down. Would the fall never come to an end? "I wonder how many miles I've fallen by this time?" she said aloud. "I must be getting somewhere near the centre of the earth. Let me see: that would be four thousand miles down, I think-" (for, you see, Alice had learnt several things of this sort in her lessons in the school-room, and though this was not a very good opportunity for showing off her knowledge, as there was no one to listen to her, still it was good practice to say it over) "-- yes that's about the right distance -- but then I wonder what Latitude or Longitude I've got to?" (Alice had not the slightest idea what Latitude was, or Longitude either, but she thought they were nice grand words to say.)

Presently she began again. "I wonder if I shall fall fight through the earth! How funny it'll seem to come out among the people that walk with their heads downwards! The antipathies, I think-" (she was rather glad there was no one listening, this time, as it didn't sound at all the right word) "-but I shall have to ask them what the name of the country is, you know. Please, Ma'am, is this New Zealand? Or Australia?" (and she tried to curtsey as she spoke- fancy, curtseying as you're falling through the air! Do you think you could manage it?) "And what an ignorant little girl she'll think me for asking! No, it'll never do to ask: perhaps I shall see it written up somewhere."

Down, down, down. There was nothing else to do, so Alice soon began talking again. "Dinah'll miss me very much to-night, I should think!" (Dinah was the cat.) "I hope they'll remember her saucer of milk at tea-time. Dinah, my dear! I wish you were down here with me! There are no mice in the air, I'm afraid, but you might catch a bat, and that's very like a mouse, you know. But do cats eat bats, I wonder?" And here Alice began to get rather sleepy, and went on saying to herself, in a dreamy son of way, "Do cats eat bats? Do cats eat bats?" and sometimes "Do bats eat cats?" for, you see, as she couldn't answer either question, it didn't much matter which way she put it. She felt that she was dozing off, and had just begun to dream that she was walking hand in hand with Dinah, and was saying to her, very earnestly, "Now, Dinah, tell me the truth: did you ever eat a bat?" when suddenly, thump! thump! down she came upon a heap of sticks and dry leaves, and the fall was over.

Alice was not a bit hurt, and she jumped up on to her feet in a moment: she looked up, but it was all dark overhead: before her was another long passage, and the White Rabbit was still in sight, hurrying down it. There was not a moment to be lost: away went Alice like the wind, and was just in time to hear it say, as it turned a comer, "Oh my ears and whiskers, how late it's getting!" She was close behind it when she turned the comer, but the Rabbit was no longer to be seen: she found herself in a long, low hall, which was lit up by a row of lamps hanging from the roof.

There were doors all round the hall, but they were all locked; and when Alice had been all the way down one side and up the other, trying every door, she walked sadly down the middle, wondering how she was ever to get out again.

Suddenly she came upon a little three-legged table, all made of solid glass: there was nothing on it but a tiny golden key, and Alice's first idea was that this might belong to one of the doors of the hall; but, alas! either the locks were too large, or the key was too small, but at any rate it would not open any of them. However, on the second time round, she came upon a low curtain she had not noticed before, and behind it was a little door about fifteen inches high: she tried the little golden key in the lock, and to her great delight it fitted!

Alice opened the door and found that it led into a small passage, not much larger than a rat-hole: she knelt down and looked along the passage into the loveliest garden you ever saw. How she longed to get out of that dark hall, and wander about among those beds of bright flowers and those cool fountains, but she could not even get her head through the doorway; "and even if my head would go through," thought poor Alice, "it would be of very little use without my shoulders. Oh, how I wish I could shut up like a telescope! I think I could, if I only knew how to begin." For, you see, so many out-of-the- way things had happened lately, that Alice had begun to think that very few things indeed were really impossible.

There seemed to be no use in waiting by the little door, so she went back to the table, half hoping she might find another key on it, or at any rate a book of rules for shutting people up like telescopes: this time she found a little bottle on it, ("which certainly was not here before," said Alice), and tied round the neck of the bottle was a paper label, with the words "DRINK ME" beautifully printed on it in large letters.It was all very well to say "Drink me," but the wise little Alice was not going to do that in a hurry. "No, I'll look first," she said, "and see whether it's marked 'poison' or not"; for she had read several nice little stories about children who had got burnt, and eaten up by wild beasts, and other unpleasant things, all because they would not remember the simple rules their friends had taught them: such as, that a red-hot poker will burn you if you hold it too long; and that, if you cut your finger very deeply with a knife, it usually bleeds; and she had never forgotten that, if you drink much from a bottle marked "poison," it is almost certain to disagree with you, sooner or later.However, this bottle was not marked "poison," so Alice ventured to taste it, and, finding it very nice (it had, in fact, a sort of mixed flavour of cherry-tart, custard, pine-apple, roast turkey, toffy, and hot buttered toast), she very soon finished it off.

"What a curious feeling!" said Alice. "I must be shutting up like a telescope!"

And so it was indeed: she was now only ten inches high, and her face brightened up at the thought that she was now the right size for going through the little door into that lovely garden. First, however, she waited for a few minutes to see if she was going to shrink any further: she felt a little nervous about this; "for it might end, you know," said Alice to herself; "in my going out altogether, like a candle. I wonder what I should be like then?" And she tried to fancy what the flame of a candle looks like after the candle is blown out, for she could not remember ever having seen such a thing.

After a while, finding that nothing more happened, she decided on going into the garden at once; but, alas for poor Alice! when she got to the door, she found she had forgotten the little golden key, and when she went back to the table for it, she found she could not possibly reach it: she could see it quite plainly through the glass, and she tried her best to climb up one of the legs of the table, but it was too slippery; and when she had tired herself out with trying, the poor little thing sat down and cried.

"Come, there's no use in crying like that!" said Alice to herself rather sharply. "I advise you to leave off this minute!" She generally gave herself very good advice (though she very seldom followed it), and sometimes she scolded herself so severely as to bring tears into her eyes; and once she remembered trying to box her own ears for having cheated herself in a game of croquet she was playing against herself, for this curious child was very fond of pretending to be two people. "But it's no use now," thought poor Alice, "to pretend to be two people! Why, there's hardly enough of me left to make one respectable person!"

Soon her eye fell on a little glass box that was lying under the table: she opened it, and found in it a very small cake, on which the words "EAT ME" were beautifully marked in currants. "Well, I'll eat it," said Alice, "and if it makes me grow larger, I can reach the key; and if it makes me grow smaller, I can creep under the door: so either way I'll get into the garden, and I don't care which happens!"

She ate a little bit, and said anxiously to herself "Which way? Which way?", holding her hand on the top of her head to feel which way it was growing; and she was quite surprised to find that she remained the same size. To be sure, this is what generally happens when one eats cake; but Alice had got so much into the way of expecting nothing but out-of-the-way things to happen, that it seemed quite dull and stupid for life to go on in the common way.

So she set to work, and very soon finished off the cake.
```

*JToolBar*

A JToolBar is a container that groups several components — usually buttons with icons — into a row or column. Often, tool bars provide easy access to functionality that is also in menus
The buttons in the tool bar are ordinary JButton instances that use images.
By adding a few lines of code to the preceding example, we can demonstrate some more tool bar features:

    Using setFloatable(false) to make a tool bar immovable.
    Using setRollover(true) to visually indicate tool bar buttons when the user passes over them with the cursor.
    Adding a separator to a tool bar.
    Adding a non-button component to a tool bar.

Because the tool bar can no longer be dragged, it no longer has bumps at its left edge. Here is the code that turns off dragging:

toolBar.setFloatable(false);

The tool bar is in rollover mode, so the button under the cursor has a visual indicator. The kind of visual indicator depends on the look and feel. For example, the Metal look and feel uses a gradient effect to indicate the button under the cursor while other types of look and feel use borders for this purpose. Here is the code that sets rollover mode:

toolBar.setRollover(true);

The following program creates a text editor with a JToolBar.


```
/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 9/22/14
 * Time: 9:02 PM
 * To change this template use File | Settings | File Templates.
 */
import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import javax.swing.plaf.basic.BasicFileChooserUI;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.print.PrinterException;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 8/1/14
 * Time: 10:07 PM
 * To change this template use File | Settings | File Templates.
 */
public class ToolBarDemo extends JFrame {

    private String []item = {"open", "save", "save As", "print", "Close"};
    private JFileChooser fileChooser = new JFileChooser(".");
    private JTextArea textArea = new JTextArea();
    private String []textFiles = {"c", "cpp", "java", "html", "xml", "bat", "txt"};
    private String fileName;
    private JToolBar toolBar = new JToolBar();
    private JButton []button = new JButton[item.length];

    public void updateUI() {
        fileChooser.updateUI();
    }

    public ToolBarDemo() {
        // Set the look'n feel
        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            // Do nothing
        }
        updateUI();
        for (int i = 0; i < button.length; i++) {
            button[i] = new JButton(new ImageIcon("Icons/" + item[i] + ".gif"));
            button[i].setActionCommand(item[i]);
            button[i].setToolTipText(item[i]);
            button[i].addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    String action = e.getActionCommand();
                    if(action.equals("open")) {
                        openFile();
                    }
                    else if(action.equals("save")) {
                        saveFile();
                    }
                    else if(action.equals("save As")) {
                        saveAs();
                    }
                    else if(action.equals("print")) {
                        try {
                            textArea.print();
                        } catch (PrinterException e1) {

                        }
                    }
                    else
                    {
                        System.exit(-1);
                    }
                }
            });
            toolBar.add(button[i]);
        }
        add(toolBar, BorderLayout.NORTH);
        textArea.setFont(new Font("Serif", Font.BOLD, 14));

        fileChooser.setAcceptAllFileFilterUsed(false);
        //Set the filter
        fileChooser.addChoosableFileFilter(new FileFilter() {
            @Override
            public boolean accept(File f) {
                for (int i = 0; i < textFiles.length; i++) {
                    if(f.isDirectory() || f.getName().endsWith(textFiles[i]))
                        return true;
                }
                return false;
            }

            @Override
            public String getDescription() {
                return "Text Files";
            }
        });

        add(new JScrollPane(textArea));
        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        setSize(scrDim.width/2, scrDim.height);
        setTitle("ToolBarDemo");
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ToolBarDemo();
            }
        });
    }

    public String getFileName(String fullPath) {
        String fSeparator = System.getProperty("file.separator");
        String fName = fullPath;
        int sIndex = fName.lastIndexOf(fSeparator);
        if (sIndex != -1) {
            fName = fName.substring(sIndex + 1);
            return fName;
        }
        return null;
    }

    // Save the file under a different name
    private void saveAs() {

        // Show a File save dialog
        fileChooser.setDialogTitle("Save As");
        int result = fileChooser.showSaveDialog(null);
        if (result != 0) {
            return;
        }
        File file = fileChooser.getSelectedFile();
        if (file == null) {
            return;
        }
        fileName = file.toString();
        BasicFileChooserUI ui = (BasicFileChooserUI) fileChooser.getUI();
        ui.setFileName(getFileName(fileName));
        if (file.exists()) {
            // Dialog, Want to overwrite ?, Yes, NO option
            final JOptionPane optionPane = new JOptionPane(
                    "Do you want to overwrite " + getFileName(fileName) + " ?",
                    JOptionPane.QUESTION_MESSAGE,
                    JOptionPane.YES_NO_OPTION);

            final JDialog dialog = new JDialog(new Frame(), "Confirm", true);
            dialog.setContentPane(optionPane);
            dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);

            optionPane.addPropertyChangeListener(new PropertyChangeListener() {

                @Override
                public void propertyChange(PropertyChangeEvent e) {
                    String prop = e.getPropertyName();

                    if (dialog.isVisible() && (e.getSource() == optionPane) && (prop.equals(JOptionPane.VALUE_PROPERTY))) {
                        //If you were going to check something
                        //before closing the window, you'd do
                        //it here.
                        dialog.setVisible(false);
                    }
                }
            });
            dialog.pack();
            dialog.setLocationRelativeTo(null);
            dialog.setVisible(true);

            int value = ((Integer) optionPane.getValue()).intValue();
            if (value == JOptionPane.YES_OPTION) {
                saveFile();
            } else if (value == JOptionPane.NO_OPTION) {
                // Show saveAs dialog , for entering a new name
                saveAs();
            }

        } else {
            // Now save the file
            saveFile();
        }
    }

    //Save the file to the disk
    private void saveFile() {
        //
        if (fileName == null) {
            return;
        }

        FileWriter writer = null;
        try {
            writer = new FileWriter(fileName);
            textArea.write(writer);
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(ToolBarDemo.this,
                    "File Not Saved", "ERROR", JOptionPane.ERROR_MESSAGE);
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException x) {
                }
            }
        }
    }
    // Open the file using the FileChooser
    private void openFile() {
        fileChooser.setDialogTitle("Open");

        int result = fileChooser.showOpenDialog(null);
        if (result != 0) {
            return;
        }
        File file = fileChooser.getSelectedFile();
        if (file == null) {
            return;
        } else {
            fileName = file.toString();
            if (fileName == null) {
                return;
            }
            else
            {
                FileReader reader = null;

                try {
                    reader = new FileReader(fileName);
                    textArea.read(reader, null);

                } catch (IOException ex) {
                    JOptionPane.showMessageDialog(ToolBarDemo.this,
                            "File Not Found", "ERROR", JOptionPane.ERROR_MESSAGE);
                } finally {
                    if (reader != null) {
                        try {
                            reader.close();
                        } catch (IOException x) {
                        }
                    }
                }
            }
        }
    }
}
```

*s27.postimg.org/q3ivk1w4v/Tool_Bar_Demo.jpg

*JMenu*

A menu provides a space-saving way to let the user choose one of several options.
Menus are unique in that, by convention, they aren't placed with the other components in the UI. Instead, a menu usually appears either in a menu bar or as a popup menu.
A menu bar contains one or more menus and has a customary, platform-dependent location — usually along the top of a window. A popup menu is a menu that is invisible until the user makes a platform-specific mouse action, such as pressing the right mouse button, over a popup-enabled component. The popup menu then appears under the cursor.
To detect when the user chooses a JMenuItem, you can listen for action events (just as you would for a JButton).

Menus support two kinds of keyboard alternatives: mnemonics and accelerators. Mnemonics offer a way to use the keyboard to navigate the menu hierarchy, increasing the accessibility of programs. Accelerators, on the other hand, offer keyboard shortcuts to bypass navigating the menu hierarchy. Mnemonics are for all users; accelerators are for power users.
The following program loads all the Images shows them in a menu (with preview). Selecting them shows the Image.


```
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 8/2/14
 * Time: 3:38 PM
 * To change this template use File | Settings | File Templates.
 */
public class MenuDemo extends JFrame {

    private String path = "Images/";
    private int MAX;
    private String []imgName;
    private JLabel label = new JLabel();
    private JMenuBar mBar = new JMenuBar();
    private JMenu menu = new JMenu("Image");
    private JMenuItem []menuItem;

    public MenuDemo() {

        File directory = new File(path);
        if (!directory.exists()) {
            System.err.println("The specified directory doesn't exist!!");
            System.exit(-1);
        }
        try
        {
           UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }  catch (Exception e) {
            // Do nothing
        }
        label.setHorizontalAlignment(SwingConstants.CENTER);
        label.setVerticalAlignment(SwingConstants.CENTER);
        mBar.updateUI();
        menu.updateUI();
        // Filter out the Images
        imgName = directory.list(new FilenameFilter() {
            String[] readFormat = ImageIO.getReaderFormatNames();

            @Override
            public boolean accept(File dir, String name) {
                for (int i = 0; i < readFormat.length; i++) {
                    if (name.endsWith(readFormat[i])) {
                        return true;
                    }
                }
                return false;
            }
        });
        MAX = imgName.length;
        if (MAX == 0) {
            System.err.println("OOps , No Images found!!");
            System.exit(-1);
        }
        //Limit the maximunm entries to 10
        if (MAX > 10) {
            MAX = 10;
        }
        menuItem = new JMenuItem[MAX];
        for (int i = 0; i < menuItem.length; i++) {
            menuItem[i] = new JMenuItem(imgName[i].substring(0, imgName[i].lastIndexOf(".")), new ImageIcon(getImage(path + imgName[i]).getScaledInstance(32, 32, Image.SCALE_SMOOTH)));
            menuItem[i].updateUI();
            menu.add(menuItem[i]);
            menuItem[i].setActionCommand(imgName[i]);
            menuItem[i].addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent ae) {
                    label.setIcon(new ImageIcon(getImage(path + ae.getActionCommand())));
                }
            });
        }
        mBar.add(menu);
        setJMenuBar(mBar);
        add(new JScrollPane(label));
        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        setSize(scrDim.width / 2 + 150, scrDim.height);
        setVisible(true);
        setTitle("MenuDemo");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    // Get the Image from the disk
    public Image getImage(String fileName) {
        try {
            return ImageIO.read(new File(fileName));
        } catch (IOException ioe) {
            System.err.println("Error loading Image : " + fileName);
        }
        return null;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new MenuDemo();
            }
        });
    }
}
```

*s14.postimg.org/rnyvd547h/Menu_Demo.jpg

*JPopupMenu*

To bring up a popup menu ( JPopupMenu), you must register a mouse listener on each component that the popup menu should be associated with. The mouse listener must detect user requests that the popup menu be brought up.
If the user selects a particular meny then that Image is shown.


```
/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 8/2/14
 * Time: 3:57 PM
 * To change this template use File | Settings | File Templates.
 */

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;

public class PopupMenuDemo extends JFrame {

    private String path = "Images/";
    private int MAX;
    private String []imgName;
    private JLabel label = new JLabel();
    private JPopupMenu popupMenu = new JPopupMenu();
    private JMenuItem []menuItem;

    public PopupMenuDemo() {

        File directory = new File(path);
        if (!directory.exists()) {
            System.err.println("The specified directory doesn't exist!!");
            System.exit(-1);
        }
        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }  catch (Exception e) {
            // Do nothing
        }
        popupMenu.updateUI();
        label.setHorizontalAlignment(SwingConstants.CENTER);
        label.setVerticalAlignment(SwingConstants.CENTER);

        // Filter out the Images
        imgName = directory.list(new FilenameFilter() {
            String[] readFormat = ImageIO.getReaderFormatNames();

            @Override
            public boolean accept(File dir, String name) {
                for (int i = 0; i < readFormat.length; i++) {
                    if (name.endsWith(readFormat[i])) {
                        return true;
                    }
                }
                return false;
            }
        });
        MAX = imgName.length;
        if (MAX == 0) {
            System.err.println("OOps , No Images found!!");
            System.exit(-1);
        }
        //Limit the maximunm entries to 14
        if (MAX > 14) {
            MAX = 14;
        }
        menuItem = new JMenuItem[MAX];
        for (int i = 0; i < menuItem.length; i++) {
            menuItem[i] = new JMenuItem(imgName[i].substring(0, imgName[i].lastIndexOf(".")), new ImageIcon(getImage(path + imgName[i]).getScaledInstance(64, 64, Image.SCALE_SMOOTH)));
            popupMenu.add(menuItem[i]);
            menuItem[i].updateUI();

            menuItem[i].setActionCommand(imgName[i]);
            menuItem[i].addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent ae) {
                    label.setIcon(new ImageIcon(getImage(path + ae.getActionCommand())));
                    label.setText("");
                }
            });
        }
        label.addMouseListener(new MouseAdapter() {

            @Override
            public void mousePressed(MouseEvent me) {
                if (me.isPopupTrigger()) {
                    //Show the Popup now
                    popupMenu.show(me.getComponent(), me.getX(), me.getY());
                }
            }

            @Override
            public void mouseReleased(MouseEvent me) {
                if (me.isPopupTrigger()) {
                    popupMenu.show(me.getComponent(), me.getX(), me.getY());
                }
            }
        });
        label.setText("Right Click to show the Popup!!");
        add(new JScrollPane(label));
        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        setSize(scrDim.width / 2 + 150, scrDim.height);
        setVisible(true);
        setTitle("PopupMenuDemo");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    // Get the Image from the disk
    public Image getImage(String fileName) {
        try {
            return ImageIO.read(new File(fileName));
        } catch (IOException ioe) {
            System.err.println("Error loading Image : " + fileName);
        }
        return null;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new PopupMenuDemo();
            }
        });
    }
}
```

*s27.postimg.org/nhespz7u7/Popup_Menu_Demo.jpg

*JTree*

With the JTree class, you can display hierarchical data. A JTree object does not actually contain your data; it simply provides a view of the data. Like any non-trivial Swing component, the tree gets data by querying its data model.
Every tree has a root node from which all nodes descend. By default, the tree displays the root node, but you can decree otherwise. A node can either have children or not. We refer to nodes that can have children — whether or not they currently have children — as branch nodes. Nodes that can not have children are leaf nodes.

Branch nodes can have any number of children. Typically, the user can expand and collapse branch nodes — making their children visible or invisible — by clicking them. By default, all branch nodes except the root node start out collapsed. 

The following demo shows the FileSystem in a JTree. This demo shows only directories.


```
// FileSystemEx1
import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.tree.*;

public class FileSystemEx1 extends JFrame {

    public FileSystemEx1() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
            System.err.println("Error loading look'n feel!!");
        }
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Computer");
        File[] roots = File.listRoots();
        for (File aFile : roots) {
            FileBasedTreeNode node = new FileBasedTreeNode(aFile);
            root.add(node);
        }
        add(new JScrollPane(new JTree(root)));
        setSize(500, 800);
        setTitle("FileSystemEx1");
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new FileSystemEx1();
            }
        });
    }
}

// extending the default node is a little messy - the key in our context
// (assuming a read only tree) is to just override the methods seen
// below. read-write trees with tree nodes needs some more methods (insert, remove)
// to be overridden as well.
class FileBasedTreeNode extends DefaultMutableTreeNode {

    private File aFile;

    FileBasedTreeNode(File newFile) {
        super(newFile.toString());
        aFile = newFile;
    }

    FileBasedTreeNode(File newFile, boolean condition) {
        super(newFile.getName());
        aFile = newFile;
    }

    @Override
    public int getChildCount() {
        ensureInited();
        return super.getChildCount();
    }

    @Override
    public TreeNode getChildAt(int idx) {
        ensureInited();
        return super.getChildAt(idx);
    }

    @Override
    public int getIndex(TreeNode aNode) {
        ensureInited();
        return super.getIndex(aNode);
    }

    @Override
    public Enumeration children() {
        ensureInited();
        return super.children();
    }

    private void ensureInited() {
        try {
            if (children == null) {
                children = new Vector<>();
                File[] file = aFile.listFiles(new FileFilter() {

                    @Override
                    public boolean accept(File pathname) {
                        // Get only directories exclude hidden directories
                        if (pathname.isDirectory() && !pathname.isHidden()) {
                            return true;
                        }
                        return false;
                    }
                });
                for (File f : file) { // aFile.listFiles() - to list files & directories
                    children.add(new FileBasedTreeNode(f, true));
                }
            }
        } catch (Exception ex) {
        }
    }
}
```

*s15.postimg.org/8inpn4viv/File_System_Ex1.jpg

Here is another demo that shows files & directories


```
// FileSystemEx2

import java.io.*;
import java.util.*;
import javax.swing.*;
import javax.swing.tree.*;

public class FileSystemEx2 extends JFrame {

    public FileSystemEx2() {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Computer");
        File[] roots = File.listRoots();
        for (File aFile : roots) {
            FileBasedTreeNodes node = new FileBasedTreeNodes(aFile);
            root.add(node);
        }
        add(new JScrollPane(new JTree(root)));
        setSize(500, 800);
        setTitle("FileSystemEx2");
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new FileSystemEx2();
            }
        });
    }
}

// extending the default node is a little messy - the key in our context
// (assuming a read only tree) is to just override the methods seen
// below. read-write trees with tree nodes needs some more methods (insert, remove)
// to be overridden as well.
class FileBasedTreeNodes extends DefaultMutableTreeNode {

    private File aFile;

    FileBasedTreeNodes(File newFile) {
        super(newFile.toString());
        aFile = newFile;
    }

    FileBasedTreeNodes(File newFile, boolean condition) {
        super(newFile.getName());
        aFile = newFile;
    }

    @Override
    public int getChildCount() {
        ensureInited();
        return super.getChildCount();
    }

    @Override
    public TreeNode getChildAt(int idx) {
        ensureInited();
        return super.getChildAt(idx);
    }

    @Override
    public int getIndex(TreeNode aNode) {
        ensureInited();
        return super.getIndex(aNode);
    }

    @Override
    public Enumeration children() {
        ensureInited();
        return super.children();
    }

    private void ensureInited() {
        try {
            if (children == null) {
                children = new Vector<>();
                File[] file = aFile.listFiles(new FileFilter() {

                    @Override
                    public boolean accept(File pathname) {
                        // Get only directories exclude hidden directories
                        if (pathname.isDirectory() && !pathname.isHidden()) {
                            return true;
                        }
                        return false;
                    }
                });
                for (File f : aFile.listFiles()) {
                    children.add(new FileBasedTreeNodes(f, true));
                }
            }
        } catch (Exception ex) {
        }
    }
}
```

*JScrollPane*

A JScrollPane provides a scrollable view of a component. When screen real estate is limited, use a scroll pane to display a component 
that is large or one whose size can change dynamically.
The scroll pane's client is also known as the view or viewport view. You can change the client dynamically by calling the setViewportView method. Note that JScrollPane has no corresponding getViewportView method. If you need to refer to the client object again, 
you can either cache it in a variable or invoke getViewport().getViewportView() on the scroll pane.

When the user manipulates the scroll bars in a scroll pane, the area of the client that is visible changes accordingly. This picture shows the relationship between the scroll pane and its client and indicates the classes that the scroll pane commissions to help:
A scroll pane uses a JViewport instance to manage the visible area of the client. The viewport is responsible for positioning and sizing the client, based on the positions of the scroll bars, and displaying it.

A scroll pane may use two separate instances of JScrollBar for the scroll bars. The scroll bars provide the interface for the user to manipulate the visible area. The following figure shows the three areas of a scroll bar: the knob (sometimes called the thumb), the (arrow) buttons, and the track.
When the user moves the knob on the vertical scroll bar up and down, the visible area of the client moves up and down. Similarly, when the user moves the knob on the horizontal scroll bar to the right and left, the visible area of the client moves back and forth accordingly. The position of the knob relative to its track is proportionally equal to the position of the visible area relative to the client. In the Java look and feel and some others, the size of the knob gives a visual clue as to how much of the client is visible.

By clicking an arrow button, the user can scroll by a unit increment. By clicking within the track, the user can scroll by a block increment. If the user has a mouse with a wheel, then the user can scroll vertically using the mouse wheel. The amount that the mouse wheel scrolls is platform dependent. For example, by default on Windows XP, the mouse wheel scrolls three unit increments; the Mouse control panel allows you to specify a different number of unit increments or to use a block increment instead. 
The scroll pane's row and column headers are provided by a custom JComponent subclass, Rule, that draws a ruler in centimeters or inches. Here's the code that creates and sets the scroll pane's row and column headers:
You can use any component for a scroll pane's row and column headers. The scroll pane puts the row and column headers in JViewPorts of their own. Thus, when scrolling horizontally, the column header follows along, and when scrolling vertically, the row header follows along. Make sure the row and column have the same width and height as the view, because JScrollPane does not enforce these values to have the same size. 
As a JComponent subclass, our custom Rule class puts its rendering code in its paintComponent method. The Rule rendering code takes care to draw only within the current clipping bounds, to ensure speedy scrolling. Your custom row and column headers should do the same.

The following program shows a JScrollPane with a Ruler.


```
/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 7/31/14
 * Time: 5:02 PM
 * To change this template use File | Settings | File Templates.
 */
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class ScrollPaneDemo extends JPanel {

    private Rule columnView;
    private Rule rowView;
    private JToggleButton isMetric;
    private ScrollablePicture picture;
    private ImageIcon icon;
    private Image image;
    private static Dimension scrDim;
    private String path = "Images/";

    public ScrollPaneDemo() {

        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }  catch (Exception e) {
            // Do nothing
        }
        image = getImage(path + "Katrina Kaif.jpg");
        icon = new ImageIcon(image);
        image = icon.getImage();
        // Scale the smaller Images to 300%
        int imgWidth = image.getWidth(null);
        int imgHeight = image.getHeight(null);
        scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        if (imgWidth <= scrDim.width || imgHeight <= scrDim.height) {
            // Scale the Image to 200%
            image = image.getScaledInstance(imgWidth * 2, imgHeight * 2, Image.SCALE_SMOOTH);
        }
        icon = new ImageIcon(image);
        // Create the row and column headers.
        columnView = new Rule(Rule.HORIZONTAL, true);
        columnView.setPreferredWidth(icon.getIconWidth());
        rowView = new Rule(Rule.VERTICAL, true);
        rowView.setPreferredHeight(icon.getIconHeight());

        // Create the corners.
        JPanel buttonCorner = new JPanel();
        isMetric = new JToggleButton("cm", true);
        isMetric.setFont(new Font("SansSerif", Font.PLAIN, 11));
        isMetric.setMargin(new Insets(2, 2, 2, 2));
        isMetric.addItemListener(new UnitsListener());
        buttonCorner.add(isMetric); //Use the default FlowLayout

        // Set up the scroll pane.
        picture = new ScrollablePicture(icon, columnView.getIncrement());
        JScrollPane pictureScrollPane = new JScrollPane(picture);
        pictureScrollPane.setPreferredSize(new Dimension(300, 250));
        pictureScrollPane.setViewportBorder(BorderFactory.createLineBorder(Color.black));

        pictureScrollPane.setColumnHeaderView(columnView);
        pictureScrollPane.setRowHeaderView(rowView);

        pictureScrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER,
                buttonCorner);
        pictureScrollPane.setCorner(JScrollPane.LOWER_LEFT_CORNER,
                new Corner());
        pictureScrollPane.setCorner(JScrollPane.UPPER_RIGHT_CORNER,
                new Corner());

        // Put it in this panel.
        setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
        add(pictureScrollPane);
        setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
    }

    public BufferedImage getImage(String fileName) {
        try {
            return ImageIO.read(new File(fileName));
        } catch (IOException ioe) {
            System.err.println("Error loading Image :" + fileName);
            System.exit(-1);
        }
        return null;
    }

    class UnitsListener implements ItemListener {

        @Override
        public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
                // Turn it to metric.
                //Show 'cm'
                isMetric.setText("cm");
                rowView.setIsMetric(true);
                columnView.setIsMetric(true);
            } else {
                // Turn it to inches.
                //Show 'Inch'
                isMetric.setText("Inch");
                rowView.setIsMetric(false);
                columnView.setIsMetric(false);
            }
            picture.setMaxUnitIncrement(rowView.getIncrement());
        }
    }

    public static void main(String s[]) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("ScrollPaneDemo");
                frame.setContentPane(new ScrollPaneDemo());
                frame.setSize(scrDim);
                frame.setVisible(true);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            }
        });
    }
}

class Corner extends JComponent
{
    public void paintComponent(Graphics g)
    {
        // Fill me with dirty brown/orange.
        g.setColor(new Color(230, 163, 4));
        g.fillRect(0, 0, getWidth(), getHeight());
    }
}

// Class to draw the Ruler
class Rule extends JComponent
{
    public static final int INCH = Toolkit.getDefaultToolkit().getScreenResolution();
    public static final int HORIZONTAL = 0;
    public static final int VERTICAL = 1;
    public static final int SIZE = 35; //width of the rectangle

    public int orientation;
    public boolean isMetric;
    private int increment;
    private int units;

    public Rule(int o, boolean m)
    {
        orientation = o;
        isMetric = m;
        setIncrementAndUnits();
    }

    public void setIsMetric(boolean isMetric)
    {
        this.isMetric = isMetric;
        setIncrementAndUnits();
        repaint();
    }

    private void setIncrementAndUnits()
    {
        if (isMetric)
        {
            units = (int)((double)INCH / (double)2.54); // dots per centimeter
            increment = units;
        }
        else
        {
            units = INCH;
            increment = units / 2;
        }
    }

    public boolean isMetric()
    {
        return this.isMetric;
    }

    public int getIncrement()
    {
        return increment;
    }

    public void setPreferredHeight(int ph)
    {
        setPreferredSize(new Dimension(SIZE, ph));
    }

    public void setPreferredWidth(int pw)
    {
        setPreferredSize(new Dimension(pw, SIZE));
    }

    public void paintComponent(Graphics g)
    {
        Rectangle drawHere = g.getClipBounds();

        // Fill clipping area with dirty brown/orange.
        g.setColor(new Color(230, 163, 4));
        g.fillRect(drawHere.x, drawHere.y, drawHere.width, drawHere.height);

        // Do the ruler labels in a small font that's black.
        g.setFont(new Font("SansSerif", Font.PLAIN, 10));
        g.setColor(Color.black);

        // Some vars we need.
        int end = 0;
        int start = 0;
        int tickLength = 0;
        String text = null;

        // Use clipping bounds to calculate first tick and last tick location.
        if (orientation == HORIZONTAL)
        {
            start = (drawHere.x / increment) * increment;
            end = (((drawHere.x + drawHere.width) / increment) + 1)*increment;
        }
        else
        {
            start = (drawHere.y / increment) * increment;
            end = (((drawHere.y + drawHere.height) / increment) + 1)*increment;
        }

        // Make a special case of 0 to display the number
        // within the rule and draw a units label.
        if (start == 0)
        {
            text = Integer.toString(0) + (isMetric ? " cm" : " in");
            tickLength = 10;
            if (orientation == HORIZONTAL)
            {
                g.drawLine(0, SIZE-1, 0, SIZE-tickLength-1);
                g.drawString(text, 2, 21);
            }
            else
            {
                g.drawLine(SIZE-1, 0, SIZE-tickLength-1, 0);
                g.drawString(text, 9, 10);
            }
            text = null;
            start = increment;
        }

        // ticks and labels
        for (int i = start; i < end; i+= increment)
        {
            if (i % units == 0)
            {
                tickLength = 10;
                text = Integer.toString(i/units);
            }
            else
            {
                tickLength = 7;
                text = null;
            }

            if (tickLength != 0)
            {
                if (orientation == HORIZONTAL)
                {
                    g.drawLine(i, SIZE-1, i, SIZE-tickLength-1);
                    if (text != null)
                        g.drawString(text, i-3, 21);
                }
                else
                {
                    g.drawLine(SIZE-1, i, SIZE-tickLength-1, i);
                    if (text != null)
                        g.drawString(text, 9, i+3); //i+3
                }
            }
        }
    }
}

class ScrollablePicture extends JLabel implements Scrollable
{

    private int maxUnitIncrement = 1;

    public ScrollablePicture(ImageIcon i, int m)
    {
        super(i);
        maxUnitIncrement = m;
    }

    public Dimension getPreferredScrollableViewportSize()
    {
        return getPreferredSize();
    }

    public int getScrollableUnitIncrement(Rectangle visibleRect,int orientation, int direction)
    {
        //Get the current position.
        int currentPosition = 0;
        if (orientation == SwingConstants.HORIZONTAL)
            currentPosition = visibleRect.x;
        else
            currentPosition = visibleRect.y;

        //Return the number of pixels between currentPosition
        //and the nearest tick mark in the indicated direction.
        if (direction < 0)
        {
            int newPosition = currentPosition -
                    (currentPosition / maxUnitIncrement) *
                            maxUnitIncrement;
            return (newPosition == 0) ? maxUnitIncrement : newPosition;
        }
        else
        {
            return ((currentPosition / maxUnitIncrement) + 1) *
                    maxUnitIncrement - currentPosition;
        }
    }

    public int getScrollableBlockIncrement(Rectangle visibleRect,int orientation,int direction)
    {
        if (orientation == SwingConstants.HORIZONTAL)
            return visibleRect.width - maxUnitIncrement;
        else
            return visibleRect.height - maxUnitIncrement;
    }

    public boolean getScrollableTracksViewportWidth()
    {
        return false;
    }

    public boolean getScrollableTracksViewportHeight()
    {
        return false;
    }

    public void setMaxUnitIncrement(int pixels)
    {
        maxUnitIncrement = pixels;
    }
}
```

*s29.postimg.org/mevc4znw3/Scroll_Pane_Demo.jpg

The next demo shows how you can scroll the scrollbar programmatically.
If you move vertical/horizontal scrollbar the values changes , they are shown on the textfields.
You can also programmatically scroll by entering a value in the (0 - 2000)


```
import java.awt.*;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author Sowndar
 */
public class ScrollDemo2 extends JFrame implements AdjustmentListener {

    private JTextField horizInput = new JTextField(23);
    private JTextField vertInput = new JTextField(23);
    private Image image;
    private JLabel label = new JLabel();
    private JLabel horizLabel = new JLabel("Horizontal ScrollBar :");
    private JLabel vertLabel = new JLabel("Vertical ScrollBar :");
    private JScrollPane scroller;
    private JLabel statusBar = new JLabel("Ready");
    private int value;

    public void updateUI() {
        horizInput.updateUI();
        vertInput.updateUI();
        label.updateUI();
        statusBar.updateUI();
    }

    public ScrollDemo2() {
        // Set the look 'n feel
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
            System.err.println("Error loading look'n feel!!");
        }
        scroller = new JScrollPane(label);
        updateUI();
        image = getImage("Collage/Lovely Ladies.jpg");
        if (image != null) {
            label.setIcon(new ImageIcon(image));
        }
        Font font = horizInput.getFont();
        String fontName = font.getName();
        int fontSize = font.getSize();
        font = new Font(fontName, Font.BOLD, fontSize + 1);
        horizInput.setFont(font);
        vertInput.setFont(font);
        statusBar.setFont(font);
        horizInput.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
        vertInput.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
        // Listen to user input
        horizInput.getDocument().addDocumentListener(new DocumentListener() {

            @Override
            public void insertUpdate(DocumentEvent e) {
                processHoriz();
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                processHoriz();
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                processHoriz();
            }
        });
        vertInput.getDocument().addDocumentListener(new DocumentListener() {

            @Override
            public void insertUpdate(DocumentEvent e) {
                processVert();
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                processVert();
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                processVert();
            }
        });

        JPanel top = new JPanel(new FlowLayout(FlowLayout.CENTER));
        horizLabel.setFont(font);
        vertLabel.setFont(font);
        top.add(horizLabel);
        top.add(horizInput);
        top.add(vertLabel);
        top.add(vertInput);
        add(top, BorderLayout.NORTH);
        add(scroller, BorderLayout.CENTER);
        add(statusBar, BorderLayout.SOUTH);
        // Add listener for both scrollbars
        scroller.getHorizontalScrollBar().addAdjustmentListener(this);
        scroller.getVerticalScrollBar().addAdjustmentListener(this);
        setTitle("ScrollDemo2");
        setSize(Toolkit.getDefaultToolkit().getScreenSize());
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public BufferedImage getImage(String fileName) {
        try {
            return ImageIO.read(new File(fileName));
        } catch (IOException ioe) {
            System.err.println("Error loading Image!!");
            System.exit(-1);
        }
        return null;
    }

    @Override
    public void adjustmentValueChanged(AdjustmentEvent evt) {

        Adjustable source = evt.getAdjustable();
        // Determine which scrollbar fired the event
        int orient = source.getOrientation();

        // getValueIsAdjusting() returns true if the user is currently
        // dragging the scrollbar's knob and has not picked a final value
        if (evt.getValueIsAdjusting()) {
            // The user is dragging the knob
            if (orient == Adjustable.HORIZONTAL) {
                // Event from horizontal scrollbar
                statusBar.setText("You are dragging the knob of the Horizontal Scrollbar");
            } else {
                // Event from vertical scrollbar
                statusBar.setText("You are dragging the knob of the Vertical Scrollbar");
            }
        } else {
            statusBar.setText("Ready");
        }

        // Get current value
        int scrollValue = evt.getValue();

        if (orient == Adjustable.HORIZONTAL) {
            // Event from horizontal scrollbar
            horizInput.setText("" + scrollValue);
        } else {
            // Event from vertical scrollbar
            vertInput.setText("" + scrollValue);
        }

        // Determine the type of event
        int type = evt.getAdjustmentType();
        switch (type) {
            case AdjustmentEvent.UNIT_INCREMENT:
                // Scrollbar was increased by one unit
                break;
            case AdjustmentEvent.UNIT_DECREMENT:
                // Scrollbar was decreased by one unit
                break;
            case AdjustmentEvent.BLOCK_INCREMENT:
                // Scrollbar was increased by one block
                break;
            case AdjustmentEvent.BLOCK_DECREMENT:
                // Scrollbar was decreased by one block
                break;
            case AdjustmentEvent.TRACK:
                // The knob on the scrollbar was dragged
                break;
        }
    }
    // Processing must be done in the event-dispatch Thread
    // Since Swing is not Thread safe!!

    public void processHoriz() {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                value = 0;
                try {
                    value = Integer.parseInt(horizInput.getText());
                } catch (NumberFormatException nfe) {
                    value = 0;
                }
                scroller.getHorizontalScrollBar().setValue(value);
            }
        });

    }

    public void processVert() {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                value = 0;
                try {
                    value = Integer.parseInt(vertInput.getText());
                } catch (NumberFormatException nfe) {
                    value = 0;
                }
                scroller.getVerticalScrollBar().setValue(value);
            }
        });

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ScrollDemo2();
            }
        });
    }
}
```

*s21.postimg.org/mg4myn45v/Scroll_Demo2.jpg

Here is another demo that shows an Image in the Viewport in a JTextArea!!


```
/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 9/23/14
 * Time: 6:04 PM
 * To change this template use File | Settings | File Templates.
 */
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;

// put a texture in the background
// put a translucent image in the foreground
// put a yellow gradient in the background
// put a translucent sun in the upper right
public class ScrollPaneWatermark extends JViewport {

    BufferedImage fgimage, bgimage;
    TexturePaint texture;

    public ScrollPaneWatermark() {
        super();
    }

    public void setBackgroundTexture(URL url) throws IOException {
        bgimage = ImageIO.read(url);
        Rectangle rect = new Rectangle(0, 0,
                bgimage.getWidth(null), bgimage.getHeight(null));
        texture = new TexturePaint(bgimage, rect);
    }

    public void setForegroundBadge(URL url) throws IOException {
        fgimage = ImageIO.read(url);
        fgimage =  toBufferedImage(fgimage.getScaledInstance(64, 64, Image.SCALE_SMOOTH));
    }

    BufferedImage toBufferedImage(Image image) {
        if(image != null) {
            BufferedImage buff = new BufferedImage(image.getWidth(this), image.getHeight(this), BufferedImage.TYPE_INT_RGB);
            Graphics gr = buff.getGraphics();
            gr.drawImage(image, 0, 0, this);
            gr.dispose();
            return buff;
        }
        return null;
    }

    @Override
    public void paintComponent(Graphics g) {
        // do the superclass behavior first
        super.paintComponent(g);

        // paint the texture
        if (texture != null) {
            Graphics2D g2 = (Graphics2D) g;
            g2.setPaint(texture);
            g.fillRect(0, 0, getWidth(), getHeight());
        }
    }

    @Override
    public void paintChildren(Graphics g) {
        super.paintChildren(g);
        if (fgimage != null) {
            g.drawImage(fgimage,
                    getWidth() - fgimage.getWidth(null), 0,
                    null);
        }
    }

    public void setView(JComponent view) {
        view.setOpaque(false);
        super.setView(view);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {

                try {
                    JFrame frame = new JFrame("ScrollPane Watermark");
                    JTextArea textArea = new JTextArea();
                    textArea.setText(fileToString(new File("ScrollPaneWatermark.java")));
                    textArea.setLineWrap(true);
                    textArea.setWrapStyleWord(true);
                    textArea.setOpaque(false);
                    textArea.setForeground(Color.green);
                    ScrollPaneWatermark viewport = new ScrollPaneWatermark();
                    //Filter out the Images
                    String []imgName = new File("Images/").list(new FilenameFilter() {
                        String []readFormat = ImageIO.getReaderFormatNames();
                        @Override
                        public boolean accept(File dir, String name) {
                            for (int i = 0; i < readFormat.length; i++) {
                                 if(name.endsWith(readFormat[i])) {
                                     return true;
                                 }
                            }
                            return false;
                        }
                    });
                    int MAX = imgName.length;
                    System.out.println(MAX);
                    int rand = getRandom(MAX);
                    viewport.setBackgroundTexture(new File("Images/" + imgName[rand]).toURI().toURL());
                    rand = getRandom(MAX);
                    viewport.setForegroundBadge(new File("Images/" + imgName[rand]).toURI().toURL());
                    viewport.setView(textArea);
                    viewport.setOpaque(false);

                    JScrollPane scroll = new JScrollPane();
                    scroll.setViewport(viewport);
                    frame.add(scroll);
                    frame.pack();
                    frame.setSize(600, 600);
                    frame.setVisible(true);
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                } catch (HeadlessException | IOException e) {
                }
            }

            private int getRandom(int max) {
                return (int) (max * Math.random());
            }
        });
    }

    public static String fileToString(File file)
            throws FileNotFoundException, IOException {
        FileReader reader = new FileReader(file);
        StringWriter writer = new StringWriter();
        char[] buf = new char[1000];
        while (true) {
            int n = reader.read(buf, 0, 1000);
            if (n == -1) {
                break;
            }
            writer.write(buf, 0, n);
        }
        return writer.toString();
    }
}
```

*s2.postimg.org/ud886ty5x/Scroll_Pane_Watermark.jpg

As you scroll the JTextArea you'll see the Image as background that remains fixed at all times. 
The foreground Image at the top right-side displays the Image on top of the JTextArea.

*JTable*

With the JTable class you can display tables of data, optionally allowing the user to edit the data. JTable does not contain or cache data;
it is simply a view of your data.
If you select a particular row then that Image is displayed in a TabbedPane. You can select multiple rows by pressing the SHIFT key &
selecting as many rows.You can filter the Table data , from the menu File -> Filter . Enter the string 'Roger' (without quotes). Click
on the OK button. You can also print the Table.

TableDemo.java


```
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.print.PrinterException;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.regex.PatternSyntaxException;

/**
 * Created with IntelliJ IDEA. User: Sowndar Date: 8/1/14 Time: 6:26 PM To
 * change this template use File | Settings | File Templates.
 */
public class TableDemo extends JFrame implements ActionListener {

    private String path = "Images/";
    private String[] imgName;
    private int MAX;
    private Image[] image;
    private String[] firstName = {"Mike", "Mark", "Tommy", "Gary", "Mark", "Jeff", "Amy", "Ben", "Roger", "Ganesh", "Ram", "Ewan", "Lara", "Mark", "Benjamin", "Brian", "Ted",
        "Mike", "Mark", "Terry", "Tom", "Mark", "Sam", "Ted", "Alex", "Ben", "Jerry", "Thomas", "Ram", "Jasson"};
    private String[] lastName = {"Albers", "Andrews", "Lee", "May", "Davidson", "Bridges", "Fisher", "Johnson", "Brinkley", "Natarajan", "Karthik", "Macgregor", "Page", "Twain",
        "Franklin", "Kenigen", "Storm", "Proctor", "Waugh", "Packer", "Woodbridge", "Green", "Barrister", "Garrison", "Tudor", "Afflek", "Robson", "Murray", "Gopal", "Kirsten"};
    private String[] film = {"Terminator II", "Congo", "Striptease", "Devil's Own", "In the Line of Fire", "Commando", "Matilda", "True Lies", "Basic Instinct", "Doom's Day Conspiracy",
        "The Fan", "Deep Impact", "The Enemy Within", "Twister", "The Exorcist", "Wild Things", "Gone with the Wind", "Wild Wild West", "Titanic", "Independence Day", "Chase",
        "GodFather", "One Fine Day", "The Game", "Octopussy", "The Big Fight", "The Mask", "The Mark of Zorro", "Gia", "The Assignment"};
    private final String[] columnNames = {"First Name", "Last Name", "Favorite Movie", "Girlfriend", "Photo"};
    // Increase row height to show Image preview
    private final int ROWHEIGHT = 70;
    private Dimension scrDim;
    private JLabel label = new JLabel("Loading Images, Please wait...", JLabel.CENTER);
    private JMenuBar mBar = new JMenuBar();
    private JMenuItem filter = new JMenuItem("Filter");
    private JMenuItem print = new JMenuItem("Print");
    private JMenuItem exit = new JMenuItem("Exit");
    private JMenu menu = new JMenu("File");
    private JTable table;

    public void updateUI() {
        mBar.updateUI();
        filter.updateUI();
        print.updateUI();
        exit.updateUI();
        menu.updateUI();
    }

    public TableDemo() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception e) {
            // Do nothing
        }
        updateUI();
        //Add the menu items to the menu
        menu.add(filter);
        menu.add(print);
        menu.add(exit);
        mBar.add(menu);
        setJMenuBar(mBar);

        //Add the listeners
        filter.addActionListener(this);
        print.addActionListener(this);
        exit.addActionListener(this);

        File directory = new File(path);
        if (!directory.exists()) {
            System.err.println("The specified directory doesn't exist!!");
            System.exit(-1);
        }
        label.setFont(new Font("Serif", Font.BOLD, 20));
        // Filter out the Images
        imgName = directory.list(new FilenameFilter() {
            String[] readFormat = ImageIO.getReaderFormatNames();

            @Override
            public boolean accept(File dir, String name) {
                for (int i = 0; i < readFormat.length; i++) {
                    if (name.endsWith(readFormat[i])) {
                        return true;
                    }
                }
                return false;
            }
        });
        MAX = imgName.length;
        image = new Image[MAX];

        if (MAX == 0) {
            System.err.println("OOps , No Images found!!");
            System.exit(-1);
        }
        if (MAX > 20) {
            MAX = 20;
        }
        add(label);
        scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        setSize(scrDim.width / 2 + 350, scrDim.height);
        setVisible(true);
        setTitle("TableDemo");
        //Start loading the Images in a separate Thread
        start();
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    //Load the Images
    public void loadImages() {

        setCursor(new Cursor(Cursor.WAIT_CURSOR));
        for (int i = 0; i < MAX; i++) {
            image[i] = getImage(path + imgName[i]);
            //Create preview Images
            image[i] = image[i].getScaledInstance(64, 64, Image.SCALE_DEFAULT);
        }
        final Object[][] data = new Object[MAX][columnNames.length];
        for (int row = 0; row < MAX; row++) {
            for (int col = 0; col < 4; col++) {
                try {
                    data[row][0] = firstName[row];
                    data[row][1] = lastName[row];
                    data[row][2] = film[row];
                    data[row][3] = imgName[row];
                    data[row][4] = new ImageIcon(image[row]);
                } catch (Exception e) {
                    // Do nothing
                }
            }
        }
        // TableModel is needed to show the preview Image
        // Create a model of the data
        TableModel dataModel = new DefaultTableModel(data, columnNames) {
            private static final long serialVersionUID = 1L;

            @Override
            public Class getColumnClass(int column) {
                Class returnValue = null;

                if ((column >= 0) && (column < getColumnCount())) {
                    returnValue = getValueAt(0, column).getClass();
                } else {
                    returnValue = Object.class;
                }
                return returnValue;
            }
        };
        // Create the table
        table = new JTable(dataModel);
        table.setRowHeight(ROWHEIGHT);
        //Set the Table sorter
        table.setRowSorter(new TableRowSorter<TableModel>(dataModel));
        //Don't allow re-ordering of columns
        table.getTableHeader().setReorderingAllowed(false);
        final JTabbedPane tabbedPane = new JTabbedPane();
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, new JScrollPane(table), tabbedPane);
        splitPane.setDividerLocation(scrDim.width / 3);
        // Table selection listener
        // You can select more than one row by pressing & holding the SHIFT key and selecting as many rows!!
        table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {

            @Override
            public void valueChanged(ListSelectionEvent e) {
                // Load the Images using the Event-dispatch Thread,
                // otherwise adds two tabs for every selected row or column!!
                SwingUtilities.invokeLater(new Runnable() {

                    public void run() {
                        // Remove the previously added Components from the TabbedPane
                        tabbedPane.removeAll();
                        String fileName = "";
                        // This works even if the JTable is sorted any alphabetic or reverse order
                        String fullPath = "";
                        for (int c : table.getSelectedRows()) {
                            // Selected table column value
                            fileName = (String) table.getValueAt(c, 3);
                            fullPath = path + fileName;
                            Image image = getImage(fullPath);
                            tabbedPane.addTab(fileName.substring(0, fileName.lastIndexOf(".")), new JScrollPane(new JLabel(new ImageIcon(image))));
                        }
                    }
                });
            }
        });
        remove(label);
        add(splitPane);
        validate();
        //Beep!!
        Toolkit.getDefaultToolkit().beep();
        setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
    }

    // Get the Image from the disk
    public Image getImage(String fileName) {
        if(fileName.endsWith("jpg") || fileName.endsWith("png")) {
            return new ImageIcon(fileName).getImage();
        }
        try {
            return ImageIO.read(new File(fileName));
        } catch (IOException ioe) {
            System.err.println("Error loading Image : " + fileName);
        }
        return null;
    }

    public void start() {
        new SwingWorker<Void, Void>() {
            @Override
            protected Void doInBackground() throws Exception {
                loadImages();
                return null;
            }
        }.execute();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TableDemo();
            }
        });
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
         Object source = ae.getSource();
        if(source == filter) {
            String filterPattern = JOptionPane.showInputDialog(
                    TableDemo.this, "Enter Filter Pattern ? : ");
            if (filterPattern == null) {
                return;
            }
            if (filterPattern.length() == 0) {
                ((TableRowSorter)table.getRowSorter()).setRowFilter(null);
            } else {
                try {
                    ((TableRowSorter)table.getRowSorter()).setRowFilter(
                            RowFilter.regexFilter(filterPattern));
                } catch (PatternSyntaxException pse) {
                    JOptionPane.showMessageDialog(null ,"Bad Regex filter pattern!!");
                }
            }
        }
        else if(source == print) {
            MessageFormat header = new MessageFormat("Page {0,number,integer}");
            try {
                table.print(JTable.PrintMode.FIT_WIDTH, header, null);
            } catch (PrinterException e) {
                JOptionPane.showMessageDialog(null, "Sorry, printing is not supported!!", "Error", JOptionPane.ERROR_MESSAGE);
            }
        }
        else
        {
            System.exit(0);
        }
    }
}
```

*s24.postimg.org/q7ziyp8tt/Table_Demo.jpg

*JDialog/JOptionPane*

A Dialog window is an independent subwindow meant to carry temporary notice apart from the main Swing Application Window.
Most Dialogs present an error message or warning to a user, but Dialogs can present images, directory trees, or just about 
anything compatible with the main Swing Application that manages them.
The following demo shows 5 buttons, clicking on them brings a  different Dialog.


```
import java.awt.*;
import java.awt.event.ActionEvent;
import java.net.URL;
import javax.swing.*;

/**
 * JOptionPaneDemo
 *
 * @author JGuru
 * @version 1.11 11/17/2013
 */
public class OptionPaneDemo extends JPanel {

    private static final Dimension VGAP15 = new Dimension(1, 15);
    private static final Dimension VGAP30 = new Dimension(1, 30);

    /**
     * OptionPaneDemo Constructor
     */
    public OptionPaneDemo() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | UnsupportedLookAndFeelException e) {
        }
        setLayout(new BoxLayout(this, BoxLayout.X_AXIS));

        JPanel bp = new JPanel() {
            @Override
            public Dimension getMaximumSize() {
                return new Dimension(getPreferredSize().width, super.getMaximumSize().height);
            }
        };
        bp.setLayout(new BoxLayout(bp, BoxLayout.Y_AXIS));

        bp.add(Box.createRigidArea(VGAP30));
        bp.add(Box.createRigidArea(VGAP30));

        bp.add(createInputDialogButton());
        bp.add(Box.createRigidArea(VGAP15));
        bp.add(createWarningDialogButton());
        bp.add(Box.createRigidArea(VGAP15));
        bp.add(createMessageDialogButton());
        bp.add(Box.createRigidArea(VGAP15));
        bp.add(createComponentDialogButton());
        bp.add(Box.createRigidArea(VGAP15));
        bp.add(createConfirmDialogButton());
        bp.add(Box.createVerticalGlue());

        add(Box.createHorizontalGlue());
        add(bp);
        add(Box.createHorizontalGlue());
    }

    private JButton createWarningDialogButton() {
        Action a = new AbstractAction("Show Warning Dialog") {
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(
                        OptionPaneDemo.this,
                        "<html><P><font color=black>This is a test of the <font color=red><b>Emergency Broadcast System</b></font>. <i><b>This is <br> only a test</b></i>.  The webmaster of your local intranet, in voluntary <br> cooperation with the <font color=blue><b>Federal</b></font> and <font color=blue><b>State</b></font> authorities, have <br> developed this system to keep you informed in the event of an <br> emergency. If this had been an actual emergency, the signal you <br> just heard would have been followed by official information, news <br> or instructions. This concludes this test of the <font color=red><b>Emergency <br> Broadcast System</b></font>.</font></P><P><br>Developer Note: This dialog demo used HTML for text formatting.</P></html>",
                        "Warning",
                        JOptionPane.WARNING_MESSAGE
                        );
            }
        };
        return createButton(a);
    }

    private JButton createMessageDialogButton() {
        Action a = new AbstractAction("Show Message Dialog") {
            final URL img = getClass().getResource("resources/images/bottle.gif");
            final String imagesrc = "<img src=\"" + img + "\" width=\"284\" height=\"100\">";
            final String message = "Message in a Bottle (yeah)";

            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(
                        OptionPaneDemo.this,
                        "<html>" + imagesrc + "<br><center>" + message + "</center><br></html>"
                        );
            }
        };
        return createButton(a);
    }

    private JButton createConfirmDialogButton() {
        Action a = new AbstractAction("Show Confirmation Dialog") {
            public void actionPerformed(ActionEvent e) {
                int result = JOptionPane.showConfirmDialog(OptionPaneDemo.this, "Is the sun shining outside today?");
                if (result == JOptionPane.YES_OPTION) {
                    JOptionPane.showMessageDialog(OptionPaneDemo.this, "<html>Well what are you doing playing on the computer?<br> Get outside! Take a trip to the beach! Get a little sun!</html>");
                } else if (result == JOptionPane.NO_OPTION) {
                    JOptionPane.showMessageDialog(OptionPaneDemo.this, "Well good thing you're inside protected from the elements!");
                }
            }
        };
        return createButton(a);
    }

    private JButton createInputDialogButton() {
        Action a = new AbstractAction("Show Input Dialog") {
            public void actionPerformed(ActionEvent e) {
                String result = JOptionPane.showInputDialog(OptionPaneDemo.this, "What is your favorite movie?");
                if ((result != null) && (result.length() > 0)) {
                    JOptionPane.showMessageDialog(OptionPaneDemo.this,
                            result + ": "
                            + "That was a pretty good movie!");
                }
            }
        };
        return createButton(a);
    }

    private JButton createComponentDialogButton() {
        Action a = new AbstractAction("Show Component Dialog") {
            public void actionPerformed(ActionEvent e) {
                // In a ComponentDialog, you can show as many message components and
                // as many options as you want:

                // Messages
                Object[] message = new Object[4];
                message[0] = "<html>JOptionPane can contain as many components <br> as you want, such as a text field:</html>";
                message[1] = new JTextField("or a combobox:");

                JComboBox<String> cb = new JComboBox<>();
                cb.addItem("item 1");
                cb.addItem("item 2");
                cb.addItem("item 3");
                message[2] = cb;

                message[3] = "<html>JOptionPane can also show as many options <br> as you want:</html>";

                // Options
                String[] options = {
                    "Yes",
                    "No",
                    "Maybe",
                    "Probably",
                    "Cancel"
                };
                int result = JOptionPane.showOptionDialog(
                        OptionPaneDemo.this, // the parent that the dialog blocks
                        message, // the dialog message array
                        "Component Dialog Example", // the title of the dialog window
                        JOptionPane.DEFAULT_OPTION, // option type
                        JOptionPane.INFORMATION_MESSAGE, // message type
                        null, // optional icon, use null to use the default icon
                        options, // options string array, will be made into buttons
                        options[3] // option that should be made into a default button
                        );
                switch (result) {
                    case 0: // yes
                        JOptionPane.showMessageDialog(OptionPaneDemo.this, "Upbeat and positive! I like that! Good choice.");
                        break;
                    case 1: // no
                        JOptionPane.showMessageDialog(OptionPaneDemo.this, "Definitely not, I wouldn't do it either.");
                        break;
                    case 2: // maybe
                        JOptionPane.showMessageDialog(OptionPaneDemo.this, "<html><font color=black> Mmmm.. yes, the situation is unclear at this <br> time. Check back when you know for sure.</font></html>");
                        break;
                    case 3: // probably
                        JOptionPane.showMessageDialog(OptionPaneDemo.this, "<html><font color=black>You know you want to. I think you should <br> have gone for broke and pressed Yes.</font></html>");
                        break;
                    default:
                        break;
                }

            }
        };
        return createButton(a);
    }

    private JButton createButton(Action a) {
        JButton b = new JButton() {
            public Dimension getMaximumSize() {
                int width = Short.MAX_VALUE;
                int height = super.getMaximumSize().height;
                return new Dimension(width, height);
            }
        };
        // setting the following client property informs the button to show
        // the action text as it's name. The default is to not show the
        // action text.
        b.putClientProperty("displayActionText", Boolean.TRUE);
        b.setAction(a);
        // b.setAlignmentX(JButton.CENTER_ALIGNMENT);
        return b;
    }

    /**
     * main method allows us to run as a standalone demo.
     *
     * [MENTION=9956]PARAM[/MENTION] args
     */
    public static void main(String[] args) {
        JFrame frame = new JFrame("OptionPane Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new OptionPaneDemo());
        frame.setPreferredSize(new Dimension(800, 600));
        frame.pack();
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

}
```

*s29.postimg.org/bbo4ihrxv/Option_Pane_Demo.jpg

*JColorChooser*

Use the JColorChooser class to enable users to choose from a palette of colors. A color chooser is a component that you can place anywhere within your program GUI. The JColorChooser API also makes it easy to bring up a dialog (modal or not) that contains a color chooser.
The following demo shows a JFrame , displays an Image using a JLabel. Clicking on the 'Choose' button brings a ColorChooser dialog.
If you select a particular color , then the JLabel's color changes to that color.


```
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.io.File;
import java.io.FilenameFilter;
import javax.imageio.ImageIO;
import java.io.IOException;

public class ColorChooserDemo2 extends JFrame {

    private JLabel label = new JLabel();
    private String []imgName;
    private String path = "Images/";
    private File directory = new File(path);
    private JButton button = new JButton("Choose");
    private JViewport viewport;

    public ColorChooserDemo2() {
        //Set look 'n feel
        try
        {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }  catch (Exception e) {
            // Do nothing
        }
        button.updateUI();
        if(!directory.exists()) {
            System.out.println("The specified directory doesn't exist!!");
            System.exit(-1);
        }
        imgName = directory.list(new FilenameFilter() {
            String []readFormat = ImageIO.getReaderFormatNames();
            @Override
            public boolean accept(File dir, String name) {
                for (int i = 0; i < readFormat.length; i++) {
                     if(name.endsWith(readFormat[i]))
                         return true;
                }
                return false;
            }
        });

        int rand = (int) (imgName.length * Math.random());
        label.setIcon(new ImageIcon(getImage(path + imgName[rand])));
        final JScrollPane scrollPane = new JScrollPane(label);
        viewport = scrollPane.getViewport();
        button.setPreferredSize(new Dimension(150, 32));
        add(scrollPane);
        JPanel bottom = new JPanel(new FlowLayout(FlowLayout.CENTER));
        bottom.add(button);

        add(bottom, BorderLayout.SOUTH);

        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Color newColor = JColorChooser.showDialog(
                        ColorChooserDemo2.this,
                        "Choose Background Color",
                         viewport.getBackground());
                if(newColor != null)
                {
                    viewport.setBackground(newColor);
                    button.setIcon(new ImageIcon(createIcon(newColor)));
                }
            }
        });
        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();
        setSize(scrDim.width/2, scrDim.height);
        setTitle("ColorChooserDemo2");
        setVisible(true);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    public BufferedImage createIcon(Color color) {
        BufferedImage buffImage = new BufferedImage(16*3, 16, BufferedImage.TYPE_INT_RGB);
        Graphics gr = buffImage.getGraphics();
        gr.setColor(color);
        gr.fillRect(0, 0, 16 * 3, 16);
        gr.dispose();
        return buffImage;
    }

    public Image getImage(String fileName) {
        try
        {
            return ImageIO.read(new File(fileName));
        }  catch (IOException ioe) {
            System.err.println("Error loading Image : " + fileName + "!!");
        }
        return null;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new ColorChooserDemo2();
            }
        });
    }

}
```

*JSpinner*

Spinners are similar to combo boxes and lists in that they let the user choose from a range of values. Like editable combo boxes, spinners allow the user to type in a value. Unlike combo boxes, spinners do not have a drop-down
list that can cover up other components. Because spinners do not display possible values — only the current value is visible — they are often used instead of combo boxes or lists when the set of possible values is extremely large.
However, spinners should only be used when the possible values and their sequence are obvious.

A spinner is a compound component with three subcomponents: two small buttons and an editor. The editor can be any JComponent, but by default it is implemented as a panel that contains a formatted text field. The spinner's possible
and current values are managed by its model.
The following demo draw a MandelBrot pattern (fractal). Clicking on the X, Y spinner changes the X, Y coordinates of the fractal.
You can also change the RGB values.


```
/**
 * Created with IntelliJ IDEA.
 * User: Sowndar
 * Date: 5/4/14
 * Time: 1:24 PM
 * To change this template use File | Settings | File Templates.
 */
import java.awt.*;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 * Demonstrates JSpinner and SwingWorker
 *
 * @author Mikhail Lapshin
 */
public class SpinnerDemo extends JPanel {

    public SpinnerDemo() {
        setLayout(new BorderLayout());

        // Create main components
        PaletteChooser chooser
                = new PaletteChooser();
        final JMandelbrot mandelbrot
                = new JMandelbrot(400, 400, chooser.getPalette());
        MandelbrotControl mandelbrotControl
                = new MandelbrotControl(mandelbrot);

        // Connect palette chooser and mandelbrot component
        chooser.addPropertyChangeListener(
                PaletteChooser.PALETTE_PROPERTY_NAME,
                new PropertyChangeListener() {
                    @Override
                    public void propertyChange(PropertyChangeEvent evt) {
                        mandelbrot.setPalette((Palette) evt.getNewValue());
                        mandelbrot.calculatePicture();
                    }
                }
        );

        // Layout components
        add(mandelbrot);

        JPanel controlPanel = new JPanel();
        controlPanel.setLayout(new BorderLayout());
        controlPanel.add(chooser, BorderLayout.NORTH);

        JPanel mandelbrotControlPanel = new JPanel();
        mandelbrotControlPanel.setLayout(new BorderLayout());
        mandelbrotControlPanel.add(mandelbrotControl, BorderLayout.NORTH);
        controlPanel.add(mandelbrotControlPanel, BorderLayout.CENTER);

        add(controlPanel, BorderLayout.EAST);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("SpinnerDemo");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new SpinnerDemo());
                frame.setPreferredSize(new Dimension(800, 600));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

/**
 * @author Mikhail Lapshin
 */
class Coords {

    private final double x;
    private final double y;

    Coords(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public double getX() {
        return x;
    }

    public double getY() {
        return y;
    }

    @Override
    public String toString() {
        return "[x=" + x + ",y=" + y + "]";
    }
}

/**
 * @author Mikhail Lapshin
 */
class JMandelbrot extends JComponent {

    private static final double EPSILON = 1E-16;
    private static final int MIN_WIDTH = 50;
    private static final int MIN_HEIGHT = 50;
    private static final double ZOOM_RATE = 3;
    private static final int NUM_OF_THREADS = 4;

    private Coords center;
    public static final String CENTER_PROPERTY_NAME = "center";

    private int maxIteration = 300;
    public static final String MAX_ITERATION_PROPERTY_NAME = "maxIteration";

    private Palette palette;
    public static final String PALETTE_PROPERTY_NAME = "palette";

    private Image buffer;
    private final MandelbrotCalculator[] calculators
            = new MandelbrotCalculator[NUM_OF_THREADS];

    private double xLowLimit = -2;
    private double xHighLimit = 2;
    private double yLowLimit = -2;
    private double yHighLimit = 2;
    private double xScale = 100;
    private double yScale = 100;
    private int oldComponentWidth = (int) (xScale * (xHighLimit - xLowLimit));
    private int oldComponentHeight = (int) (yScale * (yHighLimit - yLowLimit));

    JMandelbrot(int width, int height, Palette palette) {
        setPreferredSize(new Dimension(width, height));
        setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
        calcConstants(width, height);
        setPalette(palette);
        setToolTipText("Use left and right mouse buttons to zoom in and zoom out");
        installListeners();
    }

    private void calcConstants() {
        calcConstants(getWidth(), getHeight());
    }

    private void calcConstants(int width, int height) {
        if ((width >= MIN_WIDTH) && (height >= MIN_HEIGHT)) {
            double oldIntervalWidth = xHighLimit - xLowLimit;
            double oldIntervalHeight = yHighLimit - yLowLimit;
            double newIntervalWidth
                    = width * oldIntervalWidth / oldComponentWidth;
            double newIntervalHeight
                    = height * oldIntervalHeight / oldComponentHeight;
            double xDiff = newIntervalWidth - oldIntervalWidth;
            double yDiff = newIntervalHeight - oldIntervalHeight;
            xLowLimit -= xDiff / 2;
            xHighLimit += xDiff / 2;
            yLowLimit -= yDiff / 2;
            yHighLimit += yDiff / 2;
            buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            oldComponentWidth = width;
            oldComponentHeight = height;
            setCenter(calcCenter());
        }
    }

    private void installListeners() {
        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                int xCoord = e.getX();
                int yCoord = e.getY();
                double intervalWidth = xHighLimit - xLowLimit;
                double intervalHeight = yHighLimit - yLowLimit;
                double x = intervalWidth * xCoord / getWidth() + xLowLimit;
                double y = intervalHeight * yCoord / getHeight() + yLowLimit;

                double newIntervalWidth;
                double newIntervalHeight;
                if (e.getButton() == MouseEvent.BUTTON1) {
                    boolean limitReached = false;
                    newIntervalWidth = intervalWidth / ZOOM_RATE;
                    if ((newIntervalWidth / getWidth()) < EPSILON) {
                        newIntervalWidth = intervalWidth;
                        limitReached = true;
                    }
                    newIntervalHeight = intervalHeight / ZOOM_RATE;
                    if ((newIntervalHeight / getHeight()) < EPSILON) {
                        newIntervalHeight = intervalHeight;
                        limitReached = true;
                    }
                    if (!limitReached) {
                        xLowLimit = x - (x - xLowLimit) / ZOOM_RATE;
                        yLowLimit = y - (y - yLowLimit) / ZOOM_RATE;
                    }
                } else {
                    newIntervalWidth = intervalWidth * ZOOM_RATE;
                    newIntervalHeight = intervalHeight * ZOOM_RATE;
                    xLowLimit = x - (x - xLowLimit) * ZOOM_RATE;
                    yLowLimit = y - (y - yLowLimit) * ZOOM_RATE;
                }

                xHighLimit = xLowLimit + newIntervalWidth;
                yHighLimit = yLowLimit + newIntervalHeight;

                setCenter(calcCenter());

                xScale = getWidth() / newIntervalWidth;
                yScale = getHeight() / newIntervalHeight;

                calculatePicture();
            }
        });

        addComponentListener(new ComponentListener() {
            public void componentResized(ComponentEvent e) {
                calcConstants();
                calculatePicture();
                repaint();
            }

            public void componentMoved(ComponentEvent e) {
            }

            public void componentShown(ComponentEvent e) {
            }

            public void componentHidden(ComponentEvent e) {
            }
        });
    }

    // Use SwingWorker to asynchronously calculate parts of the picture
    public void calculatePicture() {
        int yStep = getHeight() / NUM_OF_THREADS;
        int yStart = 0;
        for (int i = 0; i < calculators.length; i++) {
            if ((calculators[i] != null) && !calculators[i].isDone()) {
                calculators[i].cancel(true);
            }
            int yEnd;
            if (i == calculators.length - 1) {
                yEnd = getHeight();
            } else {
                yEnd = yStart + yStep;
            }
            calculators[i] =
                    new MandelbrotCalculator(0, getWidth(), yStart, yEnd);
            calculators[i].execute();
            yStart = yEnd;
        }
    }

    private Coords calcCenter() {
        return new Coords(xLowLimit + (xHighLimit - xLowLimit) / 2,
                yLowLimit + (yHighLimit - yLowLimit) / 2);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(buffer, 0, 0, null);
    }

    // Use SwingWorker to asynchronously calculate parts of the picture
    private class MandelbrotCalculator extends SwingWorker<Object, Object> {
        private final int xStart;
        private final int xEnd;
        private final int yStart;
        private final int yEnd;

        public MandelbrotCalculator(int xStart, int xEnd, int yStart, int yEnd) {
            this.xStart = xStart;
            this.xEnd = xEnd;
            this.yStart = yStart;
            this.yEnd = yEnd;
        }

        protected Object doInBackground() throws Exception {
            Graphics bg = buffer.getGraphics();
            for (int yCo = yStart; yCo < yEnd; yCo++) {
                for (int xCo = xStart; xCo < xEnd; xCo++) {
                    double x = xCo / xScale + xLowLimit;
                    double y = yCo / yScale + yLowLimit;
                    int value = calcValue(x, y);
                    bg.setColor(getColorByValue(value));
                    bg.fillRect(xCo, yCo, 1, 1);
                }
                if (Thread.currentThread().isInterrupted()) {
                    return null;
                }
                publish();
            }
            return null;
        }

        private int calcValue(double x, double y) {
            int iteration = 0;
            double x0 = x;
            double y0 = y;
            while (iteration < maxIteration) {
                double x2 = x * x;
                double y2 = y * y;
                if (x2 + y2 > 4) {
                    break;
                }
                y = 2 * x * y + y0;
                x = x2 - y2 + x0;
                iteration++;
            }
            return iteration;
        }

        private Color getColorByValue(int value) {
            if (value == maxIteration) {
                return Color.BLACK;
            }
            return palette.getColor(value);
        }

        @Override
        protected void process(java.util.List<Object> chunks) {
            repaint();
        }
    }


    // Getters and Setters
    public int getMaxIteration() {
        return maxIteration;
    }

    public void setMaxIteration(int maxIteration) {
        int oldValue = this.maxIteration;
        this.maxIteration = maxIteration;
        firePropertyChange(MAX_ITERATION_PROPERTY_NAME, oldValue, maxIteration);
        palette.setSize(maxIteration);
    }

    public double getXHighLimit() {
        return xHighLimit;
    }

    public double getXLowLimit() {
        return xLowLimit;
    }

    public double getYLowLimit() {
        return yLowLimit;
    }

    public double getYHighLimit() {
        return yHighLimit;
    }

    public Coords getCenter() {
        return center;
    }

    public void setCenter(Coords coords) {
        Coords oldValue = this.center;
        this.center = coords;

        double width = xHighLimit - xLowLimit;
        double height = yHighLimit - yLowLimit;

        xLowLimit = coords.getX() - width / 2;
        xHighLimit = xLowLimit + width;
        yLowLimit = coords.getY() - height / 2;
        yHighLimit = yLowLimit + height;

        firePropertyChange(CENTER_PROPERTY_NAME, oldValue, coords);
    }

    public Palette getPalette() {
        return palette;
    }

    public void setPalette(Palette palette) {
        Palette oldValue = this.palette;
        palette.setSize(maxIteration);
        this.palette = palette;
        firePropertyChange(PALETTE_PROPERTY_NAME, oldValue, palette);
    }
}

/**
 * @author Mikhail Lapshin
 */
class JPaletteShower extends JComponent {

    private Palette palette;

    JPaletteShower(Palette palette, int width, int height) {
        setPreferredSize(new Dimension(width, height));
        setMinimumSize(new Dimension(width, height));
        this.palette = palette;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        int w = getSize().width;
        int h = getSize().height;
        int maxIndex = palette.getSize() - 1;
        double rate = (double) maxIndex / w;
        for (int x = 0; x < w; x++) {
            g.setColor(palette.getColor((int) (x * rate)));
            g.fillRect(x, 0, 1, h);
        }
    }

    public Palette getPalette() {
        return palette;
    }

    public void setPalette(Palette palette) {
        this.palette = palette;
        repaint();
    }
}

/**
 * Arranges labels and spinners into two vertical columns. Labels at the left,
 * spinners at the right.
 *
 * @author Mikhail Lapshin
 */
//Helpful component for layout of labeled spinners
class JSpinnerPanel extends JPanel {

    private final JPanel labelPanel;
    private final JPanel spinnerPanel;

    JSpinnerPanel() {
        setLayout(new BoxLayout(this, BoxLayout.X_AXIS));

        labelPanel = new JPanel();
        labelPanel.setLayout(new GridLayout(0, 1));

        spinnerPanel = new JPanel();
        spinnerPanel.setLayout(new GridLayout(0, 1));

        add(labelPanel);
        add(Box.createHorizontalStrut(5));
        add(spinnerPanel);
    }

    public void addSpinner(String labelText, JSpinner spinner) {
        JLabel label = new JLabel(labelText);
        label.setHorizontalAlignment(SwingConstants.TRAILING);
        labelPanel.add(label);

        JPanel flowPanel = new JPanel();
        flowPanel.setLayout(new FlowLayout(FlowLayout.LEADING, 5, 1));
        flowPanel.add(spinner);
        spinnerPanel.add(flowPanel);
    }
}

class MandelbrotControl extends JPanel {

    private final JMandelbrot mandelbrot;
    private JSpinner iterSpinner;
    private CoordSpinner xSpinner;
    private CoordSpinner ySpinner;
    private static final double COORD_SPINNER_STEP = 0.1d; // part of width or height

    MandelbrotControl(JMandelbrot mandelbrot) {
        this.mandelbrot = mandelbrot;
        createUI();
        installListeners();
    }

    private void createUI() {
        setLayout(new FlowLayout(FlowLayout.LEADING, 5, 0));
        setBorder(BorderFactory.createTitledBorder(
                "Fractal controls"));
        JSpinnerPanel spinnerPanel = new JSpinnerPanel();

        // Create spinner
        iterSpinner = new JSpinner(new SpinnerNumberModel(
                mandelbrot.getMaxIteration(), 10, 100000, 50));

        // Add change listener using anonymus inner class
        iterSpinner.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                mandelbrot.setMaxIteration((Integer) iterSpinner.getValue());
                mandelbrot.calculatePicture();
            }
        });

        spinnerPanel.addSpinner(
                "Iterations", iterSpinner);

        // Create spinner
        final double xValue = mandelbrot.getCenter().getX();
        double width = mandelbrot.getXHighLimit() - mandelbrot.getXLowLimit();
        xSpinner = new CoordSpinner(xValue, width * COORD_SPINNER_STEP);

        // Add change listener using anonymus inner class
        xSpinner.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                Double newX = (Double) xSpinner.getValue();
                mandelbrot.setCenter(
                        new Coords(newX, mandelbrot.getCenter().getY()));
                mandelbrot.calculatePicture();
            }
        });

        spinnerPanel.addSpinner("X", xSpinner);

        // Create spinner
        final double yValue = mandelbrot.getCenter().getY();
        double height = mandelbrot.getYHighLimit() - mandelbrot.getYLowLimit();
        ySpinner = new CoordSpinner(yValue, height * COORD_SPINNER_STEP);

        // Add change listener using anonymus inner class
        ySpinner.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                Double newY = (Double) ySpinner.getValue();
                mandelbrot.setCenter(
                        new Coords(mandelbrot.getCenter().getX(), newY));
                mandelbrot.calculatePicture();
            }
        });

        spinnerPanel.addSpinner("Y", ySpinner);

        add(spinnerPanel);
    }

    private void installListeners() {
        mandelbrot.addPropertyChangeListener(
                JMandelbrot.CENTER_PROPERTY_NAME,
                new PropertyChangeListener() {
                    @Override
                    public void propertyChange(PropertyChangeEvent evt) {
                        double width = mandelbrot.getXHighLimit()
                                - mandelbrot.getXLowLimit();
                        double newX = mandelbrot.getCenter().getX();
                        xSpinner.updateModel(newX, width * COORD_SPINNER_STEP);
                        double height = mandelbrot.getYHighLimit()
                                - mandelbrot.getYLowLimit();
                        double newY = mandelbrot.getCenter().getY();
                        ySpinner.updateModel(newY, height * COORD_SPINNER_STEP);
                    }
                }
        );
    }

    // Customized spinner class
    // It uses special format for NumberEditor and has constant preferred width
    private static class CoordSpinner extends JSpinner {

        @Override
        protected JComponent createEditor(SpinnerModel model) {
            return new NumberEditor(this, "#.####################");
        }

        public CoordSpinner(double value, double stepSize) {
            super(new SpinnerNumberModel(value, null, null, stepSize));
        }

        //A useful shortcut method
        public void updateModel(double value, double stepSize) {
            SpinnerNumberModel model = (SpinnerNumberModel) getModel();
            model.setValue(value);
            model.setStepSize(stepSize);
        }

        @Override
        public Dimension getPreferredSize() {
            Dimension prefSize = super.getPreferredSize();
            prefSize.setSize(180, prefSize.getHeight());
            return prefSize;
        }
    }

}

class Palette {

    private final int minColor;
    private final int colorRange;
    private Color[] colors;
    private final int rSteps;
    private final int gSteps;
    private final int bSteps;
    private int totalRange;
    private int rRange;
    private int gRange;
    private int bRange;
    private final double rStart;
    private final double gStart;
    private final double bStart;

    Palette(int totalRange, int minColor, int maxColor, double rStart,
            double gStart, double bStart, int rSteps, int gSteps, int bSteps) {
        this.minColor = minColor;
        this.colorRange = maxColor - minColor;
        this.rStart = rStart;
        this.gStart = gStart;
        this.bStart = bStart;
        this.rSteps = rSteps;
        this.gSteps = gSteps;
        this.bSteps = bSteps;
        setSize(totalRange);
    }

    public void setSize(int newSize) {
        totalRange = newSize;
        rRange = totalRange / rSteps;
        gRange = totalRange / gSteps;
        bRange = totalRange / bSteps;
        fillColorTable();
    }

    private void fillColorTable() {
        colors = new Color[totalRange];
        for (int i = 0; i < totalRange; i++) {
            double cosR = Math.cos(i * 2 * Math.PI / rRange + rStart);
            double cosG = Math.cos(i * 2 * Math.PI / gRange + gStart);
            double cosB = Math.cos(i * 2 * Math.PI / bRange + bStart);
            Color color = new Color(
                    (int) ((cosR * colorRange) + colorRange) / 2 + minColor,
                    (int) ((cosG * colorRange) + colorRange) / 2 + minColor,
                    (int) ((cosB * colorRange) + colorRange) / 2 + minColor);
            colors[i] = color;
        }
    }

    public Color getColor(int index) {
        return colors[index];
    }

    public int getSize() {
        return totalRange;
    }
}

class PaletteChooser extends JPanel {

    private static final int MIN_COLOR = 50;
    private static final int MAX_COLOR = 255;
    private static final int R_STEPS = 5;
    private static final int G_STEPS = 5;
    private static final int B_STEPS = 5;
    private static final int R_ANGLE = 270;
    private static final int G_ANGLE = 90;
    private static final int B_ANGLE = 0;

    public static final String PALETTE_PROPERTY_NAME = "palette";
    private Palette palette;
    private final JPaletteShower shower;
    private final ChangeListener changeListener;

    private JSpinner rsSpinner;
    private JSpinner gsSpinner;
    private JSpinner bsSpinner;
    private JSpinner raSpinner;
    private JSpinner gaSpinner;
    private JSpinner baSpinner;

    PaletteChooser() {

        palette = new Palette(MAX_COLOR - MIN_COLOR, MIN_COLOR, MAX_COLOR,
                Math.toRadians(R_ANGLE), Math.toRadians(G_ANGLE),
                Math.toRadians(B_ANGLE), R_STEPS, G_STEPS, B_STEPS);
        shower = new JPaletteShower(palette, 250, 25);

        // Use single change listener for several spinners
        changeListener = new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                setPalette(createPalette());
                shower.setPalette(palette);
                repaint();
            }
        };


        setBorder(BorderFactory.createTitledBorder(
                "Color palette"));
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
        add(shower);
        add(createControlPanel());
    }

    private double toRadians(JSpinner spinner) {
        return Math.toRadians(getIntValue(spinner));
    }

    private Palette createPalette() {
        return new Palette(getWidth(), MIN_COLOR, MAX_COLOR,
                toRadians(raSpinner), toRadians(gaSpinner),
                toRadians(baSpinner), getIntValue(rsSpinner),
                getIntValue(gsSpinner), getIntValue(bsSpinner));
    }

    private static int getIntValue(JSpinner spinner) {
        return (Integer) spinner.getValue();
    }

    private JPanel createControlPanel() {
        JPanel controlPanel = new JPanel();
        controlPanel.setLayout(new GridLayout(1, 2));
        controlPanel.add(createStepPanel());
        controlPanel.add(createStartAnglePanel());
        return controlPanel;
    }

    private JPanel createStartAnglePanel() {
        JSpinnerPanel startAnglePanel = new JSpinnerPanel();
        startAnglePanel.setBorder(BorderFactory.createTitledBorder(
                "Start angle 0..360"));

        raSpinner = createAngleSpinner(R_ANGLE, "R", startAnglePanel);
        gaSpinner = createAngleSpinner(G_ANGLE, "G", startAnglePanel);
        baSpinner = createAngleSpinner(B_ANGLE, "B", startAnglePanel);

        return startAnglePanel;
    }

    private JPanel createStepPanel() {
        JSpinnerPanel stepPanel = new JSpinnerPanel();
        stepPanel.setBorder(BorderFactory.createTitledBorder(
                "Steps 1..1000"));

        rsSpinner = createStepSpinner(R_STEPS, "R", stepPanel);
        gsSpinner = createStepSpinner(G_STEPS, "G", stepPanel);
        bsSpinner = createStepSpinner(B_STEPS, "B", stepPanel);
        return stepPanel;
    }

    private JSpinner createAngleSpinner(int startAngle, String resourceName,
                                        JSpinnerPanel parent) {
        SpinnerModel model = new SpinnerNumberModel(startAngle, 0, 360, 10);
        return createSpinner(model, resourceName, parent);
    }

    private JSpinner createStepSpinner(int startSteps, String resourceName,
                                       JSpinnerPanel parent) {
        SpinnerModel model = new SpinnerNumberModel(startSteps, 1, 1000, 1);
        return createSpinner(model, resourceName, parent);
    }

    private JSpinner createSpinner(SpinnerModel model, String resourceName,
                                   JSpinnerPanel parent) {

        // Create spinner
        JSpinner spinner = new JSpinner(model);

        // Use single change listener for several spinners
        spinner.addChangeListener(changeListener);

        parent.addSpinner(resourceName, spinner);
        return spinner;
    }

    public Palette getPalette() {
        return palette;
    }

    private void setPalette(Palette palette) {
        Palette oldValue = this.palette;
        this.palette = palette;
        firePropertyChange(PALETTE_PROPERTY_NAME, oldValue, palette);
    }
}
```

*s8.postimg.org/kg9irl2y9/Spinner_Demo.jpg

* JFileChooser*

File choosers provide a GUI for navigating the file system, and then either choosing a file or directory from a list, or entering the name of a file or directory. To display a file chooser, you usually use the JFileChooser API to show a modal dialog containing the file chooser. Another way to present a file chooser is to add an instance of JFileChooser to a container.
The JFileChooser API makes it easy to bring up open and save dialogs. The type of look and feel determines what these standard dialogs look like and how they differ. In the Java look and feel, the save dialog looks the same as the open dialog, except for the title on the dialog's window and the text on the button that approves the operation. 
By default, a file chooser displays all of the files and directories that it detects, except for hidden files. A program can apply one or more file filters to a file chooser so that the chooser shows only some files. The file chooser calls the filter's accept method for each file to determine whether it should be displayed. A file filter accepts or rejects a file based on criteria such as file type, size, ownership, and so on. Filters affect the list of files displayed by the file chooser. The user can enter the name of any file even if it is not displayed.
The file chooser GUI provides a list of filters that the user can choose from. When the user chooses a filter, the file chooser shows only those files accepted by that filter. FileChooserDemo2 adds a custom file filter to the list of user-choosable filters:

fc.addChoosableFileFilter(new ImageFilter());

By default, the list of user-choosable filters includes the Accept All filter, which enables the user to see all non-hidden files. This example uses the following code to disable the Accept All filter:

fc.setAcceptAllFileFilterUsed(false);

Launch the program & select a Image(s). The selected Images will be shown in a tabbedPane.
You can select more than one Image by holding & pressing the SHIFT key , selecting as many Images as you like.


```
/**
 * Created with IntelliJ IDEA.
 * User: JGuru
 * Date: 8/3/14
 * Time: 1:48 PM
 * To change this template use File | Settings | File Templates.
 */
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import javax.swing.plaf.basic.BasicFileChooserUI;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Sowndar
 */

public class FileChooserDemo extends JFrame implements ActionListener {

    private String path = "Images/";
    private JMenu menu = new JMenu("File", true);
    private JMenuItem open = new JMenuItem("Open");
    private JMenuItem exit = new JMenuItem("Exit");
    private JMenuBar mBar = new JMenuBar();
    private JFileChooser fChooser = new JFileChooser(path);
    private JLabel previewLabel = new JLabel();
    private File file;
    private int X = 10, Y = 10;
    private String[] readFormat = ImageIO.getReaderFormatNames();
    private Image image;
    private JTabbedPane tabbedPane = new JTabbedPane();

    public void updateUI() {
        menu.updateUI();
        open.updateUI();
        exit.updateUI();
        mBar.updateUI();
        fChooser.updateUI();
        previewLabel.updateUI();
        tabbedPane.updateUI();
    }

    public FileChooserDemo() {

        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException | IllegalAccessException | InstantiationException | UnsupportedLookAndFeelException e) {
            // Do nothing
        }
        updateUI();
        Dimension scrDim = Toolkit.getDefaultToolkit().getScreenSize();

        open.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_DOWN_MASK));
        exit.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E, KeyEvent.CTRL_DOWN_MASK));
        menu.add(open);
        menu.add(exit);
        mBar.add(menu);

        setJMenuBar(mBar);
        // Add action listener
        open.addActionListener(this);
        exit.addActionListener(this);

        previewLabel.setPreferredSize(new Dimension(250, 150));
        previewLabel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
        previewLabel.setHorizontalAlignment(SwingConstants.CENTER);
        previewLabel.setVerticalAlignment(SwingConstants.CENTER);
        // Show Image preview
        fChooser.setAccessory(previewLabel);
        fChooser.setPreferredSize(new Dimension(750, 500));
        fChooser.setAcceptAllFileFilterUsed(false);
        // Choose as many files as you intend to
        fChooser.setMultiSelectionEnabled(true);
        fChooser.setDragEnabled(true);
        // Set a File filter
        fChooser.addChoosableFileFilter(new javax.swing.filechooser.FileFilter() {

            @Override
            public boolean accept(File f) {
                String name = f.getName();
                for (int i = 0; i < readFormat.length; i++) {
                    if (f.isDirectory() || name.endsWith(readFormat[i])) {
                        return true;
                    }
                }
                return false;
            }

            @Override
            public String getDescription() {
                return "Image Filter";
            }
        });

        fChooser.addPropertyChangeListener(new PropertyChangeListener() {

            @Override
            public void propertyChange(final PropertyChangeEvent evt) {
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        boolean update = false;
                        String prop = evt.getPropertyName();

                        //If the directory changed, don't show an image.
                        if (JFileChooser.DIRECTORY_CHANGED_PROPERTY.equals(prop)) {
                            file = null;
                            update = true;

                            //If a file became selected, find out which one.
                        } else if (JFileChooser.SELECTED_FILE_CHANGED_PROPERTY.equals(prop)) {
                            file = (File) evt.getNewValue();
                            update = true;
                        }

                        if (update) {
                            if (file != null) {
                                //Show the Image preview
                                previewLabel.setIcon(null);
                                previewLabel.setText("Processing, Please wait...");
                                image = getImage(file.toString());
                                previewLabel.setIcon(new ImageIcon(setImage(image)));
                                previewLabel.setText("");
                            } else {
                                image = null;
                                previewLabel.setIcon(null);
                                previewLabel.setText("");
                            }
                        }
                    }
                }).start();
            }
        });
        tabbedPane.setBackground(getBackground());
        add(tabbedPane);
        setSize(scrDim.width / 2 + 150, scrDim.height);
        setTitle("FileChooserDemo");
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    @Override
    public void actionPerformed(ActionEvent ae) {
        Object source = ae.getSource();
        if (source == open) {
            // Open the file
            //Don't show any preview until the user selects an Image
            previewLabel.setIcon(null);
            fChooser.setSelectedFile(null);
            BasicFileChooserUI ui = (BasicFileChooserUI) fChooser.getUI();
            ui.setFileName("");
            int returnVal = fChooser.showOpenDialog(null);
            if (returnVal == JFileChooser.APPROVE_OPTION) {
                new Thread(new Runnable() {

                    @Override
                    public void run() {
                        // Get the selected files
                        //You can select more than one file by pressing & holding the SHIFT key & selecting as many as you like!!
                        File []file = fChooser.getSelectedFiles();
                        if (file != null) {
                            //Remove all the previously added Components
                            tabbedPane.removeAll();
                            for (int i = 0; i < file.length; i++) {
                                tabbedPane.addTab(file[i].getName(), getIcon(getImage(file[i].toString())), new JScrollPane(new JLabel(new ImageIcon(getImage(file[i].toString())))));
                            }
                            //Enable the Components
                            setEnabled(true);
                        }
                    }
                }).start();
            }
        }
        else
        {
            System.exit(0);
        }
    }

    public ImageIcon getIcon(Image image) {
        if (image != null) {
            return new ImageIcon(image.getScaledInstance(32, 32, Image.SCALE_SMOOTH));
        }
        return null;
    }

    public Image setImage(Image image) {
        if (image != null) {
            int imgWidth = image.getWidth(null);
            int imgHeight = image.getHeight(null);
            double aspect = ((double) imgWidth) / ((double) imgHeight);
            int maxWidth, maxHeight;

            // If aspect ratio exceeds 1.3333
            if (aspect > 1.3333) {
                // Fix the width as maxWidth, calculate the maxHeight
                maxWidth = 260;
                maxHeight = (int) (((double) maxWidth) / aspect);
            } else {
                // Fix the height as iconHeight, calculate the maxWidth for this
                maxHeight = 240;
                maxWidth = (int) (((double) maxHeight) * aspect);
            }
            return image.getScaledInstance(maxWidth, maxHeight, Image.SCALE_SMOOTH);
        }
        return null;
    }

    //Get the Image from the disk
    public Image getImage(String fileName) {
        if(fileName.endsWith("jpg")|| fileName.endsWith("png")) {
            return new ImageIcon(fileName).getImage();
        }
        try {
            return ImageIO.read(new File(fileName));
        } catch (IOException ioe) {
            System.err.println("Error loading Image : " + fileName);
        }
        return null;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new FileChooserDemo();
            }
        });
    }
}
```

*s30.postimg.org/ti570ic25/File_Chooser.jpg

*Look and Feel*

Swing's architecture enables multiple L&Fs by separating every component into two distinct classes: a JComponent subclass and a corresponding ComponentUI subclass. For example, every JList instance has a concrete implementation of ListUI (ListUI extends ComponentUI). The ComponentUI subclass is referred to by various names in Swing's documentation—"the UI," "component UI," "UI delegate," and "look and feel delegate" are all used to identify the ComponentUI subclass.

Most developers never need to interact with the UI delegate directly. For the most part, the UI delegate is used internally by the JComponent subclass for crucial functionality, with cover methods provided by the JComponent subclass for all access to the UI delegate. For example, all painting in JComponent subclasses is delegated to the UI delegate. By delegating painting, the 'look' can vary depending upon the L&F.

To programatically specify a L&F, use the UIManager.setLookAndFeel() method with the fully qualified name of the appropriate subclass of LookAndFeel as its argument. For example, the bold code in the following snippet makes the program use the cross-platform Java L&F:


```
public static void main(String[] args) {
    try {
            // Set cross-platform Java L&F (also called "Metal")
        UIManager.setLookAndFeel(
            UIManager.getCrossPlatformLookAndFeelClassName());
    } 
    catch (UnsupportedLookAndFeelException e) {
       // handle exception
    }
    catch (ClassNotFoundException e) {
       // handle exception
    }
    catch (InstantiationException e) {
       // handle exception
    }
    catch (IllegalAccessException e) {
       // handle exception
    }
        
    new SwingApplication(); //Create and show the GUI.
}
```

Alternatively, this code makes the program use the System L&F:


```
public static void main(String[] args) {
    try {
            // Set System L&F
        UIManager.setLookAndFeel(
            UIManager.getSystemLookAndFeelClassName());
    } 
    catch (UnsupportedLookAndFeelException e) {
       // handle exception
    }
    catch (ClassNotFoundException e) {
       // handle exception
    }
    catch (InstantiationException e) {
       // handle exception
    }
    catch (IllegalAccessException e) {
       // handle exception
    }

    new SwingApplication(); //Create and show the GUI.
}
```

Specifying the Look and Feel: Command Line

You can specify the L&F at the command line by using the -D flag to set the swing.defaultlaf property. For example:

java -Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel MyApp

java -Dswing.defaultlaf=com.sun.java.swing.plaf.windows.WindowsLookAndFeel MyApp

Changing the Look and Feel After Startup

You can change the L&F with setLookAndFeel even after the program's GUI is visible. To make existing components reflect the new L&F, invoke the SwingUtilities updateComponentTreeUI method once per top-level container. Then you might wish to resize each top-level container to reflect the new sizes of its contained components. For example:


```
UIManager.setLookAndFeel(lnfName);
SwingUtilities.updateComponentTreeUI(frame);
frame.pack();
```

The following program shows the different look'n feel that are available. By select a look'n feel that program changes the look
to that look'n feel!!

```
//Get the available Look n Feel!!

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class ChangingLaF extends JFrame {

    private static ButtonGroup group = new ButtonGroup();

    ChangingLaF() {
        super("Changing LAF");
        JPanel myPanel = new JPanel();
        getContentPane().add(myPanel, BorderLayout.SOUTH);
        setLaFButtons(myPanel);
        add(new JFileChooser(), BorderLayout.CENTER);
        pack();
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    private void setLaFButtons(JPanel choices) {
        installGTK();
        UIManager.LookAndFeelInfo[] laf = UIManager.getInstalledLookAndFeels();
        choices.setLayout(new GridLayout(laf.length, 1));
        LaFButton lafButton = null;
        for (int i = 0; i < laf.length; i++) {
            lafButton = new LaFButton(laf[i]);
            choices.add(lafButton);
        }
        // Select the last option in the look 'n feel
        lafButton.doClick();
    }

    private void installGTK() {
        try {
            String GTK = "com.sun.java.swing.plaf.gtk.GTKLookAndFeel";
            UIManager.setLookAndFeel(GTK);
            UIManager.installLookAndFeel("GTK", GTK);
        } catch (Exception e) {
            System.err.println("Could not install GTK");
        }
    }

    private class LaFButton extends JRadioButton implements ActionListener {

        LaFButton(UIManager.LookAndFeelInfo laf) {
            super(laf.getClassName());
            group.add(this);
            addActionListener(this);
        }

        @Override
        public void actionPerformed(ActionEvent event) {
            try {
                UIManager.setLookAndFeel(getText());
                SwingUtilities.updateComponentTreeUI(
                        ChangingLaF.this);
                // call myFrame.pack()
                // to resize frame for laf
            } catch (IllegalAccessException e) {
                // insert code to handle this exception
            } catch (UnsupportedLookAndFeelException e) {
                // insert code to handle this exception
            } catch (InstantiationException e) {
                // insert code to handle this exception
            } catch (ClassNotFoundException e) {
                // insert code to handle this exception
            }
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ChangingLaF();
            }
        });
    }
}
```

*s22.postimg.org/x7x5gz89p/Changing_La_F.jpg

*Drag And Drop Support*

Technically speaking, the framework for drag and drop supports all Swing components — the data transfer mechanism is built into every JComponent. If you wanted, you could implement drop support for a JSlider so that it could fully participate in data transfer. While JSlider does not support drop by default, the components you would want (and expect) to support drag and drop do provide specialized built-in support.

The following components recognize the drag gesture once the setDragEnabled(true) method is invoked on the component. For example, once you invoke myColorChooser.setDragEnabled(true) you can drag colors from your color chooser:

    JColorChooser
    JEditorPane
    JFileChooser
    JFormattedTextField
    JList
    JTable
    JTextArea
    JTextField
    JTextPane
    JTree

The following components support drop out of the box. If you are using one of these components, your work is done.

    JEditorPane
    JFormattedTextField
    JPasswordField
    JTextArea
    JTextField
    JTextPane
    JColorChooser

The framework for drop is in place for the following components, but you need to plug in a small amount of code to customize the support for your needs.

    JList
    JTable
    JTree

For these critical components, Swing performs the drop location calculations and rendering; it allows you to specify a drop mode; and it handles component specific details, such as tree expansions. Your work is fairly minimal.

The following program shows how to implement DnD support for a JLabel.


```
// ImageDropper.java
// A simple drag & drop tester application.
//
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;

public class ImageDropper extends JFrame implements DropTargetListener {

    private DropTarget dt;
    private JLabel label;
    private java.util.List list;
    private Image image;
    private String fileName;

    public ImageDropper() {
        super("ImageDropper");
        setSize(800, 600);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        add(new JLabel("Drop an Image from the O.S!!"), BorderLayout.NORTH);
        label = new JLabel();
        label.setVerticalAlignment(SwingConstants.CENTER);
        label.setHorizontalAlignment(SwingConstants.CENTER);
        JScrollPane scroller = new JScrollPane(label);
        add(scroller, BorderLayout.CENTER);

        // Set up our text area to recieve drops...
        // This class will handle drop events
        dt = new DropTarget(label, this);
        setVisible(true);
    }

    @Override
    public void dragEnter(DropTargetDragEvent dtde) {
        System.out.println("Drag Enter");
    }

    @Override
    public void dragExit(DropTargetEvent dte) {
        System.out.println("Source: " + dte.getSource());
        System.out.println("Drag Exit");
    }

    @Override
    public void dragOver(DropTargetDragEvent dtde) {
        System.out.println("Drag Over");
    }

    @Override
    public void dropActionChanged(DropTargetDragEvent dtde) {
        System.out.println("Drop Action Changed");
    }

    @Override
    public void drop(DropTargetDropEvent dtde) {
        try {
            // Ok, get the dropped object and try to figure out what it is
            Transferable tr = dtde.getTransferable();
            DataFlavor[] flavors = tr.getTransferDataFlavors();
            for (int i = 0; i < flavors.length; i++) {
                System.out.println("Possible flavor: " + flavors[i].getMimeType());
                // Check for file lists specifically
                if (flavors[i].isFlavorJavaFileListType()) {
                    // Great!  Accept copy drops...
                    dtde.acceptDrop(DnDConstants.ACTION_COPY);
                    System.out.println("Successful file list drop.\n\n");

                    // And add the list of file names to our JLabel
                    list = (java.util.List) tr.getTransferData(flavors[i]);
                    for (int j = 0; j < list.size(); j++) {
                        setCursor(new Cursor(Cursor.WAIT_CURSOR));
                        fileName = "" + list.get(j);
                        image = getImage(fileName);
                        if (image != null) {
                            label.setIcon(new ImageIcon(image));
                            repaint();
                            setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
                        } else {
                            JOptionPane.showMessageDialog(null, "Not a valid Image!!");
                            setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
                        }

                    }
                    // If we made it this far, everything worked.
                    dtde.dropComplete(true);
                    return;
                }
            }
            // Hmm, the user must not have dropped a file list
            System.out.println("Drop failed: " + dtde);
            dtde.rejectDrop();
        } catch (UnsupportedFlavorException | IOException e) {
            dtde.rejectDrop();
        }
    }

    public BufferedImage getImage(String fileName) {
        try {
            return ImageIO.read(new File(fileName));
        } catch (IOException ioe) {
            System.err.println("Error loading Image!!");
        }
        return null;
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ImageDropper();
            }
        });
    }
}
```

[img=*s30.postimg.org/um7ovfq8d/Image_Dropper.jpg]

Launch the application. Drag & drop an Image(JPEG, GIF, PNG, BMP) from the Windows Explorer into the JFrame.
This program fetches the Image from the disk & displays it.	

To master Java Swing (JFC) study these books: 

1) Java Tutorial 5th Edition

2) JFC Unleashed (Techmedia)

3) Java Swing by Eckstein 5th Edition (Oreilly)

4) The Java Developers Almanac 1.4 ( 2 Volumes)

5) John Zukowski's Definitive Guide to Swing 

6) Graphic Java 2 : Volume 2 Swing , Mastering the JFC by David M Geary

Remember mastering JFC takes a long time. So be patient & work hard to master them.
The more programs you write , the more comfortable you'll be!!


----------



## Shah (Sep 25, 2014)

Those pics in the screenshot are NSFW. Please change/remove them.


----------



## Desmond (Sep 25, 2014)

"I find your choice of images....disturbing."

*img3.wikia.nocookie.net/__cb20130221005632/starwars/images/thumb/4/42/I_find_your_lack_of_faith_disturbing.png/1024px-I_find_your_lack_of_faith_disturbing.png

Dude, please change the images or the mods will have a field day banning you.


----------



## Faun (Sep 25, 2014)

Stick to JAVA. No nsfw pics.


----------



## JGuru (Nov 10, 2014)

Thanks Mods. Posted Images suitable for the Young audience.
The original Images (Screenshots) were posted by my friend on my behalf.


----------



## archananair (Mar 13, 2015)

Good to know about this java swing i was not much aware about it.
The post being really useful and informative.


----------

