Who’s On Phirst

Official blog of Phurnace Software.

Shawn Spiars's Blog
Description:
No desc available

Posted by: Shawn Spiars on

Before we get started here are a couple of definitions that may help you understand this example.

  • A wizard is a series of pages that guide a user through a complex task.
  • JFace is a user interface framework that is used to handle many common UI programming tasks.

JFace provides all the user interface components needed to create a wizard for your application. Most of the time when designing a wizard you will know at design time how many pages are required to complete each step of your wizard. But on occasion you will run across a use case where you need to create pages dynamically based upon the user’s input from a previous page. Solving this problem with JFace is a little tricky, so I’ve created an example program demonstrating how to dynamically create wizard pages based upon the input from the first page. Give it a try and let me know what you think.


import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

/**
 * Example program demonstrating how to dynamically add pages to a JFace Wizard.
 *
 * @author Shawn Spiars 
 * 
 */ 
public class DynamicWizardPageExample {

      private static class MyWizard extends Wizard {
            public MyWizard() {
                  super();
                  setForcePreviousAndNextButtons(true);
            }

            public void addPages() {
                  addPage(new StartingWizardPage());
            }

            public boolean performFinish() {
                  return true;
            }

            @Override
            public IWizardPage getNextPage(IWizardPage page) {
                  IWizardPage nextPage = super.getNextPage(page);
                  
                  //TODO - create logic here to skip pages that you
                  //have added to the framework, but no longer wish to display
                  
                  return nextPage;
            }

      };

      private static class StartingWizardPage extends WizardPage {
            private Button firstPageButton;
            private Button secondPageButton;
            private Button thirdPageButton;

            protected StartingWizardPage() {
                  super("startingPage");
                  setTitle("Starting Page");
              setMessage("Select the desired pages and press the Next button.");
            }

            public void createControl(Composite parent) {
                  Composite composite = new Composite(parent, SWT.NONE);
              GridLayout layout = new GridLayout(1, false);
              layout.verticalSpacing = 12;
              composite.setLayout(layout);
              composite.setLayoutData(new GridData(GridData.FILL_BOTH));
              
              firstPageButton = new Button(composite, SWT.CHECK);
              firstPageButton.setText("Page One");
              firstPageButton.addSelectionListener(new SelectionAdapter() {
                        public void widgetSelected(SelectionEvent e) {
                              Wizard wizard = (Wizard) getWizard();
                              wizard.addPage(new MyWizardPage("Page One"));
                              getContainer().updateButtons();
                        }
                  });
              
              secondPageButton = new Button(composite, SWT.CHECK);
              secondPageButton.setText("Page Two");
              secondPageButton.addSelectionListener(new SelectionAdapter() {
                        public void widgetSelected(SelectionEvent e) {

                              Wizard wizard = (Wizard) getWizard();
                              wizard.addPage(new MyWizardPage("Page Two"));
                              getContainer().updateButtons();
                        }
                  });
              
              thirdPageButton = new Button(composite, SWT.CHECK);
              thirdPageButton.setText("Page Three");
              thirdPageButton.addSelectionListener(new SelectionAdapter() {
                        public void widgetSelected(SelectionEvent e) {
                              Wizard wizard = (Wizard) getWizard();
                              wizard.addPage(new MyWizardPage("Page Three"));
                              getContainer().updateButtons();
                        }
                  });
              
              setControl(composite);
            }
            
      }
      
      private static class MyWizardPage extends WizardPage {
            protected MyWizardPage(String pageName) {
                  super(pageName);
                  setTitle(pageName);
            }

            public void createControl(Composite parent) {
                  Composite composite = new Composite(parent, SWT.NONE);
                  setControl(composite);
            }
      }

