Creating a JTable with nested headers

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



GroupableHeaderExample.java:

/* (swing1.1beta3)
 *
 * |-----------------------------------------------------|
 * |        |       Name      |         Language         |
 * |        |-----------------|--------------------------|
 * |  SNo.  |        |        |        |      Others     |
 * |        |   1    |    2   | Native |-----------------|
 * |        |        |        |        |   2    |   3    |  
 * |-----------------------------------------------------|
 * |        |        |        |        |        |        |
 *
 */
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
 
/**
 * @version 1.0 11/09/98
 */
public class GroupableHeaderExample extends JFrame {
 
  GroupableHeaderExample() {
    super( "Groupable Header Example" );
 
    DefaultTableModel dm = new DefaultTableModel();
    dm.setDataVector(new Object[][]{
      {"119","foo","bar","ja","ko","zh"},
      {"911","bar","foo","en","fr","pt"}},
    new Object[]{"SNo.","1","2","Native","2","3"});
 
    JTable table = new JTable( dm ) {
      protected JTableHeader createDefaultTableHeader() {
        return new GroupableTableHeader(columnModel);
      }
    };
    TableColumnModel cm = table.getColumnModel();
    ColumnGroup g_name = new ColumnGroup("Name");
    g_name.add(cm.getColumn(1));
    g_name.add(cm.getColumn(2));
    ColumnGroup g_lang = new ColumnGroup("Language");
    g_lang.add(cm.getColumn(3));
    ColumnGroup g_other = new ColumnGroup("Others");
    g_other.add(cm.getColumn(4));
    g_other.add(cm.getColumn(5));
    g_lang.add(g_other);
    GroupableTableHeader header = (GroupableTableHeader)table.getTableHeader();
    header.addColumnGroup(g_name);
    header.addColumnGroup(g_lang);
    JScrollPane scroll = new JScrollPane( table );
    getContentPane().add( scroll );
    setSize( 400, 120 );   
  }
 
  public static void main(String[] args) {
    GroupableHeaderExample frame = new GroupableHeaderExample();
    frame.addWindowListener( new WindowAdapter() {
      public void windowClosing( WindowEvent e ) {
        System.exit(0);
      }
    });
    frame.setVisible(true);
  }
}

ColumnGroup.java:

import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
 
  
/**
  * ColumnGroup
  *
  * @version 1.0 10/20/98
  * @author Nobuo Tamemasa
  */
 
public class ColumnGroup {
  protected TableCellRenderer renderer;
  protected Vector v;
  protected String text;
  protected int margin=0;
 
  public ColumnGroup(String text) {
    this(null,text);
  }
 
  public ColumnGroup(TableCellRenderer renderer,String text) {
    if (renderer == null) {
      this.renderer = new DefaultTableCellRenderer() {
        public Component getTableCellRendererComponent(JTable table, Object value,
                         boolean isSelected, boolean hasFocus, int row, int column) {
          JTableHeader header = table.getTableHeader();
          if (header != null) {
            setForeground(header.getForeground());
            setBackground(header.getBackground());
            setFont(header.getFont());
          }
          setHorizontalAlignment(JLabel.CENTER);
          setText((value == null) ? "" : value.toString());
          setBorder(UIManager.getBorder("TableHeader.cellBorder"));
          return this;
        }
      };
    } else {
      this.renderer = renderer;
    }
    this.text = text;
    v = new Vector();
  }
 
   
  /**
   * @param obj    TableColumn or ColumnGroup
   */
  public void add(Object obj) {
    if (obj == null) { return; }
    v.addElement(obj);
  }
 
  
  /**
   * @param c    TableColumn
   * @param v    ColumnGroups
   */
  public Vector getColumnGroups(TableColumn c, Vector g) {
    g.addElement(this);
    if (v.contains(c)) return g;    
    Enumeration enum = v.elements();
    while (enum.hasMoreElements()) {
      Object obj = enum.nextElement();
      if (obj instanceof ColumnGroup) {
        Vector groups = 
          (Vector)((ColumnGroup)obj).getColumnGroups(c,(Vector)g.clone());
        if (groups != null) return groups;
      }
    }
    return null;
  }
    
  public TableCellRenderer getHeaderRenderer() {
    return renderer;
  }
    
  public void setHeaderRenderer(TableCellRenderer renderer) {
    if (renderer != null) {
      this.renderer = renderer;
    }
  }
    
  public Object getHeaderValue() {
    return text;
  }
  
