Incorporating speech in a Swing application

1) First you need to download a speech engine. For example, you can download for free the Microsoft’s Speech SDK here. (Beware: version 5.1 is 68MB). Use the tools available to make sure the SDK is properly installed and trained to your voice.

2) Then get an implementation of Sun’s Java Speech API (JSAPI). The one I used in this example is from the CloudGarden. Follow the instructions on this page to find out how to install: copy the files jsapi.dll and jsapi.jar to JRE_HOME/lib/ext and adjust your classpath so that it includes jsapi.jar, necessary to compile following sample program.

3) This sample program was written by looking at the Cloud Garden examples. I dictated the following text to the app: “Last night, after a productive day of work, I joined my girlfriend in bed and quoted a very famous poet, who’s name escapes me. I said: ‘I feel great sexual desire for you right now.’. She said she’s not into poetry.”. The result (see window) was better than I expected.

Main.java:

import javax.speech.recognition.*;
import javax.speech.synthesis.*;
import javax.speech.*;
 
import javax.swing.text.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame
{ 
   TextComponentSpeechEnabler tcse;
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            tcse.deallocate();
            System.exit(1);
         }
      });
 
      getContentPane().setLayout(new BorderLayout(10, 10));
      JTextArea textArea = new JTextArea();
      textArea.setLineWrap(true);
 
      try {
         tcse = new TextComponentSpeechEnabler(textArea);
         getContentPane().add(BorderLayout.CENTER, tcse.getPanel());
      }
      catch(Exception e) {
         e.printStackTrace();
      }
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(500, 500);
      main.setVisible(true);
   }
}
 
class TextComponentSpeechEnabler
{
   static Recognizer recognizer;
 
   JPanel         textComponentPanel;
   JTextComponent textComponent;
   JTextField     speakerName;
   JTextArea      statusArea;
 
   public TextComponentSpeechEnabler(JTextComponent textComponent) throws Exception {
      this.textComponent = textComponent;
      
      createPanel();
      initializeRecognizer();
   }
  
   public void initializeRecognizer() throws Exception {
      recognizer = Central.createRecognizer(null);
      recognizer.addResultListener(new MyResultListener());
      recognizer.allocate();
      recognizer.waitEngineState(Recognizer.ALLOCATED);
 
      SpeakerManager speakerManager = recognizer.getSpeakerManager();
      SpeakerProfile[] speakers = speakerManager.listKnownSpeakers();
      for (int i=0; i<speakers.length; i++) {
         addStatusText("Found profile of " + speakers[i].getName());
      }
 
      addStatusText("Current profile is " +
                                   speakerManager.getCurrentSpeaker().getName());
      speakerName.setText(speakerManager.getCurrentSpeaker().getName());
      speakerManager.setCurrentSpeaker(speakers[0]);
 
      DictationGrammar dictation = recognizer.getDictationGrammar("dictation");
      dictation.setEnabled(true);
 
      recognizer.commitChanges();
 
      recognizer.requestFocus();
      recognizer.resume(); 
   }
 
   public void deallocate() {
      System.out.println("deallocated!");
      try {
         recognizer.deallocate();
      }
      catch(Exception e) {
         e.printStackTrace();
      }
   }
 
   private void createPanel() {
      textComponentPanel = new JPanel(new BorderLayout(10, 10));
      JPanel northPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
      northPanel.add(new JLabel("Speaker name:  "));
      speakerName = new JTextField(25);
      northPanel.add(speakerName);
      textComponentPanel.add(BorderLayout.NORTH, northPanel);
      textComponentPanel.add(BorderLayout.CENTER, new JScrollPane(textComponent));
 
      statusArea = new JTextArea(10, 50);
      textComponentPanel.add(BorderLayout.SOUTH, new JScrollPane(statusArea));   
   }
  
   public JPanel getPanel() {
      return textComponentPanel;
   }
 
   public void addStatusText(final String s) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            statusArea.append(s + "n");
            statusArea.setCaretPosition(statusArea.getDocument().getLength());
         }
      });
   }
 
   public void addText(final String s) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            textComponent.setText(textComponent.getText() + s);
            textComponent.setCaretPosition(textComponent.getDocument().getLength());
         }
      });
   }
  
   class MyResultListener extends ResultAdapter {
      public void resultRejected(ResultEvent e) {
      }
 
      public void resultCreated(ResultEvent e) {
      }
 
      public void resultUpdated(ResultEvent e) {
      }
 
      public void resultAccepted(ResultEvent e) {
         FinalResult finalResult = (FinalResult)(e.getSource());
         ResultToken tokens[] = null;
         tokens = finalResult.getBestTokens();
 
         StringBuffer sb = new StringBuffer();
         for (int i=0; i<tokens.length; i++) {
            sb.append(tokens[i].getSpokenText() + " ");  
         }
         addText(sb.toString());
         addStatusText("" + finalResult);
      }
   }
}

