The Source for Java Technology Collaboration
User: Password:



Kirill Grouchnikov's Blog

December 2005 Archives


Swinging Java IDEs

Posted by kirillcool on December 29, 2005 at 11:05 AM | Permalink | Comments (2)

This entry on JavaLobby has caught my eye a few days ago. It talks about a RAD-race at JavaPolis and the fact that the top three teams were using JDeveloper. During the course of (so) many flamewars on "which IDE is better", it's always Eclipse vs. NetBeans vs. IntelliJ (and don't start another one in the comments by telling that your favourite IDE should be the first in the list). I have started reading a little bit more about JDeveloper - it's free (but not open-source) and it's pure Swing application. The download size is comparable to that of the above three "flamewar heroes" (about 51MB without JDK 5.0), so you should definitely keep this option in mind.

After showing how to put watermark on IntelliJ (described here) and NetBeans (described here and here), it's JDeveloper's turn to take a ride.

Here is what you need to do in order to run JDeveloper under Substance (or any other) look-and-feel (originally described in Oracle forums):
  • Put the latest substance.jar (and any of its plugins) under $JDEV_DIR$/jdev/lib/patches directory (don't create sub-directories).
  • Locate settings.xml file under $JDEV_DIR$/jdev/system/oracle.ide.10.1.NNN directory (replace NNN by the installed version - it's 10.1.3.34.12 for the latest drop of 10.1.3).
  • Locate the lafClass tag and put the following value: org.jvnet.substance.SubstanceLookAndFeel.
  • For additional Substance parameters:
    • Locate jdev.conf file under $JDEV_DIR$/jdev/bin directory
    • For every VM flag, add a line prefixed with AddVMOption at the end of the configuration file
Now, double-click the jdeveloper.exe (on Windows) - and voila (click for full-size image):



The parameters in the jdev.conf file are:
AddVMOption -Dsubstancelaf.theme=org.jvnet.substance.theme.SubstanceSunsetTheme 
AddVMOption -Dsubstancelaf.watermark=org.jvnet.substance.watermark.SubstanceImageWatermark 
AddVMOption -Dsubstancelaf.watermark.image=H:\JProjects\substance\temp\KingArthur.png
AddVMOption -Dsubstancelaf.watermark.tobleed
AddVMOption -Dsubstancelaf.useDecorations
AddVMOption -Dsubstancelaf.heapStatusPanel
AddVMOption -Duser.language=en
AddVMOption -Duser.country=US


NetBeans look and feel competition - a low-hanging iPod

Posted by kirillcool on December 26, 2005 at 01:55 AM | Permalink | Comments (2)

About two weeks ago NetBeans has announced a Look and Feel competition (which should really by Look only, since they are accepting screenshots). One of the more enjoyable ways to create an attractive screenshot (although this depends on male-to-female ratio on the judging panel :) is to use the Substance NB module that allows using the Substance LAF integrated into the View menu.

One of the users has asked me if it would be possible to make the watermark image "bleed" through the editor panel. Obviously, without changing the NB editor module it's not possible. However, now it is possible to make the watermark bleed through trees, tables and lists. First, you are welcome to view a few Substance-enhanced NetBeans screenshots - note that the trees / tables / lists are opaque and do not show the watermark. Starting from the latest drop of version 2.2 (available in NBM download), Substance supports the -Dsubstancelaf.watermark.tobleed VM flag (no value needed). Once specified, this flag makes all trees, tables and lists transparent. Here's a screenshot to illustrate this (note the left-side trees that show the watermark - click for a fullsize view):

keira-netbeans-small.png

Note that although it's nice to use this option for the above competition, not all NetBeans screens will look good using this VM flag. Although this option instructs all trees, tables and lists (along with the cell renderers) to be transparent, it can't prevent the cell renderers from painting their own background if they override the paint() method. On the other hand this option can spot such problematic places in your application (unless they're there on purpose).

In addition, the latest NBM version (under dev 2.2 directory) allows changing the watermark image from View -> Watermark -> Image menu. The history is limited to five entries (updated on selection) and persisted.

One last thing - if you like Substance, help internationalize it! (small print - eternal glory is not guaranteed :) Starting from version 2.2 (code-named El Paso) the additional UI elements (system menu items, heap status panel, menu search panel) are internationalized. You are welcome to view the list of available translations and send me additional translations to kirillcool [at] yahoo.com. Thanks in advance

Spicing up your JTabbedPane - part II

Posted by kirillcool on December 22, 2005 at 12:49 PM | Permalink | Comments (0)

This entry describes the capabilities that release 2.1 of Substance look-and-feel provides for your tabbed panes. They are:
  • Animation effect for tabs with modified (and unsaved) content
  • Close buttons on tabs with listeners
Following the feedback from the users (thanks Raj), the latest daily drop of version 2.2 (code-named El Paso) provides even more functionality available to your Swing application once you start using Substance LAF.

The first request was to enhance the listener mechanism on close buttons of tabbed panes. As mentioned in the above blog, you can register any number of listeners that will be called when close button of some tab in some tabbed pane is clicked. The CloseTabListener interface defines the following two methods:
/**
 * Called when a tab is about to be closed.
 */
public void tabClosing(JTabbedPane tabbedPane, Component tabComponent);

/**
 * Called when a tab is closed.
 */
public void tabClosed(JTabbedPane tabbedPane, Component tabComponent);
There were two separate requests regarding this mechanism:
  1. Allow the application listener to veto the tab closing
  2. Allow registering listeners per tabbed pane (and not globally)
Now, if you want to provide additional logic and veto the tab closing, you need to implement the VetoableTabCloseListener that extends the TabCloseListener and adds the following function:
/**
 * Called when a tab is about to be closed. Can veto the tab closing.
 *
 * @return true if the corresponding tab shouldn't be closed,
 *         false otherwise.
 */
public boolean vetoTabClosing(JTabbedPane tabbedPane,
	Component tabComponent);
All vetoable listeners that are either registered for the specific tabbed pane, or are registered globally (for all tabbed panes) are called when the close icon is clicked. If at least one of them returns false, the tab will not be closed. Otherwise, the tabClosing and tabClose functions will be called. A simple example is to show the confirmation dialog as:
public void tabClosed(JTabbedPane tabbedPane,
            Component tabComponent) {
  System.out.println("Closed tab - specific");
}

public void tabClosing(JTabbedPane tabbedPane,
            Component tabComponent) {
  System.out.println("Closing tab - specific");
}

public boolean vetoTabClosing(JTabbedPane tabbedPane,
            Component tabComponent) {
  int userCloseAnswer = JOptionPane.showConfirmDialog(
      Check.this,
      "Are you sure you want to close this tab?",
      "Confirm dialog", JOptionPane.YES_NO_OPTION);
  return (userCloseAnswer == JOptionPane.NO_OPTION);
}
The following dialog will be shown to the user when the tab close button is clicked:



Note that this extension doesn't break the existing API which is still fully supported and provides the exact same functionality as before.

The second request was to provide an option for drawing vertical rotated tabs when the current placement for the tabbed pane is either LEFT or RIGHT. The solutions described elsewhere (by Santosh and Lee Ann) involve a composite icon that simulates the tab and effectively hides the text from the tabbed pane UI delegate (by putting it in the icon and rotating the entire icon). The above solutions work, but involve using third-party classes and changing your code to use these classes. In addition, since Substance provides the close buttons on tabs, they are not easily applicable.

Substance provides unintrusive solution for rotated vertical tabs. There are two properties that you can set:
  • SubstanceLookAndFeel.TABBED_PANE_VERTICAL_ORIENTATION is set on a tabbed pane or on UIManager (or both) and instructs the UI delegate to use vertical (rotated) layout for the LEFT and RIGHT-placed tabbed panes.
  • SubstanceLookAndFeel.TABBED_PANE_VERTICAL_ORIENTATION_ROTATE_ICONS is set a tab, a tabbed pane or on UIManager (or any combination) and instructs the UI delegate to leave the icon unrotated.
Note that if you don't wish to create the explicit dependency in your code on the SubstanceLookAndFeel class, you can use the string values for the above properties. Here are a few screenshots to illustrate the outcome, followed by code samples:
  • TOP-placed tabbed pane with five tabs. Each tab has text, icon and a close button (visible when the tab is either selected or under mouse):

  • LEFT-placed tabbed pane under standard layout. Note that the tabs are not rotated and take too much horizontal space:

  • Four parts of the image, from left to right:
    • LEFT-placed tabbed pane with vertical layout. The first tab has unrotated icon, the third tab has unrotated icon which is also disabled, all other tabs have rotated icons.
    • LEFT-placed tabbed pane with vertical and scroll layout. The icons are same as above.
    • RIGHT-placed tabbed pane with vertical and scroll layout. The icons are same as above.
    • RIGHT-placed tabbed pane with vertical layout. The icons are same as above.


Here is how the tabs in the last examples were created:
JTabbedPane jtp = new JTabbedPane();
TabNumberedPanel tnp1 = new TabNumberedPanel(jtp, 1);
tnp1.putClientProperty(
  SubstanceLookAndFeel.TABBED_PANE_VERTICAL_ORIENTATION_ROTATE_ICONS,
  Boolean.TRUE);
jtp.addTab("tab1", SubstanceImageCreator.getThemeIcon(null), tnp1);
jtp.addTab("tab2", SubstanceImageCreator.getThemeIcon(null),
    new TabNumberedPanel(jtp, 2));
TabNumberedPanel tnp3 = new TabNumberedPanel(jtp, 3);
tnp3.putClientProperty(
  SubstanceLookAndFeel.TABBED_PANE_VERTICAL_ORIENTATION_ROTATE_ICONS,
  Boolean.TRUE);
jtp.addTab("tab3", SubstanceImageCreator.getThemeIcon(null), tnp3);
jtp.addTab("tab4", SubstanceImageCreator.getHexaMarker(4,
    SubstanceLookAndFeel.getTheme()), new TabNumberedPanel(jtp,
    4));
jtp.addTab("tab5", SubstanceImageCreator.getHexaMarker(5,
    SubstanceLookAndFeel.getTheme()), new TabNumberedPanel(jtp,
    5));
jtp.setEnabledAt(2, false);
jtp.setEnabledAt(3, false);
jtp.putClientProperty(
  SubstanceLookAndFeel.TABBED_PANE_VERTICAL_ORIENTATION, true);
Note that you get the desired behaviour by setting a few client properties, which have no effect under other look-and-feels.

The only limitation of this technique is for tabs that support arbitrary components (added in Mustang, described in this blog entry by Alexander Potochkin). Such tabs will not be rotated correctly, since these components are not painted using the UI delegates at all. I have discussed this with Alexander and he pointed out additional problem - the need to translate mouse coordinates to allow the tab component to correctly handle the events. The bottom line (at least for Mustang) is - do not use this feature if your application is using the new JTabbedPane functions (which automatically implies that it's running under Mustang).

One last thing - if you like Substance, help internationalize it! (small print - eternal glory is not guaranteed :) Starting from version 2.2 (code-named El Paso) the additional UI elements (system menu items, heap status panel, menu search panel) are internationalized. You are welcome to view the list of available translations and send me additional translations to kirillcool [at] yahoo.com. Thanks in advance

Visual feedback on password strength

Posted by kirillcool on December 16, 2005 at 03:03 AM | Permalink | Comments (1)

The GMail provides a nice visual feedback while you are typing a new password. On each keystroke, the currently typed string is sent to the Google servers (hopefully encrypted) and the computed strength is shown to the user (weak - red, medium - yellow, strong - green). This can serve as either suggestion only (as is in Google's case) or as semi-client side validation (providing feedback to the user before he clicks OK).

The new version of Substance LAF (currently starting its development) provides an option for specifying such feedback. First - three screenshots illustrating the technique:

Weak password - red strip on the password field and custom tooltip text:



Medium password - yellow strip on the password field and custom tooltip text:



Strong password - green strip on the password field and custom tooltip text:



You can also view view this short video clip (412KB, 0:22 min) that illustrates the interaction.

The implementation is quite simple. The PasswordStrengthChecker interface in org.jvnet.substance.utils package defines the following two functions:
public enum PasswordStrength {
  WEAK, MEDIUM, STRONG
}
	
public PasswordStrength getStrength(char[] password);
	
public String getDescription(PasswordStrength strength);
You need to implement this interface (the implementation for the above screenshots looks at the length of the password and returns the corresponding value):
   private static class MyPasswordStrengthChecker implements
         PasswordStrengthChecker {
      public PasswordStrength getStrength(char[] password) {
         if (password == null)
            return PasswordStrength.WEAK;
         int length = password.length;
         if (length < 3)
            return PasswordStrength.WEAK;
         if (length < 6)
            return PasswordStrength.MEDIUM;
         return PasswordStrength.STRONG;
      }

      public String getDescription(PasswordStrength strength) {
         switch (strength) {
         case WEAK:
            return "<html>This password is <b>way</b> too weak</html>";
         case MEDIUM:
            return "<html>Come on, you can do<br> a little better than that</html>";
         case STRONG:
            return "OK";
         }
         return null;
      }
   }
Note that you can return HTML text for the tooltip (as for any Swing tooltip). The last thing you need to do - decide which password fields need this functionality and set the following client property on them:
JPasswordField jpf = new JPasswordField("password", 10);
jpf.putClientProperty(
   SubstanceLookAndFeel.PASSWORD_STRENGTH_CHECKER,
   new MyPasswordStrengthChecker());
The value of the above property must be an instance of PasswordStrengthChecker (will be ignored otherwise).

One last thing - starting from version 2.2 of Substance (code-named El Paso) the additional UI elements (system menu items, heap status panel, menu search panel) are internationalized. You are welcome to view the list of available translations and send me additional translations to kirillcool [at] yahoo.com.

JRockit 5.0 on desktop - show me the money

Posted by kirillcool on December 13, 2005 at 08:24 AM | Permalink | Comments (9)

In the world of seemingly arbitrary records set by JRockit 5.0 JVM from BEA (see this comment on the JavaLobby thread), i have decided to take my test Swing application for a ride.

This application is a test-bed for Substance LAF, so it utilizes a lot of Swing-related stuff, creating all possible core components, a lot of listeners, various layouts, colors etc. After downloading the latest release of JRockit 5.0 and installing it, here are the results (first of all i should mention that i didn't get any compilation or runtime errors, so i guess that "write once run everywhere" is still partly relevant).

There are two phases that i had timed - the UIManager.setLookAndFeel function (which eventually calls the constructor of some LAF, but also does a lot of other stuff) and the creation of the main frame itself (constructor, pack, setting the size, location and visibility). The results are:
  • For JRockit R26.0.0 version 5.0_04 - 1890 ms for initializing the LAF, 3690 ms for showing the main frame and 22MB taken on the heap.
  • For Sun VM version 5.0_06 - 1200 ms for initializing the LAF, 1430 ms for showing the main frame and 7MB taken on the heap.
  • For Sun VM version 6.0 b63 - 840 ms for initializing the LAF, 1500 ms for showing the main frame and 8MB taken on the heap.
The results are for single-CPU (2.4GHz) running WinXP SP2.

As usual, the results of such a 'benchmark' should be taken with a shovel of salt, since you may have different LAF and different Swing application altogether. However, the main conclusion is that JRockit may be 'smoking' hot for running the WebLogic, but it's certainly not a prime option for running desktop applications.

Substance 2.1 official release

Posted by kirillcool on December 12, 2005 at 11:40 AM | Permalink | Comments (7)

Substance look-and-feel has reached the 2.1 release, with a lot of new features and a lot of bugs fixed.

The brief overview of new features:
  • JGoodies Looks' package for drop shadows support on popup windows (menus, tooltips etc)

  • Heap status panel when application is run under decorated mode has been added. The panel can be shown / hidden from the top-level frame menu. Clicking on the panel runs the garbage collector. This panel is shown only when substancelaf.heapStatusPanel VM flag (no value needed) is specified.

  • Added optional rectangular shaper for buttons.

  • Added optional wave gradient painter for buttons.

  • Menu items in the same JMenu or JPopupMenu are aligned so that the texts start at the same X offset. This functionality takes into account menu item icons, menu item marks (for JRadioButtonMenuItem and JCheckBoxMenuItem) and nested menu icons.



  • Support for Mac-like indication on frames that have unsaved content. Application should set SubstanceLookAndFeel.WINDOW_MODIFIED client property on either the JRootPane of the corresponding frame / dialog / internal frame or on the JInternalFrame. The value that corresponds to unsaved state is Boolean.TRUE. See 31-second AVI movie (530 KB) illustrating the technique.

  • Support for Mac-like indication on tabs in JTabbedPane that have unsaved content. Application should set SubstanceLookAndFeel.WINDOW_MODIFIED client property on the tabbed pane's Component (if it's JComponent). The value that corresponds to unsaved state is Boolean.TRUE. See 67-second AVI movie (1.2 MB) illustrating the technique.

  • Support for NetBeans-like close button on tabs in JTabbedPane. Application should set SubstanceLookAndFeel.TABBED_PANE_CLOSE_BUTTONS_PROPERTY client property on either the tabbed pane's Component (if it's JComponent), JTabbedPane (for all tabs of that pane) or the UIManager (for all tabbed panes). The value that corresponds to tab with close button is Boolean.TRUE. In addition, there's rollover effect on enabled tabs (like on any other control such as buttons or scroll bars). See 45-second AVI movie (810 KB) illustrating the technique.

  • The substancelaf.fontSizeExtra VM flag specifies the base font size for all UI controls. The value is integer followed by optional plus + or minus - sign. The integer value plus 11 is the base font size for all UI controls. If plus sign follows the integer value, the base font will be bold. If this flag is not specified, the base font size is 11. For example, -Dsubstancelaf.fontSizeExtra=3+ results in

  • Xoetrope XUI has contributed their color wheel chooser panel:

  • Twenty one additional themes have been provided in the Theme pack plugin.

  • Additional Brushed metal watermark has been added in org.jvnet.substance.watermarkpack.ExtraBrushedMetalWatermark. This watermark is in the Watermark pack plugin.

  • Custom UI delegates for NetBeans components (tabbed container and sliding button) have been added under NetBeans.

  • Eight additional button shapers have been provided in the Button shaper pack plugin.

The full list of new features is available, along with the Web Start demo.

When you know that a programmer is a Java programmer

Posted by kirillcool on December 04, 2005 at 04:47 AM | Permalink | Comments (21)

A long long time ago in a blog far far away I wrote about JDK collections and how should you choose your data structures. This topic has been on my mind during the past year, and I still haven't reached a definitive conclusion.

First, I should mention that i have interviewed about 40 people this year for the technical positions in our project, which gave me an opportunity to see a large variety of programming backgrounds, styles and approaches. Second, we program in Java, which is quite important for the following discussion. Now that this is said, let's continue.

There are numerous techniques for interviewing candidates for technical positions. They range from writing the code on the paper to open-ended design discussions. Most would argue that the best candidate should be well-versed in many conceptually different languages (such as Java / Perl / Lisp), but doesn't have to be a master of any. This will allow him / her to pick the tool (language) that best suites the task. This is true in theory. In practice, however, there are quite a few formidable obstacles to this.

First, most existing projects have already chosen an implementation language, so it would be quite annoying hearing "Let's do this in Ruby" when you have hundreds of man-years invested in the project under your belt. In addition, it's not only your decision - you have existing deployments at customer sites, when sometimes the customer is the one dictating the language (say, somebody invested in a farm of WebLogic servers and wishes your application to be a part of the eco-system there). Furthermore, what about other developers? Sure, in Ruby you can do it in half the time, if only you have 10 experienced Ruby developers (not all applications are CRUD in the real world, unfortunately). Until we get that many available Ruby developers, curb your enthusiasm :(

And now, for the interesting part. Suppose you have an excellent Perl developer and a good Java developer. Which one should you take to your Java project? Arguably, an excellent non-Java developer can learn Java syntax in 4-5 days. But is syntax everything you need to know to write excellent Java code? How much time will it take until he starts to write Java code that looks like Java code and not like Perl code (don't forget that working on team means that the code is maintained by everybody, and even if somebody leaves, his code stays)? Do big projects really need "stellar" developers, or perhaps a team of good developers with solid Java knowledge does better job in the long run?

Which brings me to something that has been on my mind - what turns a programmer to a Java programmer? In my opinion, it's the correct way of working with collections. Once I see a candidate using iterators and maps, this is a very good sign. Most of the people coming from C or C++ work only with arrays or vectors. They sure look like hammers, but most of the real-world problems are bolts. It takes some time to get used to the syntax, it takes more time to know the available options, and it takes much more time to make the correct and informed choice. During this time, an excellent ex-Perl developer is prone to make your code base slower, dirtier and a mess to maintain.

Any thoughts?



Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds