Personal notes on Java
For other technologies like HTML, CSS, .NET, PHP, etc. check my other blog

ref: The AffableBean tutorial - creating the servlet controller

Package:
javax.servlet.annotation: The javax.servlet.annotation package contains a number of annotations that allow users to use annotations to declare servlets, filters, listeners and specify the metadata for the declared component.
 
Description:

Annotation used to declare a servlet.
This annotation is processed by the container at deployment time, and the corresponding servlet made available at the specified URL patterns.
This Annotation lets you define URLs patterns that invoke the servlet.

Annotation elements:

  • name: the name of the servlet resource;
  • loadOnStartUp: include the loadOnStartup element so that the servlet is instantiated and initialized when the application is deployed. A value of 0 or greater will cause this to happen (-1 is the default);
  • urlPatterns: the urls that this servlet will manage. For example, if you enter '/category', and your app is hosted has "http://localhost/AffableBean" you are directing the servlet to handle a request that appears as "http://localhost/AffableBean/category"; 
  • for other elements check the javadoc: javax.servlet.annotation#WebServlet

Ex.:
@WebServlet(name="ControllerServlet",
            loadOnStartup = 1,
            urlPatterns = {"/category",
                           "/addToCart",
                           "/viewCart",
                           "/updateCart",
                           "/checkout",
                           "/purchase",
                           "/chooseLanguage"})
public class ControllerServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

        String userPath = request.getServletPath();

        // if category page is requested
        if (userPath.equals("/category")) {
            // TODO: Implement category request

        // if cart page is requested
        } else if (userPath.equals("/viewCart")) {
            // TODO: Implement cart page request

            userPath = "/cart";

        // if checkout page is requested
        } else if (userPath.equals("/checkout")) {
            // TODO: Implement checkout page request

        // if user switches language
        } else if (userPath.equals("/chooseLanguage")) {
            // TODO: Implement language request

        }

        // use RequestDispatcher to forward request internally
        String url = "/WEB-INF/view" + userPath + ".jsp";

        try {
            request.getRequestDispatcher(url).forward(request, response);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
} 

XML alternative:
Instead of using the @Webservlet annotation you can also add this info in XML in the deployment descriptor (web.xml) of your project, ex:
<servlet>
    <servlet-name>ControllerServlet</servlet-name>
    <servlet-class>controller.ControllerServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ControllerServlet</servlet-name>
    <url-pattern>/category</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>ControllerServlet</servlet-name>
    <url-pattern>/addToCart</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>ControllerServlet</servlet-name>
    <url-pattern>/viewCart</url-pattern>
</servlet-mapping> 

Border Layout

Ex.:
myJFrame.setLayout(new BorderLayout(10, 5));
Container pane = myJFrame.getContentPane();
JButton button = new JButton("yeahhhh");
pane.add(button, BorderLayout.PAGE_START);

A BorderLayout object has five areas. These areas are specified by the BorderLayout constants:
  • PAGE_START
  • PAGE_END
  • LINE_START
  • LINE_END
  • CENTER
NOTE: Before JDK release 1.4, the preferred names for the various areas were different, ranging from points of the compass (for example, BorderLayout.NORTH for the top area, or SOUTH, EAST, WEST).
But now the constants described above are preferred because they are standard and enable programs to adjust to languages that have different orientations.

BoxLayout

ref: How to Use BoxLayout

javax.swing.BoxLayout arranges components either on top of each other or in a row.
You might think of it as a version of FlowLayout, but with greater functionality.
As the box layout arranges components, it takes the components' alignments and minimum, preferred, and maximum sizes into account.

Set vertical(BoxLayout.PAGE_AXIS) or horizontal (BoxLayout.LINE_AXIS) flow:
myJFrame.setLayout(new BoxLayout(myJFrame.getContentPane(), BoxLayout.Y_AXIS));
Note: LINE_AXIS and PAGE_AXIS are preferred over the old X_AXIS and Y_AXIS because they enable programs to adjust to languages that have different orientations.

BoxLayout tries to size each component at the component's preferred height. If the vertical space of the layout does not match the sum of the preferred heights, then BoxLayout tries to resize the components to fill the space.
Alignments affect not only the components' positions relative to each other, but also the location of the components (as a group) within their container.

