package org.docear.plugin.services.workspace; import java.awt.Component; import java.awt.Frame; import java.awt.Point; import java.awt.event.ContainerEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowEvent; import java.awt.event.WindowFocusListener; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.event.TreeModelEvent; import org.docear.plugin.core.CoreConfiguration; import org.docear.plugin.core.DocearController; import org.docear.plugin.core.ui.IViewportOverlay; import org.docear.plugin.core.ui.OverlayLayoutManager; import org.docear.plugin.core.ui.OverlayViewport; import org.freeplane.core.ui.components.UITools; import org.freeplane.core.util.TextUtils; import org.freeplane.features.map.MapModel; import org.freeplane.features.mode.Controller; import org.freeplane.plugin.workspace.WorkspaceController; import org.freeplane.plugin.workspace.model.WorkspaceModelEvent; import org.freeplane.plugin.workspace.model.WorkspaceModelListener; import org.freeplane.plugin.workspace.model.project.AWorkspaceProject; import org.freeplane.view.swing.map.MapView; public class MapViewWaringOverlay implements IViewportOverlay { private MouseAdapter mouseAdapter; private JDialog d; private final JLabel labelField = new JLabel(); private WindowFocusListener focusListener; private final JLabel component; private OverlayViewport parent; public MapViewWaringOverlay() { component = new JLabel(new ImageIcon(CoreConfiguration.class.getResource("/images/dialog-warning-64x64.png"))); component.setToolTipText(TextUtils.getRawText("docear.map.project.missing")); WorkspaceController.getCurrentModel().addWorldModelListener(new WorkspaceModelListener() { public void treeStructureChanged(TreeModelEvent e) {} public void treeNodesRemoved(TreeModelEvent e) {} public void treeNodesInserted(TreeModelEvent e) {} public void treeNodesChanged(TreeModelEvent e) {} public void projectRemoved(WorkspaceModelEvent event) { DocearController.getController().getEventQueue().invoke(new Runnable() { public void run() { updateWarningState(Controller.getCurrentController().getMap()); parent.repaint(); } }); } public void projectAdded(WorkspaceModelEvent event) { DocearController.getController().getEventQueue().invoke(new Runnable() { public void run() { updateWarningState(Controller.getCurrentController().getMap()); parent.repaint(); } }); } }); } public boolean isVisible() { return component.isVisible(); } public Component getComponent() { return component; } public void viewChanged(VIEW_CHANGE type, ContainerEvent e) { if(type == VIEW_CHANGE.ADD) { if(e.getChild() instanceof MapView) { e.getChild().addMouseMotionListener(getMouseAdapter()); MapModel map = ((MapView)e.getChild()).getModel(); updateWarningState(map); } } else if(type == VIEW_CHANGE.REMOVE) { if(e.getChild() instanceof MapView) { e.getChild().removeMouseMotionListener(getMouseAdapter()); } } } public void updateWarningState(MapModel map) { AWorkspaceProject project = WorkspaceController.getMapProject(map); if(map != null && (project == null || !project.isLoaded())) { component.setVisible(true); } else { component.setVisible(false); } } private MouseAdapter getMouseAdapter() { if(mouseAdapter == null) { mouseAdapter = new MouseAdapter() { @Override public void mouseMoved(MouseEvent e) { Point origin = parent.getViewPosition(); Point p = parent.toViewCoordinates(e.getPoint()); p.translate(-origin.x, -origin.y); JComponent comp = parent.getIntersectingOverlay(p); if(comp != null) { handlePopup(comp, e); } else { if(d != null && d.isVisible()) { d.setVisible(false); } } } private void handlePopup(JComponent comp, MouseEvent e) { if(d == null) { final Frame frame = UITools.getFrame(); d = new JDialog(frame, comp.getName()); d.setUndecorated(true); d.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); d.setModal(false); d.add(labelField); } labelField.setText(comp.getToolTipText()); d.setLocation(e.getLocationOnScreen().x, e.getLocationOnScreen().y+24); d.removeWindowFocusListener(getWindowFocusListener()); d.addWindowFocusListener(getWindowFocusListener()); d.pack(); d.setVisible(true); } @Override public void mouseExited(MouseEvent e) { if(d != null) { d.setVisible(false); } } }; } return mouseAdapter; } private WindowFocusListener getWindowFocusListener() { if (focusListener == null) { final Frame frame = UITools.getFrame(); focusListener = new WindowFocusListener() { public void windowLostFocus(WindowEvent e) { } public void windowGainedFocus(WindowEvent e) { frame.addWindowFocusListener(new WindowFocusListener() { public void windowLostFocus(WindowEvent e) { if (d != null) { d.setVisible(false); } } public void windowGainedFocus(WindowEvent e) { if (d != null) { d.setVisible(false); } frame.removeWindowFocusListener(this); } }); if (d != null) { d.removeWindowFocusListener(this); } } }; } return focusListener; } public void setParent(OverlayViewport parent) { this.parent = parent; } public String[] getPositionConstraints() { return new String[] {OverlayLayoutManager.ALIGN_TOP, OverlayLayoutManager.FLOAT_RIGHT}; } }