      public static void main(String[] args) {
            Display display = new Display();

            final Shell shell = new Shell(display);
            shell.setLayout(new FillLayout());

            Button b = new Button(shell, SWT.PUSH);
            b.setText("Press here to open wizard");
            b.addSelectionListener(new SelectionAdapter() {
                  public void widgetSelected(SelectionEvent e) {
                        WizardDialog dialog = new WizardDialog(shell, new MyWizard());
                        dialog.open();
                  }
            });

            shell.open();

            while (!shell.isDisposed()) {
                  if (!display.readAndDispatch())
                        display.sleep();
            }

            display.dispose();
      }
}


For more information on JFace, check out these links:

In Untagged 
Comment (0) Read More...


Posted by: Shawn Spiars on

 We use the Eclipse Rich Client Platform (RCP) extensively here at Phurnace Software. Because of that and my years of experience, I was recently invited to do a presentation on the Eclipse RCP at a technical user’s group in Silicon Valley.

Preparing my talk got me thinking a lot about how Eclipse has evolved over the years and how misunderstood it often is. I think the most common misunderstanding is that Eclipse is simply a popular open source Java IDE (Integrated Development Environment). It’s true that Eclipse is a very popular open source Java IDE, but that’s just the tip of the iceberg. Eclipse is also an extensible platform for Developing IDE’s, tools, and applications.

Eclipse is built upon a mechanism for discovering, integrating, and running modules called plug-ins. A plug-in is an encapsulation of behavior and/or data that interacts with other plug-ins to form a running program. This plug-in extensibility makes it easy for third-party software tool vendors to integrate with Eclipse and/or contribute to the Eclipse Platform.

One of the coolest things about Eclipse to me, as a commercial application developer, is the extensible framework for building applications. Removing Eclipse’s IDE elements, Java support, and a few other components leaves you with a fairly comprehensive framework for building your own application. Using the Eclipse RCP gives you a huge head start when developing your own application and allows developers to focus on the core application rather than the plumbing. Another big advantage to using Eclipse RCP for your application framework is that when you need to add functionality there are so many available Plug-ins to leverage rather than writing everything yourself. For example, when Phurnace needed an XML Editor in our Phurnace Deliver product, we simply bundled the XML Editor from the Web Tools Platform (WTP) and we had an awesome, free, XML Editor as part of our offering.

For more information on the Eclipse Rich Client Platform check out these links.
Eclipse Rich Client Platform FAQ
Eclipse Rich Client Platform Wiki

In Eclipse
Comment (0) Read More...


Posted by: Shawn Spiars on

The Eclipse Resources Plug-in (org.eclipse.core.resources) is one of the handiest Eclipse plug-ins that no one ever talks about. The Resources Plug-in is rarely talked about because it works behind-the-scenes to enable other plug-ins and APIs to function well. For example, it is the Resources Plug-in that enables the Resource Navigator view to expose a tree hierarchy of all the projects, folders, and files in your Eclipse workspace.

Before we get into the details of the Resources Plug-in it's important to understand the function of the Eclipse Workspace. The Eclipse Workspace is where the Eclipse IDE stores all your development artifacts (Projects/Folders/Files). The Eclipse Workspace's resource model is very similar to a file system. All Workspace resources are backed by a real file or directory in the native file system.

The Resources Plug-in, or API, contains many interfaces to help developers access and manipulate the artifacts within the workspace. Here are a few definitions of the more common interface classes.

 

  • IResource – all artifacts in the workspace are resources
  • IWorkspace – the basis for the Eclipse Platform resource management
  • IWorkspaceRoot – a root resource that represents the top of the workspace hierarchy
  • IContainer – resources which may contain other resources (projects and folders)
  • IProject – a type of resource which groups resources into buildable, reusable units
  • IFolder – may be leaf or non-leaf resources, and may contain files or other folders
  • IFile – files are leaf resources which contain data

If you are a java developer you are probably familiar with the java.io.* class library. The java.io.File class is what java developers normally use when reading and writing files and directories. When you are working with files and directories within the Eclipse workspace you should use the Eclipse Resources API, rather than the java.io.File class. If you use the standard java.io.File class to modify files or directories within the workspace you will need to force a refresh in your viewer so the changes made to the model (resources) are visible to the user.