  public Dimension getSize(JTable table) {
    Component comp = renderer.getTableCellRendererComponent(
        table, getHeaderValue(), false, false,-1, -1);
    int height = comp.getPreferredSize().height; 
    int width  = 0;
    Enumeration enum = v.elements();
    while (enum.hasMoreElements()) {
      Object obj = enum.nextElement();
      if (obj instanceof TableColumn) {
        TableColumn aColumn = (TableColumn)obj;
        width += aColumn.getWidth();
        width += margin;
      } else {
        width += ((ColumnGroup)obj).getSize(table).width;
      }
    }
    return new Dimension(width, height);
  }
 
  public void setColumnMargin(int margin) {
    this.margin = margin;
    Enumeration enum = v.elements();
    while (enum.hasMoreElements()) {
      Object obj = enum.nextElement();
      if (obj instanceof ColumnGroup) {
        ((ColumnGroup)obj).setColumnMargin(margin);
      }
    }
  }
}

GroupableTableHeader.java:

import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
 
/**
  * GroupableTableHeader
  *
  * @version 1.0 10/20/98
  * @author Nobuo Tamemasa
  */
 
public class GroupableTableHeader extends JTableHeader {
  private static final String uiClassID = "GroupableTableHeaderUI";
  protected Vector columnGroups = null;
    
  public GroupableTableHeader(TableColumnModel model) {
    super(model);
    setUI(new GroupableTableHeaderUI());
    setReorderingAllowed(false);
  }
  
  public void setReorderingAllowed(boolean b) {
    reorderingAllowed = false;
  }
    
  public void addColumnGroup(ColumnGroup g) {
    if (columnGroups == null) {
      columnGroups = new Vector();
    }
    columnGroups.addElement(g);
  }
 
  public Enumeration getColumnGroups(TableColumn col) {
    if (columnGroups == null) return null;
    Enumeration enum = columnGroups.elements();
    while (enum.hasMoreElements()) {
      ColumnGroup cGroup = (ColumnGroup)enum.nextElement();
      Vector v_ret = (Vector)cGroup.getColumnGroups(col,new Vector());
      if (v_ret != null) { 
        return v_ret.elements();
      }
    }
    return null;
  }
   
  public void setColumnMargin() {
    if (columnGroups == null) return;
    int columnMargin = getColumnModel().getColumnMargin();
    Enumeration enum = columnGroups.elements();
    while (enum.hasMoreElements()) {
      ColumnGroup cGroup = (ColumnGroup)enum.nextElement();
      cGroup.setColumnMargin(columnMargin);
    }
  } 
}

GroupableTableHeaderUI.java:

import java.util.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.plaf.basic.*;
 
public class GroupableTableHeaderUI extends BasicTableHeaderUI {
  
  public void paint(Graphics g, JComponent c) {
    Rectangle clipBounds = g.getClipBounds();
    if (header.getColumnModel() == null) return;
    ((GroupableTableHeader)header).setColumnMargin();
    int column = 0;
    Dimension size = header.getSize();
    Rectangle cellRect  = new Rectangle(0, 0, size.width, size.height);
    Hashtable h = new Hashtable();
    int columnMargin = header.getColumnModel().getColumnMargin();
    
    Enumeration enumeration = header.getColumnModel().getColumns();
    while (enumeration.hasMoreElements()) {
      cellRect.height = size.height;
      cellRect.y      = 0;
      TableColumn aColumn = (TableColumn)enumeration.nextElement();
      Enumeration cGroups = ((GroupableTableHeader)header).getColumnGroups(aColumn);
      if (cGroups != null) {
        int groupHeight = 0;
        while (cGroups.hasMoreElements()) {
          ColumnGroup cGroup = (ColumnGroup)cGroups.nextElement();
          Rectangle groupRect = (Rectangle)h.get(cGroup);
          if (groupRect == null) {
            groupRect = new Rectangle(cellRect);
            Dimension d = cGroup.getSize(header.getTable());
            groupRect.width  = d.width;
            groupRect.height = d.height;    
            h.put(cGroup, groupRect);
          }
          paintCell(g, groupRect, cGroup);
          groupHeight += groupRect.height;
          cellRect.height = size.height - groupHeight;
          cellRect.y      = groupHeight;
        }
      }      
      cellRect.width = aColumn.getWidth() + columnMargin;
      if (cellRect.intersects(clipBounds)) {
        paintCell(g, cellRect, column);
      }
      cellRect.x += cellRect.width;
      column++;
    }
  }
 