Feel free to mail me any improvements!

Scrolling a JScrollPane to the bottom programmatically

Call the method scrollRectToVisible of the component that is added to the JScrollPane container as shown in following example:

Main.java:

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame
{
   public Main() throws Exception {
      getContentPane().setLayout(new BorderLayout());
 
      final JPanel panel = createPanel(); 
      final JScrollPane scrollpane = new JScrollPane(panel);
 
      JButton button = new JButton("Scroll to bottom!");
      button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            panel.scrollRectToVisible(
              new Rectangle(0, panel.getHeight()-1, 1, 1));
         }
      });
 
      getContentPane().add(BorderLayout.NORTH, button);
      getContentPane().add(BorderLayout.CENTER, scrollpane);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
   }
 
   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);
   } 
} 

Have two JTrees vertically aligned in a JScrollPane

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 tree1 = new JTree(root);
      JTree tree2 = new JTree(root);
 
      tree1.addTreeSelectionListener(new TreeSelectionListener() {
         public void valueChanged(TreeSelectionEvent e) {         
            TreePath path = e.getPath();
            System.out.println(path.getLastPathComponent());     
         }
      });
 
      tree2.addTreeSelectionListener(new TreeSelectionListener() {
         public void valueChanged(TreeSelectionEvent e) {         
            TreePath path = e.getPath();
            System.out.println(path.getLastPathComponent());     
         }
      });
  
      Box box = Box.createVerticalBox();
      box.add(tree1);
      box.add(tree2);
 
      // bugparade #4833645
      tree1.setMinimumSize(tree1.getPreferredSize());
      tree1.setAlignmentX(0);
      tree2.setMinimumSize(tree2.getPreferredSize());
      tree2.setAlignmentX(0);
 
      getContentPane().setLayout(new BorderLayout());
     
      JScrollPane sp = new JScrollPane(box);
      sp.getViewport().setBackground(Color.white);
 
      getContentPane().add(BorderLayout.NORTH, sp);
 
      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);
   }
}

Force the JScrollPane to scroll to the next JTextField when I press the TAB-Key

There are three steps to this:

1. Listen for focus events coming from the components that you want to scroll to. (This works for most component classes, not just JTextField.)

2. In the event listener, find the location of the component that now has focus with getBounds().

3. Ask the scrolled component to make that location visible with scrollRectToVisible(). NOTE! The obvious thing to call scrollRectToVisible on is the JScrollPane, which will compile fine but won’t do what you want. You must call scrollRectToVisible on the object contained in viewport of the scrollpane.

This Forte-generated example shows how this works for a simple panel containing a number of JTextFields. Notice that scrollRectToVisible is called on the JPanel containing the text fields.

TestFocus.java:

public class TestFocus extends javax.swing.JFrame {
 
