Creating a full screen AWT Frame

From 1.4 onwards, call the method setFullScreenMode on the default screen device.

Main.java:

import java.awt.event.*;
import java.awt.*;
 
public class Main extends Frame implements ActionListener
{
   public Main()
   {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      Button maxButton = new Button("Make this Frame full-screen");
      setLayout(new FlowLayout(FlowLayout.LEFT));
      add(maxButton);
      maxButton.addActionListener(this);
   }
 
   public void actionPerformed(ActionEvent ae) {     
      GraphicsDevice device = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
      device.setFullScreenWindow(this);
   }
 
   public static void main(String args[])
   {
      Main main = new Main();
      main.setSize(300, 150);
      main.setVisible(true);
   }
}

Drawing an arbitrary shape in Swing

This example uses the class GeneralPath with the methods LineTo, MoveTo and QuadTo.

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 {
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
   }
 
   public void paint(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
 
      GeneralPath gp = new GeneralPath();
      gp.moveTo(   0,  100);
      gp.quadTo( -75,   25,    0, -100);
      gp.quadTo(  75,   25,    0,  100);
      gp.lineTo( -50,  -50);
      gp.lineTo(  50,  -50);
      gp.closePath();
 
      // set origin to middle of window
      g2d.translate(150f, 150f);
 
      g2d.draw(gp);
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(300, 300);
      main.setVisible(true);
   }
}

Drawing an attributed string in Swing

Main.java:

import java.awt.event.*;
import java.awt.geom.*;
import java.awt.font.*;
import javax.swing.*;
import java.text.*;
import java.awt.*;
 
public class Main extends JFrame {
   private Image img;
  
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      }); 
 
      img = new javax.swing.ImageIcon("per.gif").getImage(); 
   }
 
   public void paint(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
  
      String text = "90% of all statistics are made up!";
 
      Font font = new Font("Serif", Font.PLAIN, 24);
      AttributedString as = new AttributedString(text);
      as.addAttribute(TextAttribute.FONT, font, 0, 11);
 
      // image in between the text
      ImageGraphicAttribute iga = new ImageGraphicAttribute(img, (int) 
                                               GraphicAttribute.TOP_ALIGNMENT);
      as.addAttribute(TextAttribute.CHAR_REPLACEMENT, iga, 2, 3);
 
      // shape in between the text
      Shape s1 = new Rectangle2D.Double(10, 0, 5, 15);
      Shape s2 = new Rectangle2D.Double(10, 18, 5, 5);
      Area a1 = new Area(s1);
      Area a2 = new Area(s2);
      a1.add(a2);
      ShapeGraphicAttribute sga = new ShapeGraphicAttribute(a1,
                                               GraphicAttribute.TOP_ALIGNMENT, false);
      as.addAttribute(TextAttribute.CHAR_REPLACEMENT, sga, 33, 34);
 
      // set the background of the first 3 characters to red
      as.addAttribute(TextAttribute.BACKGROUND, Color.red, 0, 3);
 
      // set the foreground of the word "are" to blue
      as.addAttribute(TextAttribute.FOREGROUND, Color.blue, 22, 25);
 
      // underline the word "all"
      as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON, 7, 10);
 
      // change fontsize and weight for word "statistics"
      as.addAttribute(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD, 11, 21);
      as.addAttribute(TextAttribute.SIZE, new Float(14f), 11, 21);
 
      // make the words "made up" italic
      as.addAttribute(TextAttribute.POSTURE,TextAttribute.POSTURE_OBLIQUE,25,text.length());
 
      g2d.drawString(as.getIterator(), 20, 100);
   }
   
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(420, 200);
      main.setVisible(true);
   }
}

Image used:

Clipping an image to be rendered with a shape in Swing



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; 
   private boolean clip = false;
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      image = toBufferedImage(new javax.swing.ImageIcon("djkrush.jpg").getImage());
      JButton button = new JButton("Clip to QuadCurve");
      button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            clip = true;
            repaint();
         }
      });
 
      getContentPane().setLayout(new BorderLayout());
      getContentPane().add(BorderLayout.SOUTH, button);
   }
 
   public void paint(Graphics g) {
      super.paint(g);
 
      Graphics2D g2d = (Graphics2D) g;
 
      if (clip) {
         BasicStroke bs = new BasicStroke(50, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,
                                          10, null, 0);
         g2d.setStroke(bs);
         QuadCurve2D.Float qc = new QuadCurve2D.Float(20, 50, 100, 140, 460, 170);
         g2d.setClip(qc);
      }
 
      // draw texture filled ellipse
      g2d.drawRect(20, 50, 80, 120);
      g2d.drawOval(140, 50, 80, 120);
      
      BasicStroke bs = new BasicStroke(5, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER,
                           10, new float[] {10}, 0);
      g2d.setStroke(bs);
      g2d.drawRect(260, 50, 80, 120);
 
      Rectangle2D tr = new Rectangle2D.Double(0, 0, image.getWidth(), image.getHeight());
      TexturePaint tp = new TexturePaint(image, tr);
      g2d.setPaint(tp);
      g2d.fillRect(380, 50, 80, 120);
   }
 
   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(480, 240);
      main.setVisible(true);
   }
}

Image used:

Darkening an image in Swing

To darken an image, you can use the class LookupOp. This class works with one or more tables that will be applied to the color values of the pixels. To darken n RGB image, the RGB values have to be decreased (lower values means darker). The lookup table reflects these changes.

The following example shows the original image and an image that has been darkened by dividing the intensities by 2.

Main.java:

import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JFrame {
   private boolean firstTime = true;
   private BufferedImage sourceBi;
   private BufferedImage destBi;
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      }); 
   } 
 
   public void paint(Graphics graphics) {
      Graphics2D g2d = (Graphics2D) graphics;
  
      if (firstTime) {
         Image img = new javax.swing.ImageIcon("djkrush.jpg").getImage(); 
         sourceBi = toBufferedImage(img);
         destBi = new BufferedImage(sourceBi.getWidth(), sourceBi.getHeight(), 
                                    BufferedImage.TYPE_INT_RGB);
         setSize(sourceBi.getWidth(), sourceBi.getHeight()*2);
 
         short[] intensity = new short[256];
         for(int i=0; i<256; i++) {
            intensity[i] = (short) (i / 2);
         }
  
         ShortLookupTable slt = new ShortLookupTable(0, intensity);
         LookupOp op = new LookupOp(slt, null);
         destBi = op.filter(sourceBi, null);
 
         firstTime = false;
      }
 
      g2d.drawImage(sourceBi, 0, 0, this);
      g2d.drawImage(destBi, 0, sourceBi.getHeight(), this);
   }
 
   public static 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.setVisible(true);
      main.setSize(300, 150);
   }
}

Image used:

To learn more about image processing,
check out this expensive but excellent book:

Reading a BufferedImage using the ImageIO API

The new ImageIO API allows you to read and write any type of image files as long
as there is a plug-in written for it. Those plug-ins can be provided by third parties.
The appropriate plug-in is choosen depending on the file suffix, mime type, contents or format name.

The following example uses the built-in JPG plug-in.

Main.java:

import javax.swing.event.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.imageio.*;
import javax.swing.*;
import java.net.*;
import java.awt.*;
import java.io.*;
 
public class Main extends JFrame
{
   BufferedImage background;
 
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(1);
         }
      });
 
      try {
         background = ImageIO.read(new URL(&quot;http://www.esus.com/images/mong.jpg&quot;));
      }
      catch(Exception e) {
         e.printStackTrace();
      }
   }
 
   public void paint(Graphics g) {
      g.drawImage(background, 0, 0, getWidth(), getHeight(), this);
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(400, 400);
      main.setVisible(true);
   }
}

Controlling permissions with a JApplet

It is important that you have installed the JRE1.3 on your machine, that includes the Java 1.3 plug-in.

An JApplet runs by default in a security sandbox, an environment where it has no permission to do anything that might harm the client’s machine.

Consider the following applet.

WriteFile.java:

import javax.swing.*;
import java.awt.*;
import java.io.*;
 
public class WriteFile extends JApplet {
   public void paint(Graphics g) {
      String filename = "/tmp/esusfoo";
      if (System.getProperty("os.name").indexOf("Windows") != -1) {
         filename = "C:\esusfoo";
      }
 
      try {
         BufferedWriter bw = new BufferedWriter(new FileWriter(filename));
         bw.write("The sun is green and the grass shines.n");
         bw.flush();
         bw.close();
 
         g.drawString("File " + filename + " created!", 10, 10);
      }
      catch (Exception e) {
         g.drawString(""+e, 10, 10);
      }
   }
}

WriteFile.html (generated with Sun’s HTMLConverter tool):

<html>
<body>
 
<!--"CONVERTED_APPLET"-->
<!-- CONVERTER VERSION 1.0 -->
<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
WIDTH = 700 HEIGHT = 100  
codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0">

<PARAM NAME = CODE VALUE = WriteFile >
 
<PARAM NAME="type" VALUE="application/x-java-applet;version=1.3">
<COMMENT>
<EMBED type="application/x-java-applet;version=1.3" java_CODE = WriteFile 
WIDTH = 700 HEIGHT = 100   
pluginspage="http://java.sun.com/products/plugin/1.3/plugin-install.html">
<NOEMBED></COMMENT>
 
</NOEMBED></EMBED>
</OBJECT>
 
<!--
<APPLET  CODE = WriteFile WIDTH = 700 HEIGHT = 100 >
 
 
</APPLET>
-->
<!--"END_CONVERTED_APPLET"-->
 
 
</body>
</html>

When you run this JApplet, you’ll get a security exception.
Check it out for yourself at http://www.esus.com/applets/WriteFile.html.

So what do we need to do to make this work?

You will have to explicitely give access to that applet to use resources it is normally not permitted to. To do so, one requirement is to sign our applet. The following procedure shows you how to sign an applet. You will need to have a certificate, either one you create yourself (a self-signed applet) or one that you have bought from a certificate authority like VeriSign or Thawte. For now, I’ll create one myself.

Create a certificate with keytool (JDK tool introduced in JDK1.2.2):

C:certificateapplet> keytool -genkey -alias esustest -keyalg rsa
Enter keystore password:  esuspass
What is your first and last name?
  [Unknown]:  Joris Van den Bogaert
What is the name of your organizational unit?
  [Unknown]:  ESUS Team
What is the name of your organization?
  [Unknown]:  ESUS, Inc.
What is the name of your City or Locality?
  [Unknown]:  Meerbeek
What is the name of your State or Province?
  [Unknown]:
What is the two-letter country code for this unit?
  [Unknown]:  BE
Is <CN=Joris Van den Bogaert, OU=ESUS Team, O="ESUS, Inc.", L=Meerbeek, ST=Unkno
wn, C=BE> correct?
  [no]:  yes

Enter key password for <esustest>
        (RETURN if same as keystore password):

C:certificateapplet>

(Note: if you haven’t used keytool before, just make up a password) Here we have created a RSA key with the name esustest. Now look in your home directory, a file should have been created called .keystore:

C:certificateapplet> dir c:windows.key*

 Volume in drive C has no label
 Volume Serial Number is 1380-0FE3
 Directory of C:WINDOWS

KEYSTO~1             1,382  07-21-01  1:28a .keystore
         1 file(s)          1,382 bytes
         0 dir(s)     164,356,096 bytes free

To see that the key has been added to the store:

C:certificateapplet> keytool -list
Enter keystore password:  esuspass

Keystore type: jks
Keystore provider: SUN

Your keystore contains 1 entry:

esustest, Sat Jul 21 01:28:48 CEST 2001, keyEntry,
Certificate fingerprint (MD5): 88:09:3D:97:3A:7B:91:AD:4B:01:B8:3E:40:B8:C6:2A

Now let’s create a JAR file from our applet:

C:certificateapplet>jar cvf WriteFile.jar WriteFile.class
added manifest
adding: WriteFile.class(in = 1250) (out= 732)(deflated 41%)

The jar has been created:

C:certificateapplet> dir *.jar

 Volume in drive C has no label
 Volume Serial Number is 1380-0FE3
 Directory of C:certificateapplet

WRITEF~1 JAR         1,196  07-21-01  1:38a WriteFile.jar
         1 file(s)          1,196 bytes
         0 dir(s)     164,347,904 bytes free

Now we can sign that JAR file with our generated keypair as follows:

C:certificateapplet> jarsigner WriteFile.jar esustest
Enter Passphrase for keystore: esuspass

C:certificateapplet> dir *.jar

 Volume in drive C has no label
 Volume Serial Number is 1380-0FE3
 Directory of C:certificateapplet

WRITEF~1 JAR         2,348  07-21-01  1:38a WriteFile.jar
         1 file(s)          2,332 bytes
         0 dir(s)     164,347,904 bytes free

Notice the size of our original JAR and the new digitally signed JAR! We can verify the JAR as follows:


C:certificateapplet>jarsigner -verify -certs -verbose WriteFile.jar

         136 Sat Jul 21 05:22:54 CEST 2001 META-INF/MANIFEST.MF
         189 Sat Jul 21 05:22:56 CEST 2001 META-INF/ESUSTEST.SF
         980 Sat Jul 21 05:22:56 CEST 2001 META-INF/ESUSTEST.RSA
           0 Sat Jul 21 05:22:16 CEST 2001 META-INF/
smk     1213 Sat Jul 21 05:21:10 CEST 2001 WriteFile.class

      X.509, CN=Joris Van den Bogaert, OU=ESUS Team, O="ESUS, Inc.", L=Meerbeek,
 ST=Unknown, C=BE (esustest)


  s = signature was verified
  m = entry is listed in manifest
  k = at least one certificate was found in keystore
  i = at least one certificate was found in identity scope

jar verified.

Notice the files that have been added to the JAR file:ESUSTEST.SF and ESUSTEST.RSA. SF stands for Signature File and it includes the filename (WriteFile.class), the name of the algorithm used (RSA) and the digest value. Test it out for yourself:

C:certificateapplet>jar -xf WriteFile.jar META-INF/ESUSTEST.SF

C:certificateapplet>dir

 Volume in drive C has no label
 Volume Serial Number is 1380-0FE3
 Directory of C:certificateapplet

.              <DIR>        07-21-01 12:32a .
..             <DIR>        07-21-01 12:32a ..
WRITEF~1 JAV           728  07-21-01  1:14a WriteFile.java
WRITEF~1 CLA         1,250  07-21-01  1:14a WriteFile.class
WRITEF~1 HTM            95  07-21-01 12:47a WriteFile.html
WRITEF~1 JAR         2,348  07-21-01  1:38a WriteFile.jar
META-INF       <DIR>        07-21-01  1:45a META-INF
         4 file(s)          4,405 bytes
         3 dir(s)     164,265,984 bytes free

C:certificateapplet>cd meta-inf

C:certificateappletMETA-INF>dir

 Volume in drive C has no label
 Volume Serial Number is 1380-0FE3
 Directory of C:certificateappletMETA-INF

.              <DIR>        07-21-01  1:45a .
..             <DIR>        07-21-01  1:45a ..
ESUSTEST SF            189  07-21-01  1:45a ESUSTEST.SF
         1 file(s)            189 bytes
         2 dir(s)     164,265,984 bytes free

C:certificateappletMETA-INF> type esustest.sf
Signature-Version: 1.0
SHA1-Digest-Manifest: Zy9znt1bwLpXeGV+pr+rkaHU4Rw=
Created-By: 1.2.2 (Sun Microsystems Inc.)

Name: WriteFile.class
SHA1-Digest: JFrqA7g/ZadrRHkJmXgsCTwZRSo=

The other file that has been added to the JAR is ESUSTEST.RSA. This is the Signature Block File It contains the certificate or certificate chain.

Now we’re ready to deploy our signed applet and see if that changed the situation. Let’s first modify our HTML file so that it uses the JAR file instead of the class file.

WriteFile2.html:

<html>
<body>
This file will create a file on your drive called esusfoo.  
Under Windows it will be located in C:, under unix it will be located in /tmp.  
If you do not want this to happen, click DENY when your browser asks you 
for additional permissions.
<br><br><br><br>
<!--"CONVERTED_APPLET"-->
<!-- CONVERTER VERSION 1.3 -->
<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
WIDTH = 700 HEIGHT = 100  
codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0">
<PARAM NAME = CODE VALUE = "WriteFile.class" >
<PARAM NAME = ARCHIVE VALUE = "WriteFile.jar" >

<PARAM NAME="type" VALUE="application/x-java-applet;version=1.3">
<PARAM NAME="scriptable" VALUE="false">
<COMMENT>
<EMBED type="application/x-java-applet;version=1.3"  CODE = "WriteFile.class" 
ARCHIVE = "WriteFile.jar" WIDTH = 700 HEIGHT = 100  scriptable=false 
pluginspage="http://java.sun.com/products/plugin/1.3/plugin-install.html">
<NOEMBED></COMMENT>

</NOEMBED></EMBED>
</OBJECT>

<!--
<APPLET CODE = "WriteFile.class" ARCHIVE = "WriteFile.jar" WIDTH = 700 HEIGHT = 100>


</APPLET>
-->
<!--"END_CONVERTED_APPLET"-->


</body>
</html>

Upload the files to your webserver and try it out! You can also try it out here:
http://www.esus.com/applets/WriteFile2.html.

With both Netscape and IE, you’ll get the following window:




Hmm, it doesn’t really create a file, does it? Well, earlier version of the plug-in (JDK1.2.2) would actually ask you if you want to grant extra permissions. But from the 1.3 plugin onwards, self-signed applets (like our WriteFile.jar) will need extra work! If you would have signed your applet with a certificate you bought from a recognized standard root CA, like VeriSign or Thawte, the browser would ask you if you want to grant additional permissions. Check out http://java.sun.com/products/plugin/1.3/docs/nsobjsigning.html!

Just like anyone else, I don’t have no money :) So for the time being, I won’t buy such a certificated from a trusted CA. But I’ll show you a way to have your applet run anyway (useful for testing purposes). It is important to realize that in order to do so, you must have access to the client’s machine(s) onto which you want to deploy your applet.

What happens when you download a signed applet is this: the browser downloads the JAR file and checks whether it is signed. If it is, it will check the security policy configuration file whether the “usePolicy” RuntimePermission is set. There are two policy files, a system-wide one, (JRE_HOME/lib/security/java.policy) and a user specific one (USER_HOME/.java.policy). In my case, my system-wide one is at C:Program FilesJavaSoftJRE1.3.1libsecurity and my user one is at C:Windows.java.policy. When the plug-in starts, it will concatenate both of them together and use them as a security policy for the rest of the session. If the usePolicy permission is set, security is controlled based on the permissions that are set in the policy files, even if you have an RSA signed applet signed by a trusted authority that wants full control over your client’s machine. This allows you to have finer-grained security control over what your signed applets are able to do.

Let’s change our policy file to grant the permission to write to the local file c:esusfoo. Add the following lines of code to your .java.policy file:

grant {
   permission java.io.FilePermission "C:${/}esusfoo", "write";
};

and test out http://www.esus.com/applets/WriteFile2.html again.

You get the following error:



Click OK, the file will be created anyway, since you granted that permission explicitely in your policy file.

To get rid of that annoying error, define the extra permission “usePolicy” in your policy file:

grant {
   permission java.lang.RuntimePermission "usePolicy";
   permission java.io.FilePermission "C:${/}esusfoo", "write";
};

Try out the applet again! No errors!

Let’s modify the applet a bit so that it also tries to write to a file c:esusfoo2. The new applet look like this.

WriteTwoFiles.java:

import javax.swing.*;
import java.awt.*;
import java.io.*;
 
public class WriteTwoFiles extends JApplet {
   public void paint(Graphics g) {
      String filename1 = "/tmp/esusfoo";
      String filename2 = "/tmp/esusfoo2";
      if (System.getProperty("os.name").indexOf("Windows") != -1) {
         filename1 = "C:\esusfoo";
         filename2 = "C:\esusfoo2";
      }
 
      BufferedWriter bw;
      try {
         bw = new BufferedWriter(new FileWriter(filename1));
         bw.write("The sun is green and the grass shines.n");
         bw.flush();
         bw.close();
 
         g.drawString("File " + filename1 + " created!", 10, 10);
      }
      catch (Exception e) {
         g.drawString(""+e, 10, 10);
      }
 
      try { 
         bw = new BufferedWriter(new FileWriter(filename2));
         bw.write("The sun shines and the grass is green.n");
         bw.flush();
         bw.close();
 
         g.drawString("File " + filename2 + " created!", 10, 50);
      }
      catch (Exception e) {
         g.drawString(""+e, 10, 50);
      }
   }
}

Sign the jar file as described above:

C:certificateapplet> jar cvf WriteTwoFiles.jar WriteTwoFiles.class
added manifest
adding: WriteTwoFiles.class(in = 1458) (out= 822)(deflated 43%)

C:certificateapplet> jarsigner WriteTwoFiles.jar esustest
Enter Passphrase for keystore: esuspass

WriteTwoFiles.html:

<html>
<body>
<br>
<!--"CONVERTED_APPLET"-->
<!-- CONVERTER VERSION 1.3 -->
<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
WIDTH = 700 HEIGHT = 100  
codebase="http://java.sun.com/products/plugin/1.3/jinstall-13-win32.cab#Version=1,3,0,0">
<PARAM NAME = CODE VALUE = "WriteTwoFiles.class" >
<PARAM NAME = ARCHIVE VALUE = "WriteTwoFiles.jar" >

<PARAM NAME="type" VALUE="application/x-java-applet;version=1.3">
<PARAM NAME="scriptable" VALUE="false">
<COMMENT>
<EMBED type="application/x-java-applet;version=1.3"  
CODE = "WriteTwoFiles.class" ARCHIVE = "WriteTwoFiles.jar" WIDTH = 700 HEIGHT = 100  
scriptable=false pluginspage="http://java.sun.com/products/plugin/1.3/plugin-install.html">
<NOEMBED></COMMENT>

</NOEMBED></EMBED>
</OBJECT>

<!--
<APPLET CODE = "WriteTwoFiles.class" ARCHIVE = "WriteTwoFiles.jar" WIDTH = 700 HEIGHT = 100>


</APPLET>
-->
<!--"END_CONVERTED_APPLET"-->


</body>
</html>

If you run this signed applet (http://www.esus.com/applets/WriteTwoFiles.html), using the same modified policy file, esusfoo was successfully accessed but, a AccessControlException is thrown in accessing esusfoo2, as expected.

One more problem: the extra permissions to write to esusfoo and esusfoo2 are granted to all applets. You can fine-tune your policy configuration file with signedBy and/or codeBase. With signedBy, you can specify the keystore entry that contains the public key so that verification of the signed JAR file is possible. The runtime system then verifies the association of the private key with which the JAR file was signed with the public key of the specified entry in the keystore. codeBase specifies that the permissions in this grant entry are only applicable to signed applets coming from a particular code source.

Because we’re using a self-signed applet, we need to import our certificate in the keystore of the plug-in. The following steps show you how to:

  1. export the certificate to a file:
    C:certificateapplet> keytool -export -alias esustest -file esustest.cer
    Enter keystore password:  esuspass
    Certificate stored in file <esustest.cer>
    
  2. copy esustest.cer to the directory that contains the file cacerts:
    C:certificateapplet> copy esustest.cer "c:program filesjavasoftjre1.3.1libsecurity
            1 file(s) copied
    
  3. make a backup of cacerts:
    C:Program FilesJavaSoftJRE1.3.1libsecurity>copy cacerts cacerts.bak
            1 file(s) copied
    
  4. import the certificate into the cacerts keystore:
    C:Program FilesJavaSoftJRE1.3.1libsecurity>keytool -import -alias esustest
     -keystore cacerts -file esustest.cer
    Enter keystore password:  changeit
    Owner: CN=Joris Van den Bogaert, OU=ESUS Team, O="ESUS, Inc.", L=Meerbeek, ST=Un
    known, C=BE
    Issuer: CN=Joris Van den Bogaert, OU=ESUS Team, O="ESUS, Inc.", L=Meerbeek, ST=U
    nknown, C=BE
    Serial number: 3b58beaa
    Valid from: Sat Jul 21 01:28:42 CEST 2001 until: Fri Oct 19 01:28:42 CEST 2001
    Certificate fingerprints:
             MD5:  88:09:3D:97:3A:7B:91:AD:4B:01:B8:3E:40:B8:C6:2A
             SHA1: 6A:A1:0E:19:45:91:07:97:B0:75:BE:BB:79:91:2A:1A:27:F2:36:93
    Trust this certificate? [no]:  yes
    Certificate was added to keystore
    

    (Note: the initial password for the cacerts file is changeit as specified in the documentation)

Our self-signed certificate is now added to our database.

Run WriteTwoFiles again. Notice that now you’ll get the following dialog box:




This dialog box would also show up if your applet was signed by a certificate assigned by a VeriSign or Thawte type trusted CA.

Now change to policy file for more fine-grained control:

grant signedBy "esustest", codeBase "http://www.esus.com/applets/WriteTwoFiles.jar" {
   permission java.lang.RuntimePermission "usePolicy";
   permission java.io.FilePermission "C:${/}esusfoo", "write";
   permission java.io.FilePermission "C:${/}esusfoo2", "write";
};

Center a JFrame on the screen

Use this little code snippet:

   Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
   int x = (int) ((d.getWidth() - getWidth()) / 2);
   int y = (int) ((d.getHeight() - getHeight()) / 2);
   setLocation(x, y);

Applied:

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
   
public class Main extends JFrame
{ 
   public Main() {
      final JButton button = new JButton("Center me!");
      getContentPane().setLayout(new FlowLayout());
      getContentPane().add(button);
      button.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
            int x = (int) ((d.getWidth() - getWidth()) / 2);
            int y = (int) ((d.getHeight() - getHeight()) / 2);
            setLocation(x, y);
         }
      });
  
      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);
   }
}

Adding a menu bar to a JSplitPane

Main.java:

 
import javax.swing.plaf.basic.*;
import java.awt.event.*;
import javax.swing.*;
import java.beans.*;
import java.awt.*;
 
public class Main extends JFrame
{
   JSplitPane splitPane;
  
   public Main() {
      addWindowListener(new WindowAdapter() {
         public void windowClosing(WindowEvent we) {
            System.exit(0);
         }
      });
 
      splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, 
                                 new JPanel(), new JPanel());
      splitPane.setDividerSize(20);
  
      splitPane.setUI(new MenuDividerUI(getMainMenuBar()));
 
      getContentPane().add(splitPane);
 
      addComponentListener(new ComponentAdapter() {
         public void componentShown(ComponentEvent event) {
            splitPane.setDividerLocation(0.5);  
                
            removeComponentListener(this);
         }
      });
   }
 
   public JMenuBar getMainMenuBar() {
      JMenuBar mainBar = new JMenuBar();
      JMenu menu = new JMenu("JSplitPane");
      JMenuItem item1 = new JMenuItem("HORIZONTAL_SPLIT");
      JMenuItem item2 = new JMenuItem("VERTICAL_SPLIT");
      menu.add(item1);
      menu.add(item2);
      mainBar.add(menu);
  
      item1.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            splitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
         }
      });
 
      item2.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent ae) {
            splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
         }
      });
 
      return mainBar;
   }
 
   public static void main(String []args) {
      Main main = new Main();
      main.setSize(300, 300);
      main.setVisible(true);
   }
}
 
class MenuDividerUI extends BasicSplitPaneUI
{
   protected JMenuBar menuBar;
 
   public MenuDividerUI(JMenuBar menuBar) {
      this.menuBar = menuBar;
   }
 
   public BasicSplitPaneDivider createDefaultDivider() {
      BasicSplitPaneDivider divider = new BasicSplitPaneDivider(this) {
         public int getDividerSize() { return menuBar.getPreferredSize().height; }
      };
      divider.setLayout(new BorderLayout());
      divider.add(BorderLayout.NORTH, menuBar);
 
      return divider;
   }
}

Setting the background color of the tabs of a JTabbedPane

You can set the background color using the method setBackgroundAt. However, this will only change the background of the tabs that are not selected. You can’t change the background of the selected tab unless you change the look and feel “TabbedPane.selected” property. This would change all JTabbedPanes that you have instantiated. A bug was filed for this: http://developer.java.sun.com/developer/bugParade/bugs/4230649.html.

import javax.swing.plaf.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
 
public class Main extends JPanel {                     
  public Main() {
    setLayout(new BorderLayout());
    
    UIManager.put("TabbedPane.selected", Color.green);
    
    JTabbedPane tabbedPane = new JTabbedPane();
    for (int i=0;i<10;i++) {
      tabbedPane.addTab("Tab #" + i, new JLabel("Tab #" + i));
      tabbedPane.setBackgroundAt(i, new Color(25*i, 25*i, 25*i));
    }
    add(tabbedPane, BorderLayout.CENTER);
  }
  
  JPanel createPane(String s) {
    JPanel p = new JPanel();
    p.add(new JLabel(s));
    return p;
  }
  
  public static void main(String[] args) {
    JFrame frame = new JFrame("JTabbedPane Selected Color Demonstration");
    frame.addWindowListener( new WindowAdapter() {
      public void windowClosing( WindowEvent e ) {
        System.exit(0);
      }
    });
    frame.getContentPane().add(new Main());
    frame.setSize(200, 100);
    frame.setVisible(true);
  }
}