  private void paintCell(Graphics g, Rectangle cellRect, int columnIndex) {
    TableColumn aColumn = header.getColumnModel().getColumn(columnIndex);
    TableCellRenderer renderer = aColumn.getHeaderRenderer();
    Component component = renderer.getTableCellRendererComponent(
      header.getTable(), aColumn.getHeaderValue(),false, false, -1, columnIndex);
    rendererPane.add(component);
    rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y,
                                cellRect.width, cellRect.height, true);
  }
 
  private void paintCell(Graphics g, Rectangle cellRect,ColumnGroup cGroup) {
    TableCellRenderer renderer = cGroup.getHeaderRenderer();
    Component component = renderer.getTableCellRendererComponent(
      header.getTable(), cGroup.getHeaderValue(),false, false, -1, -1);
    rendererPane.add(component);
    rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y,
                                cellRect.width, cellRect.height, true);
  }
 
  private int getHeaderHeight() {
    int height = 0;
    TableColumnModel columnModel = header.getColumnModel();
    for(int column = 0; column < columnModel.getColumnCount(); column++) {
      TableColumn aColumn = columnModel.getColumn(column);
      TableCellRenderer renderer = aColumn.getHeaderRenderer();
      Component comp = renderer.getTableCellRendererComponent(
        header.getTable(), aColumn.getHeaderValue(), false, false,-1, column);
      int cHeight = comp.getPreferredSize().height;
      Enumeration enum = ((GroupableTableHeader)header).getColumnGroups(aColumn);      
      if (enum != null) {
        while (enum.hasMoreElements()) {
          ColumnGroup cGroup = (ColumnGroup)enum.nextElement();
          cHeight += cGroup.getSize(header.getTable()).height;
        }
      }
      height = Math.max(height, cHeight);
    }
    return height;
  }
 
  private Dimension createHeaderSize(long width) {
    TableColumnModel columnModel = header.getColumnModel();
    width += columnModel.getColumnMargin() * columnModel.getColumnCount();
    if (width > Integer.MAX_VALUE) {
      width = Integer.MAX_VALUE;
    }
    return new Dimension((int)width, getHeaderHeight());
  }
 
  public Dimension getPreferredSize(JComponent c) {
    long width = 0;
    Enumeration enumeration = header.getColumnModel().getColumns();
    while (enumeration.hasMoreElements()) {
      TableColumn aColumn = (TableColumn)enumeration.nextElement();
      width = width + aColumn.getPreferredWidth();
    }
    return createHeaderSize(width);
  }
}

Create borders for JTable cells

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



CellBorderTableExample.java:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.event.*;
import javax.swing.border.*;
 
/**
 * @version 1.0  3/06/99
 */
public class CellBorderTableExample extends JFrame {

  public CellBorderTableExample() {
    super( &quot;Cell Border Example&quot; );
    
    final Color color = UIManager.getColor(&quot;Table.gridColor&quot;);
        
    DefaultTableModel dm = new DefaultTableModel(12,6) {
      public void setValueAt(Object obj, int row, int col) {
        if (obj instanceof MyData) {
          super.setValueAt(obj, row, col);
        } else {
          MyData myData=null;
          Object oldObject = getValueAt(row, col);
          if (oldObject == null) {
            myData = new MyData(obj, new LinesBorder(color,0));
          } else if (oldObject instanceof MyData) {
            myData = (MyData)oldObject;
          } else {
            System.out.println(&quot;error&quot;);
            return;
          }
          myData.setObject(obj);
          super.setValueAt(myData, row, col);
        }
      }
    };
    
    JTable table = new JTable( dm );
    table.setIntercellSpacing(new Dimension(0,0));
    table.setCellSelectionEnabled(true);
    table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
    table.setDefaultRenderer(Object.class, new BorderCellRenderer());

    JScrollPane scroll = new JScrollPane( table );
    ThicknessPanel thicknessPanel = new ThicknessPanel();
    Box box = new Box(BoxLayout.Y_AXIS);    
    box.add(thicknessPanel);
    box.add(new ButtonPanel(table, thicknessPanel));
    getContentPane().add(scroll, BorderLayout.CENTER);
    getContentPane().add(box,    BorderLayout.EAST);
  }

  public static void main(String[] args) {
    CellBorderTableExample frame = new CellBorderTableExample();
    frame.addWindowListener( new WindowAdapter() {
      public void windowClosing( WindowEvent e ) {
        System.exit(0);
      }
    });
    frame.setSize( 400, 240 );
    frame.setVisible(true);
  }

  
  class ThicknessPanel extends JPanel {    
    JComboBox[] combos;
    
