 |
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 Digg DZone Furl 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
|