Creating a JMenuItem with an image

Two constructors of JMenuItem take an Icon as parameters. Try the following example with these animated! GIFs:

Main.java:

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
   
public class Main extends JFrame {
   public Main() {
      getContentPane().setLayout(new FlowLayout());
 
      JMenuBar menuBar = new JMenuBar();
      JMenu menu = new JMenu("menu");
      JMenuItem menuItem1 = new JMenuItem("male", new ImageIcon("male.gif"));
      JMenuItem menuItem2 = new JMenuItem("female", new ImageIcon("female.gif"));
      menu.add(menuItem1);
      menu.add(menuItem2);
      menuBar.add(menu);
 
      this.setJMenuBar(menuBar); 
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent event) {
            System.exit(0);   
         }      
      });
 
      setSize(400, 400);
   }
 
   public static void main(String[] args) {
      (new Main()).show();
   }
}

Using an image for the slider knob in a JSlider


You could override the default JSlider Icons that are used using UIManager.put. Just because this is what happens inside the Slider UI classes:
    Icon horizThumbIcon = UIManager.getIcon( "Slider.horizontalThumbIcon" );
    Icon vertThumbIcon = UIManager.getIcon( "Slider.verticalThumbIcon" );

This would make the image that is used as the thumb the same for all JSliders you make.

Another way is to create your own UI (and hence breaking LAF capabilities). In the following example, I override the two methods paintThumb and getThumbSize.

Main.java:

import javax.swing.plaf.metal.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
    
public class Main extends JFrame {
   public Main() {
      getContentPane().setLayout(new FlowLayout());
  
      final JSlider hslider = new JSlider(JSlider.HORIZONTAL, 0, 30, 15);
      final JSlider vslider = new JSlider(JSlider.VERTICAL, 0, 30, 15);
      // draw the major tick marks (one for every tick label)
      hslider.setMajorTickSpacing(10);
      vslider.setMajorTickSpacing(10);
      // draw the minor tick marks (between the tick labels)
      hslider.setMinorTickSpacing(1);
      vslider.setMinorTickSpacing(1);
      // draw the tick marks
      hslider.setPaintTicks(true);
      vslider.setPaintTicks(true);
      // draw the tick mark labels
      hslider.setPaintLabels(true);
      vslider.setPaintLabels(true);
  
      getContentPane().add(hslider);
      getContentPane().add(vslider);
   
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent event) {
            System.exit(0);   
         }      
      });
  
      Icon maleIcon   = new ImageIcon("male.gif");
      Icon femaleIcon = new ImageIcon("female.gif");
 
      hslider.setUI(new IconThumbSliderUI(maleIcon, femaleIcon));
      vslider.setUI(new IconThumbSliderUI(maleIcon, femaleIcon));
      pack();
   }
  
   public static void main(String[] args) {
      (new Main()).show();
   }
}
  
class IconThumbSliderUI extends MetalSliderUI {
    protected Icon hThumbIcon = null;
    protected Icon vThumbIcon = null;
  
    public IconThumbSliderUI(Icon hThumbIcon, Icon vThumbIcon) {
        setHorizontalThumbIcon(hThumbIcon);
        setVerticalThumbIcon(vThumbIcon);
    }
  
    public void setHorizontalThumbIcon(Icon hThumbIcon) {
       if (hThumbIcon == null) this.hThumbIcon = horizThumbIcon;
       else                    this.hThumbIcon = hThumbIcon;
    }
 
    public void setVerticalThumbIcon(Icon vThumbIcon) {
       if (vThumbIcon == null) this.vThumbIcon = vertThumbIcon;
       else                    this.vThumbIcon = vThumbIcon;
 
    }
 
    public void paintThumb(Graphics g)  {
        Rectangle knobBounds = thumbRect;
 
        g.translate( knobBounds.x, knobBounds.y );
 
        if ( slider.getOrientation() == JSlider.HORIZONTAL ) {
            hThumbIcon.paintIcon( slider, g, 0, 0 );
        }
        else {
            vThumbIcon.paintIcon( slider, g, 0, 0 );
        }
  
        g.translate( -knobBounds.x, -knobBounds.y );
    }
 
    protected Dimension getThumbSize() {
        Dimension size = new Dimension();
 
        if ( slider.getOrientation() == JSlider.VERTICAL ) {
	    size.width = vThumbIcon.getIconWidth();
	    size.height = vThumbIcon.getIconHeight();
	}
	else {
	    size.width = hThumbIcon.getIconWidth();
	    size.height = hThumbIcon.getIconHeight();
	}
 
	return size;
    }
}

Images used in this example:

Enabling a component depending on the text entered in a JTextField

Add a document listener to the JTextField and listen to the characters that are inserted and removed.

Main.java:

import javax.swing.event.*;
import javax.swing.text.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame implements DocumentListener
{
   private JTextField tf; 
   private JButton button;
 
   public Main() {           
      getContentPane().setLayout(new BorderLayout());
      JPanel northPanel = new JPanel(new GridLayout(1, 2));
      northPanel.add(new JLabel("Enter an integer: "));
      tf = new JTextField();
      northPanel.add(tf);
      getContentPane().add(BorderLayout.NORTH, northPanel);
      button = new JButton("OK"); 
      getContentPane().add(BorderLayout.SOUTH, button);
      // Add a document listener to the textfield
      Document document = tf.getDocument();
      document.addDocumentListener(this);
 
      button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            System.exit(1);
         }
      });
      button.setEnabled(false);
 
      pack();
   }
 
   public void insertUpdate(DocumentEvent evt) {
      String s = tf.getText();
 
      try {
         int v = Integer.parseInt(s);
         button.setEnabled(true);
      }
      catch(NumberFormatException e) {
         button.setEnabled(false);
      }
   }
 
   public void removeUpdate(DocumentEvent evt) {
      if (tf.getText().length() == 0) {
         button.setEnabled(false);
      }
      else {
         insertUpdate(evt);
      }
   }
 
   public void changedUpdate(DocumentEvent evt) {
   }
 
   public static void main(String args[]) {
      Main main = new Main();
      main.setVisible(true);
   }
}

Change the color of a JToolTip

To change the color of a tooltip, create a JToolTip instance and use the methods setForeground and setBackground to change its appearance. Then override the method createToolTip on the component where this tooltip applies to and return your own JToolTip instance.

(btw. to change the colors of all your tooltips, use the class UIManager and change the keys ToolTip.background and ToolTip.foreground.)

Main.java:

import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
 
public class Main extends JFrame {
   public Main() {
      super("JToolTip Delay Demonstration");
 
      getContentPane().setLayout(new FlowLayout()); 
   
      final JToolTip tooltip = new JToolTip();
      tooltip.setBackground(Color.red);
      tooltip.setForeground(Color.yellow);
 
      JLabel label = new JLabel("How was I?") {
         public JToolTip createToolTip() {
            return tooltip;
         }
      };
 
      label.setToolTipText("too commercial");
    
      getContentPane().add(label);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            System.exit(0);
         }
      });
 
      setSize(400, 300);
   }
 
   public static void main(String[] args) {
      Main main = new Main();
      main.setVisible(true);
   }
}

Prevent a JFileChooser from being resizable

JFileChooser extends from JComponent, not from JDialog. When you call JFileChooser.showXXXXDialog, it will
create a JDialog and add JFileChooser to the content pane. You don’t have access to that instance to make it not-
resizable, but it’s not difficult to make a custom one.

Displaying a menu when right clicking on a cell

Try this:

import javax.swing.event.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame 
{
   JTable table;
   TablePopup tablePopup;
 
   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" };
 
      table = new JTable(tabledata, columnheaders);
      table.setPreferredScrollableViewportSize(new Dimension(500, 70));
      JScrollPane scrollPane = new JScrollPane(table); 
      tablePopup = new TablePopup(table);
 
      table.addMouseListener(new MouseAdapter() {
            public void mouseReleased (MouseEvent e) {
                if (e.isPopupTrigger()) {
                   tablePopup.show (e.getComponent(), e.getX(), e.getY());
                }
            }
      });
  
      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();
   }
 
   class TablePopup extends JPopupMenu {
      public TablePopup(JTable table) {
         JMenuItem itemDelete = new JMenuItem("Delete row");
         JMenuItem itemAdd = new JMenuItem("Add row");
         itemDelete.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
               System.out.println("Delete row");
            }
         });
         itemAdd.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
               System.out.println("Add row");
            }
         });
 
         add(itemDelete);
         add(new JSeparator());
         add(itemAdd);
      }
   }
}

Setting the background color of a JTable inside a JScrollPane

Try the following (JDK1.3+):

   scrollPane.getViewport().setBackground(table.getBackground());

Main.java:

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));
 
      table.setBackground(Color.red);
  
      JScrollPane scrollPane = new JScrollPane(table);
      scrollPane.getViewport().setBackground(table.getBackground());
 
      getContentPane().setLayout(new BorderLayout());
      getContentPane().add(BorderLayout.CENTER, scrollPane);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(550, 300);
      main.setVisible(true);
   }
}

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

Get started with a JTree

These sample codes will just teach you how to create a simple JTree, without worrying about how the tree is displayed. For detailed information about this, look at the other examples in this category.

DefaultMutableTreeNode

You create the simpliest JTree by constructing the hierarchy using the class DefaultMutableTreeNode. With its add method, children (of type DefaultMutableTreeNode) can be added. A child can have children as well.

Then, pass the root element to a JTree instance.

This simple example shows you how to.

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

Extending TreeModel

But if you already have an existing tree-based model, you want to use it directly (and not create a mirror that is a set of DefaultMutableTreeNodes). This way, your view stays in sync with your existing model.

You can reuse your tree-based datastructure by creating your own class that implements TreeModel as shown in the following example. The custom datastructure Category contains the data and a CategoryTreeModel passes it on to the view.

Category.java:

import java.util.*;
 
public class Category
{
   private String name;
   private Vector subCategories = new Vector();
   private Vector links = new Vector();
 
   public Category(String name) {
      this.name = name;
   }
 
   public void addSubCategory(Category category) {
      subCategories.addElement(category);
   }
 
   public void addLink(String link) {
      links.addElement(link);
   }
 
   public Vector getSubCategories() {
      return subCategories;
   }
 
   public Vector getLinks() {
      return links;
   } 
 
   public String toString() {
      return name;
   }
}

CategoryTree.java:

import javax.swing.*;
import javax.swing.tree.*;
 
public class CategoryTree extends JTree {
    CategoryTreeModel model;
 
    public CategoryTree(Category category) {
        super(new CategoryTreeModel(category));
    }
}

CategoryTreeModel.java:

import javax.swing.event.*;
import javax.swing.tree.*;
import java.util.*;
 
public class CategoryTreeModel implements TreeModel {
   private Category rootCategory;
   private Vector listeners = new Vector();
 
   public CategoryTreeModel(Category rootCategory) {
      this.rootCategory = rootCategory;
   }
 
   public Object getChild(Object parent, int index) {
      Category category = (Category) parent;
  
      // if the index falls in the subcategories vector
      if (index < category.getSubCategories().size()) {
         return category.getSubCategories().elementAt(index);
      }
 
      // else if the index falls in the links vector
      index -= category.getSubCategories().size();
      return category.getLinks().elementAt(index);
   }
 
   public int getChildCount(Object parent) {
      Category category = (Category) parent;
 
      return category.getSubCategories().size() +
             category.getLinks().size();
   }
 
   public int getIndexOfChild(Object parent, Object child) {
      Category category = (Category) parent;
 
      if (child instanceof Category) {
         return category.getSubCategories().indexOf(child);
      }
      else {
         return category.getLinks().indexOf(child);
      }
   }
 
   public Object getRoot() {
      return rootCategory;
   }
 
   public boolean isLeaf(Object node) {
      return node instanceof String;
   }
 
   public void addTreeModelListener(TreeModelListener l) {
      listeners.addElement(l);
   } 
 
   public void removeTreeModelListener(TreeModelListener l) {
      listeners.removeElement(l);
   }
 
   public void valueForPathChanged(TreePath path, Object newValue) {
      System.out.println("Value for path changed, " + newValue);
   }  
}

Main.java:

import java.net.*;
import java.awt.event.*;
  
public class Main extends JFrame
{
   public Main() {
      Category category = createCategory();
 
      CategoryTree tree = new CategoryTree(category);
  
      getContentPane().add(new JScrollPane(tree));
  
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
   }
 
   public static Category createCategory() {
      Category category = new Category("Java");
 
      Category j2se = new Category("j2se");
      j2se.addLink("http://java.sun.com/j2se/");
 
      Category j2ee = new Category("j2ee");
      j2ee.addLink("http://java.sun.com/j2ee/");
 
      Category j2me = new Category("j2me");
      j2me.addLink("http://java.sun.com/j2me/");
 
      category.addSubCategory(j2se);
      category.addSubCategory(j2ee);
      category.addSubCategory(j2me);
 
      return category;
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(400, 400);
      main.setVisible(true);
   }
}