Drawing a curve with two control points

Use the class CubicCurve.

This example draws a curve on a frame using two end points and two control points. It allows you to grab an end or control point and drag it around. In addition, the curve has been texture-painted.

Main.java:

import java.awt.image.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame {
   private BufferedImage image; 
   Point2D[] curvePoints; 
   Point2D selectedCurvePoint;
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      image = toBufferedImage(new javax.swing.ImageIcon("c:\djkrush.jpg").getImage());
 
      curvePoints = new Point2D[4];
      curvePoints[0] = new Point2D.Double( 50, 150);
      curvePoints[1] = new Point2D.Double(100,  50);
      curvePoints[2] = new Point2D.Double(200, 250);
      curvePoints[3] = new Point2D.Double(250, 150);
 
      addMouseListener(new MouseAdapter() {
         public void mousePressed(MouseEvent me) {
            selectedCurvePoint = null;
            for (int i=0; i<curvePoints.length; i++) {
               Rectangle2D rect = getCurvePoint(curvePoints[i]);
               if (rect.contains(me.getPoint())) {
                  selectedCurvePoint = curvePoints[i];
                  break;
               }
            }
         }
      });
 
      addMouseMotionListener(new MouseMotionAdapter() {
         public void mouseDragged(MouseEvent me) {
            if (selectedCurvePoint != null) {
               selectedCurvePoint.setLocation(me.getPoint());
               repaint();
            }
         }
      });
   }
 
 
   public void paint(Graphics g) {
      super.paint(g); 
 
      Graphics2D g2d = (Graphics2D) g;
 
      Rectangle2D tr = new Rectangle2D.Double(0, 0, image.getWidth(), image.getHeight());
      TexturePaint tp = new TexturePaint(image, tr);
 
      // draw texture filled ellipse, but with antialiasing
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                           RenderingHints.VALUE_ANTIALIAS_ON);
      BasicStroke bs = new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,
                           10, null, 0);
      g2d.setStroke(bs);
      g2d.setPaint(tp);
 
      CubicCurve2D cc = new CubicCurve2D.Float();
      cc.setCurve(curvePoints, 0);
      g2d.draw(cc);
      g2d.setColor(Color.black);
      for (int i=0; i<4; i++) {
         g2d.draw(getCurvePoint(curvePoints[i]));
      } 
   }
 
   public Rectangle2D.Float getCurvePoint(Point2D p2d) {
      return new Rectangle2D.Float((int) p2d.getX()-2, (int) p2d.getY()-2, 4, 4);
   }
 
   public BufferedImage toBufferedImage(Image image) {
      BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), 
                                           BufferedImage.TYPE_INT_RGB); 
 
      // copy the original image
      Graphics g = bi.createGraphics();
    
      g.drawImage(image, 0, 0, null);
      g.dispose();
 
      return bi;
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(300, 300);
      main.setVisible(true);
   }
}

Image used:

Manipulate the elements of a GlyphVector in Swing

Main.java:

import java.awt.event.*;
import java.awt.geom.*;
import java.awt.font.*;
import javax.swing.*;
import java.util.*;
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);
 
      String text = "90% of all statistics are made up!";
      Font font = new Font("Serif", Font.PLAIN, 24);
      FontRenderContext frc = g2d.getFontRenderContext();
      g2d.translate(40, 100);
 
      GlyphVector gv = font.createGlyphVector(frc, text);
      int numGlyps = gv.getNumGlyphs();
      Random r = new Random();
      for (int i=0; i<numGlyps; i++) {
         Point2D p = gv.getGlyphPosition(i);
         AffineTransform at = AffineTransform.getTranslateInstance(p.getX(), p.getY());
 
         at.scale(1, 0.2+r.nextFloat()*2);
 
         Shape glyph = gv.getGlyphOutline(i);
         Shape newGlyph = at.createTransformedShape(glyph);
         g2d.fill(newGlyph);
      }
   }
   
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(400, 150);
      main.setVisible(true);
   }
}

Creating image thumbnails

Use the class AffineTransform.

Main.java:

import javax.swing.event.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.*;
import java.io.*;
 
