Using a JList component as a cell inside a JTable

JListTableExample.java:

import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
  
public class JListTableExample extends JFrame {
 
  public JListTableExample() {
    super( "JList inside JTable Example" );
  
    DefaultTableModel dtm = new DefaultTableModel() {
       // make first cell uneditable
       public boolean isCellEditable(int row, int column)
       {
          return !(column == 0);
       }
    };

    final MyListModel dlm1 = new MyListModel(new Object[] { "value1", "value2", "value3",
                                                            "value4", "value5", "value6" });
    final MyListModel dlm2 = new MyListModel(new Object[] { "value7", "value8", "value9",
                                                            "value10", "value11", "value12" });

    dtm.setDataVector(new Object[][]{ { "JList1", dlm1},
                                      { "JList2", dlm2} },
                      new Object[]{ "String","JList"});
                     
    JTable table = new JTable(dtm);
    table.getColumn("JList").setCellRenderer(new JListRenderer());
    table.getColumn("JList").setCellEditor(new JListEditor());
    table.setRowHeight(80);

    JButton addButton = new JButton("Add an element to List1");
    addButton.addActionListener(new ActionListener() {
       public void actionPerformed(ActionEvent ae) {
          dlm1.addElement("new value");
       }
    });

    JScrollPane scroll = new JScrollPane(table);
    getContentPane().setLayout(new BorderLayout(10, 10));
    getContentPane().add(BorderLayout.CENTER, scroll);
    getContentPane().add(BorderLayout.SOUTH, addButton);

    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) { 
        System.out.println(dlm1);
        System.out.println(dlm2);
        System.exit(0);
      }
    });
  }
 
  public static void main(String[] args) {
    JListTableExample frame = new JListTableExample();
 
    frame.setSize(400, 250);
    frame.setVisible(true);
  }
}
  
class JListRenderer extends JScrollPane implements TableCellRenderer
{
   JList list;
 
   public JListRenderer() {
      list = new JList();
      list.setSelectionBackground(Color.red);
      getViewport().add(list);
   }
 
   public Component getTableCellRendererComponent(JTable table, Object value,
                                  boolean isSelected, boolean hasFocus,
                                  int row, int column)
   {
      if (isSelected) {
         setForeground(table.getSelectionForeground());
         setBackground(table.getSelectionBackground());
         list.setForeground(table.getSelectionForeground());
         list.setBackground(table.getSelectionBackground());
      } else {
         setForeground(table.getForeground());
         setBackground(table.getBackground());
         list.setForeground(table.getForeground());
         list.setBackground(table.getBackground());
      }
 
      list.setModel((MyListModel) value) ;
      list.setSelectedIndices(((MyListModel) value).getSelectedIndices());

      return this;
   }
}

class JListEditor extends DefaultCellEditor {
   protected JScrollPane scrollpane;
   protected JList list; 
   protected MyListModel mlm;
 
   public JListEditor() {
      super(new JCheckBox());
      scrollpane = new JScrollPane();
      list = new JList();  
//      list.setSelectionForeground(Color.red);
      list.setSelectionBackground(Color.red);
      scrollpane.getViewport().add(list);
   }
 
   public Component getTableCellEditorComponent(JTable table, Object value,
                                   boolean isSelected, int row, int column) {
      list.setModel((MyListModel) value);

      mlm = (MyListModel) value;

      return scrollpane;
   }
 
   public Object getCellEditorValue() {
      mlm.setSelectedIndices(list.getSelectedIndices());
      return mlm;
   }
}


class MyListModel extends DefaultListModel
{
   private int[] selectedIndices;

   public MyListModel(Object[] data) {
      for (int i=0; i<data.length; i++) {
         addElement(data[i]);
      }
   }

   public void setSelectedIndices(int[] selectedIndices) {
      this.selectedIndices = selectedIndices;
   }

   public int[] getSelectedIndices() {
      if (selectedIndices == null) return new int[]{};
      return selectedIndices;
   }
 
   public String toString() {
      StringBuffer sb = new StringBuffer();
      sb.append(super.toString());
      if (selectedIndices != null) {
         sb.append("nSelected:n");
         for (int i=0; i<selectedIndices.length; i++) {
            sb.append(get(selectedIndices[i]) + "n");
         }
      }
      return sb.toString();
   }
}

Changing the font size of the column headers in a JTable

Main.java:

import javax.swing.table.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame 
{
   public Main() {
      super("Table example, Wines from Bordeaux");
 
      Object[][] tabledata = {
            { "Chateau Meyney, St. Estephe", 	   new Integer(1994), "$18.75"},
            { "Chateau Montrose, St. Estephe", 	   new Integer(1975), "$54.25" },
            { "Chateau Gloria, St. Julien", 	   new Integer(1993), "$22.99" },
            { "Chateau Beychevelle, St. Julien",   new Integer(1970), "$61.63" },
            { "Chateau La Tour de Mons, Margeaux", new Integer(1975), "$57.03" },
            { "Chateau Brane-Cantenac, Margeaux",  new Integer(1978), "$49.92" },
      };
 
      String columnheaders[] = { "Wine", "Vintage", "Price" };
 
      JTable table = new JTable(tabledata, columnheaders);
      table.setPreferredScrollableViewportSize(new Dimension(500, 70));
      JScrollPane scrollPane = new JScrollPane(table);
 
      // set font for headers
      Font f = new Font("Arial", Font.BOLD, 25);
      JTableHeader header = table.getTableHeader();
      header.setFont(f);

      getContentPane().add(scrollPane);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
 
      pack();
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.show();
   }
}

Displaying a popup menu when right-clicking on a JTree node

Main.java:

import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import java.awt.*;
import java.net.*;
import java.awt.event.*;
 
public class Main extends JFrame
{
   public Main() {
      DefaultMutableTreeNode root = createNodes();
      JTree tree = new JTree(root);
 
      final TreePopup treePopup = new TreePopup(tree);
      tree.addMouseListener(new MouseAdapter() {
         public void mouseReleased (MouseEvent e) {
            if (e.isPopupTrigger()) {
               treePopup.show(e.getComponent(), e.getX(), e.getY());
            }
         }
      });
  
      getContentPane().add(new JScrollPane(tree));
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
   }
 
   public static DefaultMutableTreeNode createNodes() {
      DefaultMutableTreeNode root = new DefaultMutableTreeNode("Java");
      
      DefaultMutableTreeNode j2se = new DefaultMutableTreeNode("J2SE");
      DefaultMutableTreeNode j2ee = new DefaultMutableTreeNode("J2EE");
      DefaultMutableTreeNode j2me = new DefaultMutableTreeNode("J2ME");
 
      j2se.add(new DefaultMutableTreeNode("http://java.sun.com/j2se/"));
      j2ee.add(new DefaultMutableTreeNode("http://java.sun.com/j2ee/"));
      j2me.add(new DefaultMutableTreeNode("http://java.sun.com/j2me/"));
 
      root.add(j2se);
      root.add(j2ee);
      root.add(j2me);
 
      return root;
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(400, 400);
      main.setVisible(true);
   }
}
 
class TreePopup extends JPopupMenu {
   public TreePopup(JTree tree) {
      JMenuItem itemDelete = new JMenuItem("Delete");
      JMenuItem itemAdd = new JMenuItem("Add");
      itemDelete.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            System.out.println("Delete child");
         }
      });
      itemAdd.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            System.out.println("Add child");
         }
      });
 
      add(itemDelete);
      add(new JSeparator());
      add(itemAdd);
   }
}

Creating an editable JList

Courtesy of Nobuo Tamemasa (http://www2.gol.com/users/tame/swing/examples/JTableExamples1.html)



EditableListExample.java:

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
 
/**
 * @version 1.0 12/24/98
 */
public class EditableListExample extends JFrame {
 
  public EditableListExample() {
    super(&quot;Editable List Example&quot;);
    
    String[] data = {&quot;a&quot;,&quot;b&quot;,&quot;c&quot;,&quot;d&quot;,&quot;e&quot;,&quot;f&quot;,&quot;g&quot;};
    
    JList list = new JList( data );
    JScrollPane scrollList = new JScrollPane( list );
    scrollList.setMinimumSize(new Dimension(100,80));
    Box listBox = new Box(BoxLayout.Y_AXIS);
    listBox.add(scrollList);
    listBox.add(new JLabel(&quot;JList&quot;));
         
    DefaultTableModel dm = new DefaultTableModel();
    Vector dummyHeader = new Vector();
    dummyHeader.addElement(&quot;&quot;);
    dm.setDataVector(
      strArray2Vector(data),
      dummyHeader);
    JTable table = new JTable( dm );
    table.setShowGrid(false);
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    JScrollPane scrollTable = new JScrollPane( table );
    scrollTable.setColumnHeader(null);
    scrollTable.setMinimumSize(new Dimension(100,80));
    Box tableBox = new Box(BoxLayout.Y_AXIS);
    tableBox.add(scrollTable);
    tableBox.add(new JLabel(&quot;JTable&quot;));
    
    Container c = getContentPane();
    c.setLayout(new BoxLayout(c, BoxLayout.X_AXIS));
    c.add(listBox);
    c.add(new JSeparator(SwingConstants.VERTICAL));
    //c.add(new JLabel(&quot;test&quot;));
    //c.add(new JSeparator(SwingConstants.HORIZONTAL));
    c.add(tableBox);
    setSize( 220, 130 );
    setVisible(true);
  } 
   
  private Vector strArray2Vector(String[] str) {
    Vector vector = new Vector();
    for (int i=0;i&lt;str.length;i++) {
      Vector v = new Vector();
      v.addElement(str[i]);
      vector.addElement(v);
    }
    return vector;
  }

  public static void main(String[] args) {
    final EditableListExample frame = new EditableListExample();
    frame.addWindowListener( new WindowAdapter() {
      public void windowClosing( WindowEvent e ) {
        System.exit(0);
      }
    });
  }
}

Changing the color of one JTable cell

Main.java:

import javax.swing.table.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
 
public class Main extends JFrame {
   public Main() {
      super("TableModel Demonstration");
  
      // create our own custom TableModel
      WineTableModel wineModel = new WineTableModel();
      JTable table = new JTable(wineModel);
 
      // since we're using values of floats and boolean here, we need
      // to set the cell renderer for every column. 
      for (int i =0; i<wineModel.getColumnCount();i++) {
         table.setDefaultRenderer(table.getColumnClass(i), new WineCellRenderer());
      }
       
      // add rows to our TableModel, each row is represented as a Wine object
      wineModel.addWine(new Wine("Chateau Meyney, St. Estephe", "1994", 18.75f, true));
      wineModel.addWine(new Wine("Chateau Montrose, St. Estephe", "1975", 54.25f, true));
      wineModel.addWine(new Wine("Chateau Gloria, St. Julien", "1993", 22.99f, false));
      wineModel.addWine(new Wine("Chateau Beychevelle, St. Julien", "1970", 61.63f, false));
      wineModel.addWine(new Wine("Chateau La Tour de Mons, Margeaux", "1975", 57.03f, true));
      wineModel.addWine(new Wine("Chateau Brane-Cantenac, Margeaux", "1978", 49.92f, false));
 
      // create the scroll pane and add the table to it. 
      JScrollPane scrollPane = new JScrollPane(table);
 
      // add the scroll pane to this window.
      getContentPane().add(scrollPane, BorderLayout.CENTER);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            System.exit(0);
         }
      });
   }
 
   public static void main(String[] args) {
      Main main = new Main();
      main.pack();
      main.setVisible(true);
   }
}
 
// a simple object that holds data about a particular wine
class Wine {
   private String  name;
   private String  vintage;
   private float   price;
   private boolean inStock;
 
   public Wine(String name, String vintage, float price, boolean inStock) {
      this.name = name;
      this.vintage = vintage;
      this.price = price;
      this.inStock = inStock;
   }
 
   public String getName()     { return name; }
   public String getVintage()  { return vintage; }
   public float  getPrice()    { return price; } 
   public boolean getInStock() { return inStock; }
 
   public String toString() { 
      return "[" + name + ", " + vintage + ", " + price + ", " + inStock + "]"; }
}
 
class WineTableModel extends AbstractTableModel {
   // holds the strings to be displayed in the column headers of our table
   final String[] columnNames = {"Name", "Vintage", "Price", "In stock?"};
 
   // holds the data types for all our columns
   final Class[] columnClasses = {String.class, String.class, Float.class, Boolean.class};
 
   // holds our data
   final Vector data = new Vector();
  
   // adds a row
   public void addWine(Wine w) {
      data.addElement(w);
      fireTableRowsInserted(data.size()-1, data.size()-1);
   }
 
   public int getColumnCount() {
      return columnNames.length;
   }
         
   public int getRowCount() {
      return data.size();
   }
 
   public String getColumnName(int col) {
      return columnNames[col];
   }
 
   public Class getColumnClass(int c) {
      return columnClasses1;
   }
 
   public Object getValueAt(int row, int col) {
      Wine wine = (Wine) data.elementAt(row);
      if (col == 0)      return wine.getName();
      else if (col == 1) return wine.getVintage();
      else if (col == 2) return new Float(wine.getPrice());
      else if (col == 3) return new Boolean(wine.getInStock());
      else return null;
   }
 
   public Object getValueAtRow(int row) {
      Wine wine = (Wine) data.elementAt(row);
      return wine;
   }
 
   public boolean isCellEditable(int row, int col) {
      return false;
   }
}
 
class WineCellRenderer extends DefaultTableCellRenderer {
   public Component getTableCellRendererComponent(
            JTable table, Object value, boolean isSelected,
            boolean hasFocus, int row, int column)
   {
      WineTableModel wtm = (WineTableModel) table.getModel();
      Wine wine = (Wine) wtm.getValueAtRow(row);
 
      if (column == 3 && wine.getInStock() == false) {
         setBackground(Color.red);
      }
      else {
         setBackground(Color.white);
      }
 
      return super.getTableCellRendererComponent(table, value, isSelected, 
                                                 hasFocus, row, column);
   }
}

Detecting JScrollPane events

Add a AdjustmentListener to the horizontal or vertical scrollbar of the JScrollPane (you can get its reference with the methods getHorizontalScrollBar and getVerticalScrollBar).

Note that the AdjustmentType will always be AdjustmentEvent.TRACK.
(From the API: “Note that the AdjustmentEvents type property will always have a placeholder value of AdjustmentEvent.TRACK because all changes to a BoundedRangeModels value are considered equivalent. To change the value of a BoundedRangeModel one just sets its value property, i.e. model.setValue(123). No information about the origin of the change, e.g. it’s a block decrement, is provided. We don’t try fabricate the origin of the change here.”)

Main.java:

import javax.swing.table.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame
{
   public Main() throws Exception {
      getContentPane().setLayout(new BorderLayout());
 
      JPanel panel = createPanel();
 
      JScrollPane scrollpane = new JScrollPane(panel);
      JScrollBar scrollbar = scrollpane.getVerticalScrollBar();
      scrollbar.addAdjustmentListener(new AdjustmentListener() {
         public void adjustmentValueChanged(AdjustmentEvent ae) {
            System.out.println(translateAdjustmentEvent(ae));
         }
      });
 
      getContentPane().add(BorderLayout.CENTER, scrollpane);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
   }
 
   public String translateAdjustmentEvent(AdjustmentEvent ae) {
      String s = "type = ";
      switch(ae.getAdjustmentType()) {
         case AdjustmentEvent.UNIT_INCREMENT:
            s += "UNIT_INCREMENT"; break;
         case AdjustmentEvent.UNIT_DECREMENT:
            s += "UNIT_DECREMENT"; break;
         case AdjustmentEvent.BLOCK_INCREMENT:
            s += "BLOCK_INCREMENT"; break;
         case AdjustmentEvent.BLOCK_DECREMENT:
            s += "BLOCK_DECREMENT"; break;
         case AdjustmentEvent.TRACK:
            s += "TRACK"; break;
         default: break;
      }
      s += ", current value = " + ae.getValue();
 
      return s;
   }
 
   public static JPanel createPanel() throws Exception {
      JPanel panel = new JPanel();
      panel.setLayout(new GridLayout(50, 20, 10, 10));
 
      for (int i=0; i<50; i++) {
         for (int j=0; j<20; j++) {
            JLabel label = new JLabel("label " + i + ", " + j);
            panel.add(label);    
         }
      }
 
      return panel;
   }
 
   public static void main(String [] args) throws Exception  {
      Main main = new Main();
      main.setSize(600, 600);
      main.setVisible(true);
   } 
} 

Programmatically iconify a JInternalFrame

Use the following line of code:

   frame.getDesktopPane().getDesktopManager().iconifyFrame(frame);

Main.java:

import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
import java.net.*;
 
public class Main extends JFrame {
   JDesktopPane desktop;
   int nframes = 0;
   Hashtable frames = new Hashtable();
 
   JMenu internalFrameMenu;
   Action iconifyAction = new IconifyAction();

   public Main() {
      desktop = new JDesktopPane(); 
      setContentPane(desktop);
      setJMenuBar(createMenuBar());
      createInternalFrame(); 
   }
 
   protected JMenuBar createMenuBar() {
      JMenuBar menuBar = new JMenuBar();
 
      JMenu createMenu = new JMenu("Create");
      createMenu.setMnemonic(KeyEvent.VK_C);
      JMenuItem newMenuItem = new JMenuItem("New");
      newMenuItem.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            createInternalFrame();
         }
      }); 
      newMenuItem.setMnemonic(KeyEvent.VK_N);
      createMenu.add(newMenuItem);
      menuBar.add(createMenu);
 
      internalFrameMenu = new JMenu("Iconify");
      internalFrameMenu.setMnemonic(KeyEvent.VK_I);
  
      menuBar.add(internalFrameMenu);     
 
      return menuBar;
   }
 
   protected void createInternalFrame() {
      nframes++;
      String title = "JInternalFrame #" + nframes;
      JInternalFrame frame = new JInternalFrame(title,
         true,    // resizable
         true,    // closable
         true,    // maximizable
         true);   // iconifiable
      frame.setVisible(true); 
      desktop.add(frame);
      frame.setSize(200, 200);
      frame.setLocation(30*nframes, 30*nframes);
      try {
         frame.setSelected(true);
      } catch (java.beans.PropertyVetoException e) {}
 
      JMenuItem menuItem = new JMenuItem(title);
      internalFrameMenu.add(menuItem);
      menuItem.addActionListener(iconifyAction);
      frames.put(title, frame);
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(500, 300);
      main.setVisible(true);
   }
 
   public class IconifyAction extends AbstractAction
   {
      public IconifyAction() {
         super("Iconify Action");
      }
 
      public void actionPerformed(ActionEvent ae) {
         JInternalFrame frame = (JInternalFrame) frames.get(((JMenuItem) ae.getSource()).getText());
         frame.getDesktopPane().getDesktopManager().iconifyFrame(frame);
      }
   }
}

Creating a rounded JButton

Extend the JButton class and override the paintComponent and paintBorder methods. To ensure that only mouse-clicks are accepted within the round shape, override the contains method too.
Main.java:

import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.*;
   
public class Main extends JFrame implements ActionListener {
   JList list; 
 
   public Main() {
      getContentPane().setLayout(new FlowLayout());
 
      RoundButton rbutton = new RoundButton("Click me!");
      rbutton.addActionListener(this);
      getContentPane().add(BorderLayout.CENTER, rbutton);
  
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent event) {
            System.exit(0);   
         }      
      });
 
      setSize(400, 400);
   }
 
   public void actionPerformed(ActionEvent ae) {
      System.out.println("Your pressed the "" + ae.getActionCommand() + "" button");
   }
   
   public static void main(String[] args) {
      (new Main()).show();
   }
}
 
class RoundButton extends JButton
{
   // for mouse detection purposes
   Shape shape;

   public RoundButton(String label) {
      super(label);
      // allows us to paint a round background
      // if true, it would be rectangular
      setContentAreaFilled(false);
   }
 
   protected void paintComponent(Graphics g) {
      // if the button is pressed and ready to be released
      if (getModel().isArmed()) {
         g.setColor(Color.lightGray);
      } else {
         g.setColor(getBackground());
      }
 
      g.fillOval(0, 0, getSize().width-1, getSize().height-1);
 
      super.paintComponent(g);
   }
 
   // paint a round border as opposed to a rectangular one
   protected void paintBorder(Graphics g) {
      g.setColor(getForeground());
      g.drawOval(0, 0, getSize().width-1, getSize().height-1);
   }
 
   // only clicks within the round shape should be accepted
   public boolean contains(int x, int y) {
      if (shape == null || !shape.getBounds().equals(getBounds())) {
         shape = new Ellipse2D.Float(0, 0, getWidth(), getHeight());
      }
 
      return shape.contains(x, y);
   }
}

Getting the selected item(s) from a JList

There are several functions to determine the selected value(s) of a JList:

  • getSelectedIndex() returns the first selected index
  • getSelectedIndices() returns all of the selected indices
  • getSelectedValue() returns the first selected value
  • getSelectedValues() returns all of the selected values

Here’s an example:

import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
  
public class Main extends JFrame {
 
   public Main() {
      getContentPane().setLayout(new FlowLayout());
 
      Vector v = new Vector();
      for (int i=0; i<20; i++) {
         v.addElement("Item #" + i);
      }
 
      final JList list = new JList(v);
      getContentPane().add(new JScrollPane(list));
      JButton button = new JButton("Show selected items");
      getContentPane().add(button);
      button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) { 
            System.out.println("Selected values:");
            Object[] oarr = list.getSelectedValues();
            for (int i=0; i<oarr.length; i++) {
               System.out.println(oarr[i]);
            }
 
            System.out.println("Selected indices:");
            int[] iarr = list.getSelectedIndices();
            for (int i=0; i<iarr.length; i++) {
               System.out.println(iarr[i]);
            }
         }
      });
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent event) {
            System.exit(0);   
         }      
      });
 
      setSize(200, 250);
   }
   
   public static void main(String[] args) {
      (new Main()).show();
   }
}

Allowing multiple selections in a JList

A JList has three different selection modes:

1) SINGLE_SELECTION: allows only one item to be selected at a time

2) SINGLE_INTERVAL_SELECTION: allows contiguous items to be selected at a time

3) MULTIPLE_INTERVAL_SELECTION: (default) allows any combination of items to be selected at a time

Following example shows you how to apply them
Main.java:

import javax.swing.event.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
  
public class Main extends JFrame implements ActionListener {
   JList list; 
 
   public Main() {
      getContentPane().setLayout(new BorderLayout());
 
      final DefaultListModel listModel = new DefaultListModel();   
 
      // populate listmodel
      for (int i=0; i<10; i++) {
         listModel.addElement("list item #" + i);
      }
 
      list = new JList(listModel); 
      getContentPane().add(BorderLayout.CENTER, new JScrollPane(list));    
 
      JPanel panel = new JPanel(new GridLayout(3, 1));
      JRadioButton rb1 = new JRadioButton("SINGLE_SELECTION");
      rb1.addActionListener(this);
      JRadioButton rb2 = new JRadioButton("SINGLE_INTERVAL_SELECTION");
      rb2.addActionListener(this);
      JRadioButton rb3 = new JRadioButton("MULTIPLE_INTERVAL_SELECTION");
      rb3.addActionListener(this);
      ButtonGroup bg = new ButtonGroup();
      bg.add(rb1);
      bg.add(rb2);
      bg.add(rb3);
      panel.add(rb1);
      panel.add(rb2);
      panel.add(rb3);
      getContentPane().add(BorderLayout.EAST, panel);
  
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent event) {
            System.exit(0);   
         }      
      });
 
      pack();
   }
 
   public void actionPerformed(ActionEvent ae) {
      if (ae.getActionCommand().equals("SINGLE_SELECTION"))
         list.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
      else if (ae.getActionCommand().equals("SINGLE_INTERVAL_SELECTION"))
         list.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
      else if (ae.getActionCommand().equals("MULTIPLE_INTERVAL_SELECTION"))
         list.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
   }
   
   public static void main(String[] args) {
      (new Main()).show();
   }
}