    /** Creates new form TestFocus */
    public TestFocus() {
        initComponents();
    }
 
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    private void initComponents() {
        scrollPane = new javax.swing.JScrollPane();
        panel = new javax.swing.JPanel();
        jTextField1 = new javax.swing.JTextField();
        jTextField2 = new javax.swing.JTextField();
        jTextField3 = new javax.swing.JTextField();
        jTextField4 = new javax.swing.JTextField();
         
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                exitForm(evt);
            }
        });
        
        scrollPane.setPreferredSize(new java.awt.Dimension(120, 80));
        panel.setLayout(new java.awt.GridLayout(0, 1, 0, 15));
        
        jTextField1.setFont(new java.awt.Font("Dialog", 0, 18));
        jTextField1.setText("jTextField1");
        jTextField1.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jTextFieldFocusGained(evt);
            }
        });
         
        panel.add(jTextField1);
        
        jTextField2.setFont(new java.awt.Font("Dialog", 0, 18));
        jTextField2.setText("jTextField2");
        jTextField2.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jTextFieldFocusGained(evt);
            }
        });
        
        panel.add(jTextField2);
        
        jTextField3.setFont(new java.awt.Font("Dialog", 0, 18));
        jTextField3.setText("jTextField3");
        jTextField3.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jTextFieldFocusGained(evt);
            }
        });
        
        panel.add(jTextField3);
        
        jTextField4.setFont(new java.awt.Font("Dialog", 0, 18));
        jTextField4.setText("jTextField4");
        jTextField4.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusGained(java.awt.event.FocusEvent evt) {
                jTextFieldFocusGained(evt);
            }
        });
        
        panel.add(jTextField4);
        
        scrollPane.setViewportView(panel);
        
        getContentPane().add(scrollPane, java.awt.BorderLayout.CENTER);
        
        pack();
    }
 
    private void jTextFieldFocusGained(java.awt.event.FocusEvent evt) {
        java.awt.Component focusedComponent = evt.getComponent();
        panel.scrollRectToVisible(focusedComponent.getBounds(null));
        repaint();
    }
 
    /** Exit the Application */
    private void exitForm(java.awt.event.WindowEvent evt) {
        System.exit(0);
    }
 
    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        new TestFocus().show();
    }
 
    // Variables declaration - do not modify
    private javax.swing.JScrollPane scrollPane;
    private javax.swing.JPanel panel;
    private javax.swing.JTextField jTextField1;
    private javax.swing.JTextField jTextField2;
    private javax.swing.JTextField jTextField3;
    private javax.swing.JTextField jTextField4;
    // End of variables declaration

}

If your panel of components contains a JTextArea, or another JTextComponent subclass, then be aware that those components will absorb TABs into themselves instead of allowing the TAB to change focus. You can disable this behavior by creating a subclass that overrides isManagingFocus() to always return false.

Scrolling a JScrollPane to the top programmatically

Call the method scrollRectToVisible of the component that is added to the JScrollPane container as shown in following example:

Main.java:

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame
{
   public Main() throws Exception {
      getContentPane().setLayout(new BorderLayout());
 
      final JPanel panel = createPanel(); 
      final JScrollPane scrollpane = new JScrollPane(panel);
 
      JButton button = new JButton("Scroll to top!");
      button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            panel.scrollRectToVisible(
              new Rectangle(0, 0, 1, 1));
         }
      });
 
      getContentPane().add(BorderLayout.NORTH, button);
      getContentPane().add(BorderLayout.CENTER, scrollpane);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
   }
 
   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);
   } 
} 

Adding a JPanel with a null layout to a JScrollPane

Make sure you set the preferredSize of the JPanel. Invoke the method setViewportView on JScrollPane.

Main.java:

import java.awt.event.*;
import javax.swing.border.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame 
{
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
 
      JPanel panel = createContactPanel();
 
      JScrollPane sp = new JScrollPane();
      sp.setViewportView(panel);
 
      getContentPane().setLayout(new BorderLayout());
      getContentPane().add(sp, BorderLayout.CENTER); 
   }
 
   public JPanel createContactPanel() {
      JLabel titleLbl      = new JLabel("Title");
      JLabel firstNameLbl  = new JLabel("First name");
      JLabel lastNameLbl   = new JLabel("Last name");
      JLabel addressLbl    = new JLabel("Address");
      JLabel cityLbl       = new JLabel("City");
      JLabel zipLbl        = new JLabel("Postal code");
      JLabel countryLbl    = new JLabel("Country");
      JLabel phoneLbl      = new JLabel("Phone number");
      JLabel faxLbl        = new JLabel("Fax number");
      JLabel emailLbl      = new JLabel("E-mail");
      JLabel birthdayLbl   = new JLabel("Birthdate");
      JLabel pickchoiceLbl = new JLabel("Pick a choice");
      JLabel creditCardTypeLbl     = new JLabel("Credit card type");
      JLabel creditCardNumberLbl   = new JLabel("Credit card number");
      JLabel expirationLbl         = new JLabel("Expiration date");
 
      JComboBox titleCombo = new JComboBox(
             new String[] { "-", "Mr", "Mrs", "Miss" });
      JTextField firstNameTf    = new JTextField();
      JTextField lastNameTf     = new JTextField();
      JTextField address1Tf     = new JTextField();
      JTextField address2Tf     = new JTextField();
      JTextField cityTf         = new JTextField();
      JTextField zipTf          = new JTextField();
      JTextField countryTf      = new JTextField();
      JTextField phoneTf        = new JTextField();
      JTextField faxTf          = new JTextField();
      JTextField emailTf        = new JTextField();
      JComboBox bd1Combo = new JComboBox();
      for (int i=1; i<=12; i++) bd1Combo.addItem(""+i);
      JComboBox bd2Combo = new JComboBox();
      for (int i=1; i<=31; i++) bd2Combo.addItem(""+i);
      JComboBox bd3Combo = new JComboBox();
      for (int i=1900; i<2000; i++) bd3Combo.addItem(""+i);
      JComboBox referCombo = new JComboBox();
      referCombo.addItem("Friend");
      referCombo.addItem("Search engine");
      referCombo.addItem("Print Media");
      referCombo.addItem("Banner Add");
      referCombo.addItem("Other");
      JComboBox creditCardTypeCombo = new JComboBox();
      creditCardTypeCombo.addItem("VISA");
      creditCardTypeCombo.addItem("MasterCard");
      creditCardTypeCombo.addItem("American Express");
      JTextField creditCardNumberTf = new JTextField();
      JComboBox expiration1Combo = new JComboBox();
      for (int i=1; i<=12; i++) expiration1Combo.addItem(""+i);
      JComboBox expiration2Combo = new JComboBox();
      for (int i=1; i<=31; i++) expiration2Combo.addItem(""+i);
      JComboBox expiration3Combo = new JComboBox();
      for (int i=1900; i<=2000; i++) expiration3Combo.addItem(""+i);
 
      JPanel panelGeneral = new JPanel();
      panelGeneral.setLayout(null);
      panelGeneral.add(titleLbl);
      panelGeneral.setBorder(new TitledBorder("General Information"));
      titleLbl.setBounds(20, 20, 150, 20);
      panelGeneral.add(firstNameLbl);
      firstNameLbl.setBounds(20, 50, 150, 20);
      panelGeneral.add(lastNameLbl);
      lastNameLbl.setBounds(20, 80, 150, 20);
      panelGeneral.add(addressLbl);
      addressLbl.setBounds(20, 110, 150, 20);
      panelGeneral.add(cityLbl);
      cityLbl.setBounds(20, 170, 150, 20);
      panelGeneral.add(zipLbl);
      zipLbl.setBounds(20, 200, 150, 20);
      panelGeneral.add(countryLbl);
      countryLbl.setBounds(20, 230, 150, 20);
      panelGeneral.add(phoneLbl);
      phoneLbl.setBounds(20, 260, 150, 20);
      panelGeneral.add(faxLbl);
      faxLbl.setBounds(20, 290, 150, 20);
      panelGeneral.add(emailLbl);
      emailLbl.setBounds(20, 320, 150, 20);
      panelGeneral.add(birthdayLbl);
      birthdayLbl.setBounds(20, 350, 150, 20); 
      panelGeneral.add(titleCombo);
      titleCombo.setBounds(150, 20, 60, 20);
      panelGeneral.add(firstNameTf);
      firstNameTf.setBounds(150, 50, 200, 20);
      panelGeneral.add(lastNameTf);
      lastNameTf.setBounds(150, 80, 200, 20);
      panelGeneral.add(address1Tf);
      address1Tf.setBounds(150, 110, 200, 20);  
      panelGeneral.add(address2Tf);
      address2Tf.setBounds(150, 140, 200, 20);  
      panelGeneral.add(cityTf);
      cityTf.setBounds(150, 170, 200, 20);
      panelGeneral.add(zipTf);
      zipTf.setBounds(150, 200, 200, 20);
      panelGeneral.add(countryTf);
      countryTf.setBounds(150, 230, 200, 20);
      panelGeneral.add(phoneTf);
      phoneTf.setBounds(150, 260, 200, 20);
      panelGeneral.add(faxTf);
      faxTf.setBounds(150, 290, 200, 20);
      panelGeneral.add(emailTf);
      emailTf.setBounds(150, 320, 200, 20);
      panelGeneral.add(bd1Combo);
      bd1Combo.setBounds(150, 350, 60, 20);
      panelGeneral.add(bd2Combo);
      bd2Combo.setBounds(220, 350, 60, 20);
      panelGeneral.add(bd3Combo);
      bd3Combo.setBounds(290, 350, 60, 20);
 
      JPanel panelReferral = new JPanel();
      panelReferral.setLayout(null);
      panelReferral.setBorder(new TitledBorder("Where did you hear about us?"));
      panelReferral.add(pickchoiceLbl);
      pickchoiceLbl.setBounds(20, 20, 150, 20);
      panelReferral.add(referCombo);
      referCombo.setBounds(150, 20, 100, 20);
 
      JPanel panelCreditCard = new JPanel();
      panelCreditCard.setLayout(null);
      panelCreditCard.setBorder(new TitledBorder("Payment method"));
      panelCreditCard.add(creditCardTypeLbl);
      creditCardTypeLbl.setBounds(20, 20, 150, 20);
      panelCreditCard.add(creditCardNumberLbl);
      creditCardNumberLbl.setBounds(20, 50, 150, 20);
      panelCreditCard.add(expirationLbl);
      expirationLbl.setBounds(20, 80, 150, 20);
 
      panelCreditCard.add(creditCardTypeCombo);
      creditCardTypeCombo.setBounds(150, 20, 100, 20);
      panelCreditCard.add(creditCardNumberTf);
      creditCardNumberTf.setBounds(150, 50, 150, 20);
      panelCreditCard.add(expiration2Combo);
      expiration2Combo.setBounds(220, 80, 60, 20);
      panelCreditCard.add(expiration3Combo);
      expiration3Combo.setBounds(290, 80, 60, 20);
 
      JPanel panel = new JPanel();
      panel.setLayout(null);
      panel.add(panelGeneral);
      panelGeneral.setBounds(10, 20, 370, 400);
      panel.add(panelReferral);
      panelReferral.setBounds(10, 430, 370, 50);
      panel.add(panelCreditCard);
      panelCreditCard.setBounds(10, 490, 370, 120);
      
      panel.setPreferredSize(new Dimension(380, 620)); 
 
      return panel;
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(400, 400);
      main.setVisible(true);
   }
}

Removing all the elements of a JList

The quickest way to find an answer to these kind of questions is to look at the API. You can call either removeAllElements or clear on the list model. clear is preferred.

import javax.swing.event.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
  
public class Main extends JFrame {
 
   public Main() {
      getContentPane().setLayout(new FlowLayout());
 
      final DefaultListModel listModel = new DefaultListModel();   
 
      // populate listmodel
      for (int i=0; i&lt;5; i++) {
         listModel.addElement(&quot;list item #&quot; + i);
      }
 
      final JList list = new JList(listModel); 
 
      getContentPane().add(new JScrollPane(list));    
      JButton removeAllButton = new JButton(&quot;Remove all elements&quot;);
      removeAllButton.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
 
            listModel.clear();
 
         }
      });
      getContentPane().add(removeAllButton);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent event) {
            System.exit(0);   
         }      
      });
 
      pack();
   }
   
   public static void main(String[] args) {
      (new Main()).show();
   }
}

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();
   }
}

Creating a JList with images

Create your own CellRenderer and change the default behavior as to show the ImageIcon:

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();
      v.addElement(new ImageString("first", new ImageIcon("c:\first.gif")));
      v.addElement(new ImageString("second", new ImageIcon("c:\second.gif")));
      v.addElement(new ImageString("third", new ImageIcon("c:\third.gif")));
      v.addElement(new ImageString("fourth", new ImageIcon("c:\fourth.gif")));
      v.addElement(new ImageString("fifth", new ImageIcon("c:\fifth.gif")));
 
      final JList list = new JList(v);
      list.setCellRenderer(new ImageStringCellRenderer());
      getContentPane().add(new JScrollPane(list));
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent event) {
            System.exit(0);   
         }      
      });
 
      setSize(200, 300);
   }
   
   public static void main(String[] args) {
      (new Main()).show();
   }
}
 
class ImageStringCellRenderer extends DefaultListCellRenderer implements ListCellRenderer {
   public Component getListCellRendererComponent(
      JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)    
   {
      ImageString is = (ImageString) value;
      setText(is.getString());
      setIcon(is.getIcon());
      if (isSelected) {
         setBackground(list.getSelectionBackground());
         setForeground(list.getSelectionForeground());
      }
      else {
         setBackground(list.getBackground());
         setForeground(list.getForeground());
      }
      setEnabled(list.isEnabled());
      setFont(list.getFont());
 
      return this;
   }
}
 
class ImageString
{
   private String s;
   private Icon icon;
 
   public ImageString(String s, Icon icon) {
      this.s = s;
      this.icon = icon;
   }
 
   public void setString(String s) {
      this.s = s;
   }
 
   public String getString() {
      return s;
   }
 
   public void setIcon(Icon icon) {
      this.icon = icon;
   }
 
   public Icon getIcon() {
      return icon;
   }
  
   public String toString() {
      return s;
   }
}