    ThicknessPanel() {
      String[] str = {&quot;top&quot;,&quot;left&quot;,&quot;bottom&quot;,&quot;right&quot;};
      int n = str.length;
      setLayout(new GridLayout(n,2));
      setBorder(new TitledBorder(&quot;Thickness&quot;));
      combos = new JComboBox[n];
      for (int i=0;i&lt;n;i++) {
        combos[i] = new JComboBox(new Object[]{&quot;0&quot;,&quot;1&quot;,&quot;2&quot;,&quot;3&quot;});
        add(new JLabel(str[i]));
        add(combos[i]);
      }
    }
     
    public Insets getThickness() {
      Insets insets = new Insets(0,0,0,0);
      insets.top    = combos[0].getSelectedIndex();      
      insets.left   = combos[1].getSelectedIndex();      
      insets.bottom = combos[2].getSelectedIndex();      
      insets.right  = combos[3].getSelectedIndex();      
      return insets;      
    }
  }

  
  class ButtonPanel extends JPanel {
    JTable table;
    ThicknessPanel thicknessPanel;
    Color color = UIManager.getColor(&quot;Table.gridColor&quot;);
    
    ButtonPanel(JTable table, ThicknessPanel thicknessPanel) {
      this.table = table;
      this.thicknessPanel = thicknessPanel;
      setLayout(new GridLayout(3,1));
      setBorder(new TitledBorder(&quot;Append Lines&quot;));
      final JCheckBox oneBlock = new JCheckBox(&quot;Block&quot;);
      JButton b_and = new JButton(&quot;REPLACE&quot;);
      JButton b_or  = new JButton(&quot;OR&quot;);
      add(oneBlock);
      add(b_and);
      add(b_or);
      b_and.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          setCellBorder(true, oneBlock.isSelected());
        }
      });
      b_or.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          setCellBorder(false, oneBlock.isSelected());
        }
      });
    }  
    
    private void setCellBorder(boolean isReplace, boolean isBlock) {
      boolean isTop,isLeft,isBottom,isRight;
      Insets insets = thicknessPanel.getThickness();
      int[] columns = table.getSelectedColumns();
      int[] rows    = table.getSelectedRows();
      int rowMax    = rows.length;
      int columnMax = columns.length;
      
      for (int i=0;i&lt;rowMax;i++) {
        int row = rows[i];
        isTop    = (i == 0       )? true: false;
        isBottom = (i == rowMax-1)? true: false;
        
        for (int j=0;j&lt;columnMax;j++) {
          int column = columns[j];
          isLeft  = (j == 0          )? true: false;
          isRight = (j == columnMax-1)? true: false;
          
          MyData myData = (MyData)table.getValueAt(row, column);
          if (myData == null) {
            myData = new MyData(&quot;&quot;, new LinesBorder(color,0));
          }
          LinesBorder border = (LinesBorder)myData.getBorder();
          
          if (isBlock) {
            Insets tmp = new Insets(0,0,0,0);
            if (isTop)    tmp.top    = Math.max(tmp.top    ,insets.top);
            if (isLeft)   tmp.left   = Math.max(tmp.left   ,insets.left);
            if (isBottom) tmp.bottom = Math.max(tmp.bottom ,insets.bottom);
            if (isRight)  tmp.right  = Math.max(tmp.right  ,insets.right);
            border.append(tmp, isReplace);
          } else {
            border.append(insets, isReplace);
          }
          
          table.setValueAt(myData, row, column);
        }
      }
      table.clearSelection();
      table.revalidate();
      table.repaint();
    }  
  }
 
  class MyData implements CellBorder {
    private Border border;
    private Object obj;
    
    public MyData(Object obj, Border border) {
      this.obj    = obj;
      this.border = border;
    }
    
    public void setObject(Object obj) {
      this.obj = obj;
    }    
    public String toString() {
      return obj.toString();
    }
    
    // CellBorder   
    public void setBorder(Border border) {
      this.border = border;
    }   
    public Border getBorder() {
      return border;
    }
    public void setBorder(Border border, int row, int col) {}
    public Border getBorder(int row, int col) { return null; }
  }
}

BorderCellRenderer.java:

import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.border.*;
 
/**
 * @version 1.0 03/06/99
 */
