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