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 public int getColumnCount() {
150 return 3;
151 }
152
153 public int getRowCount() {
154 return allCommits != null ? allCommits.size() : 0;
155 }
156
157 public Object getValueAt(final int rowIndex, final int columnIndex) {
158 final PlotCommit<SwingLane> c = allCommits.get(rowIndex);
159 switch (columnIndex) {
160 case 0:
161 return c;
162 case 1:
163 return authorFor(c);
164 case 2:
165 return authorFor(c);
166 default:
167 return null;
168 }
169 }
170
171 PersonIdent authorFor(final PlotCommit<SwingLane> c) {
172 if (c != lastCommit) {
173 lastCommit = c;
174 lastAuthor = c.getAuthorIdent();
175 }
176 return lastAuthor;
177 }
178 }
179
180 static class NameCellRender extends DefaultTableCellRenderer {
181 private static final long serialVersionUID = 1L;
182
183 public Component getTableCellRendererComponent(final JTable table,
184 final Object value, final boolean isSelected,
185 final boolean hasFocus, final int row, final int column) {
186 final PersonIdent pi = (PersonIdent) value;
187
188 final String valueStr;
189 if (pi != null)
190 valueStr = pi.getName() + " <" + pi.getEmailAddress() + ">";
191 else
192 valueStr = "";
193 return super.getTableCellRendererComponent(table, valueStr,
194 isSelected, hasFocus, row, column);
195 }
196 }
197
198 static class DateCellRender extends DefaultTableCellRenderer {
199 private static final long serialVersionUID = 1L;
200
201 private final DateFormat fmt = new SimpleDateFormat(
202 "yyyy-MM-dd HH:mm:ss");
203
204 public Component getTableCellRendererComponent(final JTable table,
205 final Object value, final boolean isSelected,
206 final boolean hasFocus, final int row, final int column) {
207 final PersonIdent pi = (PersonIdent) value;
208
209 final String valueStr;
210 if (pi != null)
211 valueStr = fmt.format(pi.getWhen());
212 else
213 valueStr = "";
214 return super.getTableCellRendererComponent(table, valueStr,
215 isSelected, hasFocus, row, column);
216 }
217 }
218
219 static class GraphCellRender extends DefaultTableCellRenderer {
220 private static final long serialVersionUID = 1L;
221
222 private final AWTPlotRenderer renderer = new AWTPlotRenderer(this);
223
224 PlotCommit<SwingLane> commit;
225
226 @SuppressWarnings("unchecked")
227 public Component getTableCellRendererComponent(final JTable table,
228 final Object value, final boolean isSelected,
229 final boolean hasFocus, final int row, final int column) {
230 super.getTableCellRendererComponent(table, value, isSelected,
231 hasFocus, row, column);
232 commit = (PlotCommit<SwingLane>) value;
233 return this;
234 }
235
236 @Override
237 protected void paintComponent(final Graphics inputGraphics) {
238 if (inputGraphics == null)
239 return;
240 renderer.paint(inputGraphics, commit);
241 }
242 }
243
244 static final Stroke[] strokeCache;
245
246 static {
247 strokeCache = new Stroke[4];
248 for (int i = 1; i < strokeCache.length; i++)
249 strokeCache[i] = new BasicStroke(i);
250 }
251
252 static Stroke stroke(final int width) {
253 if (width < strokeCache.length)
254 return strokeCache[width];
255 return new BasicStroke(width);
256 }
257
258 }