The Source for Java Technology Collaboration
User: Password:



Craig Castelaz

Craig Castelaz's Blog

Help maximize screen space with a small UI trick

Posted by castelaz on October 19, 2004 at 07:32 PM | Comments (11)

Janus2.JPG

Way back in the primordial ooze stage of our new product, it was decided that we needed a custom control rather than use the standard combobox to handle dropdown lists. So, instead of using a JComboBox, we created our own LookupField control that combined a JTextField with a JButton to simulate the more traditional component. There were several reasons for this decision. Two of the more compelling ones had to do with the ability to control the dropdown button. First, it was felt that the standard button on the JComboBox was too wide. We could easily set a narrower width for the button in our custom control. Second, we could completely hide the custom control’s dropdown button whenever we desired. One of the key features of the product is that users can design their own forms. Frequently, screen space on these forms becomes extremely limited. However, if the user sizes the custom control correctly, they can see the entire text of the item they selected from the dropdown list whenever focus is off the custom control because we hide the dropdown button. The button only becomes visible when the LookupField control gains focus. In other words, the full text is only hidden when the user is on the field, most likely because they wish to set or change the control’s value from the dropdown list. Since the user doesn’t have to account for the extra space of the dropdown button when designing their forms, they can maximize the available screen space.

The LookupField served us well for quite some time, but as we migrated to other platforms, and as the look-and-feel of Windows continued to evolve, the custom component began to stick out like the proverbial sore thumb. After collecting samples of what the standard combobox looked like on several target platforms, it was decided that we couldn’t realistically make the LookupField match all them, and that we needed to use the JComboBox. Of course, that meant we would lose our control of the dropdown button. However, as cool as the ability to hide the button was, it wasn’t felt to be critical, and we got the OK to replace the LookupField with the JComboBox control.

Now, many of you are going to be able to guess the rest of this story. Development and Testing were fine with the substitution, but Support and Sales nearly stroked. Everyone agreed that the JComboBox looked way better, but Sales and Support were adamant that hiding the dropdown button was extremely important. Fortunately, this story has a happy ending. After a fair amount time fooling around in the debugger, and writing small experimental snippets of code, we were able to hide the dropdown button on a JComboBox.

As you can see in the example below, Field 2 is somewhat limited in space. However, the control is able to display the full text of the item selected from the dropdown list since the button associated with the combobox is not visible.

comboboxunfocued.JPG

Once Field 2 has focus, the dropdown button becomes visible, and the selection list is just a click away. Note, Field 2 did not increase in size to accommodate the button.

comboboxfocused.JPG

Finally, once the user has made their selection, and moved to another field, the dropdown button disappears, once again revealing the full text of the item selected from the dropdown list.

comboboxnewvalue.JPG

Like our custom LookupField control, the JComboBox is actually made up of several separate controls. While I haven’t confirmed it across all platforms and look-and-feels, the JComboBox appears to have three underlying components: a rendering pane, a button, and a text field if the combobox has been set to editable. Our small UI trick involves adjusting the widths of the underlying button and text field during the control's focus events. The initialization code in the over-ridden paint method records the original sizes for the button and text field, and then adjusts the widths of the two underlying controls so that the combobox does not have a visible dropdown button when the screen is first painted. In other words, the button doesn't appear until the control gains focus. Usage of the custom control isn't any different than that of a standard JComboBox as shown in the QuickTest code. The setting of the preferred height and width in the QuickTest is to simulate a "tight squeeze" on one of the fields.

//CustomComboBox.java
import javax.swing.*;
import java.awt.*;

public class CustomComboBox extends JComboBox  implements FocusListener {

	private boolean initialization;
	private int textFieldWidth;
	private int textFieldHeight;
	private int buttonWidth;
	private int buttonHeight;
	private Component tf;
	private Component bt;

	public CustomComboBox() {
		super();
		initialization = true;
		setEditable(true);
		bt = getComponent(0);
		tf = getComponent(2);
		tf.addFocusListener(this);
	}

