Skip to main content

Help maximize screen space with a small UI trick

Posted by castelaz on October 19, 2004 at 7:32 PM PDT

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.

Related Topics >>