Scala, Spring, Maven example

This is a quick, bare minimum example of how Scala, Spring and Maven live happily together.

First, in the default directory structure that Maven offers out of the box, we need to create two new dirs:

  • /src/main/scala
  • /test/main/scala

If you are managing the project from within Eclipse or IntelliJ you’ll have to denote these dirs as source folders explicitly.

The POM looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>ScalaSpringMaven</groupId>
    <artifactId>ScalaSpringMaven</artifactId>
    <version>1.0</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
            </plugin>
            <plugin>
                <groupId>org.scala-tools</groupId>
                <artifactId>maven-scala-plugin</artifactId>
                <version>2.15.2</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>compile</goal>
                            <goal>testCompile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin></plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>3.1.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.scala-lang</groupId>
            <artifactId>scala-compiler</artifactId>
            <version>2.9.1</version>
        </dependency>
    </dependencies>

</project>
 

Note how the Scala compiler plugin hijacks the compile and testCompile phases of Maven lifecycle and happily co-exists with the Java compiler.

Next, the application context looks as follows:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

<context:component-scan base-package="com.dimitrisli.scala"/>

</beans>

The above Spring config file looks identical like in any other Java project where we want to activate component scanning for post Spring 3 annotation-enabled beans.
Our Bean looks like:

package com.dimitrisli.scala

import org.springframework.stereotype.Component

@Component
class MyBean {

  def performTask = "Greetings from MyBean!"
}

and the Scala Object where we startup the Spring context:

package com.dimitrisli.scala

import org.springframework.context.ApplicationContext
import org.springframework.context.support.ClassPathXmlApplicationContext


object Application {

  def main(args: Array[String]) {

    val context:ApplicationContext = new ClassPathXmlApplicationContext("application-context.xml")
    val myBean:MyBean = context.getBean("myBean").asInstanceOf[MyBean]
    print(myBean performTask)
  }
}

The code can be found in this Github repository.

Advertisements

Java Swing Scrollbar

This is a quick demo on how to add a Java Swing scrollbar following the footpaths of this previous example if you need detailed explanation on the Swing construct so far.

Without further ado the code looks like so:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class SwingScrollBarDemo {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new MyFrame("Hello Swing World!");
            }
        });
    }
}

//Branching out of a JPanel to create our more complicated
//component which for now will only serve as a wrapper around
//JTextArea, with its own layout and its scrollable functionality
class MyTextComponent extends JPanel {

    //state of our custom text
    private final JTextArea text = new JTextArea();

    MyTextComponent(){
       //this component has a layout in its own right
       setLayout(new BorderLayout());
       add(getScrollable(), BorderLayout.CENTER);
    }

    //A fancy way to confine in a method the sole purpose
    //of this whole exercise: to wrap JTextArea around a
    //JScrollPane, serving when we are adding the
    //component into the panel
    private JScrollPane getScrollable(){
        //this is where the magic happens wrapping JScrollPane
        //around JTextArea
        return new JScrollPane(this.text);
    }

    void append(String text){
        this.text.append(text);
        this.text.append("\n");
    }
}

//Pay attention on that we are implementing ActionListener
//More comments to follow below on that
class MyFrame extends JFrame implements ActionListener {

    //state of the frame: a button and some text
    private final JButton button = new JButton("Click me!");
    private final MyTextComponent text = new MyTextComponent();

    MyFrame(String title){
        //boilerplate begins
        super(title);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(200,300);
        setLocationRelativeTo(null);
        //boilerplate ends

        //Setting an easy Layout that is positioning components based
        //on intuitive compass signs
        setLayout(new BorderLayout());

        //Pay attention that the class is implementing ActionListener
        //therefore the button is adding this to its action listener.
        //This practically means every time the button is clicked
        //the overriden actionPerformed method of this class will be
        //called and will append some text to the text component
        button.addActionListener(this);

        //Last but not least adding the two components into the
        //frame passing as well as a second parameter their
        //position inside the layout
        add(text, BorderLayout.CENTER);
        add(button, BorderLayout.SOUTH);
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
        //If we are here it's because the button was clicked
        //therefore it's time to do something exciting with the
        //text component
        text.append("Button Clicked!");
    }
}
  • All we are doing in this example following incrementally this previous example so far (you can follow the comments if you want to skip reading the article) is to add a separate class to wrap around a JTextArea component.
  • The sole state of the new class is the JTextArea and in its constructor includes a separate BorderLayout. Before adding the JTextArea into its own layout it is wrapping it around JScrollPane which gives the effect of horizontal/vertical side scrolls effect into our text area inside of the broader frame.

Java Swing Components and Layout basic example

This is a basic example demonstrating a Swing frame with two components and a basic interaction between them.

You might also want to take a look at the bare minimum Swing app that is demonstrating all the boilerplate needed code demonstrated in this article.

The source code looks like this:


import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class BasicComponentsLayouts {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new InnerFrame("Hello Swing World!");
            }
        });
    }
}

//Pay attention on that we are implementing ActionListener
//More comments to follow below on that
class InnerFrame extends JFrame implements ActionListener {

    //state of the frame: a button and some text
    private JButton button = new JButton("Click me!");
    private JTextArea text = new JTextArea();

    InnerFrame(String title){
        //boilerplate begins
        super(title);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(200,300);
        setLocationRelativeTo(null);
        //boilerplate ends

        //Setting an easy Layout that is positioning components based
        //on intuitive compass signs
        setLayout(new BorderLayout());

        //Pay attention that the class is implementing ActionListener
        //therefore the button is adding this to its action listener.
        //This practically means every time the button is clicked
        //the overriden actionPerformed method of this class will be
        //called and will append some text to the text component
        button.addActionListener(this);

        //Last but not least adding the two components into the
        //frame passing as well as a second parameter their
        //position inside the layout
        add(text, BorderLayout.NORTH);
        add(button, BorderLayout.SOUTH);
    }

    @Override
    public void actionPerformed(ActionEvent actionEvent) {
       //If we are here it's because the button was clicked
       //therefore it's time to do something exciting with the
       //text component
       text.append("Button Clicked!");
       text.append("\n");
    }
}

Some comments:

  • This time we have a state in our frame, namely a button and a text area
  • Pay attention that our JFrame child is implementing ActionListener. This interface brings us the actionPerformed() overriden method that fires when this frame is used as a listener somewhere.
  • Other than the ceremonial code of frame visibility etc we have the setLayout() method where we define a nice basic BorderLayout(). For more information on layouts please have a look at this useful link.
  • Next stop is where we are adding our frame using its identity as ActionListener (we are implementing this interface remember?) to the button component. This effectively means that when the button gets clicked the ActionListener overriden method will fire.
  • Last piece of the puzzle before the end of the frame constructor and effectively completing the initialisation it’s the addition of both components to the frame using BorderLayout compass points depicted through static intuitive fields.
  • Finally we have the sole method of ActionListener which gets overriden in the Frame child class where we are not using its parameter but rather grabbing the text field (part of the frame state remember?) and appending a basic message that will reflect in a text string every time the listener gets invoked.

Java Swing basic example

This is the bare minimum that we need in order to have a Java Swing application up and running.

The code looks like this:

import javax.swing.*;

public class BasicFirstExample {

    public static void  main(String ... args){
        //Avoiding threading issues by invoking the frame through an anonymous
        //inner class via the static Swing Utilities method as follows
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                //Initialization the frame with a title as parameter
                //in the constructor
                JFrame myFirstFrame = new JFrame("Hello Frame World!");
                
                //Here comes the boilerplate code:
                
                //Setting the frame as visible. If it was not there
                //we wouldn't see the frame
                myFirstFrame.setVisible(true);
                //Setting the close-down of the application upon clicking the
                //close button in the swing frame. If it was not there, the JVM
                //would be holding on there even after closing down the swing through the button
                myFirstFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                //Setting the size of the frame according to our needs. If this
                //wasn't there the default width is non-existant and the length barely visible
                //for a couple of chars of title
                myFirstFrame.setSize(200,100);
                //Setting the default position of the frame in the center of the screen.
                //If that wasn't there it will be initialized at the top left of the screen
                myFirstFrame.setLocationRelativeTo(null);
            }
        });
    }
}

Things to note:

  • We are first creating a JFrame instance call the constructor with a String as a parameter representing it’s title bar inscription.
  • We are are then calling setVisible(true) on the instance because surprisingly enough by default the visibility is set to false then non-visible.
  • We are then setting setDefaultCloseOperation() method because if we are not then after we close the little swing app from the close button the java application will still remain alive and running although counter-intuitive.
  • We are then setting setSize() because the default values are barely living any space for the title and almost non width space.
  • We are then calling setLocalisationRelativeTo() because otherwise our little Swing app will reside on the top left corner of our screen by default. Calling this method with null parameter will initialise it in the center of the screen.
  • All of the above are found in the body of an anonymous inner Runnable#run() call that is passed as a parameter inside the static SwingUtilities#invokeLater() method as per the suggestions of Sun in order for us not to run into unwanted exceptions following the rule of thumb of not setting state to components from within threads we are instantiating.

Performing a bit of housekeeping, namely including all the JFrame specific actions on a separate child class we could deduce the clutter inside the Runnable#run() method and extract it on the constructor of the child JFrame class. Besides all these actions we’ve seen (setting visibility, setting size, setting exit on close, setting relative position) are integral parts of the initialization of the frame and this makes total sense to include them within the constructor:

import javax.swing.*;

public class BasicFirstExample2 {

    public static void main(String ... args) {
         SwingUtilities.invokeLater(new Runnable() {
             @Override
             public void run() {
                 new MyFrame("Hello Frame World!");
             }
         });
    }

}

class MyFrame extends JFrame{

    MyFrame(String title) {
        super(title);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(200,100);
        setLocationRelativeTo(null);
    }
}