The screenshot below shows a Package Explorer view exposing the contents of an Eclipse Workspace. This workspace contains a single project named “My Project”. The project contains a single folder named “My Folder”, and the folder contains a single file named “deleteMe.txt”.

 

The following code snippet demonstrates how to use the Resources API to access the project, folder, and file in this workspace example. After getting a handle to the workspace file “deleteMe.txt” we use the IFile delete method to delete the file from the folder.


try {

IWorkspace workspace = ResourcesPlugin.getWorkspace();

IWorkspaceRoot workspaceRoot = workspace.getRoot();

IProject myProject = workspaceRoot.getProject("MyProject");

if (myProject.exists()) {
IFolder myFolder = myProject.getFolder("My Folder");

if (myFolder.exists()) {
IFile myFile = myFolder.getFile("deleteMe.txt");

if (myFile.exists()) {
myFile.delete(true, true, null);
}

}

}

} catch (CoreException e) {
}

This is a very simple demonstration of how to use the Resources API to access and manipulate artifacts within the Eclipse Workspace. For more information on the Resources Plug-in and the Eclipse Workspace, check out these links:

Eclipse Wiki - Resources
Eclipse Workspace Team
Eclipse.org

In Eclipse
Comment (0) Read More...


Posted by: Shawn Spiars on

The best part about a vacation get-away is the getting away from it all – away from work, away from household chores and getting out of the rat race. The next best thing is coming back home to familiarity – sleeping in your own bed, eating food you recognize, clean restrooms, etc. The “coming back home” experience can be really special when returning from another country where things like food, customs, and various creature comforts are just not the same as in the good old USA. We don’t often appreciate the little things. I think it is healthy to be reminded of what we do have here, by seeing other places.

I recently returned from a week-long trip to Trinidad and Tobago and boy is it nice to be home! Don’t get me wrong – Trinidad is a great place to visit with wonderful people, beautiful tropical forests, and awesome beaches. My visit to Trinidad was not your typical Caribbean island vacation get-away. But, that was by choice. I spent a week in Trinidad with a team of 18 people from my church conducting a Vacation Bible School for children. Before we left the states I was explaining to my 14 year old son how Trinidad is not a third-world country, yet the day we arrived the electricity went out in the town of Gasparillo where we were staying. Consequently, when the electricity went out the household water pump stopped working leaving us with no running water. My son quickly pointed out to me, “Dad, now we are in a third-world country”. Amazing how we all view the world through our own reference point. I must point out, that the locals didn’t freak out a bit.

The driving in Trinidad is either frightening or exhilarating, depending on your point of view. First off, they drive on the left side, or should I say (as an American driver) the “wrong” side of the road. Rarely do they stop at stop signs and when they come to an intersection they all cram their cars in together and aggressively negotiate who goes next by moving their vehicle within inches of each other. Eventually someone gives in, toots their horn and waves the other car in, or yells something like “go on boy”. It just seems to all work. Not really sure how, but it does.

The most beautiful place we visited in Trinidad was Maracas Bay. Even short-term missionaries deserve their day in the sun. We spent a day eating Bake-N-Shark sandwiches, body surfing, and just limin’ on the beach. The waves at Maracas Bay are very powerful and can hurt you if you’re not careful. A teenage girl in our group was pummeled by a large wave and broke her collar bone. As in all new endeavors or experiences -- “be prepared”.

Some of the experiences from my trip that made me really appreciate the things we too often take for granted were the daily cold showers (or no showers), very hot and humid weather (even though Austin does have its share, Trinidad has it beat in that department), no air conditioning, large downpours of rain every day, and tons of mosquitoes. However, none of that dampened our great experience.

In spite of the temporary discomforts in Trinidad, I’ll definitely be going back again. The people were fantastic and we achieved our objectives. Using vacation time to serve others is rewarding and the kindness and friendship returned was well worth the investment.

In Untagged 
Comment (0) Read More...


Posted by: Shawn Spiars on

From time to time I visit the Eclipse news groups to find a solution to a problem I am having with a particular area of Eclipse. Since Eclipse is such a huge platform with many projects there are many different news groups, each designed to cover a particular project or API (Application Programming Interface).

Some of my favorite Eclipse news groups are:

eclipse.platform
eclipse.platform.rcp
eclipse.platform.swt

Often while I am looking for answers in a news group I run across questions that I have already conquered and so I try to give back and help others. Recently I responded to a question about how to perform in-line editing within the cell of an SWT (Standard Widget Toolkit) table. I have included my example java program below. If you are a Java developer and somewhat familiar with SWT/JFace then you should have no problems understanding the example code. If you are new to SWT/JFace I have provided a brief summary of the primary components used to create the example.

Looking at the java code below you will see that the program contains a main method to launch the java program. The primary UI component is an SWT Table which is added to an SWT Composite. Under the table I have added SWT buttons to “Add” and “Remove” rows from the table. The SelectionListeners on the buttons handle the add and remove actions. The model for the table is a POJO (Plain Old Java Object) which I have named “Row”. A TableContentProvider and TableLabelProvider provide the content and labels for the table and the TextCellEditor provides the ability to edit the table allowing a user to type data directly into the table’s cells.


import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.ICellModifier;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;

/**
* This is an example program showing how to use a TableCellEditor
* to allow direct editing of a table's cell.
*
* @author Shawn Spiars
*
*/

public class TableCellModifierExample {

private Table table;
private TableViewer tableViewer;

private final static String[] COLUMN_HEADINGS = {"Property",
"Value"}
;

public static void main(String [] args) {
new TableCellModifierExample();
}

public TableCellModifierExample() {
Display display = new Display();
Shell shell = new Shell(display, SWT.SHELL_TRIM);
shell.setText("TableCellModifier Example");
shell.setLayout(new FillLayout());

createContents(shell);

shell.setSize(400, 400);
shell.open();

while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}

protected Control createContents(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
GridLayout layout = new GridLayout(1, false);
layout.verticalSpacing = 10;
composite.setLayout(layout);
GridData data = new GridData(GridData.FILL_BOTH);
data.grabExcessHorizontalSpace = true;
composite.setLayoutData(data);

table = new Table(composite, SWT.BORDER | SWT.V_SCROLL
| SWT.MULTI | SWT.FULL_SELECTION);
table.setLinesVisible(true);
table.setHeaderVisible(true);
data = new GridData(SWT.FILL, SWT.FILL, true, false);
data.heightHint = 300;
table.setLayoutData(data);

TableLayout tableLayout = new TableLayout();
table.setLayout(tableLayout);

tableLayout.addColumnData(new ColumnWeightData(10, 100,
true));
TableColumn column = new TableColumn(table, SWT.NONE);
column.setText(COLUMN_HEADINGS[0]);
column.setAlignment(SWT.LEFT);

tableLayout.addColumnData(new ColumnWeightData(15, 200,
true));
column = new TableColumn(table, SWT.NONE);
column.setText(COLUMN_HEADINGS[1]);
column.setAlignment(SWT.LEFT);

tableViewer = new TableViewer(table);
tableViewer.setColumnProperties(COLUMN_HEADINGS);
tableViewer.setContentProvider(new
TableContentProvider());
tableViewer.setLabelProvider(new TableLabelProvider());

CellEditor[] editors = new CellEditor[2];
editors[0] = new TextCellEditor(table);
editors[1] = new TextCellEditor(table);
tableViewer.setCellEditors(editors);
tableViewer.setCellModifier(new TableCellModifier());

Composite buttonComposite = new Composite(composite,
SWT.NONE);
FillLayout fillLayout = new FillLayout(SWT.HORIZONTAL);
fillLayout.spacing = 10;
buttonComposite.setLayout(fillLayout);

Button addButton = new Button(buttonComposite,
SWT.PUSH);
addButton.setText("Add");
addButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
Row row = new Row("", "");
tableViewer.add(row);
table.setTopIndex(table.getItemCount());
table.select(table.getItemCount()-1);
tableViewer.editElement(row, 0);
}
});

Button removeButton = new Button(buttonComposite,
SWT.PUSH);
removeButton.setText("Remove");
removeButton.addSelectionListener(new
SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
ISelection selection =
tableViewer.getSelection();
if (selection instanceof
IStructuredSelection) {
Iterator iterator =
((IStructuredSelection)selection).iterator();
while(iterator.hasNext()) {
Object obj = iterator.next();
tableViewer.remove(obj);
}
}
}
});

return composite;
}

public class TableLabelProvider extends LabelProvider
implements
ITableLabelProvider {
public Image getColumnImage(Object element, int
columnIndex) {
return null;
}

public String getColumnText(Object element,
int columnIndex) {
Row row = (Row) element;

switch
(columnIndex) {
case 0:
return row.getKey();
case 1:
return row.getValue();
}

return null;
}

}

public class TableContentProvider implements
IStructuredContentProvider {
public Object[] getElements(Object parent) {
List results = new ArrayList();
if (parent instanceof ArrayList) {
results = (ArrayList) parent;
}
return results.toArray();
}

public void dispose() {
}

public void inputChanged(Viewer viewer, Object oldInput,
Object newInput) {
}

}

class TableCellModifier implements ICellModifier {

public boolean canModify(Object element,
String property) {
return true;
}

public Object getValue(Object element,
String property) {
Object result = null;

Row row = (Row) element;

List list = Arrays.asList(COLUMN_HEADINGS);
int columnIndex = list.indexOf(property);

switch (columnIndex) {
case 0:
result = row.getKey();
break;
case 1:
result = row.getValue();
break;
}

return result;
}

public void modify(Object element, String property,
Object value) {
List list = Arrays.asList(COLUMN_HEADINGS);
int columnIndex = list.indexOf(property);

TableItem tableItem = (TableItem) element;
Row row = (Row) tableItem.getData();

switch (columnIndex) {
case 0:
String key = (String) value;
if (key.length() > 0) {
row.setKey(key);
}
break;

case 1:
String v = (String) value;
if (v.length() > 0) {
row.setValue(v);
}
break;
}
tableViewer.update(row, null);
}

}

private class Row {
private String key;
private String value;

public Row(String key, String value) {
setKey(key);
setValue(value);
}

public void setKey(String key) {
this.key = key
}

public String getKey() {
return key;
}

public void setValue(String value) {
this.value = value;
}

public String getValue() {
return value;
}
}

}

In SWTJFaceSWTStandard Widget ToolkitEclipse
Comment (0) Read More...


Posted by: Shawn Spiars on

It seems like there are more visual GUI builder products available on the market today than ever before. Visual GUI builders propose an easier way to design and create user interface components. They usually consist of a palette from which you select and drag controls or widgets onto a window, frame, or dialog. Then they provide a table or list where you can manipulate the properties of your controls (size, font, color, coordinates, etc) without requiring the user to know the subtleties’ of the syntax or layout managers. Here is a really good link if you are interested in Java GUI Builders.

Call me old fashion, but I always prefer a language editor (HTML, XML, Java, etc…) over a visual editor because I want to understand the commands I write, and I want to format and organize the code in a way that is meaningful to me so I can easily edit the code later. A good language editor will have syntax highlighting, syntax checking, command completion and various other features to assist you in developing the code, but it won’t generate the substance of the code for you.

Another type of code generation tool falls into the Model Driven Development (MDA) category. With MDD, logical models are used to capture design decisions and generate code, and sometimes the generated code is user interface code. The problem I have with user interfaces generated from models is that there is no consideration by the machine for who the user is, their technical aptitude, or the way they approach a task (workflow). The entire human experience is missing and the user interface has been reduced to a bunch of domain objects and business rules.

For example, the Eclipse Modeling Framework (EMF) can use a model to quickly generate a cool looking prototype consisting of a relational tree, object listeners, pop-up menus, and a properties view, but this in no way resembles a complex, well designed, user friendly application. And don’t be fooled into thinking you can easily tweak the generated code to get it to behave the way you want it to. I’ve spent hours and hours digging thru layers and layers of cryptic machine generated code trying to find the one line that needs to be changed to get the desired behavior.

There are plenty of MDD advocates out there who will disagree with me. Most of them are experts in modeling, but I’ve never met one who is an expert in user interface design. Since most project leads and architects today are very familiar with UML and modeling tools they often buy into the promise that MDD will save them time on their UI development. This has not been my experience.

If you do choose to use a modeling tool to generate UI code – I recommend you decouple the UI model from the back-end model. Just imagine a project where every time the back-end architect decides to change a relationship in the model the UI mysteriously breaks with no warnings.

“And that’s all I have to say about that.”

-Shawn

In Java GUIEclipse
Comment (0) Read More...


Posted by: Shawn Spiars on

When I started working with Eclipse in 2003 I would just download the plug-ins I needed from the Eclipse website, unzip them into my plugins directory, and restart Eclipse. Sometime later, the Eclipse Update Manager was introduced to help you configure your Eclipse development environment providing the ability to update your existing features and plug-ins and search for new features. I have always found the Update Manager dialogs difficult to understand and use. Customizing the Update Manager to work with my Rich Client Platform (RCP) applications has also been very difficult.

When I heard about the new Equinox p2 provisioning system at EclipseCon this year I was excited that the Update Manager was finally being replaced. However, one thing I have learned when working with Eclipse is to take a “wait and see” approach before adopting the newest and improved APIs and methodologies. So, I have been reading various blogs to see what experiences developers are having implementing p2 in their products. Here are a couple of postings that make me think that p2 may not be quite ready for prime time:

Why Eclipse Equinox P2 Update Manager Sucks

Why Eclipse Equinox P2 Update Manager is not good enough for me yet #2

If you have had a positive experience replacing Update Manager functionality with p2 in your software product I would love to hear about it.

-Shawn

 

In Eclipse
Comment (0) Read More...


Posted by: Shawn Spiars on

There are quite a few toolkits available for Java developers. Let me help point you in some directions and maybe save you some research time.

Many of you will be familiar with the Abstract Windows Toolkit (AWT) that is available with every Java Runtime Environment (JRE). AWT is the original Java GUI toolkit developed by Sun Microsystems. AWT is a peer-based toolkit meaning that each AWT control is dependent upon a host operating system control. AWT usage is limited because it was designed to only support controls which are available in all Java host environments. For example, AWT does not support Trees and Tables.

Swing is another Java GUI toolkit developed by Sun Microsystems and was designed to work with AWT and is built on top of AWT components. Unlike AWT, most Swing controls are emulated. This emulation makes user interfaces written in Swing portable across all operating systems and supports Sun’s “write-once, run anywhere” motto. One disadvantage to Swing is that the emulated controls often don’t result in a native looking application. Swing’s answer to this problem is provided by look-and-feel emulators that attempt to change the appearance and behavior of their components to adapt to a particular operation system or theme. Another disadvantage to Swing is that the emulated controls tend to run slower than peer-based controls.

The Standard Widget Toolkit (SWT) is another peer-based GUI toolkit. IBM designed SWT to solve some of the problems that have limited the usage of AWT. SWT provides a different Java implementation for each operating system platform using Java Native Interface (JNI) calls. One disadvantage for SWT is that developers are required to dispose of OS-dependent objects within their application code.

JFace is a GUI library that was developed to compliment SWT and simplify common GUI programming tasks. SWT and JFace libraries are used extensively throughout the Eclipse IDE.

As a Java user interface developer I have used each of these GUI libraries and I find the combination of SWT/JFace my favorite choice because of the native look-and-feel of the components. I also find the SWT and JFace APIs cleaner and easier to develop with than AWT and Swing. My two cents, comments welcome.

In Java GUI ToolkitsJava GUIjavaAbstract Windows Toolkit
Comment (0) Read More...


Posted by: Shawn Spiars on

As a software engineer I often find it entertaining reading the technology job postings. You can learn a lot about a company's values and culture by what they reveal in their job postings. I once had a job interview with a VP of Engineering who was bragging to me during the interview about how much money he saved his company by sending half of his development positions offshore. So I am thinking to myself "if I take this job just how long until my position goes offshore"?

One of my biggest pet peeves is with the postings that say "Entry Level Programmer" and then go on to list detailed requirements that would take 10 to 15 years of experience to accumulate. This type of posting tells me that the company is really cheap and doesn't want to pay for the experience that is required for the position.

Then there are the companies that think they are doing you a big favor by allowing you to Join their world-class team because they are so much smarter than everyone else in the industry. They only hire engineers with advanced degrees and certifications and take great pride in Their superior intellect. A few years ago I had a short stint at one of these companies with "All Chiefs and no Indians". These folks were so smart that it took them over 2 years to get a software release out the door. They just kept arguing about how to do things better and better, and ended up rewriting the same Code over and over again until they ran out of money.

One of the things I like most about working at Phurnace is the "No Punks Allowed" philosophy as Robert likes to phrase it. "No Punks Allowed" basically means we look for people who are mature in how they perform their work and in how they relate to others. It also refers to the notion of egos in check, and a willingness to constructively share ideas and have ideas shared with you. After all it's the quality and character of the people that you work with that makes a job enjoyable or not. So, if you are a developer and you are trying to decide on your next gig, just remember - "No Punks Allowed."

Shawn

In java
Comment (1) Read More...


Posted by: Shawn Spiars on

 Last week I attended the EclipseCon 2008 conference in Santa Clara, CA.  This was my third EclipseCon and by far my best experience.  ThisEclipseCon year there were a lot more technical sessions to choose from and overall the presentations seemed more professional than in the previous years.  I also liked that the Monday tutorials were included in the overall conference registration fee, rather than an extra charge.

I think the highlight of the conference was the key note speech of Dan Lyon (Fake Steve Jobs).   Here's a quote about Dan from the EclipseCon website.

"At his blog, fakesteve.blogspot.com, Lyons has captured the Zeitgeist, from perhaps the one place it is clearest-the point of view of Steve Jobs. In the tradition of Jonathan Swift and The Onion, he uses a pitch-perfect satirical style to deliver trenchant social commentary, reflecting on everything from the Cult of Steve and the rise of Apple ("Dude, I invented the friggin' iPhone. Perhaps you've heard of it!") to the ubiquitous influence of the tech industry on our everyday lives."

Another key note speaker was Sam Ramji, Director of Platform Strategy at Microsoft.   I think of Microsoft as the Borg and their presence at EclipseCon as another strategy to assimilate the Eclipse Community and open source.

The sessions that I found most interesting were those discussing the Rich AJAX Platform (RAP), The Rich Client Platform (RCP), and the Web Tools Platform (WTP).  I particularly enjoyed the "GWT vs RAP" presentation by Mark Russell and Dan Rubel, discussing the differences between Google Web Toolkit (GWT) and Eclipse Rich AJAX Platform (RAP) development.

If you are a software developer I would highly recommend you check out next year's EclipseCon.                 

In Open SourceEclipse
Comment (1) Read More...