Java tutorial
/* * Copyright 2011-2012 University of Toronto * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.ut.biolab.medsavant.client.view; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.*; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.ut.biolab.medsavant.MedSavantClient; import org.ut.biolab.medsavant.client.login.LoginController; import org.ut.biolab.medsavant.shared.model.Notification; import org.ut.biolab.medsavant.shared.model.ProjectDetails; import org.ut.biolab.medsavant.client.project.ProjectController; import org.ut.biolab.medsavant.client.util.ClientMiscUtils; import org.ut.biolab.medsavant.client.util.MedSavantWorker; import org.ut.biolab.medsavant.client.util.PeriodicChecker; import org.ut.biolab.medsavant.client.view.images.IconFactory; import org.ut.biolab.medsavant.client.view.util.DialogUtils; import org.ut.biolab.medsavant.client.view.util.ViewUtil; /** * * @author Andrew */ public class UpdatesPanel extends JPanel { private static final Log LOG = LogFactory.getLog(UpdatesPanel.class); private static final int UPDATE_INTERVAL = 1000 * 60; //one minute private static final Color ALERT_COLOUR = new Color(200, 0, 0); private static final int ICON_WIDTH = 17; //private static final Dimension MENU_ICON_SIZE = new Dimension(260, 90); private static final Dimension MENU_ICON_SIZE = new Dimension(290, 90); private Notification[] notifications; private JPopupMenu popup; //private final JLabel numNotifications; private final JPanel buttonContainer; private static boolean serverChecks = true; public UpdatesPanel() { //setOpaque(false); //setPreferredSize(new Dimension(120, 20)); //setBackground(Color.GREEN); //setVisible(false); setOpaque(false); ViewUtil.applyVerticalBoxLayout(this); JButton button = ViewUtil .getIconButton(IconFactory.getInstance().getIcon(IconFactory.StandardIcon.MENU_NOTIFY)); //numNotifications = new JLabel("0"); buttonContainer = ViewUtil.getClearPanel(); ViewUtil.applyHorizontalBoxLayout(buttonContainer); buttonContainer.add(button); //buttonContainer.add(ViewUtil.getSmallSeparator()); //buttonContainer.add(ViewUtil.centerVertically(numNotifications)); //setCursor(new Cursor(Cursor.HAND_CURSOR)); button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { showPopup(0); } }); new PeriodicChecker(UPDATE_INTERVAL) { @Override public void actionPerformed(ActionEvent ae) { update(); if (!serverChecks) { stop(); } } }; setNotifications(new Notification[0]); } public void update() { if (LoginController.getInstance().isLoggedIn()) { new MedSavantWorker<Notification[]>("Notifications") { @Override protected void showProgress(double fraction) { } @Override protected void showSuccess(Notification[] result) { setNotifications(result); } @Override protected void showFailure(Throwable ex) { if (serverChecks) { LOG.error("Unable to get notifications.", ex); setNotifications(null); } } @Override protected Notification[] doInBackground() throws Exception { if (serverChecks) { return MedSavantClient.NotificationManager.getNotifications( LoginController.getInstance().getSessionID(), LoginController.getInstance().getUserName()); } return null; } }.execute(); } } /** * Aborts checking the server for notifications from ALL update panels. Used * during the shutdown of MedSavant subsequent to auto-publishing (e.g. * variant import, removal, etc.) */ public static void stopServerChecks() { serverChecks = false; } /* @Override public void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D)g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g.setColor(Color.BLACK); g2.drawString(notifications.length == 1 ? "Notification" : "Notifications", ICON_WIDTH + 3, ICON_WIDTH - 4); g2.setColor(ALERT_COLOUR); g2.fill(new Ellipse2D.Double(0.0, 0.0, ICON_WIDTH, ICON_WIDTH)); g2.setColor(Color.WHITE); g2.setFont(getFont().deriveFont(Font.BOLD, 10.0f)); ClientMiscUtils.drawCentred(g2, Integer.toString(notifications.length), new Rectangle2D.Double(0.0, 0.0, ICON_WIDTH, ICON_WIDTH)); } */ private void showPopup(final int start) { popup = new JPopupMenu(); popup.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1)); if (notifications == null) { popup.add(new NotificationIcon(null, null)); } else { //add notifications for (int i = start; i < Math.min(start + 5, notifications.length); i++) { popup.add(new NotificationIcon(notifications[i], popup)); if (i != Math.min(start + 5, notifications.length) - 1) { popup.add(createSeparator()); } } //add page header if (notifications.length > 5) { JPanel header = new JPanel(); header.setMinimumSize(new Dimension(1, 15)); header.setLayout(new BoxLayout(header, BoxLayout.X_AXIS)); if (start >= 5) { JLabel prevButton = ViewUtil.createLabelButton(" Prev Page "); prevButton.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { showPopup(start - 5); } }); header.add(prevButton); } header.add(Box.createHorizontalGlue()); if (start + 5 < notifications.length) { JLabel nextButton = ViewUtil.createLabelButton(" Next Page "); nextButton.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { showPopup(start + 5); } }); header.add(nextButton); } popup.add(createSeparator()); popup.add(header); } } //int offset = -Math.min(5, notifications.length - start) * (MENU_ICON_SIZE.height + 2) -3 - (headerAdded ? 16 : 0); popup.show(this, 0, this.getPreferredSize().height); } private JSeparator createSeparator() { JSeparator sep = new JSeparator(JSeparator.HORIZONTAL); sep.setMaximumSize(new Dimension(1000, 1)); sep.setBackground(Color.WHITE); sep.setForeground(Color.LIGHT_GRAY); return sep; } private void removeNotification(Notification n) { if (notifications.length > 1) { ArrayUtils.removeElement(notifications, n); setNotifications(notifications); } else { setNotifications(null); } } private void setNotifications(Notification[] list) { notifications = list; refreshNotificationCount(); //numNotifications.setText(notifications.length + ""); setVisible(list != null && list.length > 0); } private void refreshNotificationCount() { removeAll(); add(ViewUtil.subTextComponent(buttonContainer, "Notifications (" + (notifications == null ? 0 : notifications.length) + ")")); } class NotificationIcon extends JPanel { public NotificationIcon(final Notification n, final JPopupMenu p) { setPreferredSize(MENU_ICON_SIZE); setLayout(new BorderLayout()); setBackground(Color.white); setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); setCursor(new Cursor(Cursor.HAND_CURSOR)); addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { setBackground(new Color(240, 240, 240)); } @Override public void mouseExited(MouseEvent e) { setBackground(Color.white); } }); if (n == null) { add(new JLabel("<HTML><P>You have no notifications</P></HTML>"), BorderLayout.CENTER); return; } String message = "<P>" + n.getMessage() + "</P>"; switch (n.getType()) { case PUBLISH: message = message + "<P><B>Click to publish or remove</B></P>"; addMouseListener(new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { p.setVisible(false); //get db lock try { if (MedSavantClient.SettingsManager .getDBLock(LoginController.getInstance().getSessionID())) { try { if (ProjectController.getInstance() .promptToPublish((ProjectDetails) n.getData())) { removeNotification(n); } } finally { try { MedSavantClient.SettingsManager .releaseDBLock(LoginController.getInstance().getSessionID()); } catch (Exception ex1) { LOG.error("Error releasing database lock.", ex1); } } } else { DialogUtils.displayMessage("Cannot make changes", "Another user is making changes to the database. You must wait until this user has finished. "); } } catch (Exception ex) { ClientMiscUtils.reportError("Error getting database lock: %s", ex); } } }); break; } add(new JLabel("<HTML>" + message + "</HTML>"), BorderLayout.CENTER); } } }