Showing a tooltip on a individual items of JList

Override the JList method getToolTipText, determine the particular JList item the mouse is pointed on and show the appropriate text. 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);
      }
      final JList list = new JList(v) {
         public String getToolTipText(MouseEvent me) {
            int index = locationToIndex(me.getPoint());
            if (index > -1) {
               String item = (String) getModel().getElementAt(index);
               return "Tooltip for " + item;
            }
            return null;
         }
      };
 
      // necessary to activate tooltips for this JList!
      list.setToolTipText("");
 
      getContentPane().add(new JScrollPane(list));    
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent event) {
            System.exit(0);   
         }      
      });
 
      setSize(200, 230);
   }
   
   public static void main(String[] args) {
      (new Main()).show();
   }
}

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

Putting a Image on a JButton

Check out the API! You’ll see that there is a constructor taking an Icon object as parameter. Here’s an example showing two buttons with the following animated gifs on 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 FlowLayout());
 
      JButton mbutton = new JButton("female", new ImageIcon("male.gif"));
      JButton fbutton = new JButton("male", new ImageIcon("female.gif"));
      mbutton.addActionListener(this);
      fbutton.addActionListener(this);
      getContentPane().add(mbutton);
      getContentPane().add(fbutton);
  
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent event) {
            System.exit(0);   
         }      
      });
 
      pack();
   }
 
   public void actionPerformed(ActionEvent ae) {
      System.out.println("Your pressed the " + ae.getActionCommand() + " button");
   }
   
   public static void main(String[] args) {
      (new Main()).show();
   }
}

Changing the color of every element in a JList

Customize the CellRenderer as in following 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();
      final JList list = new JList(
         new Colorable[] { new ColoredItem("Item 1", Color.yellow),
                           new ColoredItem("Item 2"),
                           new ColoredItem("Item 3", Color.blue),
                           new ColoredItem("Item 4", Color.red),
                           new ColoredItem("Item 5", Color.green)
                         });
 
      list.setCellRenderer(new ColoredCellRenderer());
      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 ColoredCellRenderer extends DefaultListCellRenderer implements ListCellRenderer {
   public Component getListCellRendererComponent(
      JList list, Object value, int index, boolean isSelected, boolean cellHasFocus)    
   {
      setText((value == null) ? "" : value.toString());
      Color c = ((Colorable) value).getColor();
      if (isSelected) {
         setBackground(list.getSelectionBackground());
         setForeground(c);
      }
      else {
         setBackground(list.getBackground());
         setForeground(c);
      }
 
      setEnabled(list.isEnabled());
      setFont(list.getFont());
 
      return this;
   }
}
 
class ColoredItem implements Colorable {
   Object  object;
   Color   color;
                            
   public ColoredItem(Object object, Color color) {
      this.object = object;
      this.color = color;
   }
                             
   ColoredItem(Object object) {
      this(object, Color.black);
   }
 
   public Color getColor() {
      return color;
   } 
 
   public void setColor(Color color) {
      this.color = color;
   }                           
                            
   public String toString() {
      return object.toString();
   }
}
                         
interface Colorable {
   public Color getColor();
   public void setColor(Color c);
}

Freezing the first column of a JTable

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



RowHeaderRenderer.java:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
 
/**
 * @version 1.0 11/09/98
 */
 
class RowHeaderRenderer extends JLabel implements ListCellRenderer {
  
  RowHeaderRenderer(JTable table) {
    JTableHeader header = table.getTableHeader();
    setOpaque(true);
    setBorder(UIManager.getBorder("TableHeader.cellBorder"));
    setHorizontalAlignment(CENTER);
    setForeground(header.getForeground());
    setBackground(header.getBackground());
    setFont(header.getFont());
  }
  
  public Component getListCellRendererComponent( JList list, 
         Object value, int index, boolean isSelected, boolean cellHasFocus) {
    setText((value == null) ? "" : value.toString());
    return this;
  }
}
 
public class RowHeaderExample extends JFrame {
 
  public RowHeaderExample() {
    super( "Row Header Example" );
    setSize( 300, 150 );
         
    ListModel lm = new AbstractListModel() {
      String headers[] = {"a", "b", "c", "d", "e", "f", "g", "h", "i"};
      public int getSize() { return headers.length; }
      public Object getElementAt(int index) {
        return headers[index];
      }
    };
 
    DefaultTableModel dm = new DefaultTableModel(lm.getSize(),10);
    JTable table = new JTable( dm );
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    
    JList rowHeader = new JList(lm);    
    rowHeader.setFixedCellWidth(50);
    
    rowHeader.setFixedCellHeight(table.getRowHeight()
                               + table.getRowMargin());
//                             + table.getIntercellSpacing().height);
    rowHeader.setCellRenderer(new RowHeaderRenderer(table));
 
    JScrollPane scroll = new JScrollPane( table );
    scroll.setRowHeaderView(rowHeader);
    getContentPane().add(scroll, BorderLayout.CENTER);
  }
 
  public static void main(String[] args) {
    RowHeaderExample frame = new RowHeaderExample();
    frame.addWindowListener( new WindowAdapter() {
      public void windowClosing( WindowEvent e ) {
        System.exit(0);
      }
    });
    frame.setVisible(true);
  }
}

Changing the setMnemonic behavior of JButton so that it responds to CTRL instead of ALT

Try this workaround!

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
   
public class Main extends JFrame {
   JList list; 
 
   public Main() {
      getContentPane().setLayout(new FlowLayout());
 
      final JButton button = new JButton("Click-Me!");
 
      ActionListener al = new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            System.out.println("Button was clicked!");
         }
      };
      button.addActionListener(al);
  
      // don't use button.setMnemonic('C') if you want only the CTRL mask to work,
      // use button.getModel() instead. 
      button.getModel().setMnemonic('C');
      KeyStroke keyStroke = KeyStroke.getKeyStroke('C', Event.CTRL_MASK, false); 
      button.registerKeyboardAction(al, keyStroke, JComponent.WHEN_FOCUSED); 
      
      getContentPane().add(button);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent event) {
            System.exit(0);   
         }      
      });
 
      setSize(400, 400);
   }
 
   public static void main(String[] args) {
      (new Main()).show();
   }
}

Scrolling a JList to the selected item

You can use the method ensureIndexIsVisible as shown in following 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);
      }
      final JList list = new JList(v);
 
      final JTextField textfield = new JTextField(5);
      getContentPane().add(new JLabel("Scroll to:"));
      getContentPane().add(textfield);
      JButton button = new JButton("Scroll!");
      getContentPane().add(button);
      button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            int n = Integer.parseInt(textfield.getText());
            list.ensureIndexIsVisible(n);
         }
      });
      getContentPane().add(new JScrollPane(list));    
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent event) {
            System.exit(0);   
         }      
      });
 
      setSize(200, 230);
   }
   
   public static void main(String[] args) {
      (new Main()).show();
   }
}

Creating a JTable with a multi-line header

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



MultiLineHeaderExample.java:

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
  
/**
 * @version 1.0 11/09/98
 */
public class MultiLineHeaderExample extends JFrame {
  MultiLineHeaderExample() {
    super( "Multi-Line Header Example" );
 
    DefaultTableModel dm = new DefaultTableModel();
    dm.setDataVector(new Object[][]{{"a","b","c"},
                                    {"A","B","C"}},
                     new Object[]{"1stnalpha","2ndnbeta","3rdngamma"});
 
    JTable table = new JTable( dm );
    MultiLineHeaderRenderer renderer = new MultiLineHeaderRenderer();
    Enumeration enum = table.getColumnModel().getColumns();
    while (enum.hasMoreElements()) {
      ((TableColumn)enum.nextElement()).setHeaderRenderer(renderer);
    }   
    JScrollPane scroll = new JScrollPane( table );
    getContentPane().add( scroll );
    setSize( 400, 110 );
    setVisible(true);
  }
 
  public static void main(String[] args) {
    MultiLineHeaderExample frame = new MultiLineHeaderExample();
    frame.addWindowListener( new WindowAdapter() {
      public void windowClosing( WindowEvent e ) {
        System.exit(0);
      }
    });
  }
}

MultiLineHeaderRenderer.java:

import java.io.*;
import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;


/**
 * @version 1.0 11/09/98
 */
public class MultiLineHeaderRenderer extends JList implements TableCellRenderer {
  public MultiLineHeaderRenderer() {
    setOpaque(true);
    setForeground(UIManager.getColor("TableHeader.foreground"));
    setBackground(UIManager.getColor("TableHeader.background"));
    setBorder(UIManager.getBorder("TableHeader.cellBorder"));
    ListCellRenderer renderer = getCellRenderer();
    ((JLabel)renderer).setHorizontalAlignment(JLabel.CENTER);
    setCellRenderer(renderer);
  }
 
  public Component getTableCellRendererComponent(JTable table, Object value,
                   boolean isSelected, boolean hasFocus, int row, int column) {
    setFont(table.getFont());
    String str = (value == null) ? "" : value.toString();
    BufferedReader br = new BufferedReader(new StringReader(str));
    String line;
    Vector v = new Vector();
    try {
      while ((line = br.readLine()) != null) {
        v.addElement(line);
      }
    } catch (IOException ex) {
      ex.printStackTrace();
    }
    setListData(v);
    return this;
  }
}

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

Creating a JTextField as an element of JList

This example uses an EditableJList, a custom JList that only allows an EditableJList.EditableListModel as model. Our EditableListModel can only contain JTextComponents (JTextField, JTextArea, …) items.
The behavior is such that when double-clicking on the JList, the selected item is detected using the method locationToIndex and a border is added to it. The border will be removed when the textfield looses focus. To ensure that the JList element is being updated while editing the textfield, every DocumentEvent is captured and fireContentsChanged is called.
Main.java:

import javax.swing.event.*;
import javax.swing.text.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
  
public class Main extends JFrame {
 
   public Main() {
      getContentPane().setLayout(new BorderLayout());
 
      EditableJList.EditableListModel listModel = new EditableJList.EditableListModel();
 
      // populate listmodel
      Random r = new Random();
      for (int i=0; i&lt;50; i++) {
         String item = &quot;list item # &quot; + (Math.abs(r.nextInt()) % 100);
         JTextField tc = new JTextField(item);
//         JTextArea tc = new JTextArea(item);
//         JEditorPane tc = new JEditorPane(&quot;text/html&quot;, &quot;&lt;h3&gt;&quot; + item + &quot;&lt;/h3&gt;&quot;);
         listModel.addElement(tc);
      }
 
      EditableJList list = new EditableJList(listModel); 
      getContentPane().add(BorderLayout.CENTER, new JScrollPane(list));    
  
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent event) {
            System.exit(0);   
         }      
      });
 
      pack();
   }
 
   public static void main(String[] args) {
      (new Main()).show();
   }
}
 
class EditableJList extends JList {
   public EditableJList(EditableListModel listModel) {
      setModel(listModel);
      addMouseListener();
 
      // set our custom cell renderer
      setCellRenderer(new TextComponentCellRenderer()); 
   }
 
   private void addMouseListener() {  
      MouseListener mouseListener = new MouseAdapter() {
         public void mouseClicked(MouseEvent e) {
            if (e.getClickCount() == 2) {
               EditableListModel listModel = (EditableListModel) getModel();
 
               // determine the clicked item
               int index = locationToIndex(e.getPoint());
               Object value = listModel.getElementAt(index);
               final JTextComponent tc = (JTextComponent) value;
 
               // set the appropriate border for editing 
               String classname = tc.getClass().getName().toString();
               classname = classname.substring(classname.lastIndexOf(&quot;.&quot;));
               tc.setBorder(UIManager.getBorder(classname + &quot;border&quot;));
 
               // make this border appear in the JList
               listModel.updateItem(index);
 
               tc.addFocusListener(new FocusListener() {
                  public void focusGained(FocusEvent fe) {
                     // no selection color desired when editing a JTextComponent
                     clearSelection();
                  }
 
                  public void focusLost(FocusEvent fe) {
                     // remove the border again when stopped editing
                     tc.setBorder(null);
                  }
               });
 
               // request the focus on this component to be able to edit it
               tc.requestFocus();
 
               // listen to all key events on the JTextComponent and update the 
               // JList item every time.  Without this, you won't see the changes.           
               tc.getDocument().addDocumentListener(new UpdateListDocumentListener(listModel, index));
            }
         }
      };
 
      addMouseListener(mouseListener);
   }
 
   // DocumentListener that takes care of updating a JList item
   // when editing it.  Calls updateItem on our custom EditableListModel
   private class UpdateListDocumentListener implements DocumentListener {
      private EditableListModel elm;
      private int index;
 
      public UpdateListDocumentListener(EditableListModel elm, int index) {
         this.elm = elm;
         this.index = index;
      }
 
      public void insertUpdate(DocumentEvent e) {
         elm.updateItem(index);
      }
 
      public void removeUpdate(DocumentEvent e) {
         elm.updateItem(index);
      }
 
      public void changedUpdate(DocumentEvent e) {
         elm.updateItem(index);
      }
   }
 
   private class TextComponentCellRenderer implements ListCellRenderer {
      public Component getListCellRendererComponent(
         JList list,
         Object value,            // value to display
         int index,               // cell index
         boolean isSelected,      // is the cell selected
         boolean cellHasFocus)    // the list and the cell have the focus
      {
         JTextComponent tc = (JTextComponent) value;
         if (isSelected) {
            tc.setBackground(list.getSelectionBackground());
            tc.setForeground(list.getSelectionForeground());
         }
         else {
            tc.setBackground(list.getBackground());
            tc.setForeground(list.getForeground());
         }
 
         tc.setEnabled(list.isEnabled());
         tc.setFont(list.getFont());
         tc.setBorder(null);
 
         return (Component) value;
      }
   }
 
   public static class EditableListModel extends DefaultListModel {
      public void updateItem(int index) {
         fireContentsChanged(this, index, index);
      }

      public void addElement(JTextComponent tc) {
         super.addElement(tc);
      }
   }
}