Windows Forms vs. Swing
From SwinBrain
This article explains the basics to creating a Graphical User Interface (GUI) using Windows Forms and Java Swing. The basics include for creation, adding components, making those components active and how to control layout of those components.
Contents |
Creating a GUI using Windows Forms
To create a Graphical User Interface (GUI), we first need to create a form to which we can add controls (buttons, labels, textboxes) that allow the user to interact with it.
using System.Windows.Forms; class MyFirstForm : Form { public MyFirstForm() { this.Text = "My First Form"; } } class MyFirstApp { static void Main() { Form form = new myFirstForm(); Application.Run(form); } }
This a very simple form, but to this we can add controls. To add a button we need to create a new button object, add the following code in the MyFirstForm() constructor:
Button aButton = new Button();
then we can alter some of the buttons properties:
aButton.Text = "Click Me";
the button currently doesn't do anything once clicked, so we need to add an EventHandler for the buttons click event:
aButton.Click += new EventHandler(abutton_Click);
then we have to add the button to the form so it gets displayed:
this.Controls.Add(aButton);
now that the button is displayed on the form and you can click we need to catch the event that is raised, this is a seperate method outside of the Main() method:
public void aButton_Click(object sender, MouseEventArgs e) { MessageBox.Show("You have clicked me"); }
Controlling Layout
This section details two helpful tools that allow you to design interfaces that are appropriatly aligned, spaced, sized and that the interface follows Windows conventions. One of many layout managers is discussed at the end of the section.
Anchoring
When a control is Anchored to the edges of a container the control will automatically resize and keep it's position relative to the edges of the container. By default a control is anchored to the top, left edges of it's parent container.
In the following figure, the text box has been anchored to the top, left and right. As you can see when the form is resized the text box also resizes automatically.
Docking
Docking allows you to arrange controls on in a container so that they are fixed to edge. They can also be Docked to all the edges of the container so that they fill the remaining space within the container.
Figure 1.2 shows three panels all docked within a form. The top and bottom panels are docked respectively and the middle panel is docked to fill in the rest of the container.
Table Layout Panel
A TableLayoutPanel splits a single panel into a grid, allowing you to add and remove columns and rows. Within each cell of the grid any type of control can be added, even another TableLayoutPanel.
Within each cell the controls can be anchored and/or docked, as seen in Figure 1.4. Just like in HTML cells can be made to span over multiple rows and columns. You can control the way in which each row or column grows or the how the TableLayoutPanel expands once all the cells have been filled.
The following link provides examples for when to use TableLayoutPanels, Best Practices.
Events in Windows Forms
When something happens on a form, for example the user clicks the left mouse button an Events is fired to notify the form that something has happened. Once the Event has been fired something needs to catch it, this is what an EventHandler is used for. Each EventHandler corresponds to a certain event. For example, a form called GridControl, has a mouse clicked EventHandler, so when the mouse button is clicked on the form the following code will be executed:
private void GridControl_MouseClick(object sender, MouseEventArgs e) { MouseButtons button = e.Button; int clicks = e.Clicks; if (button == MouseButtons.Left && clicks == 1) //Left mouse button was clicked once }
There are two parameters that are passed when the Event is raised. In the above example the object sender refers to the object that raised the event and the MouseEventArgs 'e' parameter allows us to access properties and methods for that specific object, e.g. e.Button tells us which mouse button was clicked.
Creating a GUI using Swing
When creating GUIs using a C# editor, the tools that are provided allow for the easy creation of an interface by allowing dragging and dropping of controls onto the form and the editor produces the majority of the code for this. In comparison Swing has limited resources available that match those for C#, so this means writing a lot more code.
The code has been and is recommended to be seperated into two seperate classes, one that launches the program and the other that creates the interface. Comments are provided to explain what certain lines of code achieve, although they take up the majority of the code.
import javax.swing.*; //This class has a ''main'' method to launch the frame public class FirstFrameTest { public static void main(String[] args) { //Creates a new FirstFrame object FirstFrame frame = new FirstFrame(); //Defines what happens when the user closes the frame frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Displays the frame on the screen frame.setVisible(true); } }
The following code creates the JFrame:
//Class used to create the frame class FirstFrame extends JFrame { public FirstFrame() { //Sets the size of the frame, using constants defined below setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); } public static final int DEFAULT_WIDTH = 300; public static final int DEFAULT_HEIGHT = 200; }
To this a panel can be added too which controls such as buttons and labels can be created and added to the panel. The following code creates a new JPanel and then adds a JButton to it.
First two lines of code need to be added to the FirstFrames constructor:
FirstPanel panel = new FirstPanel(); //Creates a new FirstFrame object add(panel); //Adds the new panel to the frame
//Class used to create the frame class FirstPanel extends JPanel { public FirstPanel() { JButton button = new JButton("Click Me"); //Creates a new JButton object add(button); //Adds the button to the panel } }
All this will display a frame that contains a panel with a button on it. At this stage the button will not do anything when clicked, that functionality is discussed in the Events in Swing section.
Controlling layout in Swing
The following only outlines a few ways in which to control the layout of components in an interface. Links are provided to documentation of more advanced layout managers at the end of the section.
Flow Layout
FlowLayout is the default layout manager for a JPanel. This simple layout places each component one after the other in a single row and when the end of the container is reached a new row is started. If the user resizes the container the components keep their preferred size and are automatically relocated to fill in the available space by the layout manager.
Border Layout
BorderLayout is the default layout manager for a JFrame. Each component can be placed using a constant CENTER, NORTH, SOUTH, EAST, WEST. If no location is specified, CENTER is applied.
panel.setLayout(new BorderLayout()); panel.add(aButton, BorderLayout.NORTH);
When the container is resized the components are also resized to fill the available space.
Panels
Swing components can be added straight onto the main frame, but when you want to create a sophisticated interface this can become a problem. To gain more control over the layout of an interface, JPanels can be used to seperate the interface into sections so that you have more control over the layout. The frame that contains the panels can apply any of the following layouts and panels can also exist within other panels, allowing for the creation of very detailed interfaces.
Grid Layout
The GridLayout is composed of rows and columns, like a spreadsheet, and the components are placed with each cell.
The grid is setup by specifying the number of rows and columns:
panel.setLayout(new GridLayout(4, 3));
Borders can also be placed around each cell by specifying the vertical or horizontal gap:
panel.setLayout(new GridLayout(4, 3, 5, 5));
When adding components into the grid the first component is placed in row one of column one, then row one column two and so on. Each component is resized to fill the whole cell, so all the components are the same size and when the container is resized the cells grow as do the components.
Events in Swing
There are a few ways to handle an event in java:
- Seperate event handler class
- Inner event handler class
- Anonymous event handler class
The following sections will discuss each of the above and provide examples using the same button, this will then show the main differences between each approach. What this event handler does is when the user clicks on the button it will display a message box informing which button the user clicked and how many times.
Seperate Class
Using this method a new class is created called ButtonClick, the following code is required to create it:
public class ButtonClick implements ActionListener { public void actionPerformed(ActionEvent event) { int buttonClicked = event.getButton(); int clickCount = event.getClickCount(); if(buttonClicked == MouseEvent.BUTTON1) JOptionPane.showConfirmDialog(getParent(),"You clicked the left mouse button " + clickCount); else if(buttonClicked == MouseEvent.BUTTON3) JOptionPane.showConfirmDialog(getParent(),"You clicked the right mouse button " + clickCount); } }
Inner Class
The code for is exactly the same as seen in the Seperate Class section but instead of creating a seperate class the code exists within the class that the button was created in. This helps cut down on the number of event handler class that would be present if each component in the interface had its own seperate class.
Anonymous Class
With an anonymous class you are not required to technically create a new class, a new object or extend the MouseAdapter to implement all the required methods. Instead you can just define the actionPerformed method of the MouseHandler and just add the code that you want to be executed when the button is clicked:
JButton button = panel.add(new MouseHandler("Click Me") { public void actionPerformed(ActionEvent event) { int buttonClicked = event.getButton(); int clickCount = event.getClickCount(); if(buttonClicked == MouseEvent.BUTTON1) JOptionPane.showConfirmDialog(getParent(),"You clicked the left mouse button " + clickCount); else if(buttonClicked == MouseEvent.BUTTON3) JOptionPane.showConfirmDialog(getParent(),"You clicked the right mouse button " + clickCount); });
Comparison of Windows Forms and Swing
A major advantage of using Windows Forms is Visual Studio which contains tools and resources to allow you to create and modify GUIs quickly and easily by dragging and dropping components onto forms. It also provides layout tools such as anchoring and docking which provide great assistance with laying out, aligning etc. of the components. There are Integrated Development Environments (IDEs) available to assist in the creation of forms but they are not at the same level of programs such as Visual Studio.
Unlike C#, Java does not allow you to draw images using floating point numbers. This has an affect on forms that contain graphics that fill the whole form. Because if the user resizes a form that uses Integers to specify the coordinates that an image is drawn at, gaps start to appear between the images.
Links
- Links to other resources/further information:
- C# Class Library
- Windows Forms Namespace
- JavaTM 2 Platform Standard Edition 5.0 API Specification
- Using Java Swing Layout Managers



