Making the cells of a JTable transparent so that background image shows through

Author: Zafir Anjum

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
 
public class Table
{
   public static void main(String[] args) {
      JFrame frame = new JFrame("Table");
      frame.addWindowListener( new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            Window win = e.getWindow();
            win.setVisible(false);
            win.dispose();
            System.exit(0);
         }
      } );	
 
      // Create your own sub-class of JTable rather than using anonymous class
      JTable table = new JTable( 15, 3 ) {
         public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
            Component c = super.prepareRenderer( renderer, row, column);
            // We want renderer component to be transparent
            // so background image is visible
            if( c instanceof JComponent )
               ((JComponent)c).setOpaque(false);
               return c;
            }

            // Hard coded value. In your sub-class add a function for this.
            ImageIcon image = new ImageIcon( "codeguruwm.gif" );

            public void paint( Graphics g ) {
               // First draw the background image - tiled 
               Dimension d = getSize();
               for( int x = 0; x < d.width; x += image.getIconWidth() )
                  for( int y = 0; y < d.height; y += image.getIconHeight() ) 
                     g.drawImage( image.getImage(), x, y, null, null );
               // Now let the regular paint code do it's work
               super.paint(g);
           }
      };
 
      // Set the table transparent
      table.setOpaque(false);
		
      JScrollPane sp = new JScrollPane( table );
      frame.getContentPane().add( sp );	

      frame.pack();
      frame.show();
   }
}

Changing the margins between JTable grid lines and cell data

You can do so with the JTable method setIntercellSpacing.

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));
      JScrollPane scrollPane = new JScrollPane(table);
 
      table.setIntercellSpacing(new Dimension (10,20));
  
      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();
   }
}

Using SAX

SAX stands for Simple API for XML. A SAX parser is event-based. Events are reported through callbacks as the parser moves through the XML document.

This example was compiled and run with JDK1.4, as the APIs and reference implementation are included. If you use a lower JDK version, download JAXP (Java APIs for XML Processing) on http://java.sun.com/xml/jaxp.html.

Main.java:

import org.xml.sax.helpers.*;
import javax.xml.parsers.*;
import org.xml.sax.*;
import java.io.*;
 
public class Main 
{
   public static void main(String []args) {
      try {
         SAXParserFactory factory = SAXParserFactory.newInstance();
         SAXParser parser = factory.newSAXParser();
 
         InputSource is = new InputSource(new FileReader("example.xml"));
         parser.parse(is, new MySAXHandler());
      }
      catch(ParserConfigurationException e) {
         e.printStackTrace();
      }
      catch(SAXException e) {
         e.printStackTrace();
      }
      catch(IOException e) {
         e.printStackTrace();
      }        
   }
}
 
class MySAXHandler extends DefaultHandler
{
   int indent = 0;
 
   public void startDocument() throws SAXException {
      System.out.println("startDocument()");
   }
 
   public void endDocument() throws SAXException {
      indent(-3);
      System.out.println("endDocument()");
   }
 
   public void characters(char[] ch, int start, int length)  {
      String s = new String(ch, start, length);
      if (!s.trim().equals("")) {
         indent(0);
         System.out.println(s);
      }
   }
 
   public void ignorableWhitespace(char[] ch, int start, int length) {
      System.out.println("[whitespace]");
   }
 
   public void startElement(String uri, String localName, 
                            String qName, Attributes attributes) {
      indent(3);
      System.out.println("[element " + qName + "]");
      for (int i=0; i<attributes.getLength(); i++) {
         indent(0);
         System.out.println("[Attribute " + attributes.getQName(i) +
                            ", value=" + attributes.getValue(i) + "]");
      }
   }
 
   public void endElement(String uri, String localName, String qName) {
      indent(0);
      System.out.println("[endelement " + qName + "]");
      indent -= 3;
   }
 
   public void indent(int pos) {
      indent += pos;
      for (int i=0; i<indent; i++) {
         System.out.print(" ");
      }
   }
}

example.xml:

<?xml version="1.0"?>
<customer id="C123456">
   <name>Joris Van den Bogaert</name>
   <email>joris1@esus.com</email>
</customer>

output:

startDocument()
   [element customer]
   [Attribute id, value=C123456]
      [element name]
      Joris Van den Bogaert
      [endelement name]
      [element email]
      joris1@esus.com
      [endelement email]
   [endelement customer]
endDocument()

Creating an underlined JLabel without using HTML

Main.java:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
 
public class Main extends JFrame
{
   public Main() {
      getContentPane().setLayout(new GridLayout(1, 2));
      JPanel panel1 = new JPanel();
      panel1.setLayout(new GridLayout(5, 1));
      panel1.add(new JLabel(&quot;JLabel/icon/LEFT&quot;, 
                           new ImageIcon(&quot;tiffIcon.gif&quot;), SwingConstants.LEFT));
      panel1.add(new JLabel(&quot;JLabel/icon/CENTER&quot;, 
                           new ImageIcon(&quot;tiffIcon.gif&quot;), SwingConstants.CENTER));
      panel1.add(new JLabel(&quot;JLabel/icon/RIGHT&quot;, 
                           new ImageIcon(&quot;tiffIcon.gif&quot;), SwingConstants.RIGHT));
      panel1.add(new JLabel(&quot;JLabel/icon/LEADING&quot;, 
                           new ImageIcon(&quot;tiffIcon.gif&quot;), SwingConstants.LEADING));
      panel1.add(new JLabel(&quot;JLabel/icon/TRAILING&quot;, 
                           new ImageIcon(&quot;tiffIcon.gif&quot;), SwingConstants.TRAILING));
 
      getContentPane().add(new JScrollPane(panel1));
 
      JPanel panel2 = new JPanel();
      panel2.setLayout(new GridLayout(5, 1));
      panel2.add(new UnderlinedJLabel(&quot;JLabel/icon/LEFT&quot;, 
                                      new ImageIcon(&quot;tiffIcon.gif&quot;), SwingConstants.LEFT));
      panel2.add(new UnderlinedJLabel(&quot;JLabel/icon/CENTER&quot;, 
                                      new ImageIcon(&quot;tiffIcon.gif&quot;), SwingConstants.CENTER));
      panel2.add(new UnderlinedJLabel(&quot;JLabel/icon/RIGHT&quot;, 
                                      new ImageIcon(&quot;tiffIcon.gif&quot;), SwingConstants.RIGHT));
      panel2.add(new UnderlinedJLabel(&quot;JLabel/icon/LEADING&quot;, 
                                      new ImageIcon(&quot;tiffIcon.gif&quot;), SwingConstants.LEADING));
      panel2.add(new UnderlinedJLabel(&quot;JLabel/icon/TRAILING&quot;, 
                                      new ImageIcon(&quot;tiffIcon.gif&quot;), SwingConstants.TRAILING));
 
      getContentPane().add(new JScrollPane(panel2));
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(300, 150);
      main.setVisible(true);   
   }
}
 
class UnderlinedJLabel extends JLabel
{
   public UnderlinedJLabel() {
   }
 
   public UnderlinedJLabel(Icon image) {
      super(image);
   }
 
   public UnderlinedJLabel(Icon image, int horizontalAlignment) {
      super(image, horizontalAlignment);
   }
 
   public UnderlinedJLabel(String text) {
      super(text);
   }

   public UnderlinedJLabel(String text, Icon icon, int horizontalAlignment) {
      super(text, icon, horizontalAlignment);
   }
 
   public UnderlinedJLabel(String text, int horizontalAlignment) {
      super(text, horizontalAlignment);
   }
 
   public void paint(Graphics g) {
      super.paint(g);
      underline(g);
   }
 
   protected void underline(Graphics g) {
      Insets insets = getInsets();
      FontMetrics fm = g.getFontMetrics();
      Rectangle textR = new Rectangle();
      Rectangle viewR = new Rectangle(
                                  insets.left, 
                                  insets.top, 
                                  getWidth() - (insets.right + insets.left), 
                                  getHeight() - (insets.bottom + insets.top));
  
      // compute and return location of the icons origin,
      // the location of the text baseline, and a possibly clipped
      // version of the compound label string.  Locations are computed 
      // relative to the viewR rectangle.
      String text = SwingUtilities.layoutCompoundLabel(
                         this,                        // this JLabel
                         fm,                          // current FontMetrics
                         getText(),                   // text
                         getIcon(),                   // icon
                         getVerticalAlignment(),      
                         getHorizontalAlignment(),
                         getVerticalTextPosition(),
                         getHorizontalTextPosition(), 
                         viewR,                       
                         new Rectangle(),             // don't care about icon rectangle
                         textR,                       // resulting text locations
                         getText() == null ? 0 : 
                            ((Integer)UIManager.get(&quot;Button.textIconGap&quot;)).intValue());
 
      // draw line
      int textShiftOffset = ((Integer) UIManager.get(&quot;Button.textShiftOffset&quot;)).intValue();
      g.fillRect(textR.x +
                 textShiftOffset - 4,
                 textR.y + fm.getAscent() + textShiftOffset + 2,
                 textR.width, 
                 1);
   }
}

Writing a custom FocusTraversalPolicy

[JDK 1.4+] Extend from FocusTraversalPolicy and implement the abstract methods!

Main.java:

import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
  
public class Main extends JFrame
{
   JLabel label = new JLabel("Forward: TAB or alt-f, Backward: SHIFT-TAB or alt-b");
   ArrayList textfields = new ArrayList();
   JRadioButton leftToRight = new JRadioButton("Left to right", true);
   JRadioButton topToBottom = new JRadioButton("Top to bottom");
  
   public Main() {
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
      Container contentPane = getContentPane();
      contentPane.setLayout(new BorderLayout(10, 10));
  
      JPanel topPanel = new JPanel(new GridLayout(3, 1));
      topPanel.add(new JLabel("Change the focus traversal policy"));
 
      ButtonGroup group = new ButtonGroup();
      group.add(leftToRight);
      group.add(topToBottom);
      topPanel.add(leftToRight); 
      topPanel.add(topToBottom);
 
      JPanel bottomPanel = new JPanel(new GridLayout(4, 2));
      for (int i=0; i<4; i++) {
         for (int j=0; j<2; j++) { 
            JTextField textfield = new JTextField("" + i + ", " + j);
            textfields.add(textfield);
            bottomPanel.add(textfield);
         }
      }     
  
      contentPane.add(BorderLayout.NORTH, topPanel);
      contentPane.add(BorderLayout.SOUTH, bottomPanel);
  
      bottomPanel.setFocusTraversalPolicy(new MyFocusTraversalPolicy());
      bottomPanel.setFocusCycleRoot(true);
   } 
  
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(350, 200);
      main.setVisible(true);
   }
 
   class MyFocusTraversalPolicy extends FocusTraversalPolicy
   {
      // Returns the Component that should receive the focus after aComponent.
      public Component getComponentAfter(Container focusCycleRoot, Component aComponent) {
         if (leftToRight.isSelected()) {
            int index = textfields.indexOf(aComponent);
            return (Component) textfields.get((index + 1) % textfields.size());
         }
         else if (topToBottom.isSelected()) {
            int index = textfields.indexOf(aComponent);
            int nextIndex = (index + 2) % textfields.size();
            if (nextIndex == 0) nextIndex = 1;
            else if (nextIndex == 1) nextIndex = 0;
            return (Component) textfields.get(nextIndex);
         }
 
         if (!aComponent.isEnabled()) {
            return getComponentAfter(focusCycleRoot, aComponent);
         }          
 
         return aComponent;
      }
  
      // Returns the Component that should receive the focus before aComponent.
      public Component getComponentBefore(Container focusCycleRoot, Component aComponent) {
         if (leftToRight.isSelected()) {
            int index = textfields.indexOf(aComponent);
            index--;
            if (index < 0) index = textfields.size() - 1;
            return (Component) textfields.get(index);
         }
         else if (topToBottom.isSelected()) {
            int index = textfields.indexOf(aComponent);
            index -= 2;
            if (index < 0) index = textfields.size() - 3 - index;
            //else if (index == 0) index = textfields.size() - 1;
            //else if (index == 1) index = textfields.size() - 2;
            return (Component) textfields.get(index);
         }
 
         return aComponent;
      }
  
      // Returns the default Component to focus.
      public Component getDefaultComponent(Container focusCycleRoot) {
         return (Component) textfields.get(0);
      }
 
      // Returns the first Component in the traversal cycle.
      public Component getFirstComponent(Container focusCycleRoot) {
         return (Component) textfields.get(0);
      }
 
      // Returns the Component that should receive the focus when a Window is made visible for the first time. 
      public Component getInitialComponent(Window window) {
         return leftToRight;
      }
 
      // Returns the last Component in the traversal cycle. 
      public Component getLastComponent(Container focusCycleRoot) {
         return (Component) textfields.get(textfields.size() - 1);
      }
   }
}

Getting the HWND handle of a Canvas

Sometimes, you need the HWND handle for example to pass it on with JNI to a native function. See related links, where the mousewheel support is implemented using this method.
This example shows you how to get the handle of a window as well as a Canvas.

HwndCanvas.java:

import java.awt.*;
import sun.awt.*;
 
public class HwndCanvas extends Canvas
{
   public int getHwnd() {
      int hwnd = 0;
                            
      DrawingSurfaceInfo w = ((DrawingSurface)(getPeer())).getDrawingSurfaceInfo();
                               
      if (w != null) {
         w.lock();
         Win32DrawingSurface win32 = (Win32DrawingSurface) w.getSurface();
         hwnd = win32.getHWnd();
         w.unlock();
      }
       
      return hwnd;
   }                    
}

Main.java:

import java.awt.event.*;
import java.awt.*;
import sun.awt.*;
 
public class Main extends Frame
{
   public HwndCanvas hwndCanvas = new HwndCanvas();
 
   public Main() {
      setLayout(new BorderLayout());
      add(BorderLayout.CENTER, hwndCanvas);
 
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            System.exit(0);
         }
      });      
 
      setSize(100, 100);
   }
 
   public int getHwnd() { 
      int hwnd = 0;
                            
      DrawingSurfaceInfo w = ((DrawingSurface)(getPeer())).getDrawingSurfaceInfo();
                               
      if (w != null) {
         w.lock();
         Win32DrawingSurface win32 = (Win32DrawingSurface) w.getSurface();
         hwnd = win32.getHWnd();
         w.unlock();
      }
      
      return hwnd;
   } 
 
   public static void main(String []args) {
      Main m = new Main();
 
      m.show();
 
      System.out.println("HWND of Frame = " + m.getHwnd());
      System.out.println("HWND of Canvas = " + m.hwndCanvas.getHwnd());
   }
}

Drawing a rounded rectangle in Swing

Use the method drawRoundRect that accepts (x, y) coordinates (top-left), the width and size, and the width and height of the arc.

Main.java:

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);
         }
      });
   }
 
   public void paint(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
  
      g2d.drawRoundRect(10, 50, 150, 150, 50, 30);
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(300, 300);
      main.setVisible(true);
   }
}

Different types of join styles in Swing

Main.java:

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);
         }
      });
   }
 
   public void paint(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
 
      g2d.drawString("JOIN_BEVEL", 20, 35); 
      g2d.setStroke(new BasicStroke(15f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
      g2d.drawRect(20, 50, 80, 80);
 
      g2d.drawString("JOIN_MITER", 140, 35); 
      g2d.setStroke(new BasicStroke(15f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER));
      g2d.drawRect(140, 50, 80, 80);       
 
      g2d.drawString("JOIN_ROUND", 260, 35); 
      g2d.setStroke(new BasicStroke(15f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND));
      g2d.drawRect(260, 50, 80, 80);
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(360, 160);
      main.setVisible(true);
   }
}

Drawing a gradient filled rectangle in Swing

Main.java:

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);
         }
      });
   }
 
   public void paint(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
 
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                           RenderingHints.VALUE_ANTIALIAS_ON);
 
      GradientPaint gp = new GradientPaint(20, 50, Color.orange, 
                                           100, 130, Color.red, true);
      g2d.setPaint(gp);
      g2d.fillRect(20, 50, 80, 80);
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(120, 180);
      main.setVisible(true);
   }
}