public class Main extends JFrame {
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      getContentPane().setLayout(new FlowLayout(FlowLayout.LEFT, 10, 10));
   }
 
   public void createThumbs() {
      setTitle("JPG thumbnail images of " + System.getProperty("user.dir"));
 
      File f[] = new File(".").listFiles();
      for (int i=0; i<f.length; i++) {
         if (f[i].getName().endsWith(".jpg")) {
            ImageIcon imageIcon = new ImageIcon(f[i].getName()); 
            ImageIcon image = getThumb(imageIcon, 50);
            JLabel label = new JLabel(image);
            label.setToolTipText(f[i].getName());
            getContentPane().add(label);
            validate();
         }
      }
   } 
  
   public ImageIcon getThumb(ImageIcon imageIcon, int wh) {
      Image source = imageIcon.getImage();
 
      double scalex = (double) wh / source.getWidth(null);
      double scaley = (double) wh / source.getHeight(null);
 
      BufferedImage dest = new BufferedImage(wh, wh, 
                                    BufferedImage.TYPE_INT_RGB);
 
      AffineTransform ta = new AffineTransform();
      ta.scale(scalex, scaley);
          
      Graphics2D g2d = dest.createGraphics();
      g2d.drawImage(source, ta, null);
      g2d.dispose();
 
      return new ImageIcon(dest); 
    }

   public static void main(String[] args) {
      Main main = new Main();
      main.setSize(500, 150);
      main.setVisible(true);
 
      main.createThumbs();
   } 
}

Morphing one image into another in Swing

Morphing is short for metamorphosing, it refers to an animation technique in which one image is gradually turned into another.

This example morphs one image into another (with same width and height). It first precalculates R G and B array that contains for each pixel the change that should be applied to a (x, y) pixel in image 1 to get to the (x, y) pixel in image 2 after iterating for nFrames steps.
Then it loops through the pixelvalues of the source image and adds the RGB change to it. After nFrames steps, the resulting image is image 2.

import java.awt.event.*;
import java.awt.image.*;
import java.awt.color.*;
import javax.swing.*;
import java.awt.*;
                           
public class Main extends JFrame
{
   int width, height; 
 
   int source[];
   int dest[];
 
   double dalpha[], dred[], dgreen[], dblue[];
 
   int nFrames;
 
   JLabel jlabel;
 
   public Main(String image1, String image2, int nFrames) throws Exception {
      BufferedImage bi1 = createBufferedImage(image1);
      BufferedImage bi2 = createBufferedImage(image2);
 
      width = bi1.getWidth();
      height = bi1.getHeight();
 
      source = new int[width*height];
      dest = new int[width*height];
 
      dalpha = new double[width*height];
      dred = new double[width*height];
      dgreen = new double[width*height];
      dblue = new double[width*height];
 
      this.nFrames = nFrames;
 
      PixelGrabber grabber1 = new PixelGrabber(bi1,0,0,width,height,source,0,width);
      grabber1.grabPixels();
 
      PixelGrabber grabber2 = new PixelGrabber(bi2,0,0,width,height,dest,0,width);
      grabber2.grabPixels();
 
      calcIntervals();
 
      // add the image inside a JLabel component to the window
      jlabel = new JLabel(new ImageIcon(bi1));
      getContentPane().add(jlabel);
      pack();
                          
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent e) {
            System.exit(0);
         }
      });
   }
 
   public void calcIntervals() {
      for (int i=0; i<source.length; i++) {
         int sourcePixel = source[i];
         int sourceAlpha = (sourcePixel >> 24) & 0xff;
         int sourceRed   = (sourcePixel >> 16) & 0xff;
         int sourceGreen = (sourcePixel >>  8) & 0xff;
         int sourceBlue  = (sourcePixel      ) & 0xff;
          
         int destPixel = dest[i];
         int destAlpha = (destPixel >> 24) & 0xff;
         int destRed   = (destPixel >> 16) & 0xff;
         int destGreen = (destPixel >>  8) & 0xff;
         int destBlue  = (destPixel      ) & 0xff;
 
         dalpha[i] = (double) (destAlpha - sourceAlpha) / nFrames;
         dred[i] = (double) (destRed - sourceRed) / nFrames;
         dgreen[i] = (double) (destGreen - sourceGreen) / nFrames;
         dblue[i] = (double) (destBlue - sourceBlue) / nFrames;
      }
   }
 
   public int[] calcFrame(int frame) {
      int result[] = new int1;
      for (int i=0; i<source.length; i++) {
         int sourcePixel = source[i];
         int sourceAlpha = (int) (((sourcePixel >> 24) & 0xff) + (dalpha[i] * frame));
         int sourceRed   = (int) (((sourcePixel >> 16) & 0xff) + (dred[i] * frame));
         int sourceGreen = (int) (((sourcePixel >>  8) & 0xff) + (dgreen[i] * frame));
         int sourceBlue  = (int) (((sourcePixel      ) & 0xff) + (dblue[i] * frame));
          
         result[i] = argb2p(sourceAlpha, sourceRed, sourceGreen, sourceBlue);
      }
 
      return result;
   }
 
   public int argb2p(int alpha, int red, int green, int blue) {
      int t = 0;
 
      t |= (alpha << 24);
      t |= (red << 16);
      t |= (green << 8);
      t |= blue;
 
      return t;
   }         
 
   public void startMorphing(int delay) {
      for (int i=0; i<nFrames+1; i++) {
         int result[] = calcFrame(i);
         Image img = createImage(new MemoryImageSource(width, height, result, 0, width));
         jlabel.setIcon(new ImageIcon(img));
 
         try {
            Thread.sleep(delay);
         }
         catch(InterruptedException e) { }
      }
   }
 
   public BufferedImage createBufferedImage(String filename) {
      Image img = Toolkit.getDefaultToolkit().getImage(filename);
      try {
         MediaTracker tracker = new MediaTracker(this);
         tracker.addImage(img, 0);
         tracker.waitForID(0);
      }
      catch ( Exception e ) {} 
  
      BufferedImage bi = 
         new BufferedImage(img.getWidth(this), img.getHeight(this),
                        BufferedImage.TYPE_INT_RGB);
      Graphics2D g2d = bi.createGraphics();
      g2d.drawImage(img, 0, 0, this);
  
      return bi;
   }
  
   public static void main(String args[]) throws Exception {
      if (args.length != 4) {
         System.out.println("usage: Java Main image1 image2 framecount delay");
         System.exit(1);
      }
 
      Main main = new Main(args[0], args[1], Integer.parseInt(args[2]));
      main.show();
      main.startMorphing(Integer.parseInt(args[3]));
   }
}

Test it out with:

java Main ally.jpg lion.jpg 200 10

Where
ally.jpg is the source image
lion.jpg is the destination image
200 is the number of frames in between
10 the delay in milliseconds between showing each frame

ally.jpg:

lion.jpg:

Catching events while an image is being read using ImageIO

Add an IIOReadProgressListener to your reader.

   IIOReadProgressListener listener = new MyReadProgressListener();
   reader.addIIOReadProgressListener(listener);

It’ll throw events while the reading process is going on. The following example shows a JProgressBar while reading the image fruit.png, to be used as background.

Main.java:

import javax.imageio.metadata.*; 
import javax.imageio.stream.*;
import javax.imageio.event.*;
import javax.imageio.*;
 
import javax.swing.event.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
import java.awt.*; 
import java.io.*;
  
public class Main extends JFrame
{
   JProgressBar progressBar;
   BufferedImage background = null;
  
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      progressBar = new JProgressBar(0, 100);
 
