Swing Program Templates
My Swing Program Template
My template is primarily meant for teaching and for ease of explanation.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
import java.awt.*; import java.awt.event.*; import javax.swing.*; // Swing Program Template @SuppressWarnings("serial") public class SwingTemplate extends JFrame { // Name-constants to define the various dimensions public static final int WINDOW_WIDTH = 300; public static final int WINDOW_HEIGHT = 150; // ...... // private variables of UI components // ...... /** Constructor to setup the UI components */ public SwingTemplate() { Container cp = this.getContentPane(); // Content-pane sets layout // cp.setLayout(new ....Layout()); // Allocate the UI components // ..... // Content-pane adds components // cp.add(....) // Source object adds listener // ..... setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Exit when close button clicked setTitle("......"); // "this" JFrame sets title setSize(WINDOW_WIDTH, WINDOW_HEIGHT); // or pack() the components setVisible(true); // show it } /** The entry main() method */ public static void main(String[] args) { // Run GUI codes in the Event-Dispatching thread for thread safety SwingUtilities.invokeLater(new Runnable() { public void run() { new SwingTemplate(); // Let the constructor do the job } }); } } |
Codes that can be Run as Application as well as Applet
To write codes that can be run as a standalone application as well as an applet, you could extend your main class from JPanel
.
- To run as an application, write a
main()
method that allocates aJFrame
and set its content-pane to your main class (JPanel
). - To run as an applet, write a class that extends
JApplet
, with aninit()
which set theJApplet
's content-pane to your main class (JPanel
). UseSwingUtilities.invokeAndWait()
to run the GUI construction codes, instead ofinvokeLater()
.
Main Graphics class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
import java.awt.*; import java.awt.event.*; import javax.swing.*; // Swing Program Template for running as application or Applet @SuppressWarnings("serial") public class SwingTemplateApp extends JPanel { // Name-constants to define the various dimensions public static final int WINDOW_WIDTH = 300; public static final int WINDOW_HEIGHT = 150; // ...... // private variables of UI components // ...... /** Constructor to setup the UI components */ public SwingTemplateApp() { // "this" JPanel sets layout // this.setLayout(new ....Layout()); // Allocate the UI components // ..... // "this" JPanel adds components // this.add(....) // Source object adds listener // ..... } /** The entry main() method */ public static void main(String[] args) { // Run GUI codes in the Event-Dispatching thread for thread safety SwingUtilities.invokeLater(new Runnable() { public void run() { JFrame frame = new JFrame(); frame.setContentPane(new SwingTemplateApp()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setTitle("......"); frame.setSize(WINDOW_WIDTH, WINDOW_HEIGHT); // or pack() frame.setVisible(true); } }); } } |
Main Applet Class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
import java.lang.reflect.InvocationTargetException; import javax.swing.JApplet; // Swing Program Template for running as Applet @SuppressWarnings("serial") public class SwingTemplateApplet extends JApplet { /** init() to setup the UI components */ @Override public void init() { // Run GUI codes in the Event-Dispatching thread for thread safety try { javax.swing.SwingUtilities.invokeAndWait(new Runnable() { public void run() { setContentPane(new SwingTemplateApplet()); } }); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } } |
Custom Graphics
[TODO]
Full-Screen Mode (for Games) Template
See below on how to use full-screen mode
[TODO] Template
NetBeans GUI Builder Template
NetBeans GUI Builder's template is similar to mine but uses many helper methods:
- Each UI component is declared as a private variable of the class, so that it can be referenced by all the methods. I typically declare UI components as private variable only if they have to be referenced. Otherwise, they are either declared inside the constructor, or anonymous instance used.
- It uses a helper method called
initComponent()
to construct all the UI component, which is invoked in the constructor. I place the GUI construction codes directly in the constructor. ThesetVisible(true)
is called (in themain()
) after theinitComponents()
. - An anonymous inner class is created for each source's action. A helper method is generated for each event handler.
- It uses
GroupLayout
(which was introduced by NetBeans and included in JDK) to layout the components. - It uses
java.awt.EventQueue.invokeLater()
, which is the same asjavax.swing.SwingUtilities.invokeLater()
, to run the GUI codes on the event-dispatching thread.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class NetBeansGUIBuilderTemplate extends JFrame { // privates variables for all the UI components // E.g., // private javax.swing.JButton btn; /** Constructor */ public NetBeansGUIBuilderTemplate() { // Setup and initialize UI via helper method initComponents() initComponents(); } /** Helper method (Generated via GUI Builder) */ private void initComponents() { // Construct the UI components // E.g., // btn = new JButton(); // Source object adds listener // Use an anonymous inner class for each source // E.g., // btn.addActionListener(new ActionListener() { // @Override // public void actionPerformed(ActionEvent evt) { // // Generate a helper method for each handler // btnActionPerformed(evt); // } // }); // Layout the container and components // NetBeans introduces the so-called GroupLayout // ..... setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); setTitle("...Title..."); pack(); // pack all the component in this JFrame } // Generated Helper method for source btn's actionPerformed() handler // private void btnActionPerformed(ActionEvent evt) { // ...... // } /** The entry main() method */ public static void main(String args[]) { // Run the GUI construction on the event-dispatching thread for thread-safety // Same as javax.swing.SwingUtilities.invokeLater() java.awt.EventQueue.invokeLater(new Runnable() { @Override public void run() { // Allocate a JFrame and show it // setVisible(true) runs after initComponents() new NetBeansGUIBuilderTemplate().setVisible(true); } }); } } |
Swing Tutorial Template
- Swing tutorial template uses a
static
method calledcreateAndShowGUI()
to setup the UI. ThecreateAndShowGUI()
is an extension to the staticmain()
method solely responsible for GUI construction. - The main class does not extend from
JFrame
. Instead, aJFrame
calledframe
is declared and constructed in thestatic
methodcreateAndShowGUI()
. - The main class may extends
JPanel
, which is the main panel for the application. IncreateAndShowGUI()
, you can create a main class (JPanel
) and set it as the content-pane of theJFrame
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class SwingTutorialTemplate extends JPanel { // Name-constants to define the various dimensions public static final int WINDOW_WIDTH = 300; public static final int WINDOW_HEIGHT = 150; // ...... // Create the GUI and show it. // For thread safety, this method should be invoked from event-dispatching thread. private static void createAndShowGUI() { // Create and set up the application window JFrame frame = new JFrame("...Your Title..."); frame.setContentPane(new SwingTutorialTemplate()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(WINDOW_WIDTH, WINDOW_HEIGHT); // or frame.pack() to "pack" all the components in this frame frame.setVisible(true); // show it } public static void main(String[] args) { // Schedule a job for the event-dispatching thread to create and show this application's GUI. SwingUtilities.invokeLater(new Runnable() { @Override public void run() { createAndShowGUI(); } }); // ...... } } |
java.awt.Robot
java.awt.Robot
(since JDK 1.3) is an interesting utility class that can be used to take control of the mouse and keyboard. It can generate mouse and key events to the underlying native system (for test automation, self-running demos, among others). Robot
can also be used to do screen capture (or print screen).
The commonly-used methods in java.awt.Robot
are:
void delay(int msec) // delay in milliseconds void keyPress(int keyCode) // press a key void keyRelease(int keyCode) // release a key void mouseMove(int x, int y) // move the mouse point to (x, y) screen coordinates void mousePress(int mouseCode) // press a mouse button void mouseRelease(int mouseCode) // release a mouse button BufferImage createScreenCapture(Rectangle r) // capture clip specified by the Rectangle
Example 1: Sending Keystrokes and Mouse-Clicks
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
import java.awt.*; import java.awt.event.*; import java.io.IOException; /** Launch NotePad, send key strokes, then send mouse events to exit. */ public class RobotDemoKeyAndMouse { public static Robot robot; public static void main(String[] args) { try { robot = new Robot(); Runtime.getRuntime().exec("notepad.exe"); // launch NotePad robot.delay(1000); // wait for NotePad to launch // Send keys to NotePad int [] keys = { KeyEvent.VK_T, KeyEvent.VK_E, KeyEvent.VK_S, KeyEvent.VK_T, KeyEvent.VK_ENTER }; for (int i = 0; i < keys.length; ++i) { sendKey(keys[i]); } // Send mouse event to exit NotePad // Need to check the (x, y) of the menu location sendMouseClick(55, 74); // File sendMouseClick(50, 260); // Exit sendKey(KeyEvent.VK_TAB); // Don't save sendKey(KeyEvent.VK_ENTER); } catch (AWTException ex) { ex.printStackTrace(); } catch (IOException ex) { ex.printStackTrace(); } } /** helper method to send the given key to the active application */ public static void sendKey(int keyCode) { robot.keyPress(keyCode); robot.keyRelease(keyCode); robot.delay(500); // for you to see the keystroke } /** helper method to send a mouse-click to the active application */ public static void sendMouseClick(int x, int y) { robot.mouseMove(x, y); robot.delay(1000); // for you to see the move robot.mousePress(InputEvent.BUTTON1_MASK); robot.mouseRelease(InputEvent.BUTTON1_MASK); } } |
Dissecting the Program
- Once a
Robot
is constructed, you could use thekeyPress()
andkeyRelease()
to send a keystroke to the native system. - You can use
mouseMove(x, y)
to position the mouse-pointer at absolute screen co-ordinates (x, y), andmousePress()
andmouseRelease()
to send a mouse-click. - A
delay()
method is also provided. Delay is needed for self-running demos.
Example 2: Screen Capture
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import java.awt.*; import java.awt.image.BufferedImage; import javax.imageio.ImageIO; import java.io.*; /** Using java.awt.Robot to capture a screen shot and saves it */ public class RobotScreenCaptureDemo { public static void main(String[] args) { try { // Get the "actual" screen size Dimension scr = Toolkit.getDefaultToolkit().getScreenSize(); System.out.println("(" + scr.width + "," + scr.height + ")"); // Allocate a Robot instance, and do a screen capture Robot robot = new Robot(); Rectangle rect = new Rectangle(0, 0, scr.width, scr.height); BufferedImage image = robot.createScreenCapture(rect); // Save the captured image to file with ImageIO (JDK 1.4) ImageIO.write(image, "jpeg", new File("captured.jpg")); } catch (AWTException ex) { // for Robot() ex.printStackTrace(); } catch (IOException ex) { // for ImageIO.write() ex.printStackTrace(); } } } |
Dissecting the Program
- Line 11 gets the actual screen size via the default
ToolKit
. - Line 15 allocate a
java.awt.Robot
instance (JDK 1.3) and Line 17 invokescreateScreenCapture()
method of theRobot
instance to take a snapshot of the screen of the given rectangular area. - Line 20 writes the captured image to a disk file, via the
javax.imageio.ImageIO
utility (JDK 1.4), which supports "jpg" and "png".
Swing How-To
Get Current Screen (Monitor) Size?
In JDK, "screen" refers to your computer monitor; "window" refers to your application window.
- Via
static
methodToolkit.getDefaultToolkit().getScreenSize()
.Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); int screenWidth = dim.width; int screenHeight = dim.heigth;
- Via
java.awt.Window
'sgetToolkit().getScreenSize()
method. - Via current
DisplayMode
of the current screenGraphicsDevice
:GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice defaultScreen = env.getDefaultScreenDevice(); DisplayMode defaultDisplayMode = defaultScreen.getDisplayMode(); int screenWidth = defaultDisplayMode.getWidth(); int screenHeight = defaultDisplayMode.getHeight();
Setting JComponent's (JFrame, JPanel) Size?
For window (JFrame
/Frame
):
setSize(int width, int height)
ofjava.awt.Window
.setBounds(int topLeftX, int topLeftY, int width, int height)
ofjava.awt.Window
.
For both window (JFrame
/Frame
)and panel (JPanel
/Panel
):
setPreferredSize(Dimension d)
ofjava.awt.Component
.- Override called-back method
getPreferredSize()
ofjava.awt.Component
, which shall return the preferredDimension
of this component.
Centralize Your Window on the Screen
In JDK, "screen" refers to your computer monitor; "window" refers to your application window.
Use JFrame
's setLocationRelativeTo(null)
.
Or,
- Get the screen width and height.
- Get your application window's width and height, via
JFrame
'sgetWidth()
andgetHeight()
. - Position your application window on the screen via
setBounds(x, y, width, height)
.
Align Text in drawString()?
Use a FontMetrics
to find out the width and height of the String
to be rendered for the current Font
, and position the baseline (x, y) of the drawString()
accordingly.
g.setFont(new Font(Font.MONOSPACED, Font.BOLD, 30));
String message = "Hello, world!";
FontMetrics fontMetrics = g.getFontMetrics();
Rectangle2D messageBounds = fontMetrics.getStringBounds(message, g);
// Centralize on the window
g.drawString(message,
(int) ((getWidth() - messageBounds.getWidth()) / 2),
(int) ((getHeight() - messageBounds.getHeight()) / 2));
It is interesting to note that in JavaME, the drawString()
provides an additional argument for setting the alignment of text string.
REFERENCES & RESOURCES
- "Creating a GUI With JFC/Swing" (aka "The Swing Tutorial") @ http://docs.oracle.com/javase/tutorial/uiswing/.