	 public void paint(Graphics g){
	 	super.paint(g);
	 	if (initialization) {
			textFieldWidth = tf.getWidth();
			textFieldHeight = tf.getHeight();
			buttonWidth = bt.getWidth();
			buttonHeight = bt.getHeight();
			bt.setSize(0, 0);
			tf.setSize(textFieldWidth + buttonWidth, textFieldHeight);
	 		initialization = false;
	 	}
	 }

	public void focusGained(FocusEvent e) {
		bt.setSize(buttonWidth, buttonHeight);
		tf.setSize(textFieldWidth, textFieldHeight);
	}

	public void focusLost(FocusEvent e) {
		bt.setSize(0, 0);
		tf.setSize(textFieldWidth + buttonWidth, textFieldHeight);
	}
}

// QuickTest.java
import javax.swing.*;
import java.awt.*;

public class QuickTest extends JFrame {

	public QuickTest(String title) {
		super(title);
		setSize(450, 75);
		Container pane = getContentPane();
		pane.setLayout(new FlowLayout());
		JLabel label1 = new JLabel("Field1");
		pane.add(label1);
		JTextField tf1 = new JTextField(10);
		pane.add(tf1);
		JLabel label2 = new JLabel("Field2");
		pane.add(label2);
		CustomComboBox ccb = new CustomComboBox();
		ccb.setPreferredSize(new Dimension(50, ccb.getPreferredSize().height));
		ccb.addItem("ABCDE");
		ccb.addItem("EDCBA");
		pane.add(ccb);
		JLabel label3 = new JLabel("Field3");
		pane.add(label3);
		JTextField tf2 = new JTextField(10);
		pane.add(tf2);
		show();
	}

	public static void main(String[] args) {
		QuickTest qt = new QuickTest("QuickTest");
	}
}

As far as UI tricks go, this one is pretty small potatoes. On the other hand, it has redeemed Development in the eyes of Sales and Support, while preserving a nice feature for the users.

