ePen 0.7

31. December, 2009

I’ve started to work on ePen again. This time, I’m using Java and SWT/JFace. Python Traits was nice but too slow for my purpose, especially the editor.

This is the main window. As you can see, there is an outline with all characters, places, items, wiki pages and books (with chapters and scenes). The whole thing is meant to save all the information in one place so you can easily find and use them.

Do you see all those nice links? The editor will create them for you from names of characters and other things. If you click on them, you’ll jump right to the meat. I’m thinking of a hover mode where you get a summary but there is a bug somewhere.

The other feature is: No save button. The editor will save your work as you type. If it crashes or your whole computer crashes or there is a power failure? No sweat. Worked for an hour and forgot to save? Won’t happen again. I’m still working on automated backups plus a client/server mode so you can have automatic off-site backups, too.

Right now, I’m shaving off a few rough edges. Then, I’ll drop it on sourceforge.

[EDIT] The project home page is at http://sourceforge.net/projects/epen/


SWT Tree and tooltips

26. December, 2009

If you need tooltips for elements in an SWT Tree or JFace TreeViewer, you had to jump through some hoops as Snippet 125 shows.

Since SWT/JFace 3.3, you should use a TreeViewer, a ColumnLabelProvider (which has all those cool getTooltip() methods) and this line of code:

ColumnViewerToolTipSupport.enableFor (viewer);

That’s it. There is a catch, though: The tooltip doesn’t wrap automatically. If you have long lines of text, you need commons-lang and this piece of code:

    private String wrap (String s)
    {
        StringBuilder buffer = new StringBuilder ();
        
        String delim = "";
        for (String line: s.trim ().split ("\n"))
        {
            buffer.append (delim);
            delim = "\n";
            buffer.append (WordUtils.wrap (line, 60, "\n", true));
        }
        
        return buffer.toString ();
    }

Note that this code is only necessary if you have several lines of text in the tooltip. For single long lines, WordUtils.wrap() alone is enough.

Link to the JFace snippet.


How to make Eclipse 3.5 work on gtk2 2.18

24. December, 2009

If you’re using Eclipse in Linux with gtk2, then you might have run into this issue: Buttons don’t work when you click on them, tree views are initially empty, icons are missing or not drawn correctly. To fix this, just run this command before you start Eclipse:

export GDK_NATIVE_WINDOWS=1

I suggest that you put it into a little wrapper script. With this option enabled, Eclipse works like it should, even on Linux/gtk.

It’s a good example of the pain when working with Eclipse developers: Everyone agrees that it’s a bug and it’s pretty clear what needs to be done. The fix apparently even exists and “just” needs to be copied from the 3.6 sources to 3.5. And nothing happens because the release process is so involved that it just takes too much time and the workaround (adding the line above or control Eclipse with the keyboard) is too simple.

I can’t say on which side I’m on here. I understand why nothing happens but it still freaks me out.


At the restaurant

22. December, 2009

After having been served a soup, the patron calls the waiter: “Please try the soup.”
The waiter is alarmed: “I will return it to the kitchen immediately!”
“No, no!” The patron shakes his head. “Please try the soup.”
W: “Is it too hot?”
P: “No. Please try it.”
W: “Too salty?”
P: “No. Please try it.”
W: “Is the taste not to your liking?”
Patron is getting irritated: “No. Just try it, will you?”
The waiter is confused and bends down, pauses. “Where is the spoon?”
Patron: “Ah!”


Finding unindexed foreign key columns

15. December, 2009

If you’re using Oracle and you have tables with foreign keys, then you must remember to add indexes to all the columns in the referenced tables (i.e. the foreign tables). If your schema has more than two tables, it’s hard to make sure all the necessary indexes exist. Fret no more and let Oracle do (most of) the work for you:

select table_name, constraint_name,
       cname1 || nvl2(cname2,','||cname2,null) ||
       nvl2(cname3,','||cname3,null) || nvl2(cname4,','||cname4,null) ||
       nvl2(cname5,','||cname5,null) || nvl2(cname6,','||cname6,null) ||
       nvl2(cname7,','||cname7,null) || nvl2(cname8,','||cname8,null)
              columns
    from ( select b.table_name,
                  b.constraint_name,
                  max(decode( position, 1, column_name, null )) cname1,
                  max(decode( position, 2, column_name, null )) cname2,
                  max(decode( position, 3, column_name, null )) cname3,
                  max(decode( position, 4, column_name, null )) cname4,
                  max(decode( position, 5, column_name, null )) cname5,
                  max(decode( position, 6, column_name, null )) cname6,
                  max(decode( position, 7, column_name, null )) cname7,
                  max(decode( position, 8, column_name, null )) cname8,
                  count(*) col_cnt
             from (select substr(table_name,1,30) table_name,
                          substr(constraint_name,1,30) constraint_name,
                          substr(column_name,1,30) column_name,
                          position
                     from sys.user_cons_columns ) a,
                  sys.user_constraints b
            where a.constraint_name = b.constraint_name
              and b.constraint_type = 'R'
            group by b.table_name, b.constraint_name
         ) cons
   where col_cnt > ALL
           ( select count(*)
               from sys.user_ind_columns i
              where i.table_name = cons.table_name
                and i.column_name in (cname1, cname2, cname3, cname4,
                                      cname5, cname6, cname7, cname8 )
                and i.column_position <= cons.col_cnt
              group by i.index_name
           )

Isn’t it a beauty? Thanks to Tom.


Groovy Eclipse V2 M2

14. December, 2009

It’s been a couple of days since the Milestone 2 of the new Goovy Eclipse V2 plugin was released. If you’re developing with Groovy and you’re using Eclipse and you’ve been living under a stone, get it now. It’s so much better than the old Groovy plugin.

In word: Development with Eclipse has become Groovy, again.

Links:
Groovy-Eclipse 2.0.0M2 New and Noteworthy
Groovy-Eclipse 2.0.0M1 New and Noteworthy


When to micromanage

11. December, 2009

When it comes to work, there are two extremes: There are those people who are enthusiastic and, once started, can hardly be stopped and there are the ones which think “Monday, 9:00am, and the weeks still isn’t over”.

Micro-managing the former will make them quit (or as Joel Spolsky put it: “Doesn’t micromanagement turn smart people into robots?“). Not micro-managing the latter will result in no work being done.

Which explains nicely why it’s a pleasure/pain to work with some craftsman: Some of them love their job, they delight in producing a perfect result which will make the customer happy. And the other ones can’t be bothered.


Why WYSIWYG doesn’t work II

7. December, 2009

In my old post “The Space Between Two Characters“, I wrote about some flaws of WYSIWYG. Since then, I got some feedback.

The real issue behind the issues with WYSIWYG is that it doesn’t work while you edit the document. The concept is flawed, not the implementation. It is flawed because it omits some vital information that you need for editing. The information is omitted because it doesn’t make sense anymore as soon as you print the document on paper. And WYSIWYG means “if you don’t see it, you won’t get it.”

So it makes sense to omit feedback on where ranges start and end, what kind of break follows after a line, there the handles for a table are. But most WYSIWYG editors today have a “show invisible” option. Word can show you all those invisible characters so you can see “oh, this is a tab and not a space”.

For this to work, we need a tight integration between the editor model, the renderer and the view. The problem here is, as usual, performance. If you add all the hooks you need to be able to show nice visual feedback in the view, printing to a printer will be slower.

How much? Well, not much. Anymore. You’re quadcore will be 95% bored. It will need memory. How much? Well, to remember the bounding boxes for all letters rendered on the screen takes at most 4’608’000 bytes (“i”, 8px font, 30″ display with 3840×1200). That might seem like a lot but almost no PC sold next year will have less then 4GB of RAM, not even the Netbooks. My mobile phone comes with 32GB!

For printing, the values are usually much smaller. A normal page of text has around 1’500 to 2’500 characters per page and for printing, you just need to remember the current and maybe the next page (unless you need a page count but with todays CPUs, you can layout the pages twice).

So the final obstacles is code complexity. OO has helped a lot to cut down complexity in algorithms but there are problems which you can’t solve nicely with OO, for example “run this algorithm but replace line 5 with …” or “before … run …”.

AOP has come to solve this but it has failed to deliver so far. Maybe this is because point-cuts are too complicated to formulate, maybe because the debuggers can’t handle this case well, maybe because the setup is too complex or the resulting code is too fragile. Or because people are afraid of the leap of faith it takes to use it.