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 package org.eclipse.jgit.awtui;
45
46 import java.awt.BasicStroke;
47 import java.awt.Component;
48 import java.awt.Graphics;
49 import java.awt.Stroke;
50 import java.text.DateFormat;
51 import java.text.SimpleDateFormat;
52
53 import javax.swing.JTable;
54 import javax.swing.ListSelectionModel;
55 import javax.swing.table.AbstractTableModel;
56 import javax.swing.table.DefaultTableCellRenderer;
57 import javax.swing.table.JTableHeader;
58 import javax.swing.table.TableCellRenderer;
59 import javax.swing.table.TableColumn;
60 import javax.swing.table.TableColumnModel;
61 import javax.swing.table.TableModel;
62
63 import org.eclipse.jgit.awtui.SwingCommitList.SwingLane;
64 import org.eclipse.jgit.lib.PersonIdent;
65 import org.eclipse.jgit.revplot.PlotCommit;
66 import org.eclipse.jgit.revplot.PlotCommitList;
67
68
69
70
71
72
73
74
75
76
77
78
79 public class CommitGraphPane extends JTable {
80 private static final long serialVersionUID = 1L;
81
82 private final SwingCommitList allCommits;
83
84
85 public CommitGraphPane() {
86 allCommits = new SwingCommitList();
87 configureHeader();
88 setShowHorizontalLines(false);
89 setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
90 configureRowHeight();
91 }
92
93 private void configureRowHeight() {
94 int h = 0;
95 for (int i = 0; i<getColumnCount(); ++i) {
96 TableCellRenderer renderer = getDefaultRenderer(getColumnClass(i));
97 Component c = renderer.getTableCellRendererComponent(this,
98 "ÅOj", false, false, 0, i);
99 h = Math.max(h, c.getPreferredSize().height);
100 }
101 setRowHeight(h + getRowMargin());
102 }
103
104
105
106
107
108
109 public PlotCommitList getCommitList() {
110 return allCommits;
111 }
112
113 @Override
114 public void setModel(final TableModel dataModel) {
115 if (dataModel != null && !(dataModel instanceof CommitTableModel))
116 throw new ClassCastException(UIText.get().mustBeSpecialTableModel);
117 super.setModel(dataModel);
118 }
119
120 @Override
121 protected TableModel createDefaultDataModel() {
122 return new CommitTableModel();
123 }
124
125 private void configureHeader() {
126 final JTableHeader th = getTableHeader();
127 final TableColumnModel cols = th.getColumnModel();
128
129 final TableColumn graph = cols.getColumn(0);
130 final TableColumn author = cols.getColumn(1);
131 final TableColumn date = cols.getColumn(2);
132
133 graph.setHeaderValue("");
134 author.setHeaderValue(UIText.get().author);
135 date.setHeaderValue(UIText.get().date);
136
137 graph.setCellRenderer(new GraphCellRender());
138 author.setCellRenderer(new NameCellRender());
139 date.setCellRenderer(new DateCellRender());
140 }
141
142 class CommitTableModel extends AbstractTableModel {
143 private static final long serialVersionUID = 1L;
144
145 PlotCommit<SwingLane> lastCommit;
146
147 PersonIdent lastAuthor;
148
149 @Override
150 public int getColumnCount() {
151 return 3;
152 }
153
154 @Override
155 public int getRowCount() {
156 return allCommits != null ? allCommits.size() : 0;
157 }
158
159 @Override
160 public Object getValueAt(final int rowIndex, final int columnIndex) {
161 final PlotCommit<SwingLane> c = allCommits.get(rowIndex);
162 switch (columnIndex) {
163 case 0:
164 return c;
165 case 1:
166 return authorFor(c);
167 case 2:
168 return authorFor(c);
169 default:
170 return null;
171 }
172 }
173
174 PersonIdent authorFor(final PlotCommit<SwingLane> c) {
175 if (c != lastCommit) {
176 lastCommit = c;
177 lastAuthor = c.getAuthorIdent();
178 }
179 return lastAuthor;
180 }
181 }
182
183 static class NameCellRender extends DefaultTableCellRenderer {
184 private static final long serialVersionUID = 1L;
185
186 @Override
187 public Component getTableCellRendererComponent(final JTable table,
188 final Object value, final boolean isSelected,
189 final boolean hasFocus, final int row, final int column) {
190 final PersonIdent pi = (PersonIdent) value;
191
192 final String valueStr;
193 if (pi != null)
194 valueStr = pi.getName() + " <" + pi.getEmailAddress() + ">";
195 else
196 valueStr = "";
197 return super.getTableCellRendererComponent(table, valueStr,
198 isSelected, hasFocus, row, column);
199 }
200 }
201
202 static class DateCellRender extends DefaultTableCellRenderer {
203 private static final long serialVersionUID = 1L;
204
205 private final DateFormat fmt = new SimpleDateFormat(
206 "yyyy-MM-dd HH:mm:ss");
207
208 @Override
209 public Component getTableCellRendererComponent(final JTable table,
210 final Object value, final boolean isSelected,
211 final boolean hasFocus, final int row, final int column) {
212 final PersonIdent pi = (PersonIdent) value;
213
214 final String valueStr;
215 if (pi != null)
216 valueStr = fmt.format(pi.getWhen());
217 else
218 valueStr = "";
219 return super.getTableCellRendererComponent(table, valueStr,
220 isSelected, hasFocus, row, column);
221 }
222 }
223
224 static class GraphCellRender extends DefaultTableCellRenderer {
225 private static final long serialVersionUID = 1L;
226
227 private final AWTPlotRenderer renderer = new AWTPlotRenderer(this);
228
229 PlotCommit<SwingLane> commit;
230
231 @Override
232 @SuppressWarnings("unchecked")
233 public Component getTableCellRendererComponent(final JTable table,
234 final Object value, final boolean isSelected,
235 final boolean hasFocus, final int row, final int column) {
236 super.getTableCellRendererComponent(table, value, isSelected,
237 hasFocus, row, column);
238 commit = (PlotCommit<SwingLane>) value;
239 return this;
240 }
241
242 @Override
243 protected void paintComponent(final Graphics inputGraphics) {
244 if (inputGraphics == null)
245 return;
246 renderer.paint(inputGraphics, commit);
247 }
248 }
249
250 static final Stroke[] strokeCache;
251
252 static {
253 strokeCache = new Stroke[4];
254 for (int i = 1; i < strokeCache.length; i++)
255 strokeCache[i] = new BasicStroke(i);
256 }
257
258 static Stroke stroke(final int width) {
259 if (width < strokeCache.length)
260 return strokeCache[width];
261 return new BasicStroke(width);
262 }
263
264 }