Skip to content

Commit d6ea27e

Browse files
authored
Merge pull request #1618 from virtualcell/dan-vcell-alert
Dan vcell alert
2 parents bf492ae + 0d5a4fb commit d6ea27e

File tree

1 file changed

+146
-38
lines changed

1 file changed

+146
-38
lines changed

vcell-client/src/main/java/cbit/vcell/client/desktop/DocumentWindow.java

Lines changed: 146 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,10 @@
5050
import java.awt.event.ActionEvent;
5151
import java.awt.event.ActionListener;
5252
import java.awt.event.MouseEvent;
53+
import java.io.BufferedReader;
5354
import java.io.File;
5455
import java.io.IOException;
56+
import java.io.InputStreamReader;
5557
import java.net.HttpURLConnection;
5658
import java.net.URI;
5759
import java.net.URISyntaxException;
@@ -1175,7 +1177,7 @@ private javax.swing.JPanel getStatusBarPane() {
11751177
gbc = new GridBagConstraints();
11761178
gbc.gridx = gridx;
11771179
gbc.gridy = 0;
1178-
gbc.insets = new Insets(2, 5, 2, 2);
1180+
gbc.insets = new Insets(2, 5, 2, 10);
11791181
this.ivjStatusBarPane.add(this.getIconBar(), gbc);
11801182

11811183
gridx++;
@@ -1207,69 +1209,175 @@ public JLabel getWarningBar() {
12071209
if (this.warningText == null) {
12081210
try {
12091211
this.warningText = new JLabel();
1210-
this.warningText.setName("");
1212+
this.warningText.setName("WarningBar");
1213+
this.warningText.setText("");
12111214
} catch (java.lang.Throwable ivjExc) {
12121215
this.handleException(ivjExc);
12131216
}
12141217
}
12151218
return this.warningText;
12161219
}
12171220

1221+
private String iconTextString = "Administrator Notification";
1222+
private String iconToolTipString = "View VCell Administrator Notification";
1223+
private Color darkRed = new Color(139, 0, 0);
12181224
public JLabel getIconBar() {
12191225
if (this.iconText == null) {
12201226
try {
12211227
this.iconText = new JLabel();
1222-
this.iconText.setName("");
1228+
this.iconText.setName("IconBarLabel");
12231229
this.iconText.setIcon(VCellIcons.noteRedIcon);
1224-
this.iconText.setToolTipText("View VCell Administrator Notification");
1230+
this.iconText.setText(iconTextString);
1231+
this.iconText.setForeground(darkRed);
1232+
this.iconText.setHorizontalTextPosition(SwingConstants.RIGHT);
1233+
this.iconText.setToolTipText(iconToolTipString);
12251234
} catch (java.lang.Throwable ivjExc) {
12261235
this.handleException(ivjExc);
12271236
}
12281237
}
12291238
return this.iconText;
12301239
}
12311240

1232-
//private static final String notificationsUrl = "//cfs05.cam.uchc.edu/vcell/apache_webroot/htdocs/webstart/VCell_alert/VCell_Alert.html";
12331241
private void checkForNotifications() {
1234-
int code = HttpURLConnection.HTTP_BAD_REQUEST;
1235-
try {
1236-
URL u = new URL(notificationsUrl);
1237-
HttpURLConnection huc = (HttpURLConnection) u.openConnection();
1238-
huc.setRequestMethod("HEAD"); // probably cheaper than huc.setRequestMethod ("GET");
1239-
huc.connect();
1240-
code = huc.getResponseCode();
1241-
} catch (IOException e) {
1242-
// we just eat the exception
1243-
// e.printStackTrace();
1244-
code = HttpURLConnection.HTTP_INTERNAL_ERROR;
1245-
}
1246-
if (code != HttpURLConnection.HTTP_OK) {
1247-
this.getIconBar().setEnabled(false);
1248-
this.getIconBar().setVisible(false);
1249-
} else {
1250-
this.getIconBar().setEnabled(true);
1251-
this.getIconBar().setVisible(true);
1242+
new SwingWorker<Integer, Void>() {
12521243

1253-
Timer blinkTimer = new Timer(500, new ActionListener() {
1254-
private int count = 0;
1255-
private final int maxCount = 110; // 55 seconds
1244+
@Override
1245+
protected Integer doInBackground() {
1246+
int code = HttpURLConnection.HTTP_BAD_REQUEST;
1247+
try {
1248+
URL u = new URL(notificationsUrl);
1249+
HttpURLConnection huc = (HttpURLConnection) u.openConnection();
1250+
huc.setRequestMethod("HEAD");
1251+
huc.connect();
1252+
code = huc.getResponseCode();
1253+
} catch (IOException e) {
1254+
code = HttpURLConnection.HTTP_INTERNAL_ERROR;
1255+
}
1256+
return code;
1257+
}
12561258

1257-
public void actionPerformed(ActionEvent e) {
1258-
if (this.count >= this.maxCount) {
1259-
DocumentWindow.this.getIconBar().setIcon(VCellIcons.noteRedIcon); // must remain on the noteRedIcon
1260-
((Timer) e.getSource()).stop();
1261-
} else {
1262-
if (this.count % 2 == 0) {
1263-
DocumentWindow.this.getIconBar().setIcon(VCellIcons.noteRedIcon);
1259+
@Override
1260+
protected void done() {
1261+
int code;
1262+
try {
1263+
code = get();
1264+
} catch (Exception e) {
1265+
code = HttpURLConnection.HTTP_INTERNAL_ERROR;
1266+
}
1267+
if (code != HttpURLConnection.HTTP_OK) {
1268+
getIconBar().setEnabled(false);
1269+
getIconBar().setVisible(false);
1270+
return;
1271+
}
1272+
1273+
fetchNotificationTitleAsync();
1274+
getIconBar().setEnabled(true);
1275+
getIconBar().setVisible(true);
1276+
1277+
Timer blinkTimer = new Timer(500, new ActionListener() {
1278+
private int count = 0;
1279+
private final int maxCount = 90; // 110 (55 seconds)
1280+
1281+
@Override
1282+
public void actionPerformed(ActionEvent e) {
1283+
getIconBar().setText(iconTextString);
1284+
if (count >= maxCount) { // end of blinking, keep the icon, remove the text
1285+
// getIconBar().setText("");
1286+
getIconBar().setIcon(VCellIcons.noteRedIcon);
1287+
fadeOutIconText(getIconBar());
1288+
((Timer) e.getSource()).stop();
1289+
return;
1290+
}
1291+
if (count % 2 == 0) {
1292+
getIconBar().setIcon(VCellIcons.noteRedIcon);
12641293
} else {
1265-
DocumentWindow.this.getIconBar().setIcon(VCellIcons.noteWhiteIcon);
1294+
getIconBar().setIcon(VCellIcons.noteWhiteIcon);
1295+
}
1296+
count++;
1297+
}
1298+
});
1299+
blinkTimer.start();
1300+
}
1301+
}.execute();
1302+
}
1303+
private void fetchNotificationTitleAsync() {
1304+
new SwingWorker<String, Void>() {
1305+
1306+
@Override
1307+
protected String doInBackground() {
1308+
try {
1309+
URL url = new URL(notificationsUrl);
1310+
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
1311+
conn.setRequestMethod("GET"); // need GET to read body
1312+
conn.setConnectTimeout(5000);
1313+
conn.setReadTimeout(5000);
1314+
1315+
try (BufferedReader br = new BufferedReader(
1316+
new InputStreamReader(conn.getInputStream()))) {
1317+
1318+
StringBuilder sb = new StringBuilder();
1319+
String line;
1320+
while ((line = br.readLine()) != null) {
1321+
sb.append(line);
12661322
}
1267-
this.count++;
1323+
String html = sb.toString();
1324+
return extractTitle(html); // may return null
12681325
}
1326+
} catch (Exception ignored) {
1327+
return null; // swallow silently
12691328
}
1270-
});
1271-
blinkTimer.start();
1272-
}
1329+
}
1330+
@Override
1331+
protected void done() {
1332+
try {
1333+
String title = get();
1334+
if (title != null && !title.isEmpty()) {
1335+
iconTextString = title;
1336+
}
1337+
} catch (Exception ignored) {
1338+
// swallow silently
1339+
}
1340+
}
1341+
}.execute();
1342+
}
1343+
private String extractTitle(String html) {
1344+
if (html == null) return null;
1345+
1346+
String lower = html.toLowerCase(); // case-insensitive search for <title>...</title>
1347+
int start = lower.indexOf("<title>");
1348+
int end = lower.indexOf("</title>");
1349+
1350+
if (start == -1 || end == -1 || end <= start) {
1351+
return null;
1352+
}
1353+
// extract the actual title text
1354+
return html.substring(start + "<title>".length(), end).trim();
1355+
}
1356+
private void fadeOutIconText(JLabel label) {
1357+
final int steps = 20; // number of fade increments
1358+
final int delay = 50; // ms between steps (total ~1 second)
1359+
final int r = darkRed.getRed();
1360+
final int g = darkRed.getGreen();
1361+
final int b = darkRed.getBlue();
1362+
1363+
Timer fadeTimer = new Timer(delay, null);
1364+
fadeTimer.addActionListener(new ActionListener() {
1365+
int step = 0;
1366+
1367+
@Override
1368+
public void actionPerformed(ActionEvent e) {
1369+
float alpha = 1.0f - (float) step / steps;
1370+
if (alpha <= 0f) {
1371+
label.setText(""); // remove text completely
1372+
fadeTimer.stop();
1373+
return;
1374+
}
1375+
Color faded = new Color(r, g, b, (int) (alpha * 255)); // create same color with decreasing alpha
1376+
label.setForeground(faded);
1377+
step++;
1378+
}
1379+
});
1380+
fadeTimer.start();
12731381
}
12741382

12751383
private javax.swing.JMenuItem getTestingFrameworkMenuItem() {

0 commit comments

Comments
 (0)