Archive for the ‘WPF’ Category

Clairvoyant Interaction

Tuesday, August 12th, 2008

This page is where I keep track of interaction design patterns. It will be particularly useful to implement these behaviors in JavaFX/Flex base-classes for nodes so that UX designer don’t have to nitpick over details like these:

  1. Yorai discusses the effect of mouse clicks and shift click, control click on focus, selection, activating in-place editing, dragging
  2. Raymond Chen discusses how a sequence of two single clicks is converted into a double-click event, and how the designer should assume that single click has occurred even if the user has double-clicked because the user double-clicks on everything (I have watched my wife do that). This is known as debouncing
  3. Just for completeness, Raymond Chen discusses triple-clicks.
  4. When waiting for a potential double click, onDragBegin() should not fire unless the mouse has moved a certain minimum distance (this is known as drag tolerance).
  5. Draggable, Droppable, Sortable
  6. Once a mouse is captured during drag-and-drop, when the mouse hovers over other objects, it should fire onDragOver instead of onMouseEnter.
  7. Robert Biggs of Vertigo discusses the minutae of drag and drop parameters
  8. A pretty complete framework for mouse-dragging … we can probably implement this for JavaFX
  9. Dragging should also trigger scrolling in containers

Comparing Owner Drawn in Winforms vs Swing

Monday, May 12th, 2008

I was having a play with custom renderers in Java Swing, and comparing them with the effort required in .NET. I find that in this case, the Swing approaches the problem at a higher level of abstraction (less effort), at the expense of a lot of new objects being created, while .NET goes for a straightforward custom paint.

Here’s an example in Swing, custom rendering JListbox control. Notice that we return a JLabel control here. This is what Swing does by default. We can also choose to return any controls, like combobox, et. c. There’s no additional painting required. In this sense, JListbox resembles a repeater control we see in WPF. The downside is a JLabel control is returned for every visible item in the listbox. Custom drawing can be done by creating an Anonymous inner class with an overridden onPaint handler.

                    jList1.setCellRenderer(new ListCellRenderer() {

                        public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                                // By default, listbox renders using a label
                                JLabel display = new JLabel(value.toString());
                                display.setOpaque(true);
                                display.setBackground(isSelected ? Color.GRAY : Color.WHITE);
                                return display;
                        }
                    });

Contrast this with the J# implementation of custom painting in .NET (sourcecode nicked from MSDN), lots of low level painting, but no new objects being created or garbage collected. However, it’s not clear if you can reuse the paint() routine from an existing control.

private void listBox1_DrawItem(Object sender,
    System.Windows.Forms.DrawItemEventArgs e)
{
    // Set the DrawMode property to draw fixed sized items.
    listBox1.set_DrawMode(DrawMode.OwnerDrawFixed);
    // Draw the background of the ListBox control for each item.
    e.DrawBackground();
    // Create a new Brush and initialize to a Black colored brush
    // by default.
    Brush myBrush = Brushes.get_Black();
    // Determine the color of the brush to draw each item based on the
    // index of the item to draw.
    switch (e.get_Index()) {
        case 0 :
            myBrush = Brushes.get_Red();
            break;
        case 1 :
            myBrush = Brushes.get_Orange();
            break;
        case 2 :
            myBrush = Brushes.get_Purple();
            break;
    }

    // Draw the current item text based on the current Font and the custom
    // brush settings.
    e.get_Graphics().DrawString(System.Convert.ToString(listBox1.
        get_Items().get_Item(e.get_Index())), e.get_Font(), myBrush,
        RectangleF.op_Implicit(e.get_Bounds()), StringFormat.
        get_GenericDefault());
    // If the ListBox has focus, draw a focus rectangle around the selected
    // item.
    e.DrawFocusRectangle();
} //listBox1_DrawItem