GXT - How to select items in non-editable ComboBox by pressing keys

We have a non-editable GXT ComboBox with quite numerous items (100-200), which is hard to select by scrolling (even if they are alphabetically ordered). It would be nice and faster to have the possibility to select items by typing the keys. Unfortunately this feature isn't built-in GXT non-editable combo-box, like it's done for the editable one.

In this case we can fix it by extending the ComboBox class and add to it a key listener and a timer. When we press a key we collect the chars into a buffer and then we look for the item that starts with that text. If we didn't type anything for more than 1 second, then we reset the buffer to allow trying another letters, if the one typed earlier aren't good.

*** The GXT solution is the implementation of the selectable combo-box (preferred ordered, but not a mandatory requirement) by keys is presented below:

public class SccComboBox<D extends ModelData> extends ComboBox<D> {
    private final StringBuilder buffer;
    private final DelayedTask resetBufferTimer; 


    /** constructor */
    public SccComboBox () {
        buffer = new StringBuilder();
resetBufferTimer = new DelayedTask(new Listener<BaseEvent>() {
@Override
public void handleEvent(final BaseEvent be) {
buffer.delete(0, buffer.length());
}
});
    }



    /**
     * {@inheritDoc}
     */
    @Override
    protected void onKeyPress(FieldEvent fe) {
        if (isExpanded()) {
            if (!fe.isSpecialKey()) {
buffer.append((char) fe.getKeyCode());
           }
           if (fe.getKeyCode() == KeyCodes.KEY_BACKSPACE) {
int idx = buffer_.length() - 1;
if (idx >= 0) {
                   buffer.deleteCharAt(idx);
}
           }


           for (D d : store.getModels()) {
String v = propertyEditor.getStringValue(d);
if (v.toLowerCase().startsWith(buffer.toString().toLowerCase())) {
                  select(d);
                  break;
}
           }


           /* timer timeout 1 second */
           resetBufferTimer.delay(1000);
}
        super.onKeyPress(fe);
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public void expand() {
        buffer.delete(0, buffer.length());
        super.expand();
    }
}

** The solution for pure GWT implementation is similar with the above code, but with few small changes. We need to replace the DelayedTask with my previous pure GWT implementation of the DelayedTask, LastCallBurstEventsMgr, like in the below code:
  1. First of all, remove the resetBufferTimer local member variable from the SccComboBox, definition and constructor.
  2. Secondly, at the line /* timer timeout 1 second */ we replace the next code line with the following ones:

   /* timer timeout 1 second */
   LastCallBurstEventMgr.addEvent (new BurstEvent ("reset-buffer-timer", new Function() {
       public void execute () {
  buffer.delete(0, buffer.length());
       }
   }, 1000));

So, having this logic added to the ComboBox will resolve your "selection in long combo-box" problem.

Cheers!

Things Every Programmer Should Know: $25, #26, #27

Here are the 97 Things Every Programmer Should Know project, pearls of wisdom for programmers collected from leading practitioners, published by O'Reilly (license link).




You can go to read the previous very interesting points #22 #23, #24.


25. Don't Be Cute with Your Test Data by Rod Begbie



It was getting late. I was throwing in some placeholder data to test the page layout I'd been working on.
I appropriated the members of The Clash for the names of users. Company names? Song titles by the Sex Pistols would do. Now I needed some stock ticker symbols — just some four letter words in capital letters.
I used those four letter words.
It seemed harmless. Just something to amuse myself, and maybe the other developers the next day before I wired up the real data source.
The following morning, a project manager took some screenshots for a presentation.

Programming history is littered with these kinds of war stories. Things that developers and designers did "that no one else would see" which unexpectedly became visible.
The leak type can vary but, when it happens, it can be deadly to the person, team, or company responsible. Examples include:
  • During a status meeting, a client clicks on an button which is as yet unimplemented. They are told: "Don't click that again, you moron."
  • A programmer maintaining a legacy system has been told to add an error dialog, and decides to use the output of existing behind-the-scenes logging to power it. Users are suddenly faced with messages such as "Holy database commit failure, Batman!" when something breaks.
  • Someone mixes up the test and live administration interfaces, and does some "funny" data entry. Customers spot a $1m "Bill Gates-shaped personal massager" on sale in your online store.
To appropriate the old saying that "a lie can travel halfway around the world while the truth is putting on its shoes," in this day and age a screw-up can be Dugg, Twittered, and Flibflarbed before anyone in the developer's timezone is awake to do anything about it.
Even your source code isn't necessarily free of scrutiny. In 2004, when a tarball of the Windows 2000 source code made its way onto file sharing networks, some folks merrily grepped through it for profanity, insults, and other funny content. (The comment // TERRIBLE HORRIBLE NO GOOD VERY BAD HACK has, I will admit, become appropriated by me from time to time since!)
In summary, when writing any text in your code — whether comments, logging, dialogs, or test data — always ask yourself how it will look if it becomes public. It will save some red faces all round.



26. Don't Ignore that Error! by Pete Goodliffe



I was walking down the street one evening to meet some friends in a bar. We hadn't shared a beer in some time and I was looking forward to seeing them again. In my haste, I wasn't looking where I was going. I tripped over the edge of a curb and ended up flat on my face. Well, it serves me right for not paying attention, I guess.
It hurt my leg, but I was in a hurry to meet my friends. So I pulled myself up and carried on. As I walked further the pain was getting worse. Although I'd initially dismissed it as shock, I rapidly realized there was something wrong.
But I hurried on to the bar regardless. I was in agony by the time I arrived. I didn't have a great night out, because I was terribly distracted. In the morning I went to the doctor and found out I'd fractured my shin bone. Had I stopped when I felt the pain, I'd've prevented a lot of extra damage that I caused by walking on it. Probably the worst morning after of my life.
Too many programmers write code like my disastrous night out.
Error, what error? It won't be serious. Honestly. I can ignore it. This is not a winning strategy for solid code. In fact, it's just plain laziness. (The wrong sort.) No matter how unlikely you think an error is in your code, you should always check for it, and always handle it. Every time. You're not saving time if you don't: You're storing up potential problems for the future.
We report errors in our code in a number of ways, including:
  • Return codes can be used as the resulting value of a function to mean "it didn't work." Error return codes are far too easy to ignore. You won't see anything in the code to highlight the problem. Indeed, it's become standard practice to ignore some standard C functions' return values. How often do you check the return value from printf?
  • errno is a curious C aberration, a separate global variable set to signal error. It's easy to ignore, hard to use, and leads to all sorts of nasty problems — for example, what happens when you have multiple threads calling the same function? Some platforms insulate you from pain here; others do not.
  • Exceptions are a more structured language-supported way of signaling and handling errors. And you can't possibly ignore them. Or can you? I've seen lots of code like this:
try {
    // ...do something...
}
catch (...) {} // ignore errors
The saving grace of this awful construct is that it highlights the fact you're doing something morally dubious.
If you ignore an error, turn a blind eye, and pretend that nothing has gone wrong, you run great risks. Just as my leg ended up in a worse state than if I'd stopped walking on it immediately, plowing on regardless can lead to very complex failures. Deal with problems at the earliest opportunity. Keep a short account.
Not handling errors leads to:
  • Brittle code. Code that's filled with exciting, hard-to-find bugs.
  • Insecure code. Crackers often exploit poor error handling to break into software systems.
  • Poor structure. If there are errors from your code that are tedious to deal with continually, you have probably have a poor interface. Express it so that the errors are less intrusive and the their handling is less onerous.
Just as you should check all potential errors in your code, you need to expose all potentially erroneous conditions in your interfaces. Do not hide them, pretending that your services will always work.
Why don't we check for errors? There are a number of common excuses. Which of these do you agree with? How would you counter each one?
  • Error handling clutters up the flow of the code, making it harder to read, and harder to spot the "normal" flow of execution.
  • It's extra work and I have a deadline looming.
  • I know that this function call will never return an error (printf always works, malloc always returns new memory — if it fails we have bigger problems...).
  • It's only a toy program, and needn't be written to a production-worthy level.



27. Don't Just Learn the Language, Understand its Culture by Anders Norås



In high school, I had to learn a foreign language. At the time I thought that I'd get by nicely being good at English so I chose to sleep through three years of French class. A few years later I went to Tunisia on vacation. Arabic is the official language there and, being a former French colony, French is also commonly used. English is only spoken in the touristy areas. Because of my linguistic ignorance, I found myself confined at the poolside reading Finnegans Wake, James Joyce's tour de force in form and language. Joyce's playful blend of more than forty languages was a surprising albeit exhausting experience. Realizing how interwoven foreign words and phrases gave the author new ways of expressing himself is something I've kept with me in my programming career.
In their seminal book, The Pragmatic Programmer, Andy Hunt and Dave Thomas encourage us to learn a new programming language every year. I've tried to live by their advice and throughout the years I've had the experience of programming in many languages. My most important lesson from my polyglot adventures is that it takes more than just learning the syntax to learn a language: You need to understand its culture. 
You can write Fortran in any language, but to truly learn a language you have to embrace the language. 
Don't make excuses if your C# code is a long Main method with mostly static helper methods, but learn why classes make sense. Don't shy away if you have a hard time understanding the lambda expressions used in functional languages, force yourself to use them.

Once you've learned the ropes of a new language, you'll be surprised how you'll start using languages you already know in new ways. 
I learned how to use delegates effectively in C# from programming Ruby, releasing the full potential of .NETs generics gave me ideas on how I could make Java generics more useful, and LINQ made it a breeze to teach myself Scala.
You'll also get a better understanding of design patterns by moving between different languages. C programmers find that C# and Java have commoditized the iterator pattern. In Ruby and other dynamic languages you might still use a visitor, but your implementation won't look like the example from the Gang of Four book.
Some might argue that Finnegans Wake is unreadable, while others applaud it for its stylistic beauty. To make the book a less daunting read, single language translations are available. Ironically, the first of these was in French. 
Code is in many ways similar. If you write Wakese code with a little Python, some Java, and a hint of Erlang, your projects will be a mess. If you instead explore new languages to expand your mind and get fresh ideas on how you can solve things in different ways, you will find that the code you write in your trusty old language gets more beautiful for every new language you've learned.



The 'episodes' #28, #29, #30 will come in the next posting :) 

Cheers!