Site Sponsors:
Faster Field Support using Enumeration & Arrays 
The humble 'enum' has come a long way. --Indeed, when I first taught the 'enumeration concept' (i.e why use numbers, when you can use names) a few decades ago, I was using C/C++.

Today both .Net and Java have their humble 'enum' equivalent:

enum codes {
one, two, three
}

--Easy enough to understand.

Object Members


What is interesting to note however is that, unlike C/C++, any 'enum' in either Java or .Net is not merely about mnemonic substitution. Rather, the enum keyword in both technologies creates a fully-qualified Object:


public String get(codes which) {
return vals.get(which.ordinal());
}

public String set(codes which, String sWho) {
return vals.set(which.ordinal(), sWho);
}


Like any Object, any instance of 'enum' in .Net and Java has member functions. Amongst other things, by default the members of an 'enum' allow us to translate between a set of zero-based integers, as well as any enumerated token.

Enumerated Rarefactions


Since by default the enum uses a zero-based ordinal (read i-n-t-e-g-e-r ;), the use of any enumerated set of tokens readily transfers over to a zero-based array usage. The piratical :) application of this default numbering series is that any set of arbitrary enumerators can be used to quickly create a class, with just as many value-storage opportunities:

class ClientSettings {
ArrayList<String> vals = new ArrayList<String>();

public enum codes {
// We could also use enums like name, address, phone (etc)
one, two, three
}

public ClientSettings() {
codes[] set = codes.values();
for (codes code : set) {
vals.add(code.name());
}
}

public String get(codes which) {
return vals.get(which.ordinal());
}

public String set(codes which, String sWho) {
return vals.set(which.ordinal(), sWho);
}

public static void main(String[] args) {
ClientSettings ref = new ClientSettings();
if (ref.get(codes.two).equals(codes.two.name()) == false) {
System.out.println("Error - Conceptual failure #1.");
}
String sTest = "Enumerated arrays are so easy, they are scary.";
ref.set(codes.two, sTest);
if (ref.get(codes.two).equals(sTest) == false) {
System.out.println("Error - Conceptual failure #2.");
}
}

In short, no mater if we have 2 or 200 values. -Whenever we want to quickly create a class to support the storing of one or all of them, all we have to do is to update a single 'enum'. --The rest is as good (or evil ;) as is the enumerated set of tokens we choose to represent our data_stored therein.

Enjoy,

-Rn

(p.s: The above is a Java demonstration. The proof of concept is in main().)

[ view entry ] ( 2832 views )   |  permalink
JDK Issues - JPanel 

X11 Errors


There I was - poised to release another version of "The Sierra Bible", when we noticed - yet again - that not all Java Implementations are equal. Each have their own problems.

In this case, a buglet we were stalking came down to how The Sun 1.6 JDK implemented their hooks into the platform window manger (in this case, X11.) While Open JDK was working just fine, Sun's implementation was proving to be - uh - exceptional.

Exception Situation


Be they hosted by JDialog or JFrame, more and more folks are using panels.

Here is a JDialog using a JPanel:


public jdlgPopUp(JFrame parent, JPanel pan, String sTitle) {
super(parent, false);
initComponents();
this.getContentPane().add(pan, "card");
setTitle(sTitle);
pack();
}


Again, all worked fine under Open JDK. Under Sun, however, we saw:


Exception in thread "AWT-EventQueue-0" sun.awt.X11.XException: Cannot write XdndAware property
at sun.awt.X11.XDnDDropTargetProtocol.registerDropTarget(XDnDDropTargetProtocol.java:79)
at sun.awt.X11.XDropTargetRegistry.registerDropSite(XDropTargetRegistry.java:554)
at sun.awt.X11.XWindowPeer.addDropTarget(XWindowPeer.java:1633)
at sun.awt.X11.XComponentPeer.addDropTarget(XComponentPeer.java:1509)
at java.awt.dnd.DropTarget.addNotify(DropTarget.java:493)
at java.awt.Component.addNotify(Component.java:6687)
at java.awt.Container.addNotify(Container.java:2567)
at javax.swing.JComponent.addNotify(JComponent.java:4685)
at java.awt.Container.addNotify(Container.java:2578)
at javax.swing.JComponent.addNotify(JComponent.java:4685)
at java.awt.Container.addNotify(Container.java:2578)
at javax.swing.JComponent.addNotify(JComponent.java:4685)
at java.awt.Container.addImpl(Container.java:1068)
at java.awt.Container.add(Container.java:927)
at com.soft9000.VerseWorker.jdlgPopUp.<init>(jdlgPopUp.java:41)

The above exception was obviously bumped into while negotiating the X11 interface ("Cannot write XdndAware property".) Some variation of the problem was the same no matter if we were using JDialog, or JFrame. The result was - on error - that only Suns' JDK fails to display the application. Without a UI, you've got to kill the zombie explicitly.

(Note: Many implementations can assist with Java 'zombie management' by providing a PID as the prefix for a process name:
ManagementFactory.getRuntimeMXBean().getName();
)

The Solution


The solution, however, was to have a little faith in the Java specification! Indeed, is as much as every other JRE we had was able to "pass the test", we decided to simply add - then remove - another container from jdlgPopUp:


public jdlgPopUp(JFrame parent, JPanel pan, String sTitle) {
super(parent, false);
initComponents();
this.getContentPane().removeAll();
this.getContentPane().add(pan, "card");
setTitle(sTitle);
pack();
}

-Adding another component insured that the dialog initially did what it takes to register another container (in this case, a mere JScrollPane,) properly.

Using .removeAll(), in-turn, then ensured that those same X11 Structures were in place. -All things attributed & properly ORed so that our JPanel can re-use them.

Conclusion


Of course it all works fine now. After the above, our beta-testing continues on-schedule.

Indeed, by laying our hands upon just about every pre-installed, de-facto, or add-on JRE we can lay think of (Windows, OS X, Ubuntu, Oracle, IBM, etc,) the mission is all about supporting our fellow software enthusiasts.

So far, this fix works on everything we can hum at it.

Enjoy,

-Rn


[ view entry ] ( 3861 views )   |  permalink  |  related link
Color Enforcement in Swing 

Santa's Clothes


When a local charity asks one to be Santa Clause for the season, the first thing to do is to consider the audience.

In as much as this charity's audience consisted some affluent, yet also some very poor children, it was for more reasons than for my geeky-girth that we decided that we might fit the fuzzy-red suit rather nicely.

Santa's Certificate


Once folks learned that we were indeed GUI-enabled however, thoughts turned to how we might warp our talents into creating something fun; A gift that might make a kid's season a little brighter:



After passing the hat, the idea was to gift each happy-lap-sitter a certificate; A smiling-enhancing present; -Something charity-affordable (read f-r-e-e) that a child might brandish to tell the world how nice they were trying to be.

Santa Tech


So in addition to donning the suit, we put-on a little Java for the season. While we could have used C#, I wanted to ensure that kids everywhere had a chance to get a certificate from elves welding as many different types of computers, as possible.

One thing leading to another (as they usually do) we also decided that since not all Elves like the same colors, that we needed a quick way to blanket an entire GUI with the same font, color, background, and foreground attributes.


package com.soft9000.gui;

import java.awt.Component;
import java.awt.Container;
import javax.swing.JComponent;

/**
* An opportunity to demonstrate a way to recursively impose an arbitrary set of
* attributes on a Component/JComponent Hierarchy.
*
* @author profnagy
*/
public class StyleMaster {

/**
* Enforce the style on a Container.
*
* @param ref A Container - Like JFrame - While not Components, they have them :)
* @param example The Component to use for the change.
*/
public static void Enforce(Container ref, Component example) {
if (ref == null || example == null) {
return;
}
ref.setForeground(example.getForeground());
ref.setBackground(example.getBackground());
ref.setFont(example.getFont());
Enforce(ref.getComponents(), example);
}

/**
* Enforce the example style on a JComponent and any JComponent Children.
*
* @param ref The Component to change.
* @param example The Component to use for the change.
*/
public static void Enforce(JComponent ref, Component example) {
if (ref == null || example == null) {
return;
}
Enforce((Component) ref, example);
Enforce(ref.getComponents(), example);
}

/**
* Enforce the example style on a Component array and any JComponent Children.
*
* @param ref The Component to change.
* @param example The Component to use for the change.
*/
public static void Enforce(Component[] ref, Component example) {
if (ref == null || example == null) {
return;
}
for (Component comp : ref) {
try {
JComponent jcomp = (JComponent) comp;
Enforce(jcomp, example);
} catch (ClassCastException ex2) {
Enforce(comp, example);
}
}
}

/**
* Enforce the example style on a Component. (Everything gets here eventually.)
*
* @param ref The Component to change.
* @param example The Component to use for the change.
*/
public static void Enforce(Component ref, Component example) {
if (ref == null) {
return;
}
ref.setFont(example.getFont());
ref.setForeground(example.getForeground());
ref.setBackground(example.getBackground());
}
}

Since I was using Swing, the task was easy enough:

/** Creates new form jpNaughtyNice01 */
public jpNaughtyNice01(JFrame parent) {
this.parent = parent;
initComponents();
jbMasterElf.setFont(new Font("Comic Sans MS", Font.BOLD, 18));
jbMasterElf.setForeground(this.jlblBrowser.getForeground());
jbMasterElf.setBackground(this.jpElfMode.getBackground());

StyleMaster.Enforce(this, jbMasterElf);
}

Our Christmas Present to aspiring Java GUI Guru's everywhere is to share with you how we were able to do that quickly, easily, and efficiently.

JComponent


While just about everything can be updated, note that the inability to set the tab-color of a JTabbedPane is well known:



What is sage, however, was to demo what setting the background color of a combo box did. By keeping the selection from looking like a JTextEdit, no matter what color we use the default dithering always seems to look rather nice:



By factoring in the foreground-color, even the blending of a button-background looks 'kewel, too.

But Wait - There's More!


(-I've always wanted to 'blog that) :)

But here is the real bonus - in as much as everything from JOptionPane to JFileChooser is a JComponent, you can use StyleMaster to make even the standard components match. So when it come time to use another component:


private void jbLocateCertActionPerformed(java.awt.event.ActionEvent evt) {
JFileChooser ref = new JFileChooser();
StyleMaster.Enforce(ref, this.jbMasterElf);
ref.showOpenDialog(parent);
}


-The above single line of code will Enforce() a nice change on just about anything 'Swing:





You've just gotta love recursion: Well done, Oracle/Sun!


--See you at the mall,

-R.A.Nagy


[ view entry ] ( 2557 views )   |  permalink  |  related link

<<First <Back | 1 | 2 | 3 | 4 | Next> Last>>