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

Line numbers in a JTextArea

Here are two examples. The second was born from the first.

First Example: an extension to a component…

The first example LineNumberedPaper is a class that extends JTextArea and draws the line numbers in the paintComponent()
method. LineNumberedPaper artificially increases the size of the border by overriding the getInsets() methods and adding room for the “line numbers” (using the method lineNumberWidth()) to the left attribute of Insets.

paintComponent(), contains the logic for determining which line
numbers must be drawn based upon the the clip rectangle of the Graphics.

LineNumeredPaper can be modified to display the line numbers on the right side of the paper, this is left as an exercise for the reader. After, this idea was completed, the “border” increase forced the writing of the second example, LineNumberedBorder.

Second Example: a new border…

LineNumberedBorder is a border which draws a left (LEFT_JUSTIFY) or right (RIGHT_JUSTIFY) justified line number on either the left (LEFT_SIDE) or right side (RIGHT_SIDE) of the component. Currently, this only supports a JTextArea, due to the reliance on the getRows() and getLineCount() methods. paintBorder() contains the drawing of the line numbers and is very similar to LineNumberedPaper.paintComponent().

Summary

  • Each class has a main() which creates all possibilities for each class and can be easily removed.
  • The font of the line numbers is the same as the text.
    How would two different fonts play together? Which class/interface in javax.swing.text or subpackage should be used or extended?
  • paintComponent() and paintBorder() are very similar and speed is important, since each blink of the cursor causes a repaint.

LineNumberedPaper.java:

import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
 
import javax.swing.BorderFactory;
import javax.swing.JTextArea;
 
/**
 * Draws line numbers next to each line, in the same font as the text.
 * Based upon the comment in {@link #getInsets(Insets) getInsets} maybe the
 * "line numbering" could be a border?
 */
public class LineNumberedPaper extends JTextArea {
 
   public static void main(String[] args)
   {
      javax.swing.JFrame frame = new javax.swing.JFrame("Line Numbers...");
      frame.addWindowListener(new java.awt.event.WindowAdapter() {
         public void windowClosing(java.awt.event.WindowEvent ev) {
            System.exit(0);
         }
      });
 
      java.awt.Container contentPane = frame.getContentPane();
      contentPane.setLayout(new java.awt.GridLayout(0,2));
 
      javax.swing.JPanel subpanel;
      LineNumberedPaper lnp;
 
      int []justified = { LineNumberedBorder.LEFT_JUSTIFY,
                          LineNumberedBorder.RIGHT_JUSTIFY};
 
      String []labels = { "Left Justified",
                          "Right Justified"};
 
      for (int idx = 0; idx < labels.length; idx++) {
         lnp = new LineNumberedPaper(10,10);
         lnp.setLineNumberJustification(justified[idx]);
 
         subpanel = new javax.swing.JPanel(new java.awt.BorderLayout());
         subpanel.add(new javax.swing.JLabel(labels[idx]), java.awt.BorderLayout.NORTH);
         subpanel.add(new javax.swing.JScrollPane(lnp), java.awt.BorderLayout.CENTER);
         contentPane.add(subpanel);
      }
 
      frame.setSize(800,600);
      frame.show();
   } // main
 
   /**
    * The line number should be right justified.
    */
   public static int RIGHT_JUSTIFY = 0;
 
   /**
    * The line number should be left justified.
    */
   public static int LEFT_JUSTIFY = 1;
 
   /**
    * Indicates the justification of the text of the line number.
    */
   private int lineNumberJustification = RIGHT_JUSTIFY;
 
   public LineNumberedPaper(int rows, int cols) {
      super(rows, cols);
      setOpaque(false);
      // if this is NOT opaque...then painting is a problem...
      // basically...this draws the line numbers...
      // but...super.paintComponent()...erases the background...and the
      // line numbers...what to do?
      //
      // "workaround": paint the background in this class...
   }
 
   public Insets getInsets() {
      return getInsets(new Insets(0,0,0,0));
   }
 
   /**
    * This modifies the insets, by adding space for the line number on the
    * left. Should be modified to add space on the right, depending upon
    * Locale.
    */
   public Insets getInsets(Insets insets) {
      insets = super.getInsets(insets);
      insets.left += lineNumberWidth();
      return insets;
   }
 
   public int getLineNumberJustification() {
      return lineNumberJustification;
   }
 
   public void setLineNumberJustification(int justify) {
      if (justify == RIGHT_JUSTIFY || justify == LEFT_JUSTIFY) {
         lineNumberJustification = justify;
      }
   }
 
