Deploy your Java Application with IzPack Installer

Posted by admin | Posted in Code Snippets, General Programming | Posted on 06-02-2010

1

This is a short tutorial on how to create simple IzPack based installation solution on windows platform with all standard features like: desktop shortcut, start menu item shortcut, copying libraries, folders, documentation into one of the ProgramFiles folder on the windows machine.
I had some problems creating windows shortcuts mysefl and I wanted to share the experience so other people can find it quicker.
Here you go.


1. First download and install IzPack itself from: izpack website

2. Prepare the application you want to make installable, I use Netbeans to build most of my Java apps, but I guess for all other ide’s the results after all are the same, we end up with SomeApp.jar file and a bunch of libraries we used to build it.
On the Netbeans platform all the files needed to launch the application we have build end up in ‘dist’ folder as a subfolder of our project main folder. If you have used any libraries to build your desktop application they will be included in the lib folder (yourproject/dist/lib/).

3. Now, once we have all the main ingredients (our application and installer) we need to connect it together. Create the folder anywhere on your machine, and call it for example ’softwarepassion’.

4. Put your jar file together with the ‘lib’ folder into the ’softwarepassion’ catalog.

5. Now we need to add some native libraries for Izpack to be able to add windows shortcuts on the desktop and start menu. Create ‘bin’ folder under the ’softwarepassion’ folder and copy whole ‘native’ content found in your izpack installation into the ‘bin’ folder of your root ’softwarepassion’ catalog.
You can find the native folder inside your IzPack installation directory, normally under: ‘C:\Program Files\IzPack\bin’

6. Create your application icon file and add it to your ’softwarepasison’ catalog. I call mine ‘exe.ico’.

7. Now comes the hardest part to get initially but after you build your first installer it all gets clear and easy :)
We need to prepare two separate xml files: one called ‘install.xml’ and another one called ’shortcutSpec.xml’.

The content of both example files is listed below:

<?xml version="1.0" encoding="iso-8859-1" standalone="yes" ?>

<!--
   A sample installation file.
   Use it as a base for your own installers :-)
   
   To compile it :
   - go in the bin directory where you installed IzPack
   - call "compile ../sample/install.xml -b ../sample"
-->

<installation version="1.0">

    <!--
       The info section.
       The meaning of the tags should be natural ...
   -->
    <info>
        <appname>SoftwarePassion Application</appname>
        <appversion>1.0</appversion>
        <authors>
            <author name="Softberries Krzysztof Grajek" email="customer.service@softberries.com"/>
        </authors>
        <url>http://www.softwarepassion.com/</url>
    </info>

    <!--
       The gui preferences indication.
       Sets the installer window to 640x480. It will not be able to change the size.
   -->
    <guiprefs width="640" height="480" resizable="yes"/>
    <variables>
        <variable name="DesktopShortcutCheckboxEnabled" value="true"/>
    </variables>
    <!--
       The locale section.
       Asks here to include the English and French langpacks.
   -->
    <locale>
        <langpack iso3="pol"/>
        <langpack iso3="eng"/>
    </locale>

    <!--
       The resources section.
       The ids must be these ones if you want to use the LicencePanel and/or the InfoPanel.
   -->
    <resources>
        <res src="shortcutSpec.xml" id="shortcutSpec.xml"/>
        <res id="LicencePanel.licence" src="Licence.txt"/>
        <res id="InfoPanel.info" src="Readme.txt"/>
    </resources>

    <!--
       The panels section.
       We indicate here which panels we want to use. The order will be respected.
   -->
    <panels>
        <panel classname="HelloPanel"/>
        <panel classname="LicencePanel"/>
        <panel classname="TargetPanel"/>
        <panel classname="PacksPanel"/>
        <panel classname="InstallPanel"/>
        <panel classname="ShortcutPanel"/>
        <panel classname="FinishPanel"/>
    </panels>

    <!--
       The packs section.
       We specify here our packs.
   -->
    <packs>
        <pack name="Base" required="yes">
            <description>The base files</description>
            <file src="Readme.txt" targetdir="$INSTALL_PATH"/>
            <file src="Licence.txt" targetdir="$INSTALL_PATH"/>
            <file src="exe.ico" targetdir="$INSTALL_PATH"/>
            <file src="SoftwarePassionHelloIzPack.jar" targetdir="$INSTALL_PATH"/>
            <fileset dir="lib" targetdir="$INSTALL_PATH\lib">
                <include name="**"/>
            </fileset>
        </pack>
    </packs>
    <native type="izpack" name="ShellLink.dll"/>
    <native type="3rdparty" name="COIOSHelper.dll" stage="both">
        <os family="windows"/>
    </native>