P.S. In case you're wondering, the opening illustration started with a vague intention of showing the somewhat pliable nature of most requirements. Obviously, it missed the mark. Then again, I was pretty happy with it on its own terms, and it cracked up a friend, so I decided to go with it.


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • I looked at this kind of thing a while back, and identified a number of tweaks that could be make to standard UI components to make them more 'footprint' friendly.

    My favourite was the poup-scrollbar. Only the thumb is visible, displaying some visual representation of the position of the scroller ("2/5" or "20%" for example). When clicked the shaft of the scrollbar pops up and allows the thumb to be dragged. When released the shaft vanishes and the thumb snaps back into place with updated details. A really really 'nifty' varient has the shaft itself scroll beneath a stationary thumb, in the opposite direction to the mouse drag. I actually built, from scratch, an example component, but failed to get the mouse pointer/cursor to remain stationary in the latter mode (which kind of spoils the effect).

    Other examples include textfields and textareas which, likewise, expand only when active (ie. focused and having their contents changed.)

    Posted by: javakiddy on October 20, 2004 at 05:01 AM

  • Sounds like a neat trick that engineers and sales might like, but a bad idea from a UI standpoint: user's shouldn't have to guess that there is a drop down menu there, it should be immediately and always obvious (even when the control does not have focus) .

    This sounds like a case of Mystery Meat UI to me.

    Posted by: jimothy on October 20, 2004 at 06:16 AM

  • Neat trick.
    I disagree in part with jimothy that this is unacceptable from a UI standpoint... It should be immediately obvious that a field can be modified, but the mechanism by which it can be modified (in this case a dropdown) isn't as important. We'd have to do useability testing to really know.

    P.S. Nice product list

    Posted by: johnreynolds on October 20, 2004 at 06:23 AM

  • I'm with Jimothy.

    This is a neat UI trick, but falls short is the interaction design category. Its a shock to users when they activate the cell and a new component shows up that covers some of the previously visible component. Some of the text that was visible before dissapears. You might say that this isthe same thing that happens when a combo box's popup is displayed, but the big difference is that the popup hides information outside the combo box and is not so unnerving.

    I generally feel that you should keep to standard components. That said, I don't think this should stifle the idea of creating new components because there is occasionally a real need for a component that doesnt exist.

    It just needs to be done with extreme caution.

    -jonathan

    Posted by: jonathansimon on October 20, 2004 at 07:04 AM

  • One more thing...

    I get asked to help out with interaction design alot around my office. Developers come to me having trouble with a component or layout manager. Often times, there is some fundamental design decision that put them down the wrong track which led them to the current problem -- I think there might be one here.

    This component is saving horizontal space for a screen where everything is laid out horizontally. As an interaction principle, users don't necessarily think horizontally. If these components were arranged vertically (one label and one editing component per row) this problem dissapears.

    -jonathan

    Posted by: jonathansimon on October 20, 2004 at 07:09 AM

  • Shocking!

    Is this an application used occasionally, or is it an application that is used day in, day out? If the latter, then the "shock" of having the dropdown appear will wear off and the user will have the ongoing benefit of an uncluttered display.
    Of course, that's just my opinion. As I mentioned before you need to let the users decide these things. In Craig's case his Sales and Support teams were adamant that this feature was needed... let's hope they were accurately reflecting what the users want.

    Posted by: johnreynolds on October 20, 2004 at 08:10 AM

  • I have to admit that I was completely surprised by the comments so far. I was expecting maybe a few along the lines of JavaKiddy's response, and hadn't thought of the trick as being particularly questionable. On the face of it, hiding the button does seem to violate something, and I certainly wouldn't recommend it as a normal practice. Then again, we limit the availability of the custom control to the user-defined forms where screen space is key concern. I believe John got to the crux nicely. The application is in daily use, and the users have grown accustomed to the behavior.

    I really liked the term "footprint friendly" and will try it out in the future. As for the horizontal layout, I wanted to simulate a tight squeeze for a field, and agree that veritcally stacking the controls would make more sense in a real application.

    Thanks for the comments. One of reasons I like to blog is the occassional whacks upside the head.

    Posted by: castelaz on October 20, 2004 at 09:50 AM

  • I figured you'd get comments about the cartoon. I got two laughs: one when I first read it, and one when the guy next to me didn't get it.

    Thanks,

    Dave

    Posted by: dwalend on October 20, 2004 at 10:50 AM

  • Footprint Friendly (TM) (R) (Pat. Pending) is becoming more and more important. Not only because of the potential future that mobile internet technologies bring, with their small display sizes, but because there has been a rise in the last few years of desktop applications with small 'deshboard' type interfaces (small, easy to use, controls). Instant Messagers, media players, etc.
    Revisiting the design of core UI components with an eye to making them more 'footprint friendly' is a valuable idea - but obviously not all attempts will succeed. (I agree that the JComboBox should *always* be recognisable as such.)
    The Popup Scrollbar works because there are certain applications, mainly audio/video (volume/mixer controls, RGB selectors) were scrollbars are commonplace - and yet they present a real dilema. The ease-of-use of a scrollbar is determined by how many pixels represent each position/value on screen. Small scrollbars are awkward to postion easily. Long scrollbars are easy to position, but use up huge amounts of desktop real estate. A popup scrollbar, with status information on the thumb, means you can have your cake and eat it. Your media player can have a tiny 'dashboard' interface, yet adjusting the volume or tracking to the right place in the current song is still easy.

    Posted by: javakiddy on October 20, 2004 at 11:35 AM

  • Nice trick, and not that shocking imho, even though the user may be a bit surprised the first time.

    But be careful not make GUI's that (rightfully) end up at the "Interface Hall of Shame"!

    http://digilander.libero.it/chiediloapippo/Engineering/iarchitect/shame.htm

    See especially the "Selecting the wrong controls" section.

    By and large, stick to the well known conventions, but allow for some tricks inbetween if it gives is a clear postivie gain.

    /Ragnar :-)

    Posted by: ragnarw on October 21, 2004 at 02:52 AM

  • Wow, I have to embedd HTML tags to get line breaks here.

    NOW I'm shocked!

    /Ragnar :-)

    Posted by: ragnarw on October 21, 2004 at 02:55 AM





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