Archive for May, 2013
Why CS teachers should stop teaching Java applets
As a veteran of applet development (see credentials below), I think it is high time to make a call that teachers should stop teaching applets in general, & especially AWT based applets. Applets are an advanced and specialized type of app. that has little place in the real world around us (most things that are done by applets can instead be better achieved using Javascript and HTML 5).
It saddens me to see new students ‘tossed in at the deep end’ to learn how to make an applet.
The reasons are multiple, but first, I’ll look a little at the history of applets and why applets were ever considered a good idea for teaching small, simple projects.
Applet vs. Frame
The simplest applet is:
import java.applet.Applet; import java.awt.Label; public class HelloWorldApplet extends Applet { @Override public void init() { add(new Label("Hello World!")); } }
Looks simple, right? This hints at the primary reason that applets were taught.
It only takes a handful of code lines to see the end result.
But an applet gets a size & position on screen from the HTML that loads it. So an applet also requires a little HTML E.G.
<html> <body> <applet code=HelloWorldApplet width=400 height=200> </applet> </body> </html>
This makes the total for a working applet 17 LOC. Not looking quite so simple now. Worse, many developers think ‘any old mark-up will do’ when that is very much not the case. Missing opening or closing elements make the HTML invalid and how a browser will interpret it is anyone’s guess.
Compare that to an application that behaves in as smooth a manner:
import java.awt.Label; import java.awt.Frame;
public class HelloWorldApplication {
public static void main(String[] args) { Frame f = new Frame(); f.add(new Label("Hello World!")); f.pack(); f.setVisible(true); } }
So, while it takes just 9 lines of code for the simplest of
applets (even including the @Override
notation), while 12 LOC for
the application doing the same thing, add the HTML and it becomes
17 lines for applet/HTML vs. just 12 LOC for the application.
AWT vs Swing
Time moves on, and the Swing component toolkit was introduced as a replacement for AWT. Nobody uses AWT anymore. Most Java GUI developers started using Swing, and those that have used AWT have largely forgotten the finer details.
This is relevant to the student in terms of getting help when they get stuck. It does not matter who we are, when approaching new areas of CS, we all tend to reach for whatever resources might help us understand the new technology. For a student the best resources are firstly the text books and class notes, but those typically only go so far at explaining, and the rest is from things like the JavaDocs, the Java Tutorial, searching the net, or asking for clarification on forums.
Those last two are particularly relevant in that:
- There is a slew of extremely poor AWT based code available on the net.
- There may also be some poor Swing based code out there, but usually there is a Swing programmer nearby that can point out the deficiencies in it.
Industry uses Swing and that is all that Swing programmers know and remember. AWT is obsolete, and a dead end in career or learning.
So let’s now look at the proper way to write a Swing applet & application. The Java Tutorial warns us that all Swing code should be started and updated on the Event Dispatch Thread, which (ironically) is an AWT based Thread.
A simple Swing applet might then be:
import javax.swing.JApplet; import javax.swing.JLabel; import javax.swing.SwingUtilities; import java.lang.reflect.InvocationTargetException;
public class HelloWorldApplet extends JApplet {
@Override public void init() {
@Override Runnable r = new Runnable() { public void run() { add(new JLabel("Hello World!")); } }; try { SwingUtilities.invokeAndWait(r); } catch(InterruptedException ie) { ie.printStackTrace(); } catch (InvocationTargetException ite) { ite.printStackTrace(); }
} }
This is slightly verbose (25 LOC) for strict clarity, but could be reduced to:
import javax.swing.*;
public class HelloWorldApplet extends JApplet {
@Override public void init() { Runnable r = new Runnable() {
@Override public void run() { add(new JLabel("Hello World!")); } }; try { SwingUtilities.invokeAndWait(r); } catch(Exception e) { e.printStackTrace(); }
} }
It could be further shortened (from 20 LOC) by declaring the Runnable
inside the
SwingUtilities
method call, but I find that notation to be confusing &
prefer to separate the Runnable
into a clearly defined instance.
And now the Swing equivalent application, using the same ‘short guidelines’.
import javax.swing.*;
public class HelloWorldApplication {
public static void main(String[] args) { Runnable r = new Runnable() {
@Override public void run() { JFrame f = new JFrame(); f.add(new JLabel("Hello World!")); f.pack(); f.setVisible(true); } }; SwingUtilities.invokeLater(r);
} }
Just 18 LOC in total.
Not very much coding to see our simple message on screen, in a free floating Swing component.
Embedded vs. not embedded
Security
Why won’t the applet load my input file?
By default, Java applets run in a security sand-box that prohibits many actions which might be damaging to other applets, the browser or the user’s machine.
While the security sand-box is of great benefit to end-users, it makes the life of the developer difficult. And it has just become that much more difficult in Java 7 update 21.
In Java 7 Update 21 Security Improvements in Detail Markus Eisele notes:
With the introduced changes it is most likely that no end-user is able to run your application when they are either self-signed or unsigned.
While that warning is a little extreme, I agree with the underlying point being made. A user (or in this case you, the teacher) will need to OK some very scary dialogs, and possibly lower the default Java security to an unsafe level, before being able to view an applet.
Error reporting
My applet is broken but shows no errors! Where are they?
The System.err
stream used for displaying stack traces appears on the command line (or in the IDE) when running an application. When a stack trace occurs in an applet it is sent to the Java Console, which is (by default) not configured to be shown.
Class caching
I changed my applet but the browser shows the same!
Many times I have responded to applet problems where the questioner swears they have changed the code & recompiled it, yet the browser is still showing the old values. The solution is relatively simple when you know how – flush the class cache from the Java Console. To someone learning, it is typically a complete mystery.
Embedded conclusion
Those 3 problems alone have probably earned me a quarter of the reputation points I’ve so far gained for applets on Stack Overflow. They pose huge problems when developing and debugging applets.
Conclusion
The question really comes down to:
Are you teaching Java/CS or how to deploy applets?
If the former, use JFrame
based applications and side-step all the
problems that are inherent to an embedded app. And don’t even consider
teaching AWT components – they are obsolete & Swing takes only a few
more LOC to get something on-screen.
Author Credentials
So who am I?
- Top ranked provider of answers on Stack Overflow for the applet tag.
- The developer of Appleteer.
- Host of many applets on my site.