Strange multiselect in Flex lists

With old halo lists mx:List you can allow the user to select multiple list items. Set allowMultipleSelection = true and you can add single items to the selected group via Ctrl + Click. Via Shift + Click you can select a set of items. Click on one item to select the first and then Shift + Click on another one to select the whole range of items between the first and last one (each included).

Nothing unexpected so far.

But if you do another Shift + Click to change the selected range, the Flex list reacts strangely. For example, say you’ve clicked on item 3 and then Shift + clicked on item 5, you select items 3 to 5. But what happens when you Shift + click on item 7 afterwards? Windows Explorer and MacOS X Finder will select items 3 to 7. If you then Shift + click on 1, they select 1 to 3. So, the general rule for those standard item lists is that you set an anchor with the first click and each following Shift + click selects all items between this anchor and the last clicked item.

But not so in the Flex list. mx:List resets the anchor with every Shift + click to the last clicked item. The following table highlights the described differences between Explorer/Finder and the Flex list:

Action Explorer Finder mx:List
click 3 3 3 3
shift+click 5 3-5 3-5 3-5
shift+click 7 3-7 3-7 5-7
shift+click 1 1-3 1-3 1-7

I think this is very confusing for the user, because there is no obvious reason for the flex lists to behave in a different way than the corresponding native lists of the operating system. So I wrote the following patch to fix this:

import mx.collections.CursorBookmark;
import mx.controls.List;
import mx.controls.listClasses.IListItemRenderer;

public class OSLikeList extends List {

    private var firstShiftClick:Boolean = true;
    private var oldAnchorBookmark:CursorBookmark;
    private var oldAnchorIndex:int;

    public function OSLikeList() {
        super();
    }

    override protected function selectItem(item:IListItemRenderer, shiftKey:Boolean, ctrlKey:Boolean, transition:Boolean = true):Boolean {
        if (shiftKey && allowMultipleSelection) {
            if (firstShiftClick) {
                oldAnchorBookmark = anchorBookmark;
                oldAnchorIndex = anchorIndex;
                firstShiftClick = false;
            } else {
                anchorIndex = oldAnchorIndex;
                anchorBookmark = oldAnchorBookmark;
            }
        } else {
            firstShiftClick = true;
        }
        return super.selectItem(item,  shiftKey, ctrlKey, transition);
    }

}
Advertisements

How to install Sun Java JDK via command line and wget

Our business software REWOO Scope runs as a Java application and uses the Sun Java JDK under CentOS 7 (minimal package). To setup a linux system with a running Sun Java, you need a browser and working filetransfer – but why not use wget to download the missing file?

Simple question, difficult answer: Sun dissalowed direct downloads of java from their servers. You have to agree with the license conditions by browser.
It seems that a single cookie is all that is needed to bypass this. If you want to download jdk7u67 for 64-bit Linux using wget, you can use:

wget --no-cookies --no-check-certificate\
--header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie"\
"http://download.oracle.com/otn-pub/java/jdk/7u67-b01/jdk-7u67-linux-x64.rpm"

But remember: each version of Java is located in a different folder. For other versions than 7u67 you have to use the respective URL.

Flex application not redrawing screen

From time to time we observe issues with the Pepper player, the built-in Flash player of the Chrome browser. Since January we fight against the problem that our Flex application is not properly redrawing the screen after user interaction.

Fortunately, we stumbled across this issue in the chromium bug database. According to the comments there we have to force the refresh of the application. Of course, we should do this for the Pepper player only, but this is not a great deal. The Adobe online help states how to detect a Pepper player.

Solution

First we check if the user has a Pepper player. In this case we create a timer which calls every 500 ms invalidateDisplayList() on the main Application object.

private static var _refreshTimer:Timer;

public static function checkPepperPlayer(app:Application):void {
    if (Capabilities.manufacturer === "Google Pepper" && !_refreshTimer) {
        _refreshTimer = new Timer(500);
        _refreshTimer.addEventListener(TimerEvent.TIMER, function(event:TimerEvent):void {
            app.invalidateDisplayList()
        });
        _refreshTimer.start();
    }
}

Postgres down after Time Machine restore

A few days ago my MacBook crashed. I had to erase the harddisk and restore the data from the latest Time Machine backup. After a few hours reading a book my MacBook worked as though nothing had happened – except the postgres server. On OS X the log files can be found in /Library/PostgreSQL/8.4/data/pg_log

I looked in the newest log file with

sudo less /Library/PostgreSQL/8.4/data/pg_log/postgresql-2014-01-14_152823.log

and found a PANIC log message

2014-01-14 15:28:23 CET LOG:  record with zero length at 19/3DA0E2C0
2014-01-14 15:28:23 CET LOG:  invalid primary checkpoint record
2014-01-14 15:28:23 CET LOG:  record with zero length at 19/3DA0E27C
2014-01-14 15:28:23 CET LOG:  invalid secondary checkpoint record
2014-01-14 15:28:23 CET PANIC:  could not locate a valid checkpoint record

If you want to analyse the transaction log switch user to postgres and use

sudo su - postgres
/Library/PostgreSQL/8.4/bin/pg_resetxlog /Library/PostgreSQL/8.4/data

In my case the transaction log was corrupt and the data didn’t matter. So I used -f to force reset

/Library/PostgreSQL/8.4/bin/pg_resetxlog -f /Library/PostgreSQL/8.4/data

See also this discussion at stackoverflow

Flash ReferenceError #1069: topMostIndex not found

Today, I struggled loading our flex application. I always got the following error

ReferenceError: Error #1069: Property http://www.adobe.com/2006/flex/mx/internal::topMostIndex not found on _Main_mx_managers_SystemManager and there is no default value.

It take me some time to find the solution: This error is caused by the new deployed version 4.57 of FlashFirebug from November 17, 2012. The newest version 4.58 fix this problem but it is not reviewed and therefore not yet deployed via auto-update. You can get this version from Mozilla and you can install it manually by moving your mouse over the version description and clicking “Add to Firefox” button.

Good font for coding

Some days ago Adobe announced a new monospaced OpenType font Source Code Pro designed for coding environments. I have used Menlo for years now and was curious if I can see any benefits from the new font for coding.

I find the described advantages of Source Code Pro in Menlo too: readability of potentially confusable characters like iI1 or O0 and readability of punctuation marks, brackets and mathematical symbols. But with the same font size the character height of Source Code Pro is smaller but the line height is larger. Take a look at a code snippet in 12pt, screenshot height 200px

Source Code Pro 12 pt

Menlo 12 pt

If you increase the real font size to get the same perceived font size the same code needs more screen width and height with Source Code Pro than with Menlo. And the additional line spacing is needless because you can configure the line spacing in most of the IDEs.

For me it’s very important to get as many information on the screen as possible. I don’t like to scroll to see the context or to read the line to its end. Sure, good code is short. A function has only twenty lines of code with no line longer than 120 characters and a class ends after two screens. But in real life you have to read some code from your colleagues. And be honest: not every line you wrote follows the rules of clean code…

I like the Menlo. It looks more elegant to me and I see more code. I will continue using it for coding.