To define space between the components you can use invisible components (fillers) like:
Constructor or Method Purpose
Box(int) Creates a Box — a container that uses a BoxLayout with the specified axis. As of release 1.3, Box extends JComponent. Before that, it was implemented as a subclass of Container.
static Box createHorizontalBox()
(in Box)
Creates a Box that lays out its components from left to right.
static Box createVerticalBox()
(in Box)
Creates a Box that lays out its components from top to bottom.
Component createRigidArea(Dimension) Create a rigid component.
Component createHorizontalGlue()
Component createVerticalGlue()
Component createGlue()
Create a glue component. Horizontal glue and vertical glue can be very useful.
Component createHorizontalStrut()
Component createVerticalStrut()
Create a "strut" component. We recommend using rigid areas instead of struts.
Box.Filler(Dimension, Dimension, Dimension) Creates a component with the specified minimum, preferred, and maximum sizes (with the arguments specified in that order). See the custom Box.Filler discussion, earlier in this section, for details.

GridLayout

A very simple layout that creates a grid layout with the specified number of rows and columns. All components in the layout are given equal size.
One, but not both, of rows and cols can be zero, meaning that rows or columns will be automatically created.
Example (rows are created automatically and each row has 2 columns):
GridLayout experimentLayout = new GridLayout(0,2);
(...)
compsToExperiment.setLayout(experimentLayout);

compsToExperiment.add(new JButton("Button 1"));
compsToExperiment.add(new JButton("Button 2"));
compsToExperiment.add(new JButton("Button 3"))

GridBagLayout

ref: How to Use GridBagLayout

Its a flexible layout manager but also very verbose.
The components are disposed according to constraints that you define for each one using the java.awt.GridBagConstraints class.
You can reuse the same GridBagContraint for each component but you'll need to reset all the previous values that are different for the new component.
Example:
GridBagLayoutTest teste = new GridBagLayoutTest();
myJFrame.setContentPane(teste);
(...)
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.gridheight = 3;
c.fill = GridBagConstraints.BOTH;
this.add(b1, c);

JButton b2 = new JButton("B");
c.gridx = 1;
c.gridy = 0;
c.gridheight = 1;
c.fill = GridBagConstraints.NONE;
this.add(b2, c); 



You can set the following java.awt.GridBagConstraints instance variables:
  • gridx and gridy:
     - takes an int that specifies the row (y) and column (x) at the upper left of the component.
     - takes GridBagConstraints.RELATIVE (the default value) to specify that the component be placed just to the right of (for gridx) or just below (for gridy).
     
  • gridwidth, gridheight:
     - takes an int (default is 1) that specify the number of columns (for gridwidth) or rows (for gridheight) in the component's display area (works similar to a span if you have the fill property set accordingly).
     - takes GridBagConstraints.REMAINDER to specify that the component be the last one in its row (for gridwidth) or column (for gridheight).
     - takes GridBagConstraints.RELATIVE to specify that the component be the next to last one in its row (for gridwidth) or column (for gridheight).
     
  • fill: determine whether and how to resize the component.
    Valid values (defined as GridBagConstraints constants) are: NONE (the default); HORIZONTAL; VERTICAL; BOTH;
     
  • ipadx, ipady: takes an int (default is 0) that specifies the internal padding in pixels (how much to add to the size of the component);
     
  • insets: Specifies the external padding of the component -- the minimum amount of space between the component and the edges of its display area. The value is specified as an Insets object. By default, each component has no external padding.
     
  • anchor: Used when the component is smaller than its display area to determine where (within the area) to place the component. Valid values (defined as GridBagConstraints constants) are CENTER (the default), PAGE_START, PAGE_END, LINE_START, LINE_END, FIRST_LINE_START, FIRST_LINE_END, LAST_LINE_END, and LAST_LINE_START.

You can implement event listeners in multiple diferent ways. This source code explores some of them.
Check the "Handle events" section under the Events page for an intro to this example.

In this example we use JButton actionListeners but you can use any other type of listners in the same way.

Download source code


Alternative 1 (file: GuiEvents1.java):

Create an anonymous inner class that implements ActionListener and routes the event to a method in your class;
public class GuiEvents1 extends JFrame {
...    
    private void init() {
        ...
        this.button1 = new JButton("generate new number");
        this.button2 = new JButton("reset lable");
        
        //add a handler to the button1 action event:            
        this.button1.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                myButton1Handler(e); //call our handler
            }
        });

        //add a handler to the button2 action event:
        this.button2.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                myButton2Handler(e);
            }
        });
        ...
    }
    
    //method responsible for handling button1 action events: 
    private void myButton1Handler(ActionEvent e) {
        //any logic here
        this.updateLabel();
    }

    //method responsible for handling button2 action events:
    private void myButton2Handler(ActionEvent e) {
        //any logic here
        this.resetLabel();
    }
} 


Alternative 2 (file: GuiEvents2.java)

Make your class implement ActionListener;
public class GuiEvents2 extends JFrame implements ActionListener {
    ...
    private void init() {        
        this.button1 = new JButton("generate new number");
        this.button2 = new JButton("reset lable");
        
        //add a handler to the button1 action event:
        this.button1.addActionListener(this);
        this.button2.addActionListener(this);
        ...
    }
    
    //implementation of the ActionListener Interface:
    @Override
    public void actionPerformed(ActionEvent e) {
        String source = e.getActionCommand();
        out("Action command: " + source);

        if (source.equals(this.button1.getActionCommand())) {
            this.myButton1Handler(e); //a normal class method
        } else if (source.equals(this.button2.getActionCommand())) {
            this.myButton2Handler(e); //a normal class method
        }
    }
    ...
} 

Alternative 3 (file: GuiEvents3.java)

Create, for each button, a dedicated inner class that implements ActionListener and is responsible for handling each button's events
 public class GuiEvents3 extends JFrame {
    private void init() {
        ...
        this.button1 = new JButton("generate new number");
        this.button2 = new JButton("reset lable");

        //add a handler to the button1 action event:
        this.button1.addActionListener(new Button1Handler());
        this.button2.addActionListener(new Button2Handler());
        ...
    }
   
    ...
   
    private class Button1Handler implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            //any logic here
            updateLabelNumber(); //a method on the parent
        }
    }

    private class Button2Handler implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            //any logic here
            resetLabel(); //a method on the parent
        }
    }
}


API Specification and Documentation


Tutorials



Intro

JSF (Java Server Faces)

What it is:
  • JavaServer Faces (JSF) is a Java web application framework intended to simplify development and integration of web-based user interfaces;
  • JSF is part of the Java Enterprise Edition;
  • JSF is a request-driven MVC web framework for constructing user interfaces using components;
  • As a display technology, JSF 2 uses Facelets: previous versions (JSF 1.x) used JavaServer Pages (JSP) instead of facelets for its display technology;
  • JSF is a standardized technology which was formalized in a specification through the Java Community Process. So, in order to code in JSF, you need to use an implementation of this specification (Mojarra is the reference implementation).

JSF is a specification for which there is a couple of implementations available:
  • Mojarra: is the JSF reference implementation, distributed by Oracle;
    It was previously named "Sun JSF Reference Implementation" (aka Sun JSF RI) until version 1.2_08;
    It's part of the Glassfish project;
     
  • MyFaces: The Apache Foundation JSF implementation with Ajax components;
References:

JSF Component libraries:
Don't confuse JSF implementations with component libraries!
There's a couple of component libraries that you can use with a JSF implementation (check this matrix for a comparison between JSF component libraries):
  • RichFaces: an open source Ajax-enabled component library for JavaServer Faces, hosted by JBoss. It allows easy integration of Ajax capabilities into enterprise application development.
  • IceFaces: open-source, Java JSF extension framework and rich components, Ajax without JavaScript;
  • many more;

