The Source for Java Technology Collaboration
User: Password:



Scott Violet

Scott Violet's Blog

Extreme List View

Posted by zixle on December 18, 2006 at 08:39 AM | Comments (16)

In my last blog we finally released the source for this years Extreme GUI Makeover talk; hooray! There are a number of aspects of the app that are worth exploring. For this blog, I want to explore how the extreme list view was done. What I'm calling the extreme list view can be seen in the following screen shot:

As you may be able to surmise from the screen shot, and the name, the extreme list view is nothing more than a JList with a custom ListCellRenderer. The ListCellRenderer is implemented as a JPanel, that uses GroupLayout to achieve the desired effect.

If you look at the layout of each cell, you'll notice the layout is nearly a grid, but not quite. The first row has two columns, the second row one column, and the third row two columns. The reason this doesn't fit well with a grid is that the second columns of the first and last row shouldn't have the same size. Most grid based layout managers enforce all columns to have the same size. I've no doubt there is some grid based layout managers that does this, but not GridBagLayout. Of course you could always implement this as nested panels, but that should be avoided when possible!

GroupLayout does not enforce the components be in a grid, although grid based layouts are certainly possible with GroupLayout. As such, GroupLayout is particularly well suited for this layout, and it gave me another chance to play with GroupLayout. Here's how this layout is implemented in terms of GroupLayout. For those wishing to learn more about GroupLayout before getting into the nitty gritty, we've just updated the Swing Tutorial to include coverage of GroupLayout, which can be found here.

GroupLayout treats each axis independently. Looking at the horizontal axis, visually you can see space needs to be provided for the image, followed by three rows of text. This translates to:

(IP + rows)
Which equates to a sequential group with the image component, followed by the rows. As the rows are positioned in the same space, horizontally, the components in each row need to be placed in a parallel group:
(I + [R1 R2 R2])
I'm using parens to denote sequential groups, and brackets to denote parallel groups. The first and third row consist of two components each for the differing labels. As the labels in each are placed one after another, a sequential group is used:
(I + [(S + C0) C1 (C2 + F)])
The key for this layout is that all extra space should go to the subject and content text. This is achieved by explicitly specifing the subject and context text have a minimum and preferred size of 1, and a maximum size of Integer.MAX_VALUE:
  addComponent(component, 1, 1, Integer.MAX_VALUE);
All other components are forced to use their preferred size for the min/pref/max. As JLabels already do this, you can use the single argument addComponent, or explicitly request this behavior with the following code:
  addComponent(component, PREFERRED_SIZE, PREFERRED_SIZE, PREFERRED_SIZE);
Viewed graphically, this looks like:

Here's the complete code for creating the horizontal grouping:

  GroupLayout.SequentialGroup hg = layout.createSequentialGroup();
  layout.setHorizontalGroup(hg);
  // Add the image panel with a fixed size
  hg.addComponent(imagePanel, IS, IS, IS).
    // Create parallel group that will contain the rows
    addGroup(layout.createParallelGroup().
      // First row contains the subject, and date labels
      // Notice the subject is infinitely resizable
      addGroup(layout.createSequentialGroup().
        addComponent(subjectLabel, 1, 1, Integer.MAX_VALUE).
        addComponent(dateLabel)).
      // Second row is a single label that is infinitely resizable.
      addComponent(labels[0], 1, 1, Integer.MAX_VALUE).
      // Third row contains two labels: text and from. The label
      // is infinitely resizable, where as the from label is fixed
      // at its preferred size.
      addGroup(layout.createSequentialGroup().
        addComponent(labels[1], 1, 1, Integer.MAX_VALUE).
        addComponent(fromLabel)));
The only other trick to mention when using a JList like this is be absolutely sure to set the prototype cell value. If you don't, JList is going to query the renderer for the preferred size for each and every value in the list. As you can imagine, a layout like this is NOT cheap! Additionally each cell should have the same size, so specifying the protoype value is the way to go!

I'm not going to go through the code for the vertical axis, hopefully it's not that hard to grok given the walk through of the horizontal axis.

Here's the complete source for the app.

Enjoy!

    -Scott


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • Man, I am still very unimpressed with GroupLayout. That code reads so poorly it's no wonder you need Netbeans to deal with it.

    Posted by: alski on December 18, 2006 at 12:04 PM

  • Keep in mind that GroupLayout was designed from the tools side first, not with readability in mind.

    -Scott

    Posted by: zixle on December 18, 2006 at 12:31 PM

  • Why go through all this trouble if you can use fewer lines of code code that documents itself? No need to draw trees and invent notation!


    Column left=new Column(imagePanel);
    left.setFixedSize((Component[]){imagePanel},true);
    Row top=new Row(Row.JUSTIFIED,Row.CENTER,subjectLabel,dateLabel);
    Row middle=new Row(labels[0]);
    Row bottom=new Row(Row.JUSTIFID,Row.CENTER,labels[1],fromLabel);
    Column right=new Column(top,middle,bottom);
    right.setFixedWidth(labels,false);
    Row topLevel=new Row(left,right);
    topLevel.createLayout(mainPanel);

    Posted by: varan on December 18, 2006 at 12:41 PM

  • Ok, now I need to post code for MigLayout as well. This is fun.. No one can post anything about layout any longer without getting code slapped right back at them! ;-)


    cell.setLayout(new MigLayout("nogrid, fillx"));
    cell.add(pic, "dock west");
    cell.add(title, "growx");
    cell.add(count, "wrap");
    cell.add(line1, "growx, wrap");
    cell.add(line2, "growx");
    cell.add(email);


    Cheers,
    Mikael Grev, miglayout.com

    Posted by: mikaelgrev on December 18, 2006 at 01:01 PM

  • Both your examples look better but GroupLayout used in NetBeans still beat them hands down. Because I don't even need to look at the code. That said I really like your layout Mikael :)

    Posted by: gfx on December 18, 2006 at 01:11 PM

  • Great.

    All these JDN posts touting the incomprehensible GroupLayout code provide a very useful service. Unintentionally though.

    Posted by: varan on December 18, 2006 at 01:17 PM

  • I forgot to mention that my code is for PageLayout.

    Posted by: varan on December 18, 2006 at 01:28 PM

  • > ..but GroupLayout used in NetBeans still beat them hands down.
    I concur. GroupLayout combined with Matisse is rocking and is better, when in a visual environment. The IDE layout problem is solved and that with flying colors. We also need an equally good layout manager for manual coding, which is also needed.

    Cheers,
    Mikael

    Posted by: mikaelgrev on December 18, 2006 at 01:32 PM

  • Mikael: I totally agree on this!

    varan: Again, GroupLayout is not meant for manual use.

    Posted by: gfx on December 18, 2006 at 02:16 PM

  • gfx:

    I agree. There is no need to show GroupLayout code snippets on the blogs as it will detract the newbies from Java GUI programming.

    Posted by: varan on December 18, 2006 at 02:58 PM

  • gfx: But isn't what this blog post is doing? Using GroupLayout manually?

    Scott: Should this line
    (I + [R1 R2 R2])
    be
    (I + [R1 R2 R3])
    instead?

    I've coded a few GUIs using GroupLayout but they were pretty straightforward ones, such as the one in this blog post. Anything requiring a complex layout was just too hard to visualise in the horizontal and vertical axes.

    Posted by: grimlock81 on December 18, 2006 at 04:12 PM

  • I don't know GroupLayout much well, so I'm speaking simplistically, but wouldn't many of the complaints about the readability of GroupLayout go away if they had convenience methods like
    addRow(...) or addParallelRows(...)
    for
    addGroup(...)
    and
    add(...)
    for
    addComponent?

    Posted by: sumitkishore on December 18, 2006 at 08:26 PM

  • Hi Scott-

    You wrote:

    Keep in mind that GroupLayout was designed from the tools side first, not with readability in mind.
    Are you familiar with why initial automation attempts in the automotive industry failed in North America? As Toyoda and others have demonstrated, the critical precondition (success factor) is simplifying a task enough so that any human can successfully do it. Once a task is trivially reproducible, then you can consider automating it.
    GroupLayout and Matisse are the pinnacle of the current GUI builder (UIMS) worldview. The logical conclusion. Very similar to CASE tools. And programmers will continue to hand-code user interfaces.
    Said another way, your best efforts only address the veneer of layout, construction, and behavior, while ignoring the fundamental issues. Kind of like treating the symptoms instead of curing disease.

    Cheers, Jason

    Posted by: josgood on December 27, 2006 at 06:29 PM


  • Jumping on: see the
    extreme renderer demo for all collection views (list table, tree) as evolving SwingX renderer support does it (with the help of FormLayout)

    Relevant code snippets and discussion in the SwingX forum

    Cheers
    Jeanette

    Posted by: kleopatra on January 12, 2007 at 04:14 AM

  • GroupLayout and Matisse are the pinnacle of the current GUI builder (UIMS) worldview. The logical conclusion. Very similar to CASE tools. And programmers will continue to hand-code user interfaces.

    Said another way, your best efforts only address the veneer of layout, construction, and behavior, while ignoring the fundamental issues. Kind of like treating the symptoms instead of curing disease.

    antivirusgratuit
    logicielgratuit
    divxgratuit
    kazaa100
    nero-gratuit
    msngratuit
    emulegratuitt
    messengergratuit
    antivirusgratuit
    logicielgratuit
    divxgratuit

    100
    101
    102
    103
    104
    105
    106
    107
    108
    109

    110
    111
    112
    113
    114
    115
    116
    117
    118
    119

    20
    21
    22
    23
    24
    25
    26
    27
    28
    29

    30
    31
    32
    33
    34
    35
    36
    37
    38
    39

    80
    81
    82
    83
    84
    85
    86
    87
    88
    89

    90
    91
    92
    93
    94
    95
    96
    97
    98
    99

    0
    1
    2
    3
    4
    5
    6
    7
    8
    9


    10
    11
    12
    13
    14
    15
    16
    17
    18
    19

    40
    41
    42
    43
    44
    45
    46
    47
    48
    49

    50
    51
    52
    53
    54
    55
    56
    57
    58
    59

    60
    61
    62
    63
    64
    65
    66
    67
    68
    69

    70
    71
    72
    73
    74
    75
    76
    77
    78
    79

    120
    121
    122
    123
    124
    125
    126
    127
    128
    129

    130
    131
    132
    133
    134
    135
    136
    137
    138
    139


    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24

    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36

    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48


    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60

    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72


    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84

    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96

    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108

    109
    111
    112
    113
    114
    115
    116
    117
    118
    119


    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11


    12
    13
    14
    15
    16
    17
    18
    19
    22
    3
    1
    2


    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119

    Posted by: juansaras83 on February 19, 2007 at 04:33 PM

  • Could somebody PLEASE delete that account from the spammer???

    Posted by: surfman on August 24, 2007 at 07:09 AM



Only logged in users may post comments. Login Here.


Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds