Welcome to Dream.In.Code
Getting Java Help is Easy!

Join 108,961 Java Programmers for FREE! Ask your question and get quick answers from experts. There are 1,467 online right now! We've got more than 500 tutorials and 2,000 snippets. Join and find out why Dream.In.Code is the #1 programming help community on the internet! Registration is fast and FREE... Join Now!



Basic GUI tutorial in Java

 
Reply to this topicStart new topic

> Basic GUI tutorial in Java, null layout

alpha02
Group Icon



post 17 Jan, 2007 - 05:14 PM
Post #1


Introduction

Making GUIs in Java can be quite difficult. Some prefer to use layouts such as BoxLayout, SpringLayout, and more (I will focus in this later). If you are not familiar with these ones, or if you want a really personalized layout, I recommend using the null layout. I will focus on this one in this tutorial. From now on, I assume you have some basic knowledge about Java.

Comparing the layouts

Here are the basic layouts and how they work:

BoxLayout: The components are aligned horizontally.
FlowLayout: The components are aligned vertically.
GridLayout: The components are placed in a grid.
GridBagLayout: More elaborate form of GridLayout. The components are in a grid, but with constraints.
SpringLayout: The components are placed using relationships between all parts.

I am passing some. As you figured out, a bunch of layouts are available and do different things. But how about using the null one? Although absolute positonning may be a problem, it's easy to program your form so the components resize or move. Using this layout, I build a form with resizing bars to adjust the GUI! All is possible, let's dig in!

Creating our form

First of all, we need to create our JFrame. This is simply the window. In this tutorial, we will use a file called gui1.java, so adapt the code for your file. Anyway, here's the basic code:

CODE
//Import packages
import javax.swing.*;
import java.awt.*;

//Main class
public class gui1{
    //Declare variables
    static JFrame frame1;
    static Container pane;
    static JButton btnConnect, btnDisconnect;
    static JLabel lblServer, lblUsername, lblPassword, lblPort;
    static JTextField txtServer, txtUsername, txtPassword, txtPort;
    static Insets insets;

    public static void main (String args[]){
        //Create the frame
        frame1 = new JFrame ("Sample GUI Application");
        //Set its size to 800x200 pixels
        frame1.setSize (800,200);
        //Prepare panel
        pane = frame1.getContentPane();
        insets = pane.getInsets();
        //Apply the null layout
        pane.setLayout (null);
    }
}


First, we need to import the Swing and AWT packages, which will be used in our GUI. We start by creating the frame. The constructor takes a string as a parameter, which will be the title of the frame (window). We resize it, and we apply the null layout to it. It is important you fully understand the above code before proceeding.

Creating the controls

We declared the controls, but we did not create them! Don't worry, it's much easier than you think. It is done the same way than in any layout. Look at the code:

CODE
btnConnect = new JButton ("Connect");
btnDisconnect = new JButton ("Disconnect");
lblServer = new JLabel ("Remote host:");
lblUsername = new JLabel ("Username:");
lblPassword = new JLabel ("Password:");
lblPort = new JLabel ("Port #:");
txtServer = new JTextField (10);
txtUsername = new JTextField  (10);
txtPassword = new JTextField  (10);
txtPort = new JTextField  (5);


The components are now created. Let's take a look at the constructors:
JButton: String, the text on the button.
JLabel: String, the text on the label.
JTextField: Integer, the size of the text field in characters. This has no influence on the maximum number of characters the user can input.

Note that for a password field you can use JPasswordField, but to keep things simple we will use JTextField.

Creating and placing a component

Placing a component is much easier in the null layout than in any other one. We, of course, add it to the panel, and then we call the method setBounds (x,y,width,height) of this component. We will start by placing the server label:

CODE
pane.add (lblServer); //Add component to panel
lblServer.setBounds (insets.left + 5, insets.top + 5, lblServer.getPreferredSize().width, lblServer.getPreferredSize().height);


This may seem complicated, but it is not. First, the pand.add instruction just puts the label in the panel, and the lblServer.setBounds places it. Let's take a look at its parameters:
1) X: The position on the X axis of the component. Remember, insets contains the coordinates of the pane's bounds. We place it at (insets+5), 5 pixels right from the left border.
2) Y: The position on the Y axis of the component. Here we specify 5 pixels down from the top of the pane.
3) Width: The width, in pixels, of the component. The getPreferredSize() method returns an object with the coordinates of its initial size.
4) Height: The height, in pixels, of the component. We do not modify its height as you can see.

Before we continue, you need to understand some other methods used to retrieve coordinates: getX(), getY(), getWidth() and getHeight(). They all return an integer. We will use them later. Make sure you understand all the previous stuff before proceeding.

Placing all components