</installation>

And the one for windows shortcuts:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>

<shortcuts>

    <skipIfNotSupported/>

    <programGroup defaultName="Siemens AWORT" location="applications"/>

      <shortcut
        name="SoftwarePassion Application"
        programGroup="yes"
        desktop="yes"
        applications="no"
        startMenu="yes"
        startup="no"
        target="$INSTALL_PATH\SoftwarePassionHelloIzPack.jar"
        commandLine=""
        description="Software Passion Example App"
        iconFile="$INSTALL_PATH\exe.ico"
        iconIndex="0"
        initialState="noShow">

         <createForPack name="Base"/>

       </shortcut>
 

    <shortcut
           name="Software Passion Example App Uninstaller"
           programGroup="yes"
           desktop="no"
           applications="no"
           startMenu="no"
           startup="no"
           target="$INSTALL_PATH\Uninstaller\uninstaller.jar"
           commandLine=""
           iconFile="%SystemRoot%\system32\SHELL32.dll"
           iconIndex="31"
           description="Uninstall SoftwarePassion Example">

        <createForPack name="Base"/>
    </shortcut>

</shortcuts>

8. Example installation script contains both Readme.txt and Licence.txt which you can add to your ’softwarepassion’ folder.
9. Once you have it all in one place, you should have a structure like in the following screenshot:

izpack_directory

10. Now assuming that your ’softwarepassion’ folder has been placed directly on the c: drive, execute the following command:

C:\Program Files\IzPack\bin>compile c:\softwarepassion\install.xml -b c:\softwarepassion

Assuming that IzPack itself was installed at: C:\Program Files\IzPack

This will produce install.jar file which is your installer.

11. If you dont’ want your end users to click on the ‘jar’ file as not everybody knows they can do that, you can add Izpack launcher app which will launch it automatically, or use another tool to create an executable called launch4j

You have to admit that it was an easy one!!!!!

Happy Installing!


Download example files from here

Add ‘count #’ column to JTable

Posted by admin | Posted in Code Snippets, General Programming, Graphics And Design, Learning Materials | Posted on 05-02-2010

0

Important note first: This is mostly not my code, I was strugling with this problem for some time, I couldn’t google it at all, and one day, I’ve just found it. Now I use it in one of my projects but I cannot find the original post again, therefore I have decided to post it on my blog (slightly modified version of the original) so other people with similar problem will have a better chance of finding the solution.
So, the idea is very simple. The whole point of displaying additional column which is kind of independent from the other columns is to simply use another table. This way you can sort one table by column and the number column will not sort with it. – thats exactly what I was looking for and I guess its kind of popular problem.
Becouse you put two tables in one scroll pane the gui looks like its just one column!


I have created one simple method to apply this technique to any tables in my application (I use JXTable actually but JTable will do as well)

private void addLPColumn(JXTable table, JScrollPane scp){
        JTable rowTable = new RowNumberTable(table);
        scp.setRowHeaderView(rowTable);
        scp.setCorner(JScrollPane.UPPER_LEFT_CORNER, rowTable.getTableHeader());
        scp.repaint();
    }


RowNumberTable is simple one column table displaying the ‘count’ number of rows in the second table.


public class RowNumberTable extends JTable
    implements ChangeListener, PropertyChangeListener
{
    private JTable main;

    public RowNumberTable(JTable table)
    {
        main = table;
        main.addPropertyChangeListener( this );

        setFocusable( false );
        setAutoCreateColumnsFromModel( false );
        setModel( main.getModel() );
        setSelectionModel( main.getSelectionModel() );

        TableColumn column = new TableColumn();
        column.setHeaderValue("Lp.");
        addColumn( column );
        column.setCellRenderer(new RowNumberRenderer());

        getColumnModel().getColumn(0).setPreferredWidth(40);
        setPreferredScrollableViewportSize(getPreferredSize());
    }

    @Override
    public void addNotify()
    {
        super.addNotify();

        Component c = getParent();

        //  Keep scrolling of the row table in sync with the main table.

        if (c instanceof JViewport)
        {
            JViewport viewport = (JViewport)c;
            viewport.addChangeListener( this );
        }
    }

    /*
     *  Delegate method to main table
     */

    @Override
    public int getRowCount()
    {
            if(main != null)
                return main.getRowCount();
            else
                return 0;
    }

    @Override
    public int getRowHeight(int row)
    {
        return main.getRowHeight(row);
    }

    /*
     *  This table does not use any data from the main TableModel,
     *  so just return a value based on the row parameter.
     */

    @Override
    public Object getValueAt(int row, int column)
    {
        return Integer.toString(row + 1);
    }

    /*
     *  Don't edit data in the main TableModel by mistake
     */

    @Override
    public boolean isCellEditable(int row, int column)
    {
        return false;
    }
//
//  Implement the ChangeListener
//
    public void stateChanged(ChangeEvent e)
    {
        //  Keep the scrolling of the row table in sync with main table

        JViewport viewport = (JViewport) e.getSource();
        JScrollPane scrollPane = (JScrollPane)viewport.getParent();
        scrollPane.getVerticalScrollBar().setValue(viewport.getViewPosition().y);
    }
//
//  Implement the PropertyChangeListener
//
    public void propertyChange(PropertyChangeEvent e)
    {
        //  Keep the row table in sync with the main table

        if ("selectionModel".equals(e.getPropertyName()))
        {
            setSelectionModel( main.getSelectionModel() );
        }

        if ("model".equals(e.getPropertyName()))
        {
            setModel( main.getModel() );
        }
    }

    /*
     *  Borrow the renderer from JDK1.4.2 table header
     */

    private static class RowNumberRenderer extends DefaultTableCellRenderer
    {
        public RowNumberRenderer()
        {
            setHorizontalAlignment(JLabel.CENTER);
        }

        public Component getTableCellRendererComponent(
            JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
        {
            if (table != null)
            {
                JTableHeader header = table.getTableHeader();

                if (header != null)
                {
                    setForeground(header.getForeground());
                    setBackground(header.getBackground());
                    setFont(header.getFont());
                }
            }

            if (isSelected)
            {
                setFont( getFont().deriveFont(Font.BOLD) );
            }

            setText((value == null) ? "" : value.toString());
            setBorder(UIManager.getBorder("TableHeader.cellBorder"));

            return this;
        }
    }
}

count_jtable_column

In my case the ‘count’ column is called ‘Lp.’ – in polish



I have created one simple method to apply this technique to any tables in my application (I use JXTable actually but JTable will do as well)

private void addLPColumn(JXTable table, JScrollPane scp){
        JTable rowTable = new RowNumberTable(table);
        scp.setRowHeaderView(rowTable);
        scp.setCorner(JScrollPane.UPPER_LEFT_CORNER, rowTable.getTableHeader());
        scp.repaint();
    }


JXTable and primary key – how to.

Posted by admin | Posted in General Programming | Posted on 07-12-2009

0

swinglabs
Today I will describe in a few words and a couple lines of code how to get the id of the row in JXTable. When working with data coming from database we don’t really want to display the primary key of the object but to hide it. This can cause a small problem once we want to find out for example which item was clicked, ok we can easily find out which row it was but its not always easy to find out which actual object it was especially when using JXTable sorting capabilities.
The whole trick is to get the the corresponding object from the model and not from the view.
Here is a short code snippet to do just that, hope that helps everyone who uses great JXTable component to display some data.

private int getObjectID(JXTable table) {
        int rowx = table.getSelectedRow();
        int resultx = 0;
        if (rowx < 0) {
            return 0;
        }
        resultx = table.convertRowIndexToModel(rowx);
        int id = (Integer) table.getModel().getValueAt(resultx, 0);
        return id;
    }

This works of course assuming that your object index is set as first column in your model (position 0).

Small Web Design Inspiration Set

Posted by admin | Posted in Graphics And Design | Posted on 01-12-2009

0

flickr
This is a small set of links I’ve found pointing to some collections of web page screenshots which you can use for your web design inspiration. I have found it very usefull and I hope you will find it usefull too. If you know some more which are not listed here please share using comments section.

  1. Patrick Haney
  2. Patrick Haney’s Group Pool
  3. Design inspiration via LittleSnapper by Elliot
  4. Web Design Patterns by FactoryJoe
  5. 50 Websites (and More) for Your Design Inspiration from Vandelay Design
  6. 30 More Portfolio Sites for Your Design Inspiration from Designm.ag
  7. Interface Design Inspiration – 36 Clean Comment Form designs
  8. 40 Textured Websites for Design Inspiration from Designm.ag

Have fun!