Tuesday, December 8, 2009

Coding java gui using Swing designing it with CSS

Building a GUI in java isn't complicated having netbeans as a great Swing gui builder.

But what if we want to have some of the design left out of the code in a CSS file?

As when building a java applet which should blend with a website, out best shot will be to use the same CSS file in the swing code as we use for the website.

How can we design the GUI components using swing?

We will use TK-UI's SwingCSSEngine (which is opensourced).

Their documentation can be reached using the following link:

http://tk-ui.sourceforge.net/user-guide/cssengine/swingcssengine.html

How is it done?

  1. Download the libraries: http://sourceforge.net/projects/tk-ui/files/org.akrogen.tkui.css.swing/
  2. Copy the jar files (also those in their "lib" directory [excluding the commons if you wish]) into your project's (the swing project) lib directory.
  3. In the code before initializing the swing components (a method which is actually called initComponents() in the netbeans IDE) add the following code:


/* Setting up the CSS styles */

// Create Swing CSS Engine

CSSEngine engine = new CSSSwingEngineImpl();

// Parse style sheet

try {

// Getting the css from a file

InputStream is = class-classNameYouAreRunning.class.getClassLoader().getResource("swing.css").openStream();

engine.parseStyleSheet(is);

} catch (IOException e) {

e.printStackTrace();

}


In the above code we assume a file named "swing.css" exists and resides in our classpath.

  1. After the initialization of the swing components (after initComponents() method in netbeans) add the following code:



JFrame frame = this.getFrame();

// Apply Styles

engine.applyStyles(frame, true);

frame.pack();

frame.setVisible(true);

Log All Your Web-method Calls

After a good deal of trial-and-error, and delving into the CXF code, I've found a way to get CXF to log every web-method call -- parameters and all.

Put the following into your Tomcat's log4j.xml:


<logger name="org.apache.cxf.service.invoker">
<level value="trace">
</level>
</logger>

The level should be set to "trace" by default; you won't get ton's of output, just a line (maybe 2) every time a web method is called. Unfortunately, the line is a bit wordy, as in

Invoking method public boolean com.company.entities.ws.EntityManagementImpl.login(java.lang.String,java.lang.String,java.lang.String) throws java.io.UnsupportedEncodingException on object com.company.entities.ws.EntityManagementImpl@71e6b with params [CLI, arg2, arg3].

but it was either use the built in log statement or write a whole interceptor and add it to the chain processing the call. If we get really annoyed we could always tweak the source and rebuild CXF, but I suggest we first try to live with it.

Java Swing Applet: HowTo

This post explains how to take an existing Java Swing application and wrap it as an applet which can then be used on any website.


This post assumes the java swing class file (which is run in the original application) to be: FileUploadClientGUIView.

  1. Create the java applet wrapper as follows:

package packageName;

import javax.swing.JApplet;
import javax.swing.SwingUtilities;

public class AppletStarter extends JApplet {
//Called when this applet is loaded into the browser.
public void init() {
//Execute a job on the event-dispatching thread;
//creating this applet's GUI.
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
createGUI();
}
});
} catch (Exception e) {
System.err.println("AppletStarter didn't complete successfully");
}
}

private void createGUI() {
//Create and set up the content pane.
FileUploadClientGUIView newContentPane = new FileUploadClientGUIView(new FileUploadClientGUIApp());
//newContentPane.getRootPane().setOpaque(true);
setContentPane(newContentPane.getRootPane());
}
}


The only line you should change is the line showing the actual GUI and is bolded out.


  1. Jar up the whole application with the wrapper class included inside. Just change the main-class in the META-INF/MANIFEST.MF file as follows (to point to the new wrapper class you have just created):

Main-Class: packageName.AppletStarter

  1. In the HTML / PHP code insert the following lines:




<applet code='packageName.AppletStarter '
archive = 'NameOfJarToRun.jar',
width = 300,
height = 260 />


before the end of the /body tag enter the following line:


<script language="JavaScript" src="/js/omi/jsc/s_code_remote.js"></script>



That's it – your applet now appears on your browser.