Eclipse 3.1 RC3
Eclipse.org has released the Eclipse 3.1 RC3 development environment for all platforms. The environment seems to be getting quicker and more stable with each RC release at this point.
Eclipse.org has released the Eclipse 3.1 RC3 development environment for all platforms. The environment seems to be getting quicker and more stable with each RC release at this point.
Posted by
Kerry
at
10:06 PM
0
comments
God took one of his children home tonight. My father's sister, Lillian Parker, was taken to be with God tonight. She had a really bad heart attack Saturday and was put in the hospital.
My parents went to see her earlier today. My mother said that she looked quite bad with only about 20% functionality in her heart. My father called just a little while ago to give me the news and said that he knew it was just a matter of time earlier today, because she seemed to be just holding on... just like her mother did so many years ago when I was young.
My aunt was a life long member of Harmony Baptist Church in a small, unincorporated area of Blount county in Alabama. She always laughed and smiled when I saw her. Her laugh was always infectious. She was definitely a special lady.
Please pray for my family in this time of mourning, but please do not shed a tear, for she is in no longer suffering and she is much happier than we could ever be, because she is laughing and singing with her mother, Jesus, and having a wonderful fellowship with God, The Father!
Posted by
Kerry
at
10:51 PM
0
comments
I recently started playing around with C++, partly because I wanted to work with a cross-platform language other than Java that I could use on my Windows based laptop and my PowerPC Mac. I have been a developer for 16+ years, but working with C++ has me feeling like I am a new programmer again.
I have been struggling with virtual methods, abstract classes, and templates. I am currently stuck on a situation where I have a pure abstract class defined that I want to use in a collection to represent one of three different derived classes, but I seem to be getting some compile errors where I use it.
At least I am not getting paid like a new developer again. I would go hungry. :)
Posted by
Kerry
at
8:56 AM
0
comments
I have been playing around with Swing tonight using JDK 1.5.0_02. I have found an issue where the setMinimumSize and setMaximumSize dimensions are not enforced on a JFrame. I wanted to keep a dialog from being resized smaller than a minimum bounds or larger than a maximum bounds. To do this, I originally used the following code in my application:
frame.setMinimumSize( new Dimension( 250, 200 ) ); frame.setMaximumSize( new Dimension( 325, 275 ) );Unfortunately, as I mentioned above, this does not prevent you from resizing the frame smaller or larger than the specified sizes. Of course, you could just decide to not allow any resizing of the frame. To do that, you could use this line of code in your application:
frame.setResizable( false );However, if you want to allow the user to resize a dialog, then this is not a viable alternative. I decided to create my own class derived from JFrame. This class takes a title as well as minimum and maximum dimensions. My constructor for the class looks like this:
private Dimension minimumSize;The initialize(): call does nothing more than make a call to addComponentListener on the frame. In this call, I create an anonymous ComponentAdapter class which overrides the componentResized method to handle the constraints on the frame. The code looks like this:
private Dimension maximumSize;
public MyJFrame( String title, Dimension minimumSize,
Dimension maximumSize ) throws HeadlessException
{
super( title );
this.minimumSize = minimumSize;
this.maximumSize = maximumSize;
initialize();
}
private void initialize() {This code is pretty straight forward. It grabs the current size constraints for the frame that fired the event. It then checks these constraints against the specified minimum and maximum dimensions. If the constraints on the frame are not met, the size of the frame is set explicitly, otherwise, the flow falls through and the frame is resized according to the size that the user has resized it.
this.addComponentListener( new ComponentAdapter() {
@Override
public void componentResized( ComponentEvent e ) {
MyJFrame frame = (MyJFrame) e.getSource();
int width = frame.getWidth();
int height = frame.getHeight();
boolean resize = false;
if ( width < minimumSize.getSize().width ) {
width = minimumSize.getSize().width;
resize = true;
}
else if ( width > maximumSize.getSize().width ) {
width = maximumSize.getSize().width;
resize = true;
}
if ( height < minimumSize.getSize().height ) {
height = minimumSize.getSize().height;
resize = true;
}
else if (height > maximumSize.getSize().height ) {
height = maximumSize.getSize().height;
resize = true;
}
if ( resize ) {
frame.setSize( width, height );
}
}
})
}
Posted by
Kerry
at
11:53 PM
0
comments
Eclipse Foundation has released the latest milestone build of Eclipse 3.1 for download. This version has quite a few bug fixes and some enhancements. One of the enhancements allows for plugins to be setup in JAR files instead of a directory structure.
I downloaded it today and set it up on my laptop. I then opened up the SWT application that I am currently working on at home and found that there appears to be an issue with SWT in this build. My classpath is setup correctly and the build works, but when the application launches, I get a NullReferenceException on a call to super.configureShell( shell ). This all works in Eclipse 3.1M5a. I am not sure what has changed, but I need to play around with it a little more to see what is going on.
One thing that I noticed with the new plugin setup is that the SWT DLL for Win32 is located in a totally different directory now. I think they have a little work to do on this new plugin strategy. Of course, that is why they call this beta software. It might not work for everything that you want to do.
Update: I worked with this some more tonight and it appears that there is definitely an issue with SWT in the latest milestone build. I would imagine that it might be in the swt-win32-3128.dll file, but of course, you should not bank on that information. I use milestone build M6 and pointed it ot the swt.jar and the swt-win32-3123.dll for milestone build M5a and my application works.
Posted by
Kerry
at
11:55 AM
1 comments
I started playing around with regular expressions this past week. I am going to use them in the personal project that I am working on to validate different user input data strings. I recently purchased a very good book from Apress called Regular Expression Recipes: A Problem-Solution Approach by Nathan A. Good. They have another book specifically for Java called Java Regular Expressions: Taming the java.util.regex Engine, but I did not know about it before I purchased the first book. It may have helped me with this problem. :)
Anyway, the book that I purchased has examples for Perl, Python, and shell scripting. Since it was the first example for each recipe, I picked off the regular expressions from the Perl code for the particulat items that I wanted to validate and used that in Java. I was dumbfounded when it did not work. As an example, I used a regular expression to validate an email address. The regular expression looked like this from the Perl example:
/^[-\w.]+@([A-z0-9][-A-z0-9]+\.)+[A-z]{2,4}$/I spent a couple of evenings after work at home on this problem before I finally figured it out. You should not use the starting and ending slash ("/") when using any regular expression in Java. Java's regular expression compiler apparently sees this as a literal character when it compiles the expression and the corresponding validation ends up failing. When I removed those slashes, the validation unit test past and things were grand!
Technorati Tags: Java, Perl, Regular Expressions, shell scripting
Posted by
Kerry
at
8:41 PM
0
comments
Whew! Did I get them all in there? I have been struggling lately with the Model-View-Controller pattern. Well, I haven't been struggling with the pattern itself as much as I had been struggling with how to implement it properly and create unit tests in an SWT/JFace application. Being new to MVC, one struggles with what should be in the controller and what should not. I was trying to put everything in the controller, but that is not always feasible.
In my case, I was unsure about the inherited methods from the JFace Window class, such as createContents(), initializeBounds(), etc. Well, those methods do not need to be in the controller, because there is no interaction with the model. These methods are strictly there to create and initialize the view. The methods that I ended up putting in the controller were only those that dealt with the view with respect to the model.
For instance, in my example application that I put together tonight to play around with this process, I have a Contact class (model), a setup dialog (view), and a controller class. The model contains nothing more than first, middle, and last name strings for this example. It is quite simple. The view is also simple in that it has three Label controls, three Text controls, and two Button controls (Print and Cancel).
My controller class ended up having the following methods:
public void onFirstNameChanged();The first three methods are called in the focusLost method for the FocusListener on the respective edit control for each component of the contact name. The onPrintClick method is called when I click on the Print button. It fires the print method on the view and does nothing more than print the contents of the model out to the console in this simple example. The onCancelClick method fires the close method on the view.
public void onMiddleNameChanged();
public void onLastNameChanged();
public void onPrintClick();
public void onCancelClick();
Technorati Tags: Java, JFace, JUnit, Martin Fowler, Model-View-Controller, Model-View-Presenter, MVC, patterns, SWT
Posted by
Kerry
at
12:32 AM
0
comments
I found what seems to be an issue with setting an jface.resource.ImageDescriptor for an jface.Action class. I have a few standard button bar images that I was going to use in my application. When I first set the image for the action, I thought I was doing something wrong. I set the image originally, like this:
public ExitAction() extends Action {Unfortunately, this produced a small red square on the button and on the menu item that the ExitAction was assigned to. I checked the image thinking it was corrupt, but all was well. After doing a little snooping, I found that you can also create an ImageDescriptor from a swt.graphics.Image. I changed the code to look like this:
public ExitAction() {
super( “E&xit@Ctrl+X“, ImageDescriptor.createFromFile( “images\\close.gif“ ) );
setToolTipText( “Exit Application“ );
}
}
public ExitAction() extends Action {This produces the desired results. I am not sure why the first way of setting the image for the action did not work, but every tutorial that I have gone through and even the code in Apress' The Definitive Guide to SWT and JFace do it like I did it in the first code fragment above.
public ExitAction() {
super( “E&xit@Ctrl+X“ );
setToolTipText( “Exit Application“ );
Image image = new Image( Display.getCurrent(), “images\\close.gif“ );
setImageDescriptor( ImageDescriptor.createFromImage( image ) );
}
}
Technorati Tags: ImageDescriptor, Java, JFace
Posted by
Kerry
at
7:46 PM
0
comments
Boy... I am tired. It is 3:09 pm in the afternoon and I have only been up for just over three hours today. I dove deep into SWT and JFace last night. I am really enjoying JFace at this point. It really makes building a GUI application with SWT so much easier.
Anyway, at some point during the night, for whatever reason (can't remember now), I decided to setup a build.xml file for Ant. I did this for two reasons: 1) I wanted to learn more about using Ant and 2) I wanted to see if I could setup a build properly for the SWT/JFace application that I am working on.
The setup of the build.xml to do a clean compile and to build a simple jar file was quite easy. The problem came in, however, when I tried to build an executable Jar. I never could get things to work correctly. I kept getting a message about java not being able to find the main class when I tried to launch the jar.
A little after 6:00 am this morning, I finally decided that I should get some sleep. I guess that helped, because after sitting here for the past 30 minutes looking at it again, I figured it out. Well, I figured it out by accident. :)
I did a little reading on the Sun Developer Network forums and something made me look at another executable jar file that I know I have on my computer. When I took a look at the manifest in the jar, I noticed that all of the files listed on the Class-Path entry were in the same deployment directory as the executable jar. I had tried putting them in a path on the classpath and putting them in the jar, but that never did work this morning.
So, I said what the heck and copied the appropriate external jar files that I knew the project needed into the directory where my jar file was located. Now, mind you, this is the same jar that had just 30 seconds earlier given me that same “Cannot find the main class” error message. After copying the files, I tried to launch the jar again and to my surprise, my application came right up. Sweet!
I hate that I have wasted most of a Saturday, but I have definitely learned a lot about Ant and creating executable jar files in the past 18 hours.
Posted by
Kerry
at
1:21 PM
0
comments
OK... duh... I read a couple of different articles tonight about using the ApplicationWindow class from JFace, but I missed both times that I had to include the org.eclipse.ui.workbench_<version>/workbench.jar and org.eclipse.core.runtime_<version>/runtime.jar to get it to work.
I was having another problem with my JFace demo application tonight when it came to Actions. I had created a couple of private inner classes to handle exit and another action that I was playing around with. Unfortunately, whenever I clicked on the menu item or the toolbar entry, I would get a stack trace in the Console window in Eclipse.
After doing some searching on Google for the past hour, I finally found out that you also have to include org.eclipse.osgi_<version>/core.jar. I am not sure exactly what this is for as of yet, but it allows everything to work properly, so it got added. :)
Technorati Tags: JFace, ApplicationWindow, Java, Eclipse
Posted by
Kerry
at
9:15 PM
0
comments
After using Ant and jCoverage at work as of late, I decided to creat a build.xml for my small application that I am writing for myself at home. I have run into a problem that I cannot figure out at this point, though. Whenever I do a full build (including jCoverage reports), I get the error shown below. Has anyone seen anything like this?
coverage:jcoverage.instrument:I am not sure what the problem is with this build. It follows everything that we do at work. Unfortunately, this is definitely something that I do not know enough about and I am unable to find too much information about it on Google.
[instrument] jcoverage 1.0.4 copyright (c)2003 jcoverage ltd. http://jcoverage.com/
[instrument] instrumenting 13 classes to C:\Projects\MyContacts\build\instrumented
[instrument] Exception in thread "main" org.apache.bcel.classfile.ClassFormatException:
Invalid constant pool reference: 1066. Constant pool size is: 1024
Posted by
Kerry
at
7:42 PM
0
comments
OK... I took a dive into JFace tonight. This is the first time that I have played around with it. For those who do not know, JFace allows you do UI development using the SWT widgets without a lot of the overhead code that you would require if you were using the raw widgets.
I was following along with an article on JavaWorld called “Rich clients with SWT and JFace”. The article shows a very simple demo that displays a simple window. The class extends ApplicationWindow, which is a more robust version of the JFace abstract Window class. Unfortunately, when I type in everything as shown and try to run it in Eclipse, I get an error that says:
I changed the demo to create a separate Window class and use that instead of extending from ApplicationWindow. This works. I am not sure why extending from ApplicationWindow does not work for me. It might be because I am using JDK5, but I doubt it. I am sure it is just something that I do not understand as of yet.
Exception in thread "main" java.lang.NoClassDefFoundError: org/eclipse/core/runtime/IProgressMonitor at com.pshack.application.Application.main(Application.java:30)
Posted by
Kerry
at
7:42 PM
0
comments
I am currently writing an application that will fill a small bit of functionality that I need. I am also using this as a way to learn more about JDK 5.0 and SWT development, in particular. Over the past hour, I have realized, at least in JDK 5.0 (never tried it in earlier versions), you cannot override the SWT Display or Shell objects.
I was thinking about a way to have a main Application class that extends Display. From that, I was going to have multiple window classes which extended Shell from SWT. Unfortunately after I put together a couple of classes and tried to launch it, I get an error stating that overrides are not allowed. I then remembered reading something like that on the web somewhere. Unfortunately, this is one of those situations where you sort of remember something, but you cannot remember exactly where you saw it, so you have no clue where to find it again. :)
Oh well, it is all a learning process. That and the fact that it is just so much fun is the reason I got into software development over 16 years ago anyway.
Posted by
Kerry
at
8:15 PM
0
comments
I came across a new date and time API for the Java community the other day, but I did not get a chance to do anything with it until tonight. The package is called Joda-Time v1.0. Joda-Time provides a quality replacement for the Java date and time classes.
It is very easy to get up to speed with Joda-Time. The main object that you will deal with if you are just doing regular date and time manipulations is the org.joda.time.DateTime class. I refactored a couple of my classes tonight and I can say that using DateTime is far simpler than using the Date and Calendar objects from java.util.
I can actually create a new DateTime object, add some specified duration to it, and assign it to a variable all in one line of code. Using the classes from java.util, I would have to get a Calendar object instance. From that, I could add some specified duration. To finally get a Date object, I call a method called getTime(). Geez!
Joda-Time is a very nice project. The documentation is very clean and the web site has all of their JCoverage information for their unit tests.
Posted by
Kerry
at
10:54 PM
0
comments
Coming from a background in C# for the past couple of years, I am so glad to see the Java SDK add constructs that I have used in the past.
In a personal project that I am working on, I had created a couple of enumeration classes. The classes had a lookup() method that I used to allow me to assign a particular enumeration label to a variable by looking up a particular id of one of the enumeration constants. To facilitate the lookup of a particular enumeration value, there was a private array of all the available enumerations in the particular class. The lookup() method was pretty straight forward...
I decided at work yesterday to come home and setup the latest milestone release of Eclipse so that I could play around with JDK 5.0. After getting that working, I refactored my enumeration classes to be actual enum classes now that Java 5 has the new enum keyword. With that refactoring, I was able to make use of the new for-each style of iteration that Java 5 has added. So, my lookup() method on the enumeration classes now look like this...
//.. lookup procedure expects an id pass in
for ( int i = 0; i < available.length; i++ ) {
if ( available[i].getId() == id ) {
return available[i];
}
return null;
}
//.. lookup procedure still expects an id passed inI have been used to this style of construct in C# which has the for-each style of iterations for a collection. For a new Java developer, this method might be a little harder to understand. There is not the explicit notion of having checking each object in a particular collection like you have in C# where you say “for each ...”, but I feel like this is a little cleaner code than the style where you use the index property, which could always lead to problems itself.
MyEnumType[] available = MyEnumType.values();
for ( MyEnumType e : available ) {
if ( e.getId() == id ) {
return e;
}
return null;
}
Posted by
Kerry
at
8:00 AM
0
comments
I have been working on a small application at home lately which is going to use MySQL for data persistence. I was messing around with my tables tonight and got into a situation where I wanted to add data into one table using the last inserted value from the auto_increment primary key field in another table.
According to the documentation for MySQL, I should be able to use LAST_INSERT_ID(), but I couldn't figure out exactly how to get it to pull the last inserted ID from a different table.
So, I then tried the following code...
INSERT INTO table2 (id, field1, field2) SELECT NULL, 4, id FROM table1 t WHERE t.id IS NULL;According to some information that I found in a comment posted on the documentation for the INSERT..SELECT command on the MySQL documentation site, this should give me the last inserted ID from the first table. Nope... this results in no errors and no rows being added to the table. Very weird!
INSERT INTO table2 (id, field1, field2) SELECT NULL, 4, MAX(id) from table1;So far, this seems to give me the results that I am after.
Technorati Tags: MySQL
Posted by
Kerry
at
10:49 PM
0
comments
This is one little item that I never can seem to remember, because I just do not use it that often, so I thought I would commit it to my blog.
When creating a new DataRow that you want to subsequently add to a DataTable, you generally create the columns that you need for the rows and then you add data values. The code for this looks something like this...
DataTable ErrorTable = new DataTable();
ErrorTable.Columns.Add(new DataColumn("Fault Code Namespace", typeof(string)));
ErrorTable.Columns.Add(new DataColumn("Fault Code Name", typeof(string)));
ErrorTable.Columns.Add(new DataColumn("SOAP Actor that threw Exception", typeof(string)));
ErrorTable.Columns.Add(new DataColumn("Error Message", typeof(string)));
ErrorTable.Columns.Add(new DataColumn("Detail", typeof(string)));
DataRow row = ErrorTable.NewRow();
row["Fault Code Namespace"] = error.Code.Namespace;
row["Fault Code Name"] = error.Code.Name;
row["SOAP Actor that threw Exception"] = error.Actor;
row["Error Message"] = error.Message;
row["Detail"] = HttpUtility.HtmlEncode(error.Detail.OuterXml);
There is a simpler way to write the code above which sets up the data values and adds the DataRow to the DataTable. That code can be written in one line like this...
ErrorTable.Rows.Add( new object[] {error.Code.Namespace, error.Code.Name, error.Actor,
error.Message, HttpUtility.HtmlEncode(error.Detail.OuterXml)} );
The code is definitely not more readable and is probably more of a headache for someone to come along later and maintain, but it is easier to type the first time around. :)
Posted by
Kerry
at
10:37 AM
0
comments
I had an issue with a java class today that I was trying to execute from the command line. I kept getting the following error:
Exception in thread "main" java.lang.NoClassDefFoundError: ExampleAfter doing a little research, I found that my CLASSPATH variable was set to c:\junit3.8.1\junit.jar which was not allowing the virtual machine to properly find the binaries it needed to execute the class. After clobbering the CLASSPATH variable (“set CLASSPATH=“), everything worked as expected.
CLASSPATH=.;c:\junit\junit3.8.1\junit.jarFor those of you who can't quite see it, that is a period at the beginning of the CLASSPATH declaration. This tells Java to use the current directory when searching for classes and JAR files.
Posted by
Kerry
at
8:49 AM
0
comments
I have been doing a lot of web service work for my job lately. I am getting data back from application and returning it to PeopleSoft. I ran into a small issue when trying to setup a new DataSet. I wanted to include only certain rows of data from one of the tables that I was getting back in the DataSet that the web application, which I am integrating into our online system, was returning.
The line of code that I was using to add the DataTable to my DataSet was quite simple...
dtNewData.Tables.Add( dsAppData.Tables[0] );Almost immediately, I found that was causing a real problem. I kept getting an error that said “DataTable already belongs to another DataSet”. I did some searching on Google and finally found that you cannot simply add a table to a DataSet that already exists in another DataSet. Luckily, there are ways around this.
dtNewData.Tables.Add( dsAppData.Tables[0].Copy() );Unfortunately, this did not meet my needs, because I only need the first few rows of data from the original table. My final code ended up looking like this:
dtNewData = dsAppData.DataSet.Copy();
while (dsAppData.Tables[0].Rows.Count > RequestedRows)
{
DataRow dr = dsAppData.Tables[0].Rows[dsAppData.Tables[0].Rows.Count-1];
dsNewData.Tables[0].Rows.Remove(dr);
}This created a copy of the entire DataSet and just removes the unwanted rows at the end of the table. Originally, I did a clone of the table and used ImportRow(), but this method seems to be just a little faster.
Posted by
Kerry
at
3:15 PM
0
comments
I wrote some code in a web service the other day to pick off the first few rows of a data in a DataTable that was returned to me from someone else's data engine. The code that I wrote looked something like this:
DataTable dsTemp = new DataTable();
for (int i = 0; i <>
Calling NewRow adds a row to the table using the existing table schema, but with default values for the row, and sets the DataRowState to Added. Calling ImportRow preserves the existing DataRowState, along with other values in the row.
DataSet dsTemp = ds.Clone();
for (int i = 0; i <>
Posted by
Kerry
at
1:16 PM
0
comments