      getContentPane().setLayout(new BorderLayout());
      getContentPane().add(BorderLayout.NORTH, progressBar);
    }
 
   public void loadBackgroundImage(String filename) throws Exception {
      Iterator readers = ImageIO.getImageReadersByFormatName("png");
      ImageReader reader = (ImageReader) readers.next();
 
      IIOReadProgressListener listener = new MyReadProgressListener();
      reader.addIIOReadProgressListener(listener);
 
      ImageInputStream iis = ImageIO.createImageInputStream(new File(filename));
      reader.setInput(iis, true);
      background = reader.read(0);
   }
 
   public static void main(String []args) throws Exception {
      Main main = new Main();
      main.setSize(400, 150);
      main.setVisible(true);
  
      main.loadBackgroundImage("fruit.png");
   }
 
   public void paint(Graphics g) {
      System.out.println(background);
      if (background != null) {
         g.drawImage(background, 0, 0, getWidth(), getHeight(), this);
      }
   }
 
   class MyReadProgressListener implements IIOReadProgressListener {
 
	public MyReadProgressListener() {}
 
        public void imageProgress(ImageReader source, final float percentageDone) {
           System.out.println("imageProgress: " + percentageDone);
 
           SwingUtilities.invokeLater(new Runnable() {
              public void run() {
                 progressBar.setValue((int) percentageDone);
              }
           });   
        }
 
        public void imageComplete(ImageReader source) {
           SwingUtilities.invokeLater(new Runnable() {
              public void run() {
                 try {
                    // wait for a bit until bufferedimage is assigned by reader
                    Thread.sleep(50);
                 }
                 catch(InterruptedException e) { }
                 repaint();
              }
           });              
        }
 
        public void imageStarted(ImageReader source, int imageIndex)  { }
        public void readAborted(ImageReader source)                   { }
        public void sequenceComplete(ImageReader source)              { }
        public void sequenceStarted(ImageReader source, int minIndex) { }
        public void thumbnailComplete(ImageReader source)             { }
        public void thumbnailProgress(ImageReader source, float percentageDone) { }
        public void thumbnailStarted(ImageReader source, int imageIndex, int thumbnailIndex) { }
   }
}

Setting the decoration style of a JFrame

(JDK1.4+!)

Main.java:

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
class Main extends JFrame {
    public Main() {
        setUndecorated(true);
        getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle("Decoration example");
        setSize(400, 400);
        Object[] options = { "COLOR_CHOOSER_DIALOG",
                             "ERROR_DIALOG",
                             "FILE_CHOOSER_DIALOG", 
                             "FRAME",
                             "INFORMATION_DIALOG",
                             "NONE",
                             "PLAIN_DIALOG", 
                             "QUESTION_DIALOG",
                             "WARNING_DIALOG" };
        final JComboBox combobox = new JComboBox(options);
        combobox.setSelectedItem("FRAME");
        getContentPane().setLayout(new FlowLayout());
        getContentPane().add(combobox);
 
        combobox.addActionListener(new ActionListener() {
           public void actionPerformed(ActionEvent ae) {
              String selected = (String) combobox.getSelectedItem();
              if (selected.equals("COLOR_CHOOSER_DIALOG"))
                 setDecorationStyle(JRootPane.COLOR_CHOOSER_DIALOG);
              else if (selected.equals("ERROR_DIALOG"))
                 setDecorationStyle(JRootPane.ERROR_DIALOG);
              else if (selected.equals("FILE_CHOOSER_DIALOG"))
                 setDecorationStyle(JRootPane.FILE_CHOOSER_DIALOG);
              else if (selected.equals("FRAME"))
                 setDecorationStyle(JRootPane.FRAME);
              else if (selected.equals("INFORMATION_DIALOG"))
                 setDecorationStyle(JRootPane.INFORMATION_DIALOG);
              else if (selected.equals("NONE"))
                 setDecorationStyle(JRootPane.NONE);
              else if (selected.equals("PLAIN_DIALOG"))
                 setDecorationStyle(JRootPane.PLAIN_DIALOG);
              else if (selected.equals("QUESTION_DIALOG"))
                 setDecorationStyle(JRootPane.QUESTION_DIALOG);
              else if (selected.equals("WARNING_DIALOG"))
                 setDecorationStyle(JRootPane.WARNING_DIALOG);
           }
        });
    }
 
    public void setDecorationStyle(int decorationStyle) {
       setVisible(false);
       getRootPane().setWindowDecorationStyle(decorationStyle);
       setVisible(true);
    }
 
    public static void main(String[] args) {
        new Main().setVisible(true);
    }
}

Catching an event when a JTabbedPane tab is selected

You can add a ChangeListener to your JTabbedPane component to catch the events. The first example shows you how. The event will be raised after the change has already occurred. If you want to catch the event before the change occurs, ie. to disallow a user from selecting a tab, you have to override the setSelectedIndex method. The second example shows how to prevent users from selecting tabs with odd index numbers.
First example:

import javax.swing.event.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame implements ActionListener {
   JTabbedPane tabbedPane;
   int ntabs = 0;
 
   public Main() {
      getContentPane().setLayout(new BorderLayout());
      tabbedPane = new JTabbedPane();
      createTab();
 
      getContentPane().add(BorderLayout.CENTER, tabbedPane);
      setJMenuBar(createMenuBar());
  
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
 
      tabbedPane.addChangeListener(new ChangeListener() {
         public void stateChanged(ChangeEvent ce) {
            System.out.println("Tab " + (tabbedPane.getSelectedIndex() + 1) + " is selected");
         }
      });
  
      setTitle("JTabbedPane Orientation Demonstration");
      setSize(new Dimension(400, 400));
   }
 
   protected JMenuBar createMenuBar() {
      JMenuBar menuBar = new JMenuBar();
 
      JMenu menu = new JMenu("JTabbedPane");
      JMenuItem menuItem1 = new JMenuItem("Create new tab");
      menuItem1.addActionListener(this);
      menu.add(menuItem1);
      menuBar.add(menu);
 
      return menuBar;
   }
  
   public void actionPerformed(ActionEvent e) {
      if (e.getActionCommand().equals("Create new tab")) {
         createTab();
      }
   }
 
   protected void createTab() {
      ntabs++;
      tabbedPane.addTab("Tab #" + ntabs, new JLabel("Tab #" + ntabs));
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.show();
   }
}

Second example:

import javax.swing.event.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame implements ActionListener {
   JTabbedPane tabbedPane;
   int ntabs = 0;
 
   public Main() {
      getContentPane().setLayout(new BorderLayout());
      tabbedPane = new JTabbedPane() {
         public void setSelectedIndex(int index) {
            System.out.println("index selected: " + index);
            if (index % 2 == 0) {
               System.out.println("allowed");
               super.setSelectedIndex(index);
            }
            else {
               System.out.println("not allowed");
            }
         }
      };
      createTab();
 
      getContentPane().add(BorderLayout.CENTER, tabbedPane);
      setJMenuBar(createMenuBar());
  
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
 
      setTitle("JTabbedPane Selection Demonstration");
      setSize(new Dimension(400, 400));
   }
 
   protected JMenuBar createMenuBar() {
      JMenuBar menuBar = new JMenuBar();
 
      JMenu menu = new JMenu("JTabbedPane");
      JMenuItem menuItem1 = new JMenuItem("Create new tab");
      menuItem1.addActionListener(this);
      menu.add(menuItem1);
      menuBar.add(menu);
 
      return menuBar;
   }
  
   public void actionPerformed(ActionEvent e) {
      if (e.getActionCommand().equals("Create new tab")) {
         createTab();
      }
   }
 
   protected void createTab() {
      tabbedPane.addTab("Tab #" + ntabs, new JLabel("Tab #" + ntabs));
      ntabs++;
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.show();
   }
}

Changing the margins of a JToolBar

Set an empty border on your JToolBar object.

Main.java:

import javax.swing.border.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
  
public class Main extends JFrame {
   public Main() {
      super("JToolBar example");
 
      final JTextArea textArea = new JTextArea(5, 30);
      JToolBar toolBar = new JToolBar();
 
      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(jpgButton);
      toolBar.add(tiffButton);
 
      toolBar.setBorder(new EmptyBorder(new Insets(10,10,10,10)));
 
      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);
   }
}

images used:


Setting the top-left icon of a JInternalFrame

Use setFrameIcon():

JInternalFrame frame = new JInternalFrame("Test",false,false,false,false);

try {
  URL url = new URL("http://localhost/images/icon.gif");
  ImageIcon icon = new ImageIcon(url);
  frame.setFrameIcon(icon);
} catch (MalformedURLException me) {}

...