commit | author | age
|
19c634
|
1 |
/*
|
JM |
2 |
* Copyright 2011 gitblit.com.
|
|
3 |
*
|
|
4 |
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5 |
* you may not use this file except in compliance with the License.
|
|
6 |
* You may obtain a copy of the License at
|
|
7 |
*
|
|
8 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9 |
*
|
|
10 |
* Unless required by applicable law or agreed to in writing, software
|
|
11 |
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13 |
* See the License for the specific language governing permissions and
|
|
14 |
* limitations under the License.
|
|
15 |
*/
|
|
16 |
package com.gitblit.client;
|
|
17 |
|
|
18 |
import java.awt.BorderLayout;
|
f14f76
|
19 |
import java.awt.Cursor;
|
841651
|
20 |
import java.awt.Dimension;
|
19c634
|
21 |
import java.awt.EventQueue;
|
ee25c8
|
22 |
import java.awt.Point;
|
19c634
|
23 |
import java.awt.event.ActionEvent;
|
JM |
24 |
import java.awt.event.ActionListener;
|
|
25 |
import java.awt.event.KeyEvent;
|
ee25c8
|
26 |
import java.awt.event.WindowAdapter;
|
JM |
27 |
import java.awt.event.WindowEvent;
|
bab9c9
|
28 |
import java.io.BufferedReader;
|
ee25c8
|
29 |
import java.io.File;
|
bab9c9
|
30 |
import java.io.FileReader;
|
JM |
31 |
import java.io.FileWriter;
|
19c634
|
32 |
import java.io.IOException;
|
2a99c3
|
33 |
import java.net.ConnectException;
|
ee25c8
|
34 |
import java.text.MessageFormat;
|
f14f76
|
35 |
import java.text.SimpleDateFormat;
|
JM |
36 |
import java.util.ArrayList;
|
|
37 |
import java.util.Collections;
|
|
38 |
import java.util.Comparator;
|
|
39 |
import java.util.Date;
|
bab9c9
|
40 |
import java.util.HashMap;
|
ee25c8
|
41 |
import java.util.LinkedHashMap;
|
f14f76
|
42 |
import java.util.List;
|
JM |
43 |
import java.util.Locale;
|
ee25c8
|
44 |
import java.util.Map;
|
JM |
45 |
import java.util.Set;
|
f14f76
|
46 |
import java.util.TimeZone;
|
19c634
|
47 |
|
841651
|
48 |
import javax.swing.ImageIcon;
|
19c634
|
49 |
import javax.swing.JFrame;
|
841651
|
50 |
import javax.swing.JMenu;
|
JM |
51 |
import javax.swing.JMenuBar;
|
|
52 |
import javax.swing.JMenuItem;
|
19c634
|
53 |
import javax.swing.JOptionPane;
|
JM |
54 |
import javax.swing.JPanel;
|
|
55 |
import javax.swing.JTabbedPane;
|
841651
|
56 |
import javax.swing.KeyStroke;
|
f14f76
|
57 |
import javax.swing.SwingWorker;
|
841651
|
58 |
import javax.swing.UIManager;
|
19c634
|
59 |
|
ee25c8
|
60 |
import org.eclipse.jgit.errors.ConfigInvalidException;
|
JM |
61 |
import org.eclipse.jgit.lib.StoredConfig;
|
|
62 |
import org.eclipse.jgit.storage.file.FileBasedConfig;
|
|
63 |
import org.eclipse.jgit.util.FS;
|
|
64 |
|
19c634
|
65 |
import com.gitblit.Constants;
|
8b7636
|
66 |
import com.gitblit.GitBlitException.ForbiddenException;
|
17820f
|
67 |
import com.gitblit.models.FeedModel;
|
38688b
|
68 |
import com.gitblit.utils.Base64;
|
19c634
|
69 |
import com.gitblit.utils.StringUtils;
|
JM |
70 |
|
841651
|
71 |
/**
|
ee25c8
|
72 |
* Gitblit Manager issues JSON RPC requests to a Gitblit server.
|
841651
|
73 |
*
|
JM |
74 |
* @author James Moger
|
|
75 |
*
|
|
76 |
*/
|
f14f76
|
77 |
public class GitblitManager extends JFrame implements RegistrationsDialog.RegistrationListener {
|
19c634
|
78 |
|
JM |
79 |
private static final long serialVersionUID = 1L;
|
c25a1d
|
80 |
private static final String SERVER = "server";
|
JM |
81 |
private static final String FEED = "feed";
|
f14f76
|
82 |
private final SimpleDateFormat dateFormat;
|
19c634
|
83 |
private JTabbedPane serverTabs;
|
ee25c8
|
84 |
private File configFile = new File(System.getProperty("user.home"), ".gitblit/config");
|
841651
|
85 |
|
ee25c8
|
86 |
private Map<String, GitblitRegistration> registrations = new LinkedHashMap<String, GitblitRegistration>();
|
841651
|
87 |
private JMenu recentMenu;
|
f14f76
|
88 |
private int maxRecentCount = 5;
|
19c634
|
89 |
|
a7a9f7
|
90 |
private GitblitManager() {
|
19c634
|
91 |
super();
|
f14f76
|
92 |
dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
|
JM |
93 |
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
|
19c634
|
94 |
}
|
JM |
95 |
|
|
96 |
private void initialize() {
|
|
97 |
setContentPane(getCenterPanel());
|
841651
|
98 |
setIconImage(new ImageIcon(getClass().getResource("/gitblt-favicon.png")).getImage());
|
a7a9f7
|
99 |
setTitle("Gitblit Manager v" + Constants.VERSION + " (" + Constants.VERSION_DATE + ")");
|
19c634
|
100 |
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
ee25c8
|
101 |
addWindowListener(new WindowAdapter() {
|
JM |
102 |
@Override
|
|
103 |
public void windowClosing(WindowEvent event) {
|
|
104 |
saveSizeAndPosition();
|
|
105 |
}
|
3f5a93
|
106 |
|
68413a
|
107 |
@Override
|
JM |
108 |
public void windowOpened(WindowEvent event) {
|
|
109 |
manageRegistrations();
|
|
110 |
}
|
ee25c8
|
111 |
});
|
JM |
112 |
|
|
113 |
setSizeAndPosition();
|
|
114 |
loadRegistrations();
|
|
115 |
rebuildRecentMenu();
|
|
116 |
}
|
|
117 |
|
|
118 |
private void setSizeAndPosition() {
|
|
119 |
String sz = null;
|
|
120 |
String pos = null;
|
|
121 |
try {
|
|
122 |
StoredConfig config = getConfig();
|
|
123 |
sz = config.getString("ui", null, "size");
|
|
124 |
pos = config.getString("ui", null, "position");
|
|
125 |
} catch (Throwable t) {
|
|
126 |
t.printStackTrace();
|
|
127 |
}
|
|
128 |
|
|
129 |
// try to restore saved window size
|
|
130 |
if (StringUtils.isEmpty(sz)) {
|
|
131 |
setSize(850, 500);
|
|
132 |
} else {
|
|
133 |
String[] chunks = sz.split("x");
|
|
134 |
int width = Integer.parseInt(chunks[0]);
|
|
135 |
int height = Integer.parseInt(chunks[1]);
|
|
136 |
setSize(width, height);
|
|
137 |
}
|
|
138 |
|
|
139 |
// try to restore saved window position
|
|
140 |
if (StringUtils.isEmpty(pos)) {
|
|
141 |
setLocationRelativeTo(null);
|
|
142 |
} else {
|
|
143 |
String[] chunks = pos.split(",");
|
|
144 |
int x = Integer.parseInt(chunks[0]);
|
|
145 |
int y = Integer.parseInt(chunks[1]);
|
|
146 |
setLocation(x, y);
|
|
147 |
}
|
|
148 |
}
|
|
149 |
|
|
150 |
private void saveSizeAndPosition() {
|
|
151 |
try {
|
|
152 |
// save window size and position
|
|
153 |
StoredConfig config = getConfig();
|
|
154 |
Dimension sz = GitblitManager.this.getSize();
|
|
155 |
config.setString("ui", null, "size",
|
|
156 |
MessageFormat.format("{0,number,0}x{1,number,0}", sz.width, sz.height));
|
|
157 |
Point pos = GitblitManager.this.getLocationOnScreen();
|
|
158 |
config.setString("ui", null, "position",
|
|
159 |
MessageFormat.format("{0,number,0},{1,number,0}", pos.x, pos.y));
|
|
160 |
config.save();
|
|
161 |
} catch (Throwable t) {
|
|
162 |
Utils.showException(GitblitManager.this, t);
|
|
163 |
}
|
19c634
|
164 |
}
|
JM |
165 |
|
841651
|
166 |
private JMenuBar setupMenu() {
|
JM |
167 |
JMenuBar menuBar = new JMenuBar();
|
b7f591
|
168 |
JMenu serversMenu = new JMenu(Translation.get("gb.servers"));
|
19c634
|
169 |
menuBar.add(serversMenu);
|
b7f591
|
170 |
recentMenu = new JMenu(Translation.get("gb.recent"));
|
841651
|
171 |
serversMenu.add(recentMenu);
|
f14f76
|
172 |
|
JM |
173 |
JMenuItem manage = new JMenuItem(Translation.get("gb.manage") + "...");
|
|
174 |
manage.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M, KeyEvent.CTRL_DOWN_MASK, false));
|
|
175 |
manage.addActionListener(new ActionListener() {
|
|
176 |
public void actionPerformed(ActionEvent event) {
|
|
177 |
manageRegistrations();
|
|
178 |
}
|
|
179 |
});
|
|
180 |
serversMenu.add(manage);
|
|
181 |
|
841651
|
182 |
return menuBar;
|
19c634
|
183 |
}
|
JM |
184 |
|
|
185 |
private JPanel getCenterPanel() {
|
|
186 |
serverTabs = new JTabbedPane(JTabbedPane.TOP);
|
841651
|
187 |
JMenuBar menubar = setupMenu();
|
19c634
|
188 |
JPanel panel = new JPanel(new BorderLayout());
|
841651
|
189 |
panel.add(menubar, BorderLayout.NORTH);
|
19c634
|
190 |
panel.add(serverTabs, BorderLayout.CENTER);
|
JM |
191 |
return panel;
|
|
192 |
}
|
|
193 |
|
f14f76
|
194 |
private void manageRegistrations() {
|
JM |
195 |
RegistrationsDialog dialog = new RegistrationsDialog(new ArrayList<GitblitRegistration>(
|
|
196 |
registrations.values()), this);
|
|
197 |
dialog.setLocationRelativeTo(GitblitManager.this);
|
|
198 |
dialog.setVisible(true);
|
|
199 |
}
|
|
200 |
|
|
201 |
@Override
|
3f5a93
|
202 |
public void login(GitblitRegistration reg) {
|
JM |
203 |
if (!reg.savePassword && (reg.password == null || reg.password.length == 0)) {
|
|
204 |
// prompt for password
|
|
205 |
EditRegistrationDialog dialog = new EditRegistrationDialog(this, reg, true);
|
|
206 |
dialog.setLocationRelativeTo(GitblitManager.this);
|
|
207 |
dialog.setVisible(true);
|
ac7f17
|
208 |
GitblitRegistration newReg = dialog.getRegistration();
|
JM |
209 |
if (newReg == null) {
|
3f5a93
|
210 |
// user canceled
|
JM |
211 |
return;
|
f14f76
|
212 |
}
|
ac7f17
|
213 |
// preserve feeds
|
17820f
|
214 |
newReg.feeds.addAll(reg.feeds);
|
JM |
215 |
|
ac7f17
|
216 |
// use new reg
|
JM |
217 |
reg = newReg;
|
f14f76
|
218 |
}
|
4cac0d
|
219 |
|
3f5a93
|
220 |
// login
|
f14f76
|
221 |
setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
|
3f5a93
|
222 |
final GitblitRegistration registration = reg;
|
4cac0d
|
223 |
final GitblitPanel panel = new GitblitPanel(registration, this);
|
f14f76
|
224 |
SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
|
JM |
225 |
|
|
226 |
@Override
|
|
227 |
protected Boolean doInBackground() throws IOException {
|
|
228 |
panel.login();
|
|
229 |
return true;
|
|
230 |
}
|
|
231 |
|
|
232 |
@Override
|
|
233 |
protected void done() {
|
|
234 |
try {
|
|
235 |
boolean success = get();
|
3f5a93
|
236 |
serverTabs.addTab(registration.name, panel);
|
f14f76
|
237 |
int idx = serverTabs.getTabCount() - 1;
|
JM |
238 |
serverTabs.setSelectedIndex(idx);
|
3f5a93
|
239 |
serverTabs.setTabComponentAt(idx, new ClosableTabComponent(registration.name,
|
JM |
240 |
null, serverTabs, panel));
|
|
241 |
registration.lastLogin = new Date();
|
|
242 |
saveRegistration(registration.name, registration);
|
|
243 |
registrations.put(registration.name, registration);
|
f14f76
|
244 |
rebuildRecentMenu();
|
3f5a93
|
245 |
if (!registration.savePassword) {
|
JM |
246 |
// clear password
|
|
247 |
registration.password = null;
|
|
248 |
}
|
f14f76
|
249 |
} catch (Throwable t) {
|
2a99c3
|
250 |
Throwable cause = t.getCause();
|
JM |
251 |
if (cause instanceof ConnectException) {
|
|
252 |
JOptionPane.showMessageDialog(GitblitManager.this, cause.getMessage(),
|
|
253 |
Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE);
|
8b7636
|
254 |
} else if (cause instanceof ForbiddenException) {
|
JM |
255 |
JOptionPane
|
|
256 |
.showMessageDialog(
|
|
257 |
GitblitManager.this,
|
|
258 |
"This Gitblit server does not allow RPC Management or Administration",
|
|
259 |
Translation.get("gb.error"), JOptionPane.ERROR_MESSAGE);
|
2a99c3
|
260 |
} else {
|
JM |
261 |
Utils.showException(GitblitManager.this, t);
|
|
262 |
}
|
f14f76
|
263 |
} finally {
|
JM |
264 |
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
|
|
265 |
}
|
|
266 |
}
|
|
267 |
};
|
|
268 |
worker.execute();
|
19c634
|
269 |
}
|
JM |
270 |
|
841651
|
271 |
private void rebuildRecentMenu() {
|
JM |
272 |
recentMenu.removeAll();
|
ee25c8
|
273 |
ImageIcon icon = new ImageIcon(getClass().getResource("/gitblt-favicon.png"));
|
f14f76
|
274 |
List<GitblitRegistration> list = new ArrayList<GitblitRegistration>(registrations.values());
|
JM |
275 |
Collections.sort(list, new Comparator<GitblitRegistration>() {
|
|
276 |
@Override
|
|
277 |
public int compare(GitblitRegistration o1, GitblitRegistration o2) {
|
|
278 |
return o2.lastLogin.compareTo(o1.lastLogin);
|
|
279 |
}
|
|
280 |
});
|
|
281 |
if (list.size() > maxRecentCount) {
|
|
282 |
list = list.subList(0, maxRecentCount);
|
|
283 |
}
|
a8cb5d
|
284 |
for (int i = 0; i < list.size(); i++) {
|
JM |
285 |
final GitblitRegistration reg = list.get(i);
|
ee25c8
|
286 |
JMenuItem item = new JMenuItem(reg.name, icon);
|
a8cb5d
|
287 |
item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_1 + i, KeyEvent.CTRL_DOWN_MASK,
|
JM |
288 |
false));
|
841651
|
289 |
item.addActionListener(new ActionListener() {
|
JM |
290 |
public void actionPerformed(ActionEvent e) {
|
f14f76
|
291 |
login(reg);
|
841651
|
292 |
}
|
JM |
293 |
});
|
|
294 |
recentMenu.add(item);
|
|
295 |
}
|
|
296 |
}
|
|
297 |
|
ee25c8
|
298 |
private void loadRegistrations() {
|
JM |
299 |
try {
|
|
300 |
StoredConfig config = getConfig();
|
c25a1d
|
301 |
Set<String> servers = config.getSubsections(SERVER);
|
ee25c8
|
302 |
for (String server : servers) {
|
3f5a93
|
303 |
Date lastLogin = new Date(0);
|
c25a1d
|
304 |
String date = config.getString(SERVER, server, "lastLogin");
|
3f5a93
|
305 |
if (!StringUtils.isEmpty(date)) {
|
JM |
306 |
lastLogin = dateFormat.parse(date);
|
|
307 |
}
|
c25a1d
|
308 |
String url = config.getString(SERVER, server, "url");
|
JM |
309 |
String account = config.getString(SERVER, server, "account");
|
5ae0b7
|
310 |
char[] password;
|
c25a1d
|
311 |
String pw = config.getString(SERVER, server, "password");
|
5ae0b7
|
312 |
if (StringUtils.isEmpty(pw)) {
|
JM |
313 |
password = new char[0];
|
|
314 |
} else {
|
|
315 |
password = new String(Base64.decode(pw)).toCharArray();
|
|
316 |
}
|
bab9c9
|
317 |
GitblitRegistration reg = new GitblitRegistration(server, url, account, password) {
|
JM |
318 |
private static final long serialVersionUID = 1L;
|
|
319 |
|
|
320 |
protected void cacheFeeds() {
|
|
321 |
writeFeedCache(this);
|
|
322 |
}
|
|
323 |
};
|
c25a1d
|
324 |
String[] feeds = config.getStringList(SERVER, server, FEED);
|
4cac0d
|
325 |
if (feeds != null) {
|
17820f
|
326 |
// deserialize the field definitions
|
JM |
327 |
for (String definition : feeds) {
|
|
328 |
FeedModel feed = new FeedModel(definition);
|
|
329 |
reg.feeds.add(feed);
|
|
330 |
}
|
4cac0d
|
331 |
}
|
f14f76
|
332 |
reg.lastLogin = lastLogin;
|
bab9c9
|
333 |
loadFeedCache(reg);
|
ee25c8
|
334 |
registrations.put(reg.name, reg);
|
JM |
335 |
}
|
|
336 |
} catch (Throwable t) {
|
|
337 |
Utils.showException(GitblitManager.this, t);
|
|
338 |
}
|
|
339 |
}
|
|
340 |
|
3f5a93
|
341 |
@Override
|
JM |
342 |
public boolean saveRegistration(String name, GitblitRegistration reg) {
|
ee25c8
|
343 |
try {
|
JM |
344 |
StoredConfig config = getConfig();
|
3f5a93
|
345 |
if (!StringUtils.isEmpty(name) && !name.equals(reg.name)) {
|
JM |
346 |
// delete old registration
|
|
347 |
registrations.remove(name);
|
c25a1d
|
348 |
config.unsetSection(SERVER, name);
|
3f5a93
|
349 |
}
|
JM |
350 |
|
|
351 |
// update registration
|
c25a1d
|
352 |
config.setString(SERVER, reg.name, "url", reg.url);
|
JM |
353 |
config.setString(SERVER, reg.name, "account", reg.account);
|
3f5a93
|
354 |
if (reg.savePassword) {
|
c25a1d
|
355 |
config.setString(SERVER, reg.name, "password",
|
3f5a93
|
356 |
Base64.encodeBytes(new String(reg.password).getBytes("UTF-8")));
|
JM |
357 |
} else {
|
c25a1d
|
358 |
config.setString(SERVER, reg.name, "password", "");
|
3f5a93
|
359 |
}
|
JM |
360 |
if (reg.lastLogin != null) {
|
c25a1d
|
361 |
config.setString(SERVER, reg.name, "lastLogin", dateFormat.format(reg.lastLogin));
|
3f5a93
|
362 |
}
|
17820f
|
363 |
// serialize the feed definitions
|
JM |
364 |
List<String> definitions = new ArrayList<String>();
|
|
365 |
for (FeedModel feed : reg.feeds) {
|
|
366 |
definitions.add(feed.toString());
|
|
367 |
}
|
|
368 |
if (definitions.size() > 0) {
|
c25a1d
|
369 |
config.setStringList(SERVER, reg.name, FEED, definitions);
|
4cac0d
|
370 |
}
|
ee25c8
|
371 |
config.save();
|
3f5a93
|
372 |
return true;
|
ee25c8
|
373 |
} catch (Throwable t) {
|
JM |
374 |
Utils.showException(GitblitManager.this, t);
|
|
375 |
}
|
3f5a93
|
376 |
return false;
|
ee25c8
|
377 |
}
|
JM |
378 |
|
3f5a93
|
379 |
@Override
|
f14f76
|
380 |
public boolean deleteRegistrations(List<GitblitRegistration> list) {
|
JM |
381 |
boolean success = false;
|
|
382 |
try {
|
|
383 |
StoredConfig config = getConfig();
|
|
384 |
for (GitblitRegistration reg : list) {
|
c25a1d
|
385 |
config.unsetSection(SERVER, reg.name);
|
a8cb5d
|
386 |
registrations.remove(reg.name);
|
f14f76
|
387 |
}
|
JM |
388 |
config.save();
|
|
389 |
success = true;
|
|
390 |
} catch (Throwable t) {
|
|
391 |
Utils.showException(GitblitManager.this, t);
|
|
392 |
}
|
|
393 |
return success;
|
|
394 |
}
|
|
395 |
|
ee25c8
|
396 |
private StoredConfig getConfig() throws IOException, ConfigInvalidException {
|
JM |
397 |
FileBasedConfig config = new FileBasedConfig(configFile, FS.detect());
|
|
398 |
config.load();
|
|
399 |
return config;
|
|
400 |
}
|
|
401 |
|
bab9c9
|
402 |
private void loadFeedCache(GitblitRegistration reg) {
|
609a16
|
403 |
File feedCache = new File(configFile.getParentFile(), StringUtils.getSHA1(reg.toString())
|
bab9c9
|
404 |
+ ".cache");
|
JM |
405 |
if (!feedCache.exists()) {
|
|
406 |
// no cache for this registration
|
|
407 |
return;
|
|
408 |
}
|
|
409 |
try {
|
|
410 |
BufferedReader reader = new BufferedReader(new FileReader(feedCache));
|
|
411 |
Map<String, Date> cache = new HashMap<String, Date>();
|
|
412 |
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
|
|
413 |
String line = null;
|
|
414 |
while ((line = reader.readLine()) != null) {
|
|
415 |
String[] kvp = line.split("=");
|
|
416 |
cache.put(kvp[0], df.parse(kvp[1]));
|
|
417 |
}
|
|
418 |
reader.close();
|
|
419 |
for (FeedModel feed : reg.feeds) {
|
|
420 |
String name = feed.toString();
|
|
421 |
if (cache.containsKey(name)) {
|
|
422 |
feed.currentRefreshDate = cache.get(name);
|
|
423 |
}
|
|
424 |
}
|
|
425 |
} catch (Exception e) {
|
|
426 |
Utils.showException(GitblitManager.this, e);
|
|
427 |
}
|
|
428 |
}
|
|
429 |
|
|
430 |
private void writeFeedCache(GitblitRegistration reg) {
|
|
431 |
try {
|
609a16
|
432 |
File feedCache = new File(configFile.getParentFile(), StringUtils.getSHA1(reg
|
JM |
433 |
.toString()) + ".cache");
|
bab9c9
|
434 |
FileWriter writer = new FileWriter(feedCache);
|
JM |
435 |
for (FeedModel feed : reg.feeds) {
|
|
436 |
writer.append(MessageFormat.format("{0}={1,date,yyyy-MM-dd'T'HH:mm:ss}\n",
|
|
437 |
feed.toString(), feed.currentRefreshDate));
|
|
438 |
}
|
|
439 |
writer.close();
|
|
440 |
} catch (Exception e) {
|
|
441 |
Utils.showException(GitblitManager.this, e);
|
|
442 |
}
|
|
443 |
}
|
|
444 |
|
19c634
|
445 |
public static void main(String[] args) {
|
JM |
446 |
EventQueue.invokeLater(new Runnable() {
|
|
447 |
public void run() {
|
841651
|
448 |
try {
|
JM |
449 |
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
|
450 |
} catch (Exception e) {
|
|
451 |
}
|
a7a9f7
|
452 |
GitblitManager frame = new GitblitManager();
|
19c634
|
453 |
frame.initialize();
|
JM |
454 |
frame.setVisible(true);
|
|
455 |
}
|
|
456 |
});
|
|
457 |
}
|
|
458 |
}
|