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("Editable List Example");
    
    String[] data = {"a","b","c","d","e","f","g"};
    
    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("JList"));
         
    DefaultTableModel dm = new DefaultTableModel();
    Vector dummyHeader = new Vector();
    dummyHeader.addElement("");
    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("JTable"));
    
    Container c = getContentPane();
    c.setLayout(new BoxLayout(c, BoxLayout.X_AXIS));
    c.add(listBox);
    c.add(new JSeparator(SwingConstants.VERTICAL));
    //c.add(new JLabel("test"));
    //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<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);
      }
    });
  }
}

Center a text over a JButton’s icon

Use the JButton’s methods setHorizontalTextPosition and setVerticalTextPosition.
Main.java:

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
   
public class Main extends JFrame implements ActionListener {
   JList list; 
 
   public Main() {
      getContentPane().setLayout(new FlowLayout());
 
      JButton fbutton = new JButton("Text Over Image", new ImageIcon("female.gif"));
      fbutton.addActionListener(this);
      fbutton.setVerticalTextPosition(SwingConstants.CENTER);
      fbutton.setHorizontalTextPosition(SwingConstants.CENTER); 
 
      getContentPane().add(BorderLayout.CENTER, fbutton);
 
      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();
   }
}

Detecting a double-click on an element in a JList

For detecting double-clicking, add a MouseListener and catch the MouseEvents where clickCount is equal to 2.

Here’s an example:

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());
 
      Vector v = new Vector();
      for (int i=0; i<50; i++) {
         v.addElement("Item #" + i);
      }
      getContentPane().add(new JLabel("Double-clicked on: "));
      final JTextField dblTextField = new JTextField(15);
      getContentPane().add(dblTextField);
      final JList list = new JList(v);
 
      // catch double-click events
      list.addMouseListener(new MouseAdapter() {
         public void mouseClicked(MouseEvent me) {
            if (me.getClickCount() == 2) {
               dblTextField.setText(""+list.getSelectedValue()); 
            }
         }
      });
 
      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();
   }
}

Creating a JList with icons and text

Main.java:

import java.awt.image.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
  
public class Main 
{
   public static void main(String args[]) {
      JFrame frame = new JFrame("JList ImageIcon Demonstration");
 
      DefaultListModel dlm = new DefaultListModel();
      dlm.addElement(new ListEntry("Audio", new ImageIcon("audio.gif")));
      dlm.addElement(new ListEntry("Control Panel", new ImageIcon("controlpanel.gif")));
      dlm.addElement(new ListEntry("Folder", new ImageIcon("folder.gif")));
      dlm.addElement(new ListEntry("Local Disk (C:)", new ImageIcon("mycomp.gif")));
      dlm.addElement(new ListEntry("doc on '192.168.0.1' (Z:)", new ImageIcon("network.gif")));
 
      JList list = new JList(dlm);
      list.setCellRenderer(new ListEntryCellRenderer());
         
      frame.getContentPane().add(BorderLayout.CENTER, new JScrollPane(list)); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setVisible(true);
   }
}
 
class ListEntry 
{
   private String value;
   private ImageIcon icon;
 
   public ListEntry(String value, ImageIcon icon) {
      this.value = value;
      this.icon = icon;
   }
 
   public String getValue() {
      return value;
   }
 
   public ImageIcon getIcon() {
      return icon;
   }
 
   public String toString() {
      return value;
   }
}
 
class ListEntryCellRenderer
 extends JLabel implements ListCellRenderer
{
   private JLabel label;
 
   public Component getListCellRendererComponent(JList list, Object value,
                                                 int index, boolean isSelected,
                                                 boolean cellHasFocus) {
      ListEntry entry = (ListEntry) value;
 
      setText(value.toString());
      setIcon(entry.getIcon());
  
      if (isSelected) {
         setBackground(list.getSelectionBackground());
         setForeground(list.getSelectionForeground());
      }
      else {
         setBackground(list.getBackground());
         setForeground(list.getForeground());
      } 
 
      setEnabled(list.isEnabled());
      setFont(list.getFont());
      setOpaque(true);
 
      return this;
   }
}

Putting a JButton inside a JComboBox

Here’s an example:

import javax.swing.plaf.basic.*;
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 JButton buttonOk = new JButton("OK");
      buttonOk.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            System.out.println(ae.getActionCommand() + " clicked!");
         }
      });
      final JButton buttonCancel = new JButton("Cancel");
      buttonCancel.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            System.out.println(ae.getActionCommand() + " clicked!");
         }
      });
 
      final JComboBox combobox = 
         new JComboBox(new Object[] {
               "Item 1",
               "Item 2",
               "Item 3",
               buttonOk,
               "Item 4",
               "Item 5",
               buttonCancel
            }
         );
 
      getContentPane().add(combobox);
      combobox.setRenderer(new ButtonComboBoxRenderer());
      combobox.addActionListener(new ButtonComboBoxListener(this, combobox));
  
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });      
   
      setSize(new Dimension(200, 200));
   } 
 
   public static void main(String[] args) throws Exception {
      Main main = new Main();
      main.setVisible(true);
   }
}
 
class ButtonComboBoxRenderer extends BasicComboBoxRenderer implements ListCellRenderer
{
   public ButtonComboBoxRenderer() {
      super();
   }
   
   public Component getListCellRendererComponent( JList list, 
           Object value, int index, boolean isSelected, boolean cellHasFocus) {
      if (isSelected) {
          setBackground(list.getSelectionBackground());
          setForeground(list.getSelectionForeground());
      }
      else {
          setBackground(list.getBackground());
          setForeground(list.getForeground());
      }
 
      setFont(list.getFont());
      if (value instanceof Icon) {
         setIcon((Icon)value);
      }
      if (value instanceof JButton) {
         return (Component) value;
      }
      else {
         setText((value == null) ? "" : value.toString());
      }
 
      return this;
  }  
}
 
class ButtonComboBoxListener implements ActionListener {
   JComboBox combobox;
   JFrame frame;
 
   ButtonComboBoxListener(JFrame frame, JComboBox combobox) {
      this.frame = frame;
      this.combobox = combobox;
      combobox.setSelectedIndex(0);
   }
     
   public void actionPerformed(ActionEvent e) {
      Object selectedItem = combobox.getSelectedItem();
      if (selectedItem instanceof JButton) {
         ((JButton) selectedItem).doClick();
      }
   }
}

Disable a JList element

Create your custom CellRenderer that takes care of blurring out the disabled items. But beware, you are still able to select them, even though you don’t see a proof for this visually. Add a custom SelectionListener and unselect the disabled items that were clicked on. Here’s the code:

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());
 
      Vector v = new Vector();
      final JList list = new JList(new ConditionableItem[] { 
                                       new ConditionableItem("Item 1"),
                                       new ConditionableItem("Item 2", false),
                                       new ConditionableItem("Item 3", false),
                                       new ConditionableItem("Item 4")
                                   });

      list.setCellRenderer(new ConditionableCellRenderer());
      list.addListSelectionListener(new ConditionableListSelectionListener());
      getContentPane().add(new JScrollPane(list));    
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent event) {
            System.out.println("Selected items were:");
            Object sv[] = list.getSelectedValues();
            for (int i=0; i<sv.length; i++)
               System.out.println(sv[i]);
 
            System.exit(0);   
         }      
      });
 
      setSize(200, 300);
   }
   
   public static void main(String[] args) {
      (new Main()).show();
   }
}
 
class ConditionableCellRenderer extends DefaultListCellRenderer implements ListCellRenderer {
   public Component getListCellRendererComponent(
      JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)    
   {
      setText((value == null) ? "" : value.toString());
      if (isSelected) {
         setBackground(list.getSelectionBackground());
         setForeground(list.getSelectionForeground());
      }
      else {
         setBackground(list.getBackground());
         setForeground(list.getForeground());
      }
 
      if (!((Conditionable) value).isEnabled()) {
         setBackground(list.getBackground());
         setForeground(UIManager.getColor("Label.disabledForeground"));
      }
 
      setEnabled(list.isEnabled());
      setFont(list.getFont());
 
      return this;
   }
}
 
class ConditionableListSelectionListener implements ListSelectionListener {
   public void valueChanged(ListSelectionEvent e) {
      JList list = (JList) e.getSource();
      ListModel lm = list.getModel();
      for (int i=e.getFirstIndex(); i<=e.getLastIndex(); i++) {
         if (list.getSelectionModel().isSelectedIndex(i)) {
            if (!((Conditionable) lm.getElementAt(i)).isEnabled()) {
               list.removeSelectionInterval(i, i);
            }
         }
      }
   }
}
 
class ConditionableItem implements Conditionable {
   Object  object;
   boolean isEnabled;
                            
   public ConditionableItem(Object object, boolean isEnabled) {
      this.object = object;
      this.isEnabled = isEnabled;
   }
                             
   ConditionableItem(Object object) {
      this(object, true);
   }
                           
   public boolean isEnabled() {
      return isEnabled;
   }
                            
   public void setEnabled(boolean isEnabled) {
      this.isEnabled = isEnabled;
   }
                            
   public String toString() {
      return object.toString();
   }
}
                         
interface Conditionable {
   public boolean isEnabled();
   public void setEnabled(boolean enabled);
   public String toString();
}

Putting a JCheckbox in a JComboBox

Here’s a working example:

Main.java:

import javax.swing.*;
import java.awt.*;
import java.util.*;
 
public class Main extends JFrame
{
   public Main() {
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       
      getContentPane().setLayout(new FlowLayout());
       
      Vector v = new Vector();
      v.add("Europe");
      v.add(new JCheckBox("Brussels", false));
      v.add(new JCheckBox("Paris", false));
      v.add(new JCheckBox("London", false));
      v.add("United States");
      v.add(new JCheckBox("New York", false));
      v.add(new JCheckBox("Detroit", false));
      v.add(new JCheckBox("San Francisco", false));
 
      getContentPane().add(new JComboCheckBox(v));
   }
    
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(300, 300);
      main.setVisible(true);
   }
}

JComboCheckBox.java:

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
 
public class JComboCheckBox extends JComboBox 
{
   public JComboCheckBox() { 
      init(); 
   }
   
   public JComboCheckBox(JCheckBox[] items) { 
      super(items); 
      init(); 
   }
   
   public JComboCheckBox(Vector items) { 
      super(items); 
      init(); 
   }
   
   public JComboCheckBox(ComboBoxModel aModel) { 
      super(aModel); 
      init(); 
   }
   
   private void init() {
      setRenderer(new ComboBoxRenderer());
      addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) { 
            itemSelected(); 
         }
      });
   }
 
   private void itemSelected() {
      if (getSelectedItem() instanceof JCheckBox) {
         JCheckBox jcb = (JCheckBox)getSelectedItem();
         jcb.setSelected(!jcb.isSelected());
      }
   }
 
   class ComboBoxRenderer implements ListCellRenderer {
      private JLabel label;
      
      public ComboBoxRenderer() { 
         setOpaque(true); 
      }
      
      public Component getListCellRendererComponent(JList list, Object value, int index, 
                                                    boolean isSelected, boolean cellHasFocus) {
         if (value instanceof Component) {
            Component c = (Component)value;
            if (isSelected) {
               c.setBackground(list.getSelectionBackground());
               c.setForeground(list.getSelectionForeground());
            } else {
               c.setBackground(list.getBackground());
               c.setForeground(list.getForeground());
            }
             
            return c;
         } else {
            if (label ==null) {
               label = new JLabel(value.toString());
            }
            else {
               label.setText(value.toString());
            }
               
            return label;
         }
      }
   }
}

Creating an editable JComboBox

Use the method setEditable. Here’s an example:

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
   
public class Main extends JFrame
{ 
   public Main() {
      getContentPane().setLayout(new BorderLayout());
      final JComboBox combobox = new JComboBox();
      final JList list = new JList(new DefaultListModel());
 
      getContentPane().add(BorderLayout.NORTH, combobox);
      getContentPane().add(BorderLayout.CENTER, list); 
 
      combobox.setEditable(true);
      combobox.addItemListener(new ItemListener() {
         public void itemStateChanged(ItemEvent ie) {
            if (ie.getStateChange() == ItemEvent.SELECTED) {
               ((DefaultListModel) list.getModel()).addElement(combobox.getSelectedItem());
               combobox.insertItemAt(combobox.getSelectedItem(), 0);
            }
         }
      });
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });      
   
      setSize(new Dimension(200, 200));
   } 
 
   public static void main(String[] args) throws Exception {
      Main main = new Main();
      main.setVisible(true);
   }
}

Having a JList go to a specific item when a user presses a key

JListKeyPressed.java:

import javax.swing.*;
import java.awt.event.*;
 
public class JListKeyPressed extends JFrame {
   private JList list;
   private JPanel p;
 
   public JListKeyPressed() {
      super("JListKeyPressed");
      p = new JPanel();
      final String data[] = {"ah","bh","ch","dh","eh","fh","gh","hh","ih"};
      list = new JList(data);
 
      list.addKeyListener(new KeyAdapter() {
         public void keyPressed(KeyEvent e) {
            for(int i = 0; i < data.length; i++) {
               if(data[i].charAt(0) == Character.toLowerCase(e.getKeyChar())) {
                  list.setSelectedIndex(i);
               }
            }
         }
      });
 
      setContentPane(p);
      p.add(list);
      setSize(300,300);
 	
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent event) {
            dispose();
            System.exit(0);
         }
      });
 	
      setVisible(true);
   }
 
   public static void main(String args[]) {
      JListKeyPressed j = new JListKeyPressed();
   }
}

Creating a JComboBox that doesn’t close when I click one of its JCheckBox items