Core JSF features
  • Managed Beans (aka "Backing Beans" or "Page Beans"): normal JavaBean classes annotated with @ManagedBean that will supply the faceletes views with properties (views access this properties through EL to gather information for display);
  • A template-based component system: you no longer need to use the include directives used on JSP+Servlets;
  • Built-in Ajax support: using <f:ajax /> (since JSF v2.0);
  • Built-in support for bookmarking & page-load actions;
  • Integration with the Unified Expression Language (EL), which is core to the function of JSF. Views may access managed bean fields and methods via EL: <my:component rendered="#{myBean.userLoggedIn}" />. This lets you separate presentation (facelets views) from busines logic (managed beans): facelets views will only contain declarative code (HTML; facelets components; EL placeholders) and use EL to call managed beans properties (managed beans are the only ones to contain Java code and responsible for all the logic);
  • A default set of HTML and web-application specific UI components:  and you can use many of-the-shelf component libraries;
  • A server-side event model : For dispatching events and attaching listeners to core system functionality, such as "Before Render Response" or "After Validation"
  • State management, supporting: "request", "session", "application", "flash", and "view" scoped Java beans.
  • Two XML-based tag libraries (core and html) for expressing a JavaServer Faces interface within a view template (can be used with both JSP or Facelets)

Facelets (aka: View templates or Facelets views)

Facelets are the XML files (xhtml) that define the JSF views. For this they are also called "view templates" or "Facelets views".
The term Facelets refers to the view declaration language for JSF technology. JSP was used as the presentation technology for JSF 1.x, but JSP does not support all the new features available in JSF 2.0. For this JSP technology is considered to be a deprecated presentation technology for JavaServer Faces 2.0. Facelets is a part of the JSF specification and also the preferred presentation technology for building JSF technology-based applications.
Facelets (which was designed specifically for JavaServer Faces) was adopted as the official view technology for JSF 2.0. This eliminates the life-cycle conflicts that existed with JSP, forcing workarounds by Java developers. Facelets allows easy component/tag creation using XML markup instead of Java code, the chief complaint against JSF 1.x.(Wikipedia also has good facelets info)

Facelets applications are a type of JSF applications that use XHTML pages rather than JSP pages.

Using facelets taglibs in XHTML:

Namespace declarationDescription
xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="enDefault XHTML namespace
xmlns:ui="http://java.sun.com/jsf/facelets"Facelets UI tags like ui:compose and ui:define
xmlns:h="http://java.sun.com/jsf/html"JSF HTML tags
xmlns:f="http://java.sun.com/jsf/core"JSF core tags
xmlns:c="http://java.sun.com/jstl/core"JSTL core tags
NOTE: Avoid using JSTL tags with Facelets! Because JSTL doesn't work with the JSF view tree, this will cause unexpected results. Yes, you can use some of the JSTL core tags with Facelets. However, there are a few that are not supported because they are either redundant (there is a JSF equivalent that is preferred) or they simply don't fit in to the JSF way of doing things.

Components/Widgets/Controls

DropDownList

ref: Managed Beans I: Using Java Classes to Represent Form Info

Some usefull classes:

  • javax.faces.model.SelectItem: represents a single item in the list of supported items associated with a UISelectMany or UISelectOne component.
    Useful for example if you want the dropdownlist to have a value (like and id) and a label (some text) for each one.
    The constructor has many overloads, ex:
    SelectItem(Object value)         
    SelectItem(Object value, String label)         
    SelectItem(Object value, String label, String description, boolean disabled, boolean escape, boolean noSelectionOption)


Example:

Download source code here
  • Company class is just a POJO Javabean with no annotations;
  • DaoMock class is just a mockup with a harcoded Company[] and methods to access this elements
  • The xhtml form:
<h:form>           
    <legend>Select Company:<br />                 
        <h:selectOneMenu value="#{myObject.companyId}">
            <f:selectItems value="#{companyOptions.companyNames}"/>
        </h:selectOneMenu>
    </legend>
    <h:commandButton value="submeter" action="#{myObject.controller()}" />
</h:form> 

  • MyObject is the @ManagedBean of the form:
@ManagedBean
public class MyObject {

    private Company selectedCompany; //will be set by the controller method after the form is submitted
    private int companyId; //this is the value set by the dropdown list

    /**
     * Used to submit the form
     * @return the destination page
     */
    public String controller() {
        DaoMock dao = new DaoMock();

        this.selectedCompany = dao.getCompanyById(companyId);
        return "resultado";
        //TODO: if companyNotFound return String for error page instead
    }
//setters/getters omitted. NOTE: selectedCompany only has get, no set - it will be set by the controller method


  • CompanyOptions class is used to get the dropDownList items and is also a @ManagedBean
@ManagedBean
public class CompanyOptions {

    public List<SelectItem> getCompanyNames() {
        List<SelectItem> listOfItems = new ArrayList<>();
        DaoMock dao = new DaoMock();
        Company[] companyArray = dao.getCompanies();

        for (Company c : companyArray) {
            listOfItems.add(
                    new SelectItem(c.getId(),c.getNome()));
        }

        return listOfItems;
    } 

O
TODO

TODO

References:


Events

One important part of swing programming  is events: check the events page.

Top Containers

For a UI Component to appear on screen it must be inserted into the content pane of a top container.
(The content pane is the main container in all frames, applets, and dialogs).

Swing provides three generally useful top-level container classes:
  1. JFrame;
  2. JDialog;
  3. JApplet;
When using these classes, you should keep these facts in mind:
  • To appear onscreen, every GUI component must be part of a containment hierarchy. A containment hierarchy is a tree of components that has a top-level container as its root. We'll show you one in a bit.
  • Each GUI component can be contained only once. If a component is already in a container and you try to add it to another container, the component will be removed from the first container and then added to the second.
  • Each top-level container has a content pane that, generally speaking, contains (directly or indirectly) the visible components in that top-level container's GUI.
  • You can optionally add a menu bar to a top-level container. The menu bar is by convention positioned within the top-level container, but outside the content pane. Some look and feels, such as the Mac OS look and feel, give you the option of placing the menu bar in another place more appropriate for the look and feel, such as at the top of the screen.

javax.swing.JComponent

For more info: The JComponent Class

With the exception of top-level containers (like JFrame and JDialog), all Swing components whose names begin with "J" descend from the JComponent class. For example, JPanel, JScrollPane, JButton, and JTable all inherit from JComponent.
The JComponent class provides the following functionality to its descendants:

Layout Managers

ref: Using Layout Managers
Test your knowledge: Questions and Exercises: Laying Out Components within a Container 
 
A layout manager is an object that implements the java.awt.LayoutManager interface and determines the size and position of the components within a container. Although components can provide size and alignment hints, a container's layout manager has the final say on the size and position of the components within the container.

Each Layout Manager has its own peculiarities check: How to Use Various Layout Managers to get information about how to use each one.

Types

For a visual representation and more info see: A Visual Guide to Layout Managers Several AWT and Swing classes provide layout managers for general use:
  • BorderLayout: default layout for content panes. Places components in up to five areas: top, bottom, left, right, and center. All extra space is placed in the center area. Tool bars that are created using JToolBar must be created within a BorderLayout container, if you want to be able to drag and drop the bars away from their starting positions;
  • BoxLayout: puts components in a single row or column;
  • CardLayout: lets you implement an area that contains different components at different times. An alternative to using CardLayout is using a tabbed pane component;
  • FlowLayout: default layout manager for every JPanel. It simply lays out components in a single row, starting a new row if its container is not sufficiently wide;
  • GridBagLayout: if you are not using a GUI builder (GridLayout) but want to manually build your GUI then this is recommended as the next most flexible and powerful layout manager - It aligns components by placing them within a grid of cells, allowing components to span more than one cell. The rows in the grid can have different heights, and grid columns can have different widths;
  • GridLayout: places components in a grid of cells. Each component takes all the available space within its cell, and each cell is exactly the same size;
  • GroupLayout: can be used manually but it was developed to be used by GUI builder tools (ex. NetBeans IDE GUI builder uses this layout by default). This layout works by defining group of components that related to each other (ex. align components together). The GUI builder will give you visual clues when you drag and drop the components next to each-other informing you how the elements will be grouped. For examples of this visual clues check this GroupLayout Example.
  • SpringLayout: a flexible layout manager designed for use by GUI builders;

Using Layout Managers

Set

As a rule, the only containers whose layout managers you need to worry about are:
  • JPanels (default is FlowLayout)
    JPanel panel = new JPanel(new BorderLayout());
  • content panes (default is BorderLayout)
    After a container has been created, you can set its layout manager using the setLayout method. For example:
    Container contentPane = frame.getContentPane();
    contentPane.setLayout(new FlowLayout());
Note: unless you are using JToolBar, the FlowLayout and BorderLayout managers are only useful for prototyping.

Add components

Depends on the Layout Manager you are using.

The how-to section for each layout manager has details on what, if any, arguments you need to specify to the add method. Some layout managers, such as GridBagLayout and SpringLayout, require elaborate setup procedures. Many layout managers, however, simply place components based on the order they were added to their container.
Example:
pane.add(aComponent, BorderLayout.PAGE_START);


NOTE: Swing containers other than JPanel and content panes generally provide API that you should use instead of the add method. For example, instead of adding a component directly to a scroll pane (or, actually, to its viewport), you either specify the component in the JScrollPane constructor or use setViewportView.

Set Size and Alignment hints

Sometimes you need to customize the size hints that a component provides to its container's layout manager, so that the component will be laid out well.
You can invoke the component's methods for:
  • setting size hints: setMinimumSize, setPreferredSize, and setMaximumSize;
  • setting alignment hints (for example, you can specify that the top edges of two components should be aligned): setAlignmentX and setAlignmentY methods;
NOTE: Many layout managers do not pay attention to a component's requested maximum size. However, BoxLayout and SpringLayout do. Furthermore, GroupLayout provides the ability to set the minimum, preferred or maximum size explicitly, without touching the component (How to Use BoxLayout).

Tips on Choosing a Layout Manager

Check the tips at the bottom of the page: Using Layout Managers

How Layout Managers work

Layout managers basically do two things: Calculate the minimum/preferred/maximum sizes for a container and lay out the container's children.

Some methods: 
  • Container.validate: used to validate an invalid container (isValid() returns true). For a container to be valid, all the container's children must be laid out already and must all be valid also. 
  • Window.pack: validates the window and lays out the window's component hierarchy for the first time. After a component is created it is in the invalid state by default. 
  • revalidate and repaint methods: If the size of a component changes, for example following a change of font, the component must be resized and repainted by calling the revalidate and repaint methods on that component. Both revalidate and repaint are thread-safe — you need not invoke them from the event-dispatching thread.

Code samples on how to use different Layout Managers Types

check this page

Borders

For more info check the: The Border API - contains tables listing the commonly used border methods

To put a border around a JComponent, you use its setBorder method.
You can use the BorderFactory class to create most of the borders that Swing provides.
If you need a reference to a border — say, because you want to use it in multiple components — you can save it in a variable of type Border.
Example:
JPanel pane = new JPanel();
pane.setBorder(BorderFactory.createLineBorder(Color.black));

Usefull Classes:
  • javax.swing.BorderFactory: used to create most of the borders that Swing provides. Returns objects that implement the Border interface.
  • javax.swing.border.Border: interface describing an object capable of rendering a border around the edges of a swing component. You often don't need to directly use anything in the border package, except when specifying constants that are specific to a particular border class or when referring to the Border type.

Components

TextComponents

All text components extend the class javax.swing.text.JTextComponent Types of text components:
  • JEditorPane;
  • JTextPane: also extends JEditorPane. Support for different styles on the text in it.
  • JTextArea: a text component that uses the same text style for all the text in it (supports only a single foreground color, background color and font); 
  • JTextField: one line text component;


Dialogs (modal window; popup)

For convenience, several Swing component classes can directly instantiate and display dialogs:
  • JOptionPane: use it to create simple, standard dialogs (error/warning/information popups);
  • ProgressMonitor: use it to put up a dialog that shows the progress of an operation;
  • JColorChooser and JFileChooser, also supply standard dialogs;
  • To bring up a print dialog, you can use the Printing API;
  • To create a custom dialog, use the JDialog class directly;
more info here: How to Make Dialogs 

JSplitPane



  • To set the initial split position use:
    setResizeWeight(.5d);
     - a value of 0 (default), indicates the right/bottom component gets all the extra space (the left/top component acts fixed)
     - a value of 1 specifies the left/top component gets all the extra space (the right/bottom component acts fixed).


Keyboard (detecting key pressed; keys)

Usefull resources:
TODO: Check out how key bindings work.

Mouse

Detecting mouse double click

someComponent.addMouseListener(new MouseAdapter(){
 public void mouseClicked(MouseEvent event){
  if (e.getClickCount() == 2 && !e.isConsumed()) {
   e.consume();
   //handle double click. 
  } 
 }
}
ref: How to detect double-click mouse events in Swing

TODO

General references:


Java defined Events, Listeners and Adapters

In java a component/object that fires some type of event (ex. ActionEvent) also has a corresponding method to add observers that will listen to this events [ex. addActionListener(ActionListener listener) ] .
This "add Listener" methods receive an implementation of the corresponding interface (ex. ActionListener) that you manually code with the required logic to execute when the event gets fired.

This interfaces may define multiple methods that you must implement but sometimes you are interested in handling only on of them.
For this java library sometimes also has corresponding adapter classes that implement this interfaces with default empty methods, so that you can use them (instead of the interface directly) and implement only the methods you need.
TIP: a good way to see if java already provides an adapter for the type of Listener you need, is to check the Javadoc of that Listener interface.
Ex.: if you need to implement a MouseWheelListener interface:
  1. visit the javadoc page for MouseWheelListener;
  2. search the word "adapter";
  3. under the section "All Known Implementing Classes" you'll find MouseAdapter. This adapter provides an implementation of MouseWheelListener (along with other listeners) with empty methods.

Main packages

Java library defines a lot of Events and their corresponding Listener interfaces and (in some cases) Adapter classes.
Some main packages where they are defined are:

Package java.awt.event

Provides interfaces and classes for dealing with different types of events fired by AWT components.

Package javax.swing.event

Provides for events fired by Swing components.
  • Events:
    CaretEvent; ChangeEvent; HyperlinkEvent; MenuDragMouseEvent; MenuEvent; MenuKeyEvent; PopupMenuEvent; SwingPropertyChangeSupport; UndoableEditEvent
    ; (many other...);
     
  • Listeners:
    «every event has its corresponding Listener interface»;
     
  • Adapters:
    - InternalFrameAdapter (adapter for InternalFrameListener);
    - MouseInputAdapter (adapter for multiple mouse related listeners: MouseListener, MouseMotionListener, MouseWheelListener, EventListener, MouseInputListener);

Package java.beans

Defines some PropertyChange related events and listeners and some other util classes to deal with events on javabeans.
TODO (complete)

Check the description for the PropertyChange API further down this page.

Handle events

Just like int the Observer pattern you can register observers (listeners) that listen to events fired by swing components.
Example of how it works:
  1. Among other events, a javax.swing.JButton fire an java.awt.event.ActionListener
    when you press it.
     
  2. In order to do something when this event is fired, you need to register any interested observers (listeners) with it.
     
  3. The JButton provides specific methods to register (add) observers (listeners) for each event that it fires. For example, for the ActionEvent mentioned above you would use the JButton method:
    public void addActionListener(ActionListener l)
  4. This method receives an java.awt.event.ActionListener (interface) type as argument. This is the interface that your observers (listeners) need to implement in order to handle the event when it gets fired.
     
  5. The ActionListener interface only defines one method that your observers must implement:
    void     actionPerformed(ActionEvent e) 
    This method will be invoked when the event is fired: its the place where you put the logic to do something.
     
  6. You can use multiple approaches to implement the required interface in your observers (listeners).
    For example, for the ActionListener mentioned above you could:
    1. create a anonymous inner class that implements ActionListener and routes the event to a method in your class;
    2. make your class implement ActionListener;
    3. create, for each button, a dedicated inner class that implements ActionListener and will be responsible for handling each button's events;
    4. if you are not interested on implementing all the events of a Listener interface, java already has some built int abstract adapter classes that implement many of this Listener interfaces with empty method implementations that you can use coding only the methods you need.
    Each have its own pros/cons and of course, you can always implement them in many other creative ways.

The Property Change Listener API

References:

Registering a PropertyChangeListener: 

Using for example the usefull java.beans.PropertyChangeSupport object: This is a utility class that can be used by beans that support bound properties. It manages a list of listeners and dispatches PropertyChangeEvents to them. You can use an instance of this class as a member field of your bean and delegate these types of work to it. The PropertyChangeListener can be registered for all properties or for a property specified by name. (The javadoc includes a simple example)
Method Purpose
addPropertyChangeListener(PropertyChangeListener) Add a property-change listener to the listener list.
addPropertyChangeListener(String, PropertyChangeListener) Add a property-change listener for a specific property. The listener is called only when there is a change to the specified property.
Interface java.beans.PropertyChangeListener
Because PropertyChangeListener has only one method, it has no corresponding adapter class.
Method Purpose
propertyChange(PropertyChangeEvent) Called when the listened-to bean changes a bound property.
Class java.beans.PropertyChangeEventA "PropertyChange" event gets delivered whenever a bean changes a "bound" or "constrained" property. A PropertyChangeEvent object is sent as an argument to the PropertyChangeListener and VetoableChangeListener methods.

Method Purpose
Object getNewValue()
Object getOldValue()
Return the new, or old, value of the property, respectively.
String getPropertyName() Return the name of the property that was changed.
void setPropagationId() Get or set the propagation ID value. Reserved for future use.
Example with source code:
A simple MVC app that uses the PropertyChangeListener to implement an Observer Pattern - the views observe (listen) model changes:
Download source code (Netbeans 7 project)

Excerpts from this app:
The model:
  • the model is a simple javabean;
  • the model has an instance of the class java.beans.PropertyChangeSupport to add/remove listners;
  • the set methods fire the property change events;
    NOTE: if the oldValue equals the newValue then the event wont be fired (this logic is transparent to the programmer - download and run the app to test it).

 public class MyModel {
    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
    private String nome = "";
    private String apelido = "";
   
    ...
   
    public void addPropertyChangeListener(PropertyChangeListener listener) {
        this.pcs.addPropertyChangeListener(listener);        
    }
   
    public void addPropertyChangeListener(String propriedade,PropertyChangeListener listener){
        this.pcs.addPropertyChangeListener(propriedade, listener);
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        this.pcs.removePropertyChangeListener(listener);
    }

    public void setNome(String nome) {        
        String oldValue = this.nome;
        this.nome = nome;
        out("Model: valor de nome foi alterado de "+oldValue+" para "+nome);
        this.pcs.firePropertyChange("nome", oldValue, nome);
    }


The Views:
  • The views implement the Interface PropertyChangeListner (it has only 1 method: "propertyChange")
public class MyViewA implements PropertyChangeListener {     
    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        out("ViewA - recebeu evento de propertyChange");
        if (evt.getPropertyName().equals("nome"))
            out("ViewA - valor da propriedade 'nome' actualizado de '"+evt.getOldValue()+"' para '"+evt.getNewValue()+"'");
        else if(evt.getPropertyName().equals("apelido"))
            out("ViewA - valor da propriedade 'apelido' actualizado de '"+evt.getOldValue()+"' para '"+evt.getNewValue()+"'");
        else
            out("ViewA - Nenhuma property match");
    } 


The controller:
  • the Controller creates the model and the views;
  • the Controller adds the views has listners (observers) of the model (so, the model and view are loosely coupled - they dont know nothing about each other);
  • the Controller makes changes to the model and the model will issue propertyChange events to the views to update them;

public class Controller {

    public static void main(String args[]) {
        out("Controller - creating model with properties: nome=aa apelido=bb");
        MyModel model = new MyModel("aa", "bb");
        
        out("Controller - creating views and registering them has model observers");
        MyViewA view = new MyViewA();        
        model.addPropertyChangeListener(view);  
        out("Controller - ViewA is observing all model properties");
        
        MyViewB view2 = new MyViewB();
        model.addPropertyChangeListener("nome", view2);
        out("Controller - ViewB is observing only the 'nome' property");

        out("\nController - Setting model properties with NEW VALUES: nome=cc apelido=dd");
        model.setNome("cc");
        model.setApelido("dd");  
        
        out("\nController - Setting model properties with SAME VALUES: nome=cc apelido=dd"
                + "\n  NOTE: since its the same values the propertychange event wont be fired and the views dont get updated");
        model.setNome("cc");
        model.setApelido("dd");  
        
        out("\nController - done.");
    }