   /**
    * Returns the width, in pixels, of the maximum line number, plus a
    * trailing space.
    */
   private int lineNumberWidth() {
      //
      // note: should this be changed to use all nines for the lineCount?
      // for example, if the number of rows is 111...999 could be wider
      // (in pixels) in a proportionally spaced font...
      //
      int lineCount = Math.max(getRows(), getLineCount() + 1);
      return getFontMetrics(getFont()).stringWidth(lineCount + " ");
   }
 
   //
   // NOTE: This method is called every time the cursor blinks...
   //       so...optimize (later and if possible) for speed...
   //
   public void paintComponent(Graphics g) {
      Insets insets = getInsets();
 
      Rectangle clip = g.getClipBounds();
 
      g.setColor(getBackground()); // see note in constructor about this...
      g.fillRect(clip.x, clip.y, clip.width, clip.height);
 
      // do the line numbers need redrawn?
      if (clip.x < insets.left) {
         FontMetrics fm = g.getFontMetrics();
         int fontHeight = fm.getHeight();
 
         // starting location at the "top" of the page...
         // y is the starting baseline for the font...
         // should "font leading" be applied?
         int y = fm.getAscent() + insets.top;
 
         //
         // now determine if it is the "top" of the page...or somewhere else
         //
         int startingLineNumber = ((clip.y + insets.top) / fontHeight) + 1;
 
         //
         // use any one of the following if's:
         //
         //			if (startingLineNumber != 1)
         if (y < clip.y) {
            //
            // not within the clip rectangle...move it...
            // determine how many fontHeight's there are between
            // y and clip.y...then add that many fontHeights
            //
 
            y = startingLineNumber * fontHeight - (fontHeight - fm.getAscent());
         }
 
         //
         // options:
         // . write the number rows in the document (current)
         // . write the number of existing lines in the document (to do)
         //   see getLineCount()
         //
         // determine which the "drawing" should end...
         // add fontHeight: make sure...part of the line number is drawn
         //
         // could also do this by determining what the last line
         // number to draw.
         // then the "while" loop whould change accordingly.
         //
         int	yend = y + clip.height + fontHeight;
 
         // base x position of the line number
         int lnxstart = insets.left;
         if (lineNumberJustification == LEFT_JUSTIFY) {
            // actual starting location of the string of a left
            // justified string...it's constant...
            // the right justified string "moves"...
            lnxstart -= lineNumberWidth();
         }
 
         g.setColor(getForeground());
         //
         // loop until out of the "visible" region...
         //
         int length = ("" + Math.max(getRows(), getLineCount() + 1)).length();
         while (y < yend) {
            //
            // options:
            // . left justify the line numbers (current)
            // . right justify the line number (to do)
            //
 
            if (lineNumberJustification == LEFT_JUSTIFY) {
               g.drawString(startingLineNumber + " ", lnxstart, y);
            } else { // right justify
               String label = padLabel(startingLineNumber, length, true);
               g.drawString(label, insets.left - fm.stringWidth(label), y);
            }
 
            y += fontHeight;
            startingLineNumber++;
         }
      } // draw line numbers?
 
      super.paintComponent(g);
   } // paintComponent
 
   /**
    * Create the string for the line number.
    * NOTE: The <tt>length</tt> param does not include the
    * <em>optional</em> space added after the line number.
    *
    * @param lineNumber to stringize
    * @param length     the length desired of the string
    * @param length     the length desired of the string
    *
    * @return the line number for drawing
    */
   private String padLabel(int lineNumber, int length, boolean addSpace) {
      StringBuffer buffer = new StringBuffer();
      buffer.append(lineNumber);
      for (int count = (length - buffer.length()); count > 0; count--) {
         buffer.insert(0, ' ');
      }
      if (addSpace) {
         buffer.append(' ');
      }
      return buffer.toString();
   }
} // LineNumberedPaper

LineNumberedBorder.java:

import java.awt.Component;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
 
import javax.swing.JTextArea;
import javax.swing.border.AbstractBorder;
 
/**
 *  Draws line numbers next to each line, in the same font as the text.
 *  Currently, this can only be used with a <tt>JTextArea</tt> , since it relies
 *  on the <tt>getRows()</tt> and <tt>getLineCount()</tt> methods. A possible
 *  extension, create an interface to return this rows/linecount.
 *
 *@author     Administrator
 *@created    January 29, 2002
 */
public class LineNumberedBorder extends AbstractBorder {
   public static void main(String[] args) {
      javax.swing.JFrame frame = new javax.swing.JFrame("Line Numbers (as Borders)...");
      frame.addWindowListener(
         new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent ev) {
               System.exit(0);
            }
         });
 
      java.awt.Container contentPane = frame.getContentPane();
      contentPane.setLayout(new java.awt.GridLayout(0, 2));
 
      int[] sides = {
            LineNumberedBorder.LEFT_SIDE,
            LineNumberedBorder.LEFT_SIDE,
            LineNumberedBorder.RIGHT_SIDE,
            LineNumberedBorder.RIGHT_SIDE};
 
      int[] justified = {
            LineNumberedBorder.LEFT_JUSTIFY,
            LineNumberedBorder.RIGHT_JUSTIFY,
            LineNumberedBorder.LEFT_JUSTIFY,
            LineNumberedBorder.RIGHT_JUSTIFY};
 
      String[] labels = {
            "Left Side/Left Justified",
            "Left Side/Right Justified",
            "Right Side/Left Justified",
            "Right Side/Right Justified"};
 
      javax.swing.JPanel subpanel;
      JTextArea textArea;
 
      boolean useMultipleBorders = false;
      if (args.length > 0 && "multiple".equals(args[0])) {
         useMultipleBorders = true;
      }
 
      for (int idx = 0; idx < labels.length; idx++) {
         textArea = new JTextArea(10, 10);
         LineNumberedBorder lnb = new LineNumberedBorder(sides[idx], justified[idx]);
         if (useMultipleBorders) {
            textArea.setBorder(
                  javax.swing.BorderFactory.createCompoundBorder(
                  javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5),
                  javax.swing.BorderFactory.createCompoundBorder(
                  javax.swing.BorderFactory.createLineBorder(java.awt.Color.red, 1),
                  javax.swing.BorderFactory.createCompoundBorder(
                  lnb,
                  javax.swing.BorderFactory.createLineBorder(java.awt.Color.blue, 1)
                  )
                  )
                  )
                  );
         } else {
            textArea.setBorder(lnb);
         }
 
         subpanel = new javax.swing.JPanel(new java.awt.BorderLayout());
         subpanel.add(new javax.swing.JLabel(labels[idx]), java.awt.BorderLayout.NORTH);
         subpanel.add(new javax.swing.JScrollPane(textArea), java.awt.BorderLayout.CENTER);
         contentPane.add(subpanel);
      }
 
      frame.setSize(800, 600);
      frame.show();
   }
   // main
 
   /**
    *  The line numbers should be drawn on the left side of the component.
    */
   public static int LEFT_SIDE = -2;
 
   /**
    *  The line numbers should be drawn on the right side of the component.
    */
   public static int RIGHT_SIDE = -1;
 
   /**
    *  The line number should be right justified.
    */
   public static int RIGHT_JUSTIFY = 0;
 
   /**
    *  The line number should be left justified.
    */
   public static int LEFT_JUSTIFY = 1;
 
   /**
    *  Indicates the justification of the text of the line number.
    */
   private int lineNumberJustification = RIGHT_JUSTIFY;
 
   /**
    *  Indicates the location of the line numbers, w.r.t. the component.
    */
   private int location = LEFT_SIDE;
 
   public LineNumberedBorder(int location, int justify) {
      setLocation(location);
      setLineNumberJustification(justify);
   }
 
   public Insets getBorderInsets(Component c) {
      return getBorderInsets(c, new Insets(0, 0, 0, 0));
   }
 
   /**
    *  This modifies the insets, by adding space for the line number on the
    *  left. Should be modified to add space on the right, depending upon
    *  Locale.
    *
    *@param  c       Description of the Parameter
    *@param  insets  Description of the Parameter
    *@return         The borderInsets value
    */
   public Insets getBorderInsets(Component c, Insets insets) {
      // if c is not a JTextArea...nothing is done...
      if (c instanceof JTextArea) {
         int width = lineNumberWidth((JTextArea) c);
         if (location == LEFT_SIDE) {
            insets.left = width;
         } else {
            insets.right = width;
         }
      }
      return insets;
   }
 
   public int getLineNumberJustification() {
      return lineNumberJustification;
   }
 
   public void setLineNumberJustification(int justify) {
      if (justify == RIGHT_JUSTIFY || justify == LEFT_JUSTIFY) {
         lineNumberJustification = justify;
      }
   }
 
   public int getLocation() {
      return location;
   }
 
   public void setLocation(int loc) {
      if (loc == RIGHT_SIDE || loc == LEFT_SIDE) {
         location = loc;
      }
   }
 
   /**
    *  Returns the width, in pixels, of the maximum line number, plus a trailing
    *  space.
    *
    *@param  textArea  Description of the Parameter
    *@return           Description of the Return Value
    */
   private int lineNumberWidth(JTextArea textArea) {
      //
      // note: should this be changed to use all nines for the lineCount?
      // for example, if the number of rows is 111...999 could be wider
      // (in pixels) in a proportionally spaced font...
      //
      int lineCount =
            Math.max(textArea.getRows(), textArea.getLineCount() + 1);
      return textArea.getFontMetrics(
            textArea.getFont()).stringWidth(lineCount + " ");
   }
 
   //
   // NOTE: This method is called every time the cursor blinks...
   //       so...optimize (later and if possible) for speed...
   //
   public void paintBorder(Component c, Graphics g, int x, int y,
         int width, int height) {
 
      java.awt.Rectangle clip = g.getClipBounds();
 
      FontMetrics fm = g.getFontMetrics();
      int fontHeight = fm.getHeight();
 
      // starting location at the "top" of the page...
      // y is the starting baseline for the font...
      // should "font leading" be applied?
      int ybaseline = y + fm.getAscent();
 
      //
      // now determine if it is the "top" of the page...or somewhere else
      //
      int startingLineNumber = (clip.y / fontHeight) + 1;
 
      //
      // use any one of the following if's:
      //
//		if (startingLineNumber != 1)
      if (ybaseline < clip.y) {
         //
         // not within the clip rectangle...move it...
         // determine how many fontHeight's there are between
         // y and clip.y...then add that many fontHeights
         //
         ybaseline = y + startingLineNumber * fontHeight -
               (fontHeight - fm.getAscent());
      }
 
      //
      // options:
      // . write the number rows in the document (current)
      // . write the number of existing lines in the document (to do)
      //   see getLineCount()
      //
 
      // determine which the "drawing" should end...
      // add fontHeight: make sure...part of the line number is drawn
      //
      // could also do this by determining what the last line
      // number to draw.
      // then the "while" loop whould change accordingly.
      //
      //int	yend = y + clip.height + fontHeight;
      //int	yend = ybaseline + height + fontHeight; // original
      int yend = ybaseline + height;
      if (yend > (y + height)) {
         yend = y + height;
      }
 
      JTextArea jta = (JTextArea) c;
      int lineWidth = lineNumberWidth(jta);
 
      // base x position of the line number
      int lnxstart = x;
      if (location == LEFT_SIDE) {
         // x (LEFT) or (x + lineWidth) (RIGHT)
         // (depends upon justification)
         if (lineNumberJustification == LEFT_JUSTIFY) {
            lnxstart = x;
         } else {
            // RIGHT JUSTIFY
            lnxstart = x + lineWidth;
         }
      } else {
         // RIGHT SIDE
         // (y + width) - lineWidth (LEFT) or (y + width) (RIGHT)
         // (depends upon justification)
         if (lineNumberJustification == LEFT_JUSTIFY) {
            lnxstart = (y + width) - lineWidth;
         } else {
            // RIGHT JUSTIFY
            lnxstart = (y + width);
         }
      }
 
      g.setColor(c.getForeground());
      //
      // loop until out of the "visible" region...
      //
      int length = ("" + Math.max(jta.getRows(), jta.getLineCount() + 1)).length();
      while (ybaseline < yend) {
         //
         // options:
         // . left justify the line numbers
         // . right justify the line numbers
         //
 
         if (lineNumberJustification == LEFT_JUSTIFY) {
            g.drawString(startingLineNumber + " ", lnxstart, ybaseline);
         } else {
            // right justify
            String label = padLabel(startingLineNumber, length, true);
            g.drawString(label, lnxstart - fm.stringWidth(label), ybaseline);
         }
 
         ybaseline += fontHeight;
         startingLineNumber++;
      }
   }
   // paintComponent
 
   /**
    *  Create the string for the line number. NOTE: The <tt>length</tt> param
    *  does not include the <em>optional</em> space added after the line number.
    *
    *@param  lineNumber  to stringize
    *@param  length      the length desired of the string
    *@param  addSpace    Description of the Parameter
    *@return             the line number for drawing
    */
   private static String padLabel(int lineNumber, int length, boolean addSpace) {
      StringBuffer buffer = new StringBuffer();
      buffer.append(lineNumber);
      for (int count = (length - buffer.length()); count > 0; count--) {
         buffer.insert(0, ' ');
      }
      if (addSpace) {
         buffer.append(' ');
      }
      return buffer.toString();
   }
}
// LineNumberedBorder

Using skins in a Java GUI

JFrame inherits from Frame, a heavyweight component and associated with its native screen resource (peer). If the underlying operating system does not support non-rectangular shapes, a skin is not possible.
The Robot class, (come with 1.3) allows you to capture screen rectangles (method createScreenCapture). A possibility is to use JWindow and set the background image with the data you get from the Robot class. Then add a MouseMotionListener, intercept the mouseDragged event and update the background of your JWindow.
You may want to look at the following sites:

http://www.enteract.com/~grieves/ which does some fancy things with the JInternalFrame
http://www.L2FProd.com/ and http://www.lookandfeel.com SkinRegion, Java irregular windows

Including binary data in an XML

All data in XML need to be characters. So, if you want to store binary data in an XML, you would have to encode it first. One way to do this is with Base64. So, you could have an XML file like the following:

   <binmessage>
      <body type="Base64">base64encodedbytearray</body>
   </binmessage>

For more information, check out this JavaWorld tip.

Redirect the browser to a URL from within a servlet

Here are two way to do this:

RedirectServlet1.java:

import java.io.*;
 
import javax.servlet.*;
import javax.servlet.http.*;
 
public class RedirectServlet1 extends HttpServlet
{
   public void doGet (HttpServletRequest request,
                      HttpServletResponse response)
      throws ServletException, IOException 
   {
      response.sendRedirect("http://www.esus.com");
   }
}

Another way has been suggested on a Java forum if the above doesn’t work:

   response.sendRedirect(response.encodeRedirectURL("http://www.esus.com"))

Alternatively, you can use the HTTP headers to redirect the client’s browser after executing your sevlet:
RedirectServlet2.java:

import java.io.*;
 
import javax.servlet.*;
import javax.servlet.http.*;
 
public class RedirectServlet2 extends HttpServlet
{ 
    public void doGet (HttpServletRequest request,
                       HttpServletResponse response) 
        throws ServletException, IOException
        {
            response.setHeader("Location", "http://www.esus.com");
            response.setStatus(301);
        }
}

Retrieving binary data from a database table

This example will read images stored in a table.

Main.java:

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.text.*;
import java.sql.*;
import java.io.*;  
 
public class Main extends JFrame {
   public Main() {
      getContentPane().setLayout(new FlowLayout(FlowLayout.LEFT));
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      ArrayList al = getImagesFromDB();
      Iterator iter = al.iterator();
      while (iter.hasNext()) {
         getContentPane().add((JLabel) iter.next());
      }
   }
 
   public ArrayList getImagesFromDB() {
      ArrayList al = new ArrayList();
 
      try {
         Class.forName("org.gjt.mm.mysql.Driver").newInstance();
         Connection conn = DriverManager.getConnection("jdbc:mysql://192.168.0.1/esus", 
                                                       "joris",
                                                       "mypass");
 
         Statement stmt = conn.createStatement();
         ResultSet rs = stmt.executeQuery("SELECT name, length, data FROM images");
      
         while(rs.next()) {
            String name = rs.getString("name");
            int length = rs.getInt("length");
            byte[] buf = rs.getBytes("data");
 
            ImageIcon ii = new ImageIcon(buf);
            JLabel label = new JLabel(name, ii, SwingConstants.CENTER); 
            al.add(label);
         }
      }
      catch(Exception e) {
         e.printStackTrace();
      }
 
      return al;
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(300, 300);
      main.setVisible(true);
   } 
}

Difference between <jsp:forward> and response.sendRedirect()

  • With response.sendRedirect(), the browser is asked to go get another page. All HTTP parameters of the original request are lost. The browser’s location bar changes.
  • <jsp:forward> is more efficient. It forwards the request to the specified JSP page on the server side, without asking the browser to generate a new request. You can only forward to resources served by your application server! It also keeps the state.
    The browser’s location bar doesn’t change.

    To test it out, check out
    response.sendRedirect()
    http://www.javaspace.com/docs/DoRedirect.jsp?orderID=100
    <jsp:forward>
    http://www.javaspace.com/docs/DoForward.jsp?orderID=100

    DoRedirect.jsp:

    <%
       response.sendRedirect("/docs/ResultingPage.jsp");
    %>
    

    DoForward.jsp:

    <jsp:forward page="ResultingPage.jsp"/>
    

    ResultingPage.jsp:

    The is the JSP page <i>ResultingPage.jsp</i> the forwarding or redirection.
    <br>
    <br>
    Did the browser's location bar change?
    <br><br>
    The parameter <i>orderID</i> is set to <%=request.getParameter("orderID")%>.