Search

Children are cool...

Children are cool...
Ireland Rugby

Monday, November 23, 2009

Simple JavaServerFaces (JSF) Reference Example - Table

In the world of modern Integrated Development Environments (IDE)s, we have become accustomed to visual development, or at least code completion. We have also come to rely on advanced JSF frameworks like Woodstock, ICEFaces, myFaces, etc. A couple of weeks ago someone asked me about how to create a JSF page including a table, and how to "bind" the values to the table. That person did not have access to an advanced framework, and wanted to use a reference implementation. I created a simple NetBeans project which included only the reference implementation. I forgot how strange it is to code everything. A lot of the modern components have taken the complexity of creating the components out of your hands.

Below is an example application which uses the reference implementation only.



JSFRIDemo-1.0.zip

Saturday, November 21, 2009

Swing Event Examples - JButton and JRadioButton

I was looking at some code examples I created, and decided to polish them up and post them. One of the most challenging issues for most Swing developers is learning, and using events. I have included to examples below: One using events associated with a JButton, and the other using ActionEvents when a JRadioButton is pressed.

Note: The attached project is a NetBeans 6.5.1 project.

Here is the JButtonsEvent.java example

/*
* Copyright 2009 John Yeary <jyeary@bluelotussoftware.com>.

*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*

* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and
* limitations under the License.
* under the License.
*/

/**
* JButtonEvents.java

*
* Created on Dec 30, 2008, 3:00:00 PM
*

* $Id: JButtonEvents.java 155 2009-11-21 15:06:40Z jyeary $
*/

package com.bluelotussoftware.examples.swing;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JButton;

import javax.swing.JFrame;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
*
* @author John Yeary <jyeary@bluelotussoftware.com>

* @version 1.0
*/
public class JButtonEvents extends javax.swing.JFrame {

JButton button;

public JButtonEvents() {
initialize();
}

private void initialize() {
button = new JButton("Press Me");

//Add Listeners as anonymous inner classes.

button.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {
System.out.println("ActionEvent!");
}
});

button.addItemListener(new ItemListener() {

public void itemStateChanged(ItemEvent e) {
System.out.println("ItemEvent!");
}
});

button.addChangeListener(new ChangeListener() {

public void stateChanged(ChangeEvent e) {
System.out.println("ChangeEvent!");
}
});


// Exit the application when the frame is closed

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(button);
this.pack();
}

/**
* @param args the command line arguments

*/
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {

public void run() {
new JButtonEvents().setVisible(true);
}
});
}
}

Here is the JRadioButtonActionEvents.java example

/*
* Copyright 2008-2009 John Yeary <jyeary@bluelotussoftware.com>.

*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*

* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and
* limitations under the License.
* under the License.
*/

/*
* JRadioButtonActionEvents.java

*
* Created on Dec 30, 2008, 3:45:09 PM
*
* $Id: JRadioButtonActionEvents.java 155 2009-11-21 15:06:40Z jyeary $
*/
package com.bluelotussoftware.examples.swing;


import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Enumeration;
import javax.swing.ButtonModel;
import javax.swing.JRadioButton;

/**

*
* @author John Yeary <jyeary@bluelotussoftware.com>
* @version 1.0

*/
public class JRadioButtonActionEvents extends javax.swing.JFrame {

/** Creates new form JRadioButtonActionEvents */

public JRadioButtonActionEvents() {
initComponents();

int value = 0;
ButtonModel[] models = new ButtonModel[3];
int ctr = 0;
Enumeration e = buttonGroup1.getElements();

while (e.hasMoreElements()) {
JRadioButton x = (JRadioButton) e.nextElement();
models[ctr++] = x.getModel();

}
jRadioButton1.setActionCommand("A");
jRadioButton2.setActionCommand("B");
jRadioButton3.setActionCommand("C");
ActionListener action = new MyActionListener();
jRadioButton1.addActionListener(action);
jRadioButton2.addActionListener(action);
jRadioButton3.addActionListener(action);
buttonGroup1.setSelected(models[value], true);
}

class MyActionListener implements ActionListener {

public void actionPerformed(ActionEvent e) {
String s = e.getActionCommand();

if ("A".equalsIgnoreCase(s)) {
System.out.println("Radio Button \"A\" ActionEvent!");
} else if ("B".equalsIgnoreCase(s)) {
System.out.println("Radio Button \"B\" ActionEvent!");
} else if ("C".equalsIgnoreCase(s)) {
System.out.println("Radio Button \"C\" ActionEvent!");
}
}
}

/** This method is called from within the constructor to

* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is

* always regenerated by the Form Editor.
*/

@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

buttonGroup1 = new javax.swing.ButtonGroup();
jRadioButton1 = new javax.swing.JRadioButton();
jRadioButton2 = new javax.swing.JRadioButton();
jRadioButton3 = new javax.swing.JRadioButton();
jLabel1 = new javax.swing.JLabel();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

buttonGroup1.add(jRadioButton1);
jRadioButton1.setText("A");

buttonGroup1.add(jRadioButton2);
jRadioButton2.setText("B");

buttonGroup1.add(jRadioButton3);
jRadioButton3.setText("C");

jLabel1.setText("Select a radio button to generate an ActionEvent");

org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.addContainerGap()
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jLabel1)
.add(layout.createSequentialGroup()
.add(21, 21, 21)
.add(jRadioButton1)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(jRadioButton2)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(jRadioButton3)))
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.add(jLabel1)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
.add(jRadioButton1)
.add(jRadioButton2)
.add(jRadioButton3))
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);

pack();
}// </editor-fold>

/**
* @param args the command line arguments

*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {

public void run() {
new JRadioButtonActionEvents().setVisible(true);
}
});
}

// Variables declaration - do not modify

private javax.swing.ButtonGroup buttonGroup1;
private javax.swing.JLabel jLabel1;
private javax.swing.JRadioButton jRadioButton1;
private javax.swing.JRadioButton jRadioButton2;
private javax.swing.JRadioButton jRadioButton3;
// End of variables declaration
}

NetBeans project files SwingEventsExamples-1.0.zip

Monday, November 02, 2009

Woodstock and Facelets

I have been asked if there is an example of how to use facelets. In this example application, I have changed the default namespace in my NetBeans project to w from webuijsf to make it simpler to see. In this example I display the customers from the sample database which is part of the default installation of NetBeans.

Here is what it looks like displayed:



Here is the facelets view:

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:w="http://www.sun.com/webui/webuijsf"
>
<body>

<ui:composition template="/template-client.xhtml">

<ui:define name="title">
Customers
</ui:define>

<ui:define name="body">
<w:head id="head1">
<w:link id="link1" url="/resources/stylesheet.css"/>
</w:head>
<w:body id="body1" style="-rave-layout: grid">
<w:form id="form1">
<w:table augmentTitle="false" id="table1" style="position: absolute; left: 48px; top: 48px" title="Table" width="0">
<w:tableRowGroup id="tableRowGroup1" rows="10" sourceData="#{CustomerBean.customerDataProvider}" sourceVar="currentRow">
<w:tableColumn headerText="CUSTOMER_ID" id="tableColumn1" sort="CUSTOMER.CUSTOMER_ID">
<w:staticText id="staticText1" text="#{currentRow.value['CUSTOMER.CUSTOMER_ID']}"/>
</w:tableColumn>
<w:tableColumn headerText="DISCOUNT_CODE" id="tableColumn2" sort="CUSTOMER.DISCOUNT_CODE">
<w:staticText id="staticText2" text="#{currentRow.value['CUSTOMER.DISCOUNT_CODE']}"/>
</w:tableColumn>
<w:tableColumn headerText="ZIP" id="tableColumn3" sort="CUSTOMER.ZIP">
<w:staticText id="staticText3" text="#{currentRow.value['CUSTOMER.ZIP']}"/>
</w:tableColumn>
<w:tableColumn headerText="NAME" id="tableColumn4" sort="CUSTOMER.NAME">
<w:staticText id="staticText4" text="#{currentRow.value['CUSTOMER.NAME']}"/>
</w:tableColumn>
<w:tableColumn headerText="ADDRESSLINE1" id="tableColumn5" sort="CUSTOMER.ADDRESSLINE1">
<w:staticText id="staticText5" text="#{currentRow.value['CUSTOMER.ADDRESSLINE1']}"/>
</w:tableColumn>
<w:tableColumn headerText="ADDRESSLINE2" id="tableColumn6" sort="CUSTOMER.ADDRESSLINE2">
<w:staticText id="staticText6" text="#{currentRow.value['CUSTOMER.ADDRESSLINE2']}"/>
</w:tableColumn>
<w:tableColumn headerText="CITY" id="tableColumn7" sort="CUSTOMER.CITY">
<w:staticText id="staticText7" text="#{currentRow.value['CUSTOMER.CITY']}"/>
</w:tableColumn>
<w:tableColumn headerText="STATE" id="tableColumn8" sort="CUSTOMER.STATE">
<w:staticText id="staticText8" text="#{currentRow.value['CUSTOMER.STATE']}"/>
</w:tableColumn>
<w:tableColumn headerText="PHONE" id="tableColumn9" sort="CUSTOMER.PHONE">
<w:staticText id="staticText9" text="#{currentRow.value['CUSTOMER.PHONE']}"/>
</w:tableColumn>
<w:tableColumn headerText="FAX" id="tableColumn10" sort="CUSTOMER.FAX">
<w:staticText id="staticText10" text="#{currentRow.value['CUSTOMER.FAX']}"/>
</w:tableColumn>
<w:tableColumn headerText="EMAIL" id="tableColumn11" sort="CUSTOMER.EMAIL">
<w:staticText id="staticText11" text="#{currentRow.value['CUSTOMER.EMAIL']}"/>
</w:tableColumn>
<w:tableColumn headerText="CREDIT_LIMIT" id="tableColumn12" sort="CUSTOMER.CREDIT_LIMIT">
<w:staticText id="staticText12" text="#{currentRow.value['CUSTOMER.CREDIT_LIMIT']}"/>
</w:tableColumn>
</w:tableRowGroup>
</w:table>
</w:form>
</w:body>
</ui:define>

</ui:composition>

</body>
</html>

Here is the source code: WoodstockFaceletsExample.zip

Friday, September 11, 2009

Using JTabbedPane on Swing Application Framework (JSR-296)

I was trying to figure out how to set the selected tab for a multi-tab JTabbedPane on my Swing Application Framework application. I thought that a quick Google search would have a simple answer. This was not the case. I found a post on a forum where a number of other people were wondering how to do it. So here is a summary of how I did it.

On the Frameview, I added a method as show below:

public void setSelectedTab (Integer tabIndex) {
tabPanel.setSelectedIndex(tabIndex);
}


The tabPanel in my case is the JTabbedPane instance.

In the SingleFrameApplication, I modified the startup() method to display the tab I want.

Note: You must set it after a call to show() the FrameView

@Override
protected void startup() {
FrameViewImpl frameView = new FrameViewImpl(this);
show(frameView);
//This must be done after the GUI is displayed
frameView.setSelectedTab(0);
}

Thursday, September 10, 2009

Beans Binding Part Deux

I have really enjoyed using the Beans Binding Framework (JSR-295) in the past. It was a really good start to making Swing a more usable platform doing client development. The project and JSR have been left abandoned by Sun. In large measure this was the result of development work done by Sun on JavaFX.

The really painful part of JavaFX currently is based on two items:
  1. No table (grid) component.
  2. No data providers to make binding to a database easy.
The result is a nearly useless framework for business developers who don't need shiny new baubles. I need Swing to work.

I am not the only person who feels this way. Fabrizio Giudici has created a project on Kenai.com to address the shortcomings: Better Beans Binding. He took the original JSR-295 code and forked it to create the new project. The package names have remained the same to allow a drop in replacement for the current beans binding framework without breaking anything. I am excited that Fabrizio has decided to do this project. I am hopeful that others wil join the project and make "better beans binding" a reality for the business users and others who need to make Swing just work.

Tuesday, September 08, 2009

OpenSolaris 2009.06 Update

Today I performed an update of my OpenSolaris 2009.06. It went perfectly. It is fascinating that I performed the update which also included a new boot environment without a hitch.

I performed a similar update to my MacBook Pro with OS X Snow Leopard, and was a lot less successful. In the Snow Leopard update, a number of my Java applications do not work now because Apple changed the packages (not names) of the GUI components. Also, the WiFi would not work. Since the introduction of the iPhone, Apple has lost some of its edge on OS X development. Don't get me wrong, I have an iPhone and love it, but Apple seems to spend more time on its development rather than core OS. I state this in spite of the claims its focus for 10.6.

Wednesday, August 26, 2009

Redmine 0.8.4 Deployment on GlassFish 2.1 using JRuby 1.3.1

Introduction

In this tutorial I will explain how to install Redmine 0.8.4 on GlassFish 2.1 using JRuby 1.3.1 with MySQL.

Required Software

  • Redmine 0.8.4

  • GlassFish 2.1

  • NetBeans 6.7

  • MySQL 5.1

Instructions


  1. First we will need to download and install JRuby 1.3.1. The binaries can be found on the Kenai site.

  2. Make sure that your PATH is set to point to your JRuby installation. You can check your install by typing jruby -v at the command prompt. You should see something similar to the listing below.
    dev:~ jyeary$ jruby -v
    jruby 1.3.1 (ruby 1.8.6p287) (2009-06-15 2fd6c3d) (Java HotSpot(TM) 64-Bit Server VM 1.6.0_15) [x86_64-java]

  3. Run from the command line
    jruby -S gem update
    This will update all of the gems required to run our application.

  4. Run from the command line
    jruby -S gem install jruby-openssl rails mongrel jdbc-mysql activerecord-jdbcmysql-adapter warbler
    This will install all of the gems required to run our application.

  5. Download a copy of Redmine 0.8.4 and unzip it.

  6. Using NetBeans 6.7.1, check the Tools --> Ruby Platform Manager to make sure that you install the JRuby 1.3.1 platform.



  7. In NetBeans, create a new Ruby on Rails Application with Existing Sources. Next



  8. Select the unzipped RoR Redmine application as the project folder.

  9. Select the JRuby 1.3.1 Platform from the combo-box menu.

  10. Select Mongrel for the server from the combo-box menu. Click Finish. NetBeans will create the RoR project and install Warbler which will create our war file for deployment on GlassFish.



  11. We are now ready to configure the application. Follow the instructions for configuring the application here.

  12. In the redmine-0.8.4 directory run the following command
    jruby -S warble config
    This will create the configuration file for warbler to build our war file for deployment on GlassFish.

  13. Edit the warble.rb file and modify the config.dirs line to the following:
    config.dirs = %w(app config lib log vendor tmp files lang)
    This will make sure that we deploy all of the application relevant files in our war file.

  14. Edit the warble.rb file and add the following line:
    config.gems = ["activerecord-jdbcmysql-adapter"]
    This will make sure that when we convert the application to a war file that the appropriate ActiveRecord JDBC drivers for MySQL are added to it.

  15. Run the application to make sure that it runs correctly on Mongrel.

  16. Run the following commands to create the war file
    jruby -S rake war:clean
    jruby -S rake war



  17. Go to the Administrative Console on GlassFish. Select Web Applications and deploy the new redmine-0.8.4.war file.




Saturday, July 04, 2009

Woodstock Dropdown List Binding Examples

I am spending the morning answering a number of questions posted to the nbj2ee list. One of the questions was how to add separators to to drop down lists. I decided to write a little code example to show how this is done.

The idea is to retrieve the data values from a database. In this case, I use a built in travel database from NetBeans.

There are two examples. The first one is a simple database binding, and the second uses the Option class to control the output.

The Option class allows us to insert any "filler" into the items we display in the list. Here is the code.
    public Option[] getOptions() {
List<Option> options = new ArrayList<Option>();
personDataProvider.cursorFirst();
Option firstOption = new Option(personDataProvider.getValue("PERSON.PERSONID"), (String) personDataProvider.getValue("PERSON.NAME"));
options.add(firstOption);
Option filler = new Option(99999, "----------");
options.add(filler);
while (personDataProvider.cursorNext()) {
Option option = new Option(personDataProvider.getValue("PERSON.PERSONID"), (String) personDataProvider.getValue("PERSON.NAME"));
options.add(option);
}
return options.toArray(new Option[options.size()]);
}
Here is the source code DropDownListExample. The example was created using NetBeans 6.5.1 and Visual JSF plugin.

Wednesday, June 10, 2009

Suggestions for IT Professionals in a Down Economy

I just read an article from Computer World about how to remain positive in a down economy. I found the article to be spot on.

The first item was going back to your roots and doing the things that attracted you to a career in IT. I agree. If you are not doing something you love now, go back and reflect on why. Perhaps it is learning something new, or fixing something old. Get the flame back.

The second item referred to social networking. I am on Linked-In, Twitter, Facebook, Plaxo, etc. I know a number of people who have made this their personal addictions. I have not become addicted to it, but I find a lot of value. The ability to connect with friends, colleagues (current and former), peers, and associates is truly satisfying. It can help you in many ways, as long as, you are careful not to post anything that you would not be proud to show your mother.

They mention getting out into the real world. I would agree. I recommend joining your local user groups (Java Users Group), and attend free conferences like the Southeast Linux Fest. These groups are your peers, and contacts to potential jobs. Conferences can enhance your technical skills, and allow you to meet like minded individuals. It also can expose you to new technologies to make your IT life better.

The article also mentions getting technical certifications. I could not agree more. Here again, your local technical user group may be able to help by offering courses, certification boot camps, or technical deep dives. You can also enhance your knowledge by offering to give talks. You will really learn how much of a subject matter expert you are based on the questions the attendees ask.

Monday, May 04, 2009

How to Convert a File to a Byte Array

I wrote an EJB which performs faxing using gnu-hylafax for Java. The trick is that I needed to convert the file to bytes[] to pass to the EJB. Here is how I did it, but it should work for most files.


/**
* Converts a file into a byte[] array.
* @param file file to be converted
* @return file converted to {@code byte[]}
* @throws java.io.IOException
*/
public static byte[] getBytesFromFile(final File file) throws IOException {
InputStream is = new FileInputStream(file);

// Get the size of the file
long length = file.length();

if (length > Integer.MAX_VALUE) {
/* File is too large. If we are trying to determine the length of the byte[]
* array, it can only return an int, so we are limited by the file size.
*/
throw new IOException(file.getName() + " is too large.");
}

// Create the byte array to hold the data
byte[] data = new byte[(int) length];

// Read in the bytes
int offset = 0;
int bytesRead = 0;
while (offset < data.length &&
(bytesRead = is.read(data, offset, data.length - offset)) >= 0) {
offset += bytesRead;
}

// Ensure all the bytes have been read in
if (offset < data.length) {
throw new IOException("An exception occurred while trying to read + "
+ file.getName() + " into the byte array.");
}

// Close the input stream and return bytes
is.close();
return data;
}
}