public class BorderCellRenderer extends JLabel
    implements TableCellRenderer {
  protected Border noFocusBorder; 
  protected Border columnBorder; 
 
  public BorderCellRenderer() {
    noFocusBorder = new EmptyBorder(1, 2, 1, 2);
    setOpaque(true);
  }
 
  public Component getTableCellRendererComponent(JTable table, Object value,
                 boolean isSelected, boolean hasFocus, int row, int column) {
    if (isSelected) {
      setForeground(table.getSelectionForeground());
      setBackground(table.getSelectionBackground());
    } else {
      setForeground(table.getForeground());
      setBackground(table.getBackground());
    }
    setFont(table.getFont());
    
    if (hasFocus) {
      setBorder( UIManager.getBorder(&quot;Table.focusCellHighlightBorder&quot;) );
      if (table.isCellEditable(row, column)) {
        setForeground( UIManager.getColor(&quot;Table.focusCellForeground&quot;) );
        setBackground( UIManager.getColor(&quot;Table.focusCellBackground&quot;) );
      }
    } else {
      if (value instanceof CellBorder) {
        Border border = ((CellBorder)value).getBorder();
        setBorder(border);
      } else {
        if (columnBorder != null) {
          setBorder(columnBorder);
        } else {
          setBorder(noFocusBorder);
        }
      }
    }
    setText((value == null) ? &quot;&quot; : value.toString());        
    return this;
  }
  
  public void setColumnBorder(Border border) {
    columnBorder = border;
  }
   
  public Border getColumnBorder() {
    return columnBorder;
  }
     
}

CellBorder.java:

import java.awt.*;
import javax.swing.border.*;
 
/**
 * @version 1.0 03/06/99
 */
public interface CellBorder {
  
  public Border getBorder();
  public Border getBorder(int row, int column);
  
  public void setBorder(Border border);
  public void setBorder(Border border, int row, int column);
}

LinesBorder.java:

import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;

/**
 * @version 1.0 03/09/99
 */
public class LinesBorder extends AbstractBorder implements SwingConstants { 
  protected int northThickness;
  protected int southThickness;
  protected int eastThickness;
  protected int westThickness;  
  protected Color northColor;
  protected Color southColor;
  protected Color eastColor;
  protected Color westColor;
  
  public LinesBorder(Color color) {
    this(color, 1);
  }

  public LinesBorder(Color color, int thickness)  {
    setColor(color);
    setThickness(thickness);
  }

  public LinesBorder(Color color, Insets insets)  {
    setColor(color);
    setThickness(insets);
  }

  public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
    Color oldColor = g.getColor();
    
    g.setColor(northColor);
    for (int i = 0; i &lt; northThickness; i++)  {
      g.drawLine(x, y+i, x+width-1, y+i);
    }
    g.setColor(southColor);
    for (int i = 0; i &lt; southThickness; i++)  {
      g.drawLine(x, y+height-i-1, x+width-1, y+height-i-1);
    }
    g.setColor(eastColor);
    for (int i = 0; i &lt; westThickness; i++)  {
      g.drawLine(x+i, y, x+i, y+height-1);
    }
    g.setColor(westColor);
    for (int i = 0; i &lt; eastThickness; i++)  {
      g.drawLine(x+width-i-1, y, x+width-i-1, y+height-1);
    }
 
    g.setColor(oldColor);
  }

  public Insets getBorderInsets(Component c)       {
    return new Insets(northThickness, westThickness, southThickness, eastThickness);
  }
 
  public Insets getBorderInsets(Component c, Insets insets) {
    return new Insets(northThickness, westThickness, southThickness, eastThickness);    
  }
 
  public boolean isBorderOpaque() { return true; }
    
  public void setColor(Color c) {
    northColor = c;
    southColor = c;
    eastColor  = c;
    westColor  = c;
  }
  
  public void setColor(Color c, int direction) {
    switch (direction) {
      case NORTH: northColor = c; break;
      case SOUTH: southColor = c; break;
      case EAST:  eastColor  = c; break;
      case WEST:  westColor  = c; break;
      default: 
    }
  }
    
  public void setThickness(int n) {
    northThickness = n;
    southThickness = n;
    eastThickness  = n;
    westThickness  = n;
  }
    
  public void setThickness(Insets insets) {
    northThickness = insets.top;
    southThickness = insets.bottom;
    eastThickness  = insets.right;
    westThickness  = insets.left;
  }
  
  public void setThickness(int n, int direction) {
    switch (direction) {
      case NORTH: northThickness = n; break;
      case SOUTH: southThickness = n; break;
      case EAST:  eastThickness  = n; break;
      case WEST:  westThickness  = n; break;
      default: 
    }
  }
 
  public void append(LinesBorder b, boolean isReplace) {
    if (isReplace) {
      northThickness = b.northThickness;
      southThickness = b.southThickness;
      eastThickness  = b.eastThickness;
      westThickness  = b.westThickness;
    } else {
      northThickness = Math.max(northThickness ,b.northThickness);
      southThickness = Math.max(southThickness ,b.southThickness);
      eastThickness  = Math.max(eastThickness  ,b.eastThickness);
      westThickness  = Math.max(westThickness  ,b.westThickness);
    }
  }

  public void append(Insets insets, boolean isReplace) {
    if (isReplace) {
      northThickness = insets.top;
      southThickness = insets.bottom;
      eastThickness  = insets.right;
      westThickness  = insets.left;
    } else {
      northThickness = Math.max(northThickness ,insets.top);
      southThickness = Math.max(southThickness ,insets.bottom);
      eastThickness  = Math.max(eastThickness  ,insets.right);
      westThickness  = Math.max(westThickness  ,insets.left);
    }
  }
}

Change the orientation of a JTextArea, eg. right to left

You can use the method setComponentOrientation defined in the Component class, so
you can invoke it on most Swing components.
It does not seem to work properly using JDK1.2, but does with JDK1.3.

import javax.swing.event.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
   
public class Main extends JFrame
{
   public Main() throws Exception {
      JTextArea tf = new JTextArea();
      getContentPane().add(tf);
      pack();

      tf.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            System.exit(0);
         }
      });
   }
 
   public static void main(String args[]) throws Exception {
      Main main = new Main();
      main.show();
   }
}

For international applications, you can determine the orientation using
the Locale:

      Locale arabic = new Locale("ar", "SA");
      jcomponent.setComponentOrientation(ComponentOrientation.getOrientation(arabic));

Creating a formatted textfield that only accepts IP addresses

JDK1.4 introduced the JFormattedTextfield with which you can set a mask on a text field.
This example not only shows you how to set the mask (eg. 255.255.xxx.xxx), but also how to use an InputVerifier to check whether the inputted digits lie in the range [0-255].

Main.java:

import javax.swing.JFormattedTextField.*;
import javax.swing.text.*;
import java.awt.event.*;
import javax.swing.*;
import java.text.*;
import java.util.*;
import java.awt.*;
 
public class Main extends JFrame 
{
   public Main() throws Exception
   {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      MaskFormatter formatter = new MaskFormatter("255.255.###.###");
      formatter.setPlaceholderCharacter('0');
 
      final JFormattedTextField formattedTf = new JFormattedTextField(formatter);
      formattedTf.setInputVerifier(new IPTextFieldVerifier());
 
      final JTextField normalTf = new JTextField(25);
      JButton button = new JButton("Get value");
      button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) { 
            normalTf.setText(""+formattedTf.getValue());
         }
      });
 
      getContentPane().setLayout(new FlowLayout(FlowLayout.LEFT));
      getContentPane().add(formattedTf);
      getContentPane().add(button);
      getContentPane().add(normalTf);
 
      formattedTf.setPreferredSize(normalTf.getPreferredSize());
   }
  
   public static void main(String args[]) throws Exception 
   {
      Main main = new Main();
      main.setSize(300, 150);
      main.setVisible(true);
   }
}
 
class IPTextFieldVerifier extends InputVerifier {
   public boolean verify(JComponent input) {
      if (input instanceof JFormattedTextField) {
         JFormattedTextField ftf = (JFormattedTextField)input;
         AbstractFormatter formatter = ftf.getFormatter();
         if (formatter != null) {
            String text = ftf.getText();
            StringTokenizer st = new StringTokenizer(text, ".");
            while (st.hasMoreTokens()) {
               int value = Integer.parseInt((String) st.nextToken());
               if (value < 0 || value > 255) {
                  // to prevent recursive calling of the 
                  // InputVerifier, set it to null and
                  // restore it after the JOptionPane has
                  // been clicked.
                  input.setInputVerifier(null);
                  JOptionPane.showMessageDialog(new Frame(), "Malformed IP Address!", "Error", 
                                                JOptionPane.ERROR_MESSAGE);
                  input.setInputVerifier(this);  
                  return false;
               }
            }
            return true;
         }
      }
      return true;
   }
 
   public boolean shouldYieldFocus(JComponent input) {
      return verify(input);
   }
}

Aligning the drop-down arrow of a JComboBox to the right

Main.java:

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame
{
   public Main() {
      this.addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
 
      getContentPane().setLayout(new FlowLayout(FlowLayout.LEFT));
      Object []items = new Object[] { "one", "two", "three", "four", 
                                      "five", "six", "seven" };
      JComboBox comboBox = new JComboBox(items);
      getContentPane().add(comboBox);
      comboBox.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(200, 200);
      main.setVisible(true);
   }
}

Creating an auto-complete JComboBox

Main.java:

import javax.swing.plaf.basic.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame
{
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      getContentPane().setLayout(new FlowLayout(FlowLayout.LEFT));
 
      String[] elements = new String[] { "arthur", "brian", "chet", "danny", "dave",  
                                         "don", "edmond", "eddy", "glen", "gregory", "john",
                                         "ken", "malcolm", "pete", "stephanie", "yvonne" };
 
      JComboBox comboBox = new AutoCompleteComboBox(elements);
      getContentPane().add(comboBox);
   }
      
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(300, 300);
      main.setVisible(true);
   }
}
 
class AutoCompleteComboBox extends JComboBox
{
   public int caretPos=0;
   public JTextField inputField=null;
 
   public AutoCompleteComboBox(final Object elements[]) {
      super(elements);
      setEditor(new BasicComboBoxEditor());
      setEditable(true);
   }
 
   public void setSelectedIndex(int index) {
      super.setSelectedIndex(index);
 
      inputField.setText(getItemAt(index).toString());
      inputField.setSelectionEnd(caretPos + tf.getText().length());
      inputField.moveCaretPosition(caretPos);
   }
 
   public void setEditor(ComboBoxEditor editor) {
      super.setEditor(editor);
      if (editor.getEditorComponent() instanceof JTextField) {
         inputField = (JTextField) editor.getEditorComponent();
 
         inputField.addKeyListener(new KeyAdapter() {
            public void keyReleased( KeyEvent ev ) {
               char key=ev.getKeyChar();
               if (! (Character.isLetterOrDigit(key) || Character.isSpaceChar(key) )) return;
 
               caretPos=inputField.getCaretPosition();
               String text="";
               try {
                  text=inputField.getText(0, caretPos);
               }
               catch (javax.swing.text.BadLocationException e) {
                  e.printStackTrace();
               }
 
               for (int i=0; i<getItemCount(); i++) {
                  String element = (String) getItemAt(i);
                  if (element.startsWith(text)) {
                     setSelectedIndex(i);
                     return;
                  }
               }
            }
         });
      }
   }
}

Adding a vertical line separator to a JToolBar

The method addSeparator in the JToolBar class only adds blank space. You could add JSeparator components to your JToolBar with add but then you run into trouble when changing the orientation. In the following example, this has been solved by listening to propertyChangeEvents and changing the JSeparator orientation so that they are opposite to the JToolBar’s orientation.

Main.java:

import javax.swing.border.*;
import java.awt.event.*;
import javax.swing.*;
import java.beans.*;
import java.awt.*;
  
public class Main extends JFrame {
   public Main() {
      super("JToolBar example");
 
      final JTextArea textArea = new JTextArea(5, 30);
      MyJToolBar toolBar = new MyJToolBar();
 
      JButton gifButton = new JButton(new ImageIcon("gifIcon.gif"));
      JButton jpgButton = new JButton(new ImageIcon("jpgIcon.gif"));
      JButton tiffButton = new JButton(new ImageIcon("tiffIcon.gif"));
 
      gifButton.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            textArea.append("gifButton clicked!n");
         }
      });
  
      jpgButton.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            textArea.append("jpgButton clicked!n");
         }
      });
        
      tiffButton.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            textArea.append("tiffButton clicked!n");
         }
      });
 
      toolBar.add(gifButton);
      toolBar.add(new JToolBar.Separator());
      toolBar.add(new JSeparator(JSeparator.VERTICAL));
      toolBar.add(new JToolBar.Separator());
      toolBar.add(jpgButton);
      toolBar.add(new JToolBar.Separator());
      toolBar.add(new JSeparator(JSeparator.VERTICAL));
      toolBar.add(new JToolBar.Separator());
      toolBar.add(tiffButton);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            System.exit(0);
         }
      });
 
      getContentPane().setLayout(new BorderLayout());
      getContentPane().add(BorderLayout.NORTH, toolBar);
      getContentPane().add(BorderLayout.CENTER, new JScrollPane(textArea));
   }
 
   public static void main(String[] args) {
      Main main = new Main();
      main.setSize(300, 300);
      main.setVisible(true);
   }
}
 
class MyJToolBar extends JToolBar
{
   public MyJToolBar() {
      super();
      listenForOrientationChange();
   }
 
   public MyJToolBar(int orientation) {
      super(orientation);
      listenForOrientationChange();
   }
 
   public MyJToolBar(String name) {
      super(name);
      listenForOrientationChange();
   }
 
   public MyJToolBar(String name, int orientation) {
      super(name, orientation);
      listenForOrientationChange();
   }
 
   protected void listenForOrientationChange() {
      addPropertyChangeListener(new PropertyChangeListener() {
         public void propertyChange(PropertyChangeEvent evt) {
            MyJToolBar toolBar = MyJToolBar.this;
            Component[] components = toolBar.getComponents();
            for (int i=0; i<components.length; i++) {
               if (components[i] instanceof javax.swing.JSeparator) {
                  JSeparator separator = (JSeparator) components[i];
                  if (toolBar.getOrientation() == SwingConstants.HORIZONTAL) {
                     separator.setOrientation(JSeparator.VERTICAL);      
                     separator.setMaximumSize(new Dimension(2,
                                              toolBar.getPreferredSize().width));
                  }
                  else {
                     separator.setOrientation(JSeparator.HORIZONTAL);
                     separator.setMaximumSize(new Dimension(
                                              toolBar.getPreferredSize().height, 2));
                  }
               }
            }
         }
      });
   }
}

Capturing an event when a JInternalFrame is selected

Main.java:

import java.awt.event.*;
import javax.swing.*;
import java.beans.*;
import java.util.*;
import java.awt.*;
import java.net.*;
 
public class Main extends JFrame {
   JDesktopPane desktop;
   int nframes = 0;
  
   public Main() {
      desktop = new JDesktopPane(); 
      setContentPane(desktop);
      setJMenuBar(createMenuBar());
      createInternalFrame(); 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
   }
 
   protected JMenuBar createMenuBar() {
      JMenuBar menuBar = new JMenuBar();
 
      JMenu createMenu = new JMenu("Create");
      createMenu.setMnemonic(KeyEvent.VK_C);
      JMenuItem newMenuItem = new JMenuItem("New");
      newMenuItem.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            createInternalFrame();
         }
      }); 
      newMenuItem.setMnemonic(KeyEvent.VK_N);
      createMenu.add(newMenuItem);
      menuBar.add(createMenu);
 
      return menuBar;
   }
 
   protected void createInternalFrame() {
      nframes++;
      String title = "JInternalFrame #" + nframes;
      MyJInternalFrame frame = new MyJInternalFrame(title,
         true,    // resizable
         true,    // closable
         true,    // maximizable
         true);   // iconifiable
      frame.setVisible(true); 
 
      desktop.add(frame);
      frame.setSize(200, 200);
      frame.setLocation(30*nframes, 30*nframes);
      try {
         frame.setSelected(true);
      } catch (java.beans.PropertyVetoException e) {}
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(500, 300);
      main.setVisible(true);
   }
} 
 
class MyJInternalFrame extends JInternalFrame 
                       implements VetoableChangeListener { 
   public MyJInternalFrame(String title, boolean resizable, 
                           boolean closable, boolean maximizable, 
                           boolean iconifiable) { 
      super(title, resizable, closable, maximizable, iconifiable); 
      addVetoableChangeListener(this); 
   } 
 
   public void vetoableChange(PropertyChangeEvent pce) 
                                 throws PropertyVetoException { 
      if (pce.getPropertyName().equals(IS_SELECTED_PROPERTY)) { 
         boolean selected = ((Boolean) pce.getNewValue()).booleanValue(); 
         if (selected) { 
            System.out.println(getTitle() + " is selected!");
         } 
      } 
   }
} 

Creating a JComboBox with a divider separator line

Create a cellRenderer that does not convert the element to a String in order to show it, but instead checks whether it is a JSeparator and returns that component instead. Then make sure the JSeparator itself cannot be selected by adding an ActionListener to the combobox.

Main.java:

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 JComboBox combobox = 
         new JComboBox(new Object[] {
               "Item 1",
               "Item 2",
               "Item 3",
               new JSeparator(JSeparator.HORIZONTAL),
               "Item 4",
               "Item 5"
            }
         );
 
      getContentPane().add(combobox);
      combobox.setRenderer(new SeparatorComboBoxRenderer());
      combobox.addActionListener(new SeparatorComboBoxListener(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 SeparatorComboBoxRenderer extends BasicComboBoxRenderer implements ListCellRenderer
{
   public SeparatorComboBoxRenderer() {
      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 JSeparator) {
         return (Component) value;
      }
      else {
         setText((value == null) ? "" : value.toString());
      }
 
      return this;
  }  
}
 
class SeparatorComboBoxListener implements ActionListener {
   JComboBox combobox;
   Object oldItem;
    
   SeparatorComboBoxListener(JComboBox combobox) {
      this.combobox = combobox;
      combobox.setSelectedIndex(0);
      oldItem = combobox.getSelectedItem();
   }
     
   public void actionPerformed(ActionEvent e) {
      Object selectedItem = combobox.getSelectedItem();
      if (selectedItem instanceof JSeparator) {
         combobox.setSelectedItem(oldItem);
      } else {
         oldItem = selectedItem;
      }
   }
}

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