Main.java:

import javax.swing.*;
import java.awt.*;
import java.util.*;
 
public class Main extends JFrame
{
   public Main() {
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       
      getContentPane().setLayout(new FlowLayout());
       
      Vector v = new Vector();
      v.add("Europe");
      v.add(new JCheckBox("Brussels", false));
      v.add(new JCheckBox("Paris", false));
      v.add(new JCheckBox("London", false));
      v.add("United States");
      v.add(new JCheckBox("New York", false));
      v.add(new JCheckBox("Detroit", false));
      v.add(new JCheckBox("San Francisco", false));
 
      getContentPane().add(new JComboCheckBox(v));
   }
    
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(300, 300);
      main.setVisible(true);
   }
}

JComboCheckBox.java:

import javax.swing.*;
import java.awt.event.*;
 
import javax.swing.plaf.ComboBoxUI;
import javax.swing.plaf.basic.*;
import javax.swing.plaf.metal.MetalComboBoxUI;
 
import com.sun.java.swing.plaf.motif.MotifComboBoxUI;
import com.sun.java.swing.plaf.windows.WindowsComboBoxUI;
 
import java.awt.*;
import java.util.*;
 
public class JComboCheckBox extends JComboBox 
{
   public JComboCheckBox() { 
      init(); 
   }
    
   public JComboCheckBox(JCheckBox[] items) { 
      super(items); 
      init(); 
   }
    
   public JComboCheckBox(Vector items) { 
      super(items); 
      init(); 
   }
    
   public JComboCheckBox(ComboBoxModel aModel) { 
      super(aModel); 
      init(); 
   }
    
   public void updateUI() {
      ComboBoxUI cui = (ComboBoxUI) UIManager.getUI(this);
      if (cui instanceof MetalComboBoxUI) {
         cui = new MetalNoCloseComboBoxUI();
      } else if (cui instanceof MotifComboBoxUI) {
         cui = new MotifNoCloseComboBoxUI();       
      } else if (cui instanceof WindowsComboBoxUI) {
         cui = new WindowsNoCloseComboBoxUI();
      }
       
      setUI(cui);
   }
    
   class MetalNoCloseComboBoxUI extends MetalComboBoxUI {
      protected ComboPopup createPopup() {
         return new NoCloseBasicComboPopup(comboBox);
      }
   }
 
   class WindowsNoCloseComboBoxUI extends WindowsComboBoxUI {
      protected ComboPopup createPopup() {
         return new NoCloseBasicComboPopup(comboBox);
      }
   }
 
   class MotifNoCloseComboBoxUI extends MotifComboBoxUI {
      protected ComboPopup createPopup() {
         return new NoCloseBasicComboPopup(comboBox);
      }
   }
    
   private void init() {
      setRenderer(new ComboBoxRenderer());
      addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) { 
            itemSelected(); 
         }
      });
   }
 
   private void itemSelected() {
      if (getSelectedItem() instanceof JCheckBox) {
         JCheckBox jcb = (JCheckBox)getSelectedItem();
         jcb.setSelected(!jcb.isSelected());
         repaint();
      }
   }
 
   class ComboBoxRenderer implements ListCellRenderer {
      private JLabel label;
      
      public ComboBoxRenderer() { 
         setOpaque(true); 
      }
      
      public Component getListCellRendererComponent(JList list, Object value, int index, 
                                                    boolean isSelected, boolean cellHasFocus) {
         if (value instanceof JCheckBox) {
            list.repaint();
         }
         if (value instanceof Component) {
            Component c = (Component)value;
            if (isSelected) {
               c.setBackground(list.getSelectionBackground());
               c.setForeground(list.getSelectionForeground());
            } else {
               c.setBackground(list.getBackground());
               c.setForeground(list.getForeground());
            }
            
            return c;
         } else {
            if (label==null) {
               label = new JLabel(value.toString());
            }
            else {
               label.setText(value.toString()); 
            }
            
            return label;
         }
      }
   }
 
   class NoCloseBasicComboPopup extends BasicComboPopup
   {
      public NoCloseBasicComboPopup(JComboBox combo) {
         super(combo);         
      }
   
      protected MouseListener createListMouseListener() {
         return new ListMouseHandler();
      }
   
      protected class ListMouseHandler extends MouseAdapter {
         public void mousePressed(MouseEvent e) {
         }
      
         public void mouseReleased(MouseEvent anEvent) {
            comboBox.setSelectedIndex(list.getSelectedIndex());
            Object o = list.getSelectedValue();
            if (! (o instanceof JCheckBox)) {
               hide();
            }
         }
      }   
   }   
}