Now that you know how to place a component, I will show you the full code to place them:

CODE
//Add all components to panel
pane.add (lblServer);
pane.add (lblUsername);
pane.add (lblPassword);
pane.add (lblPort);
pane.add (txtServer);
pane.add (txtUsername);
pane.add (txtPassword);
pane.add (txtPort);
pane.add (btnConnect);
pane.add (btnDisconnect);

//Place all components
lblServer.setBounds (insets.left + 5, insets.top + 5, lblServer.getPreferredSize().width, lblServer.getPreferredSize().height);
txtServer.setBounds (lblServer.getX() + lblServer.getWidth() + 5, insets.top + 5, txtServer.getPreferredSize().width, txtServer.getPreferredSize().height);

lblUsername.setBounds (txtServer.getX() + txtServer.getWidth() + 5, insets.top + 5, lblUsername.getPreferredSize().width, lblUsername.getPreferredSize().height);
txtUsername.setBounds (lblUsername.getX() + lblUsername.getWidth() + 5, insets.top + 5, txtUsername.getPreferredSize().width, txtUsername.getPreferredSize().height);

lblPassword.setBounds (txtUsername.getX() + txtUsername.getWidth() + 5, insets.top + 5, lblPassword.getPreferredSize().width, lblPassword.getPreferredSize().height);
txtPassword.setBounds (lblPassword.getX() + lblPassword.getWidth() + 5, insets.top + 5, txtPassword.getPreferredSize().width, txtPassword.getPreferredSize().height);

lblPort.setBounds (txtPassword.getX() + txtPassword.getWidth() + 5, insets.top + 5, lblPort.getPreferredSize().width, lblPort.getPreferredSize().height);
txtPort.setBounds (lblPort.getX() + lblPort.getWidth() + 5, insets.top + 5, txtPort.getPreferredSize().width, txtPort.getPreferredSize().height);

btnConnect.setBounds (txtPort.getX() + txtPort.getWidth() + 5, insets.top + 5, btnConnect.getPreferredSize().width, btnConnect.getPreferredSize().height);

//Place disconnect button (start a new line!)
btnDisconnect.setBounds (insets + 15, lblServer.getY() + lblServer.getHeight() + 5, btnDisconnect.getPreferredSize().width, btnDisconnect.getPreferredSize().height);


This used only methods you already know, there is nothing new here.

Finishing the layout

We are almost finished. If you run the program now, nothing shows. We need a last line:

CODE
frame1.setVisible (true);


Now run the program. All controls are placed! However, the Java default style is used. It is different depending on your version of JVM (Java Virtual Machine). To use the correct style, we must use Look and Feel.

Look and Feel

Look and Feel, also known as L&F, sets the style of your form to the one of your operating system. Don't forget that Java is cross-platform! This way, Windows users will have the Windows style, and Mac OS users will have their own style. Put these lines in your code:

CODE
//Set Look and Feel
try {UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());}
catch (ClassNotFoundException e) {}
catch (InstantiationException e) {}
catch (IllegalAccessException e) {}
catch (UnsupportedLookAndFeelException e) {}


This does all the job. Now what about actions and getting the input from the GUI? This is not quite a hard thing, so let's give it a shot:

Registering actions

Import the package java.awt.event.*, it will be used (I assume you know how to import a package). Now, we must add an action to the Connect button to make it do something. Use:

CODE
btnConnect.addActionListener(new btnConnectAction()); //Register action


The addActionListener method takes a ActionListener as a parameter. We must create a class which will inherit all attributes from that superclass:

CODE
public static class btnConnectAction implements ActionListener{

}


Since we create an interface (with the "implements" keyword), we absolutly need to create some methods inherited from the super interface:

CODE
public static class btnConnectAction implements ActionListener{
    public void actionPerformed (ActionEvent e){
        //Do something..
    }
}


Add any instructions you want in that method, they will be executed when you will click the button. Example, if you want to know what the user entered in the User name field, use:

CODE
public static class btnConnectAction implements ActionListener{
    public void actionPerformed (ActionEvent e){
        System.out.println("You entered "+txtUsername.getText());
    }
}


Feel free to explore the methods of the text fields, radio buttons, checkboxes, and more to find out how you can get user input. It is often a simple thing.

Putting it all together

If you followed this tutorial correcty, you should have this:

CODE
//Import packages
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

//Main class
public class gui1{
    //Declare variables
    static JFrame frame1;
    static Container pane;
    static JButton btnConnect, btnDisconnect;
    static JLabel lblServer, lblUsername, lblPassword, lblPort;
    static JTextField txtServer, txtUsername, txtPassword, txtPort;
    static Insets insets;

    public static void main (String args[]){
        //Set Look and Feel
        try {UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());}
        catch (ClassNotFoundException e) {}
        catch (InstantiationException e) {}
        catch (IllegalAccessException e) {}
        catch (UnsupportedLookAndFeelException e) {}

        //Create the frame
        frame1 = new JFrame ("Sample GUI Application");
        frame1.setSize (800,200);
        pane = frame1.getContentPane();
        insets = pane.getInsets();
        pane.setLayout (null);

        //Create controls
        btnConnect = new JButton ("Connect");
        btnDisconnect = new JButton ("Disconnect");
        lblServer = new JLabel ("Remote host:");
        lblUsername = new JLabel ("Username:");
        lblPassword = new JLabel ("Password:");
        lblPort = new JLabel ("Port #:");
        txtServer = new JTextField (10);
        txtUsername = new JTextField  (10);
        txtPassword = new JTextField  (10);
        txtPort = new JTextField  (5);

        //Add all components to panel
        pane.add (lblServer);
        pane.add (lblUsername);
        pane.add (lblPassword);
        pane.add (lblPort);
        pane.add (txtServer);
        pane.add (txtUsername);
        pane.add (txtPassword);
        pane.add (txtPort);
        pane.add (btnConnect);
        pane.add (btnDisconnect);

        //Place all components
        lblServer.setBounds (insets.left + 5, insets.top + 5, lblServer.getPreferredSize().width, lblServer.getPreferredSize().height);
        txtServer.setBounds (lblServer.getX() + lblServer.getWidth() + 5, insets.top + 5, txtServer.getPreferredSize().width, txtServer.getPreferredSize().height);
        lblUsername.setBounds (txtServer.getX() + txtServer.getWidth() + 5, insets.top + 5, lblUsername.getPreferredSize().width, lblUsername.getPreferredSize().height);
        txtUsername.setBounds (lblUsername.getX() + lblUsername.getWidth() + 5, insets.top + 5, txtUsername.getPreferredSize().width, txtUsername.getPreferredSize().height);
        lblPassword.setBounds (txtUsername.getX() + txtUsername.getWidth() + 5, insets.top + 5, lblPassword.getPreferredSize().width, lblPassword.getPreferredSize().height);
        txtPassword.setBounds (lblPassword.getX() + lblPassword.getWidth() + 5, insets.top + 5, txtPassword.getPreferredSize().width, txtPassword.getPreferredSize().height);
        lblPort.setBounds (txtPassword.getX() + txtPassword.getWidth() + 5, insets.top + 5, lblPort.getPreferredSize().width, lblPort.getPreferredSize().height);
        txtPort.setBounds (lblPort.getX() + lblPort.getWidth() + 5, insets.top + 5, txtPort.getPreferredSize().width, txtPort.getPreferredSize().height);
        btnConnect.setBounds (txtPort.getX() + txtPort.getWidth() + 5, insets.top + 5, btnConnect.getPreferredSize().width, btnConnect.getPreferredSize().height);
        btnDisconnect.setBounds (insets.left + 15, lblServer.getY() + lblServer.getHeight() + 5, btnDisconnect.getPreferredSize().width, btnDisconnect.getPreferredSize().height);

        //Set frame visible
        frame1.setVisible (true);

        //Button's action
        btnConnect.addActionListener(new btnConnectAction()); //Register action
    }

    public static class btnConnectAction implements ActionListener{
        public void actionPerformed (ActionEvent e){
            System.out.println("You entered "+txtUsername.getText());
        }
    }
}


Run the program. Everything should be fine.

Conclusion

Java is a powerful language, and therefore it can create impressive GUIs. I recommend using the null layout, it is not harder than the others and you can create really nice things. I managed to make splitter bars to move all parts of my GUI, and it works fine! If you have questions, do not hesitate to contact me!

This post has been edited by alpha02: 11 Oct, 2007 - 06:53 PM
Go to the top of the page
+Quote Post


Register to Make This Ad Go Away!

UnholyStar
Group Icon



post 24 Jan, 2007 - 01:00 PM
Post #2
Very nice, it helps smile.gif
Go to the top of the page
+Quote Post

Snooty_Head
*



post 7 Sep, 2007 - 11:11 AM
Post #3
Very nice, easy to follow tutorial. Although, I'm getting a "void is an invalid type for the variable main" error, and a "Syntax error on token ")", ; expected" on the same line. I put the code together as follows:

CODE

//Import packages
import javax.swing.*;
import java.awt.*;

//Main class
public class gui1{
    //Declare variables
    JFrame frame1;
    Container pane;
    JButton btnConnect, btnDisconnect;
    JLabel lblServer, lblUsername, lblPassword, lblPort;
    JTextField txtServer, txtUsername, txtPassword, txtPort;
    Insets insets;
    {
    
    btnConnect = new JButton ("Connect");
    btnDisconnect = new JButton ("Disconnect");
    lblServer = new JLabel ("Remote host:");
    lblUsername = new JLabel ("Username:");
    lblPassword = new JLabel ("Password:");
    lblPort = new JLabel ("Port #:");
    txtServer = new JTextField (10);
    txtUsername = new JTextField  (10);
    txtPassword = new JTextField  (10);
    txtPort = new JTextField  (5);
    
//  Add all components to panel
    pane.add (lblServer);
    pane.add (lblUsername);
    pane.add (lblPassword);
    pane.add (lblPort);
    pane.add (txtServer);
    pane.add (txtUsername);
    pane.add (txtPassword);
    pane.add (txtPort);
    pane.add (btnConnect);
    pane.add (btnDisconnect);

//    Place all components
    lblServer.setBounds (insets.left + 5, insets.top + 5, lblServer.getPreferredSize().width, lblServer.getPreferredSize().height);
    txtServer.setBounds (lblServer.getX() + lblServer.getWidth() + 5, insets.top + 5, txtServer.getPreferredSize().width, txtServer.getPreferredSize().height);

    lblUsername.setBounds (txtServer.getX() + txtServer.getWidth() + 5, insets.top + 5, lblUsername.getPreferredSize().width, lblUsername.getPreferredSize().height);
    txtUsername.setBounds (lblUsername.getX() + lblUsername.getWidth() + 5, insets.top + 5, txtUsername.getPreferredSize().width, txtUsername.getPreferredSize().height);

    lblPassword.setBounds (txtUsername.getX() + txtUsername.getWidth() + 5, insets.top + 5, lblPassword.getPreferredSize().width, lblPassword.getPreferredSize().height);
    txtPassword.setBounds (lblPassword.getX() + lblPassword.getWidth() + 5, insets.top + 5, txtPassword.getPreferredSize().width, txtPassword.getPreferredSize().height);

    lblPort.setBounds (txtPassword.getX() + txtPassword.getWidth() + 5, insets.top + 5, lblPort.getPreferredSize().width, lblPort.getPreferredSize().height);
    txtPort.setBounds (lblPort.getX() + lblPort.getWidth() + 5, insets.top + 5, txtPort.getPreferredSize().width, txtPort.getPreferredSize().height);

    btnConnect.setBounds (txtPort.getX() + txtPort.getWidth() + 5, insets.top + 5, btnConnect.getPreferredSize().width, btnConnect.getPreferredSize().height);

//    Place disconnect button (start a new line!)
    btnDisconnect.setBounds (insets.top + 15, lblServer.getY() + lblServer.getHeight() + 5, btnDisconnect.getPreferredSize().width, btnDisconnect.getPreferredSize().height);

    frame1.setVisible (true);
    
    public static void main(String[] args){
        
        //Create the frame
        frame1 = new JFrame ("Sample GUI Application");
        //Set its size to 800x200 pixels
        frame1.setSize (800,200);
        //Prepare panel
        pane = frame1.getContentPane();
        insets = pane.getInsets();
        //Apply the null layout
        pane.setLayout (null);
    }
  }
}


I'm using Eclipse.

Also, when I take out that third curly brace, which looks like it's not necessary to me, it gives me a ton of errors.

Any clues? smile.gif

Thanks in advance. biggrin.gif
Go to the top of the page
+Quote Post

alpha02
Group Icon



post 7 Sep, 2007 - 12:43 PM
Post #4
This tutorial has been tested throughly and works fine. You used:

CODE
Insets insets;
{


which makes absolutely no sense. Just copy and paste the code without forgetting anything!
Go to the top of the page
+Quote Post

PennyBoki
Group Icon



post 11 Oct, 2007 - 02:52 PM
Post #5
Hi alpha02, I just tried your "Putting it all together" code but it doesn't compile.
Please check. All of them are referencing a non-static variable from a static context.
Go to the top of the page
+Quote Post

Chopster
*



post 29 Mar, 2008 - 10:28 AM
Post #6
Brilliant Tutorial, Thanks alot, i understand Gui's alot better now
Go to the top of the page
+Quote Post


Reply to this topicStart new topic
1 User(s) are reading this topic (1 Guests and 0 Anonymous Users)
0 Members:

 

Lo-Fi Version Time is now: 9/4/08 09:45PM

Live Java Help!

Java Tutorials

Reference Sheets

Java Snippets

Bye Bye Ads

Free DIC T-Shirt

T-Shirt Example

Related Sites

Monthly Drawing

Thumb Drive

Partners

Top Contributors

Top 10 Kudos This Month