package com.baselet.diagram; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; import java.awt.event.ContainerEvent; import java.awt.event.ContainerListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.File; import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.Scanner; import javax.swing.JEditorPane; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.baselet.control.constants.SystemInfo; import com.baselet.control.enums.Metakey; import com.baselet.control.enums.Program; import com.baselet.control.util.Utils; import com.baselet.gui.CurrentGui; import com.baselet.gui.listener.HyperLinkActiveListener; public class StartUpHelpText extends JEditorPane implements ContainerListener, ComponentListener { private static final long serialVersionUID = 1L; static final Logger log = LoggerFactory.getLogger(StartUpHelpText.class); private DrawPanel panel; private boolean visible; public StartUpHelpText(DrawPanel panel) { super(); this.panel = panel; // If the GUI is null (e.g.: if main is used in batch mode) the startup help text is not required if (CurrentGui.getInstance().getGui() == null) { return; } panel.addContainerListener(this); panel.addComponentListener(this); addMouseListener(new DelegatingMouseListener()); try { if (UpdateCheckTimerTask.getInstance().getFilename() == null) { showHTML(createTempFileWithText(getDefaultTextWithReplacedSystemspecificMetakeys())); } else { showHTML(UpdateCheckTimerTask.getInstance().getFilename()); } } catch (IOException e) { // #361: such an error should not crash UMLet, instead a simple information should be shown that something has gone wrong log.error("Cannot load startupinfo", e); setText("Cannot load startupinfo"); setSize(130, 10); } } // Must be overwritten to hide the helptext if a the custom elements panel is toggled without elements on the drawpanel @Override public void setEnabled(boolean en) { super.setEnabled(en); if (en && visible) { if (panel.getGridElements().size() == 0) { setVisible(true); } else { visible = false; } } else { visible = isVisible(); setVisible(false); } } static InputStream getStartUpFileName() { return StartUpHelpText.class.getClassLoader().getResourceAsStream("startuphelp.html"); } private void showHTML(String filename) throws MalformedURLException, IOException { this.setPage(new URL("file:///" + filename)); addHyperlinkListener(new HyperLinkActiveListener()); setEditable(false); setBackground(Color.WHITE); setSelectionColor(getBackground()); setSelectedTextColor(getForeground()); } static String createTempFileWithText(String textToWriteIntoFile) throws IOException { File tempFile = File.createTempFile(Program.getInstance().getProgramName() + "_startupfile", ".html"); tempFile.deleteOnExit(); FileWriter w = new FileWriter(tempFile); w.write(textToWriteIntoFile); w.close(); return tempFile.getAbsolutePath(); } private static String getDefaultTextWithReplacedSystemspecificMetakeys() throws FileNotFoundException { StringBuilder sb = new StringBuilder(""); Scanner sc = null; try { sc = new Scanner(getStartUpFileName()); while (sc.hasNextLine()) { String line = sc.nextLine(); if (SystemInfo.META_KEY == Metakey.CTRL) { line = line.replace(Metakey.CMD.toString(), Metakey.CTRL.toString()); } else if (SystemInfo.META_KEY == Metakey.CMD) { line = line.replace(Metakey.CTRL.toString(), Metakey.CMD.toString()); } sb.append(line).append("\n"); } } finally { if (sc != null) { sc.close(); } } return sb.toString(); } @Override public void componentAdded(ContainerEvent e) { boolean gridElementAdded = panel.getElementToComponent(e.getChild()) != null; if (gridElementAdded) { setVisible(false); } } @Override public void componentRemoved(ContainerEvent e) { if (e.getContainer().getComponentCount() <= 1 && !equals(e.getChild())) { setVisible(true); } } @Override public void componentResized(ComponentEvent arg0) { Dimension size = panel.getSize(); Dimension labelSize = getPreferredSize(); this.setSize(labelSize); int minDistanceFromTop = 25; int labelSizeToSubtract = Math.max(150, labelSize.height); // the upper border of the startup panel is at least 200px over the middle of the screen (necessary to have a good position for small update info windows) this.setLocation(size.width / 2 - labelSize.width / 2, Math.max(minDistanceFromTop, size.height / 2 - labelSizeToSubtract)); } @Override public void paint(Graphics g) { // Subpixel rendering must be disabled for the startuphelp (looks bad) ((Graphics2D) g).setRenderingHints(Utils.getUxRenderingQualityHigh(false)); super.paint(g); ((Graphics2D) g).setRenderingHints(Utils.getUxRenderingQualityHigh(true)); } @Override public void componentHidden(ComponentEvent arg0) {} @Override public void componentMoved(ComponentEvent arg0) {} @Override public void componentShown(ComponentEvent arg0) {} /** * The MouseListener of this JEditorPane just delegates the * MouseEvents up to the DiagramListener of the Handler */ private class DelegatingMouseListener implements MouseListener { @Override public void mouseClicked(MouseEvent e) { panel.getHandler().getListener().mouseClicked(e); } @Override public void mouseEntered(MouseEvent e) { panel.getHandler().getListener().mouseEntered(e); } @Override public void mouseExited(MouseEvent e) { panel.getHandler().getListener().mouseExited(e); } @Override public void mousePressed(MouseEvent e) { panel.getHandler().getListener().mousePressed(e); } @Override public void mouseReleased(MouseEvent e) { panel.getHandler().getListener().mouseReleased(e); } } }