/** * Constructor. * * @param owner The parent window. * @param msg The text of the tool tip. This can be HTML. */ public TipWindow(Window owner, FocusableTip ft, String msg) { super(owner); this.ft = ft; // Render plain text tool tips correctly. if (msg != null && msg.length() >= 6 && !msg.substring(0, 6).toLowerCase().equals("<html>")) { msg = "<html>" + RSyntaxUtilities.escapeForHtml(msg, "<br>", false); } this.text = msg; tipListener = new TipListener(); JPanel cp = new JPanel(new BorderLayout()); cp.setBorder(TipUtil.getToolTipBorder()); cp.setBackground(TipUtil.getToolTipBackground()); textArea = new JEditorPane("text/html", text); TipUtil.tweakTipEditorPane(textArea); if (ft.getImageBase() != null) { // Base URL for images ((HTMLDocument) textArea.getDocument()).setBase(ft.getImageBase()); } textArea.addMouseListener(tipListener); textArea.addHyperlinkListener( new HyperlinkListener() { public void hyperlinkUpdate(HyperlinkEvent e) { if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { TipWindow.this.ft.possiblyDisposeOfTipWindow(); } } }); cp.add(textArea); setFocusableWindowState(false); setContentPane(cp); setBottomPanel(); // Must do after setContentPane() pack(); // InputMap/ActionMap combo doesn't work for JWindows (even when // using the JWindow's JRootPane), so we'll resort to KeyListener KeyAdapter ka = new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { TipWindow.this.ft.possiblyDisposeOfTipWindow(); } } }; addKeyListener(ka); textArea.addKeyListener(ka); // Ensure only 1 TipWindow is ever visible. If the caller does what // they're supposed to and only creates these on the EDT, the // synchronization isn't necessary, but we'll be extra safe. synchronized (TipWindow.class) { if (visibleInstance != null) { visibleInstance.dispose(); } visibleInstance = this; } }
/** Disposes of this window. */ @Override public void dispose() { // System.out.println("[DEBUG]: Disposing..."); Container cp = getContentPane(); for (int i = 0; i < cp.getComponentCount(); i++) { // Okay if listener is already removed cp.getComponent(i).removeMouseListener(tipListener); } ft.removeListeners(); super.dispose(); }
public void actionPerformed(ActionEvent e) { if (!getFocusableWindowState()) { setFocusableWindowState(true); setBottomPanel(); textArea.removeMouseListener(tipListener); pack(); addWindowFocusListener( new WindowAdapter() { @Override public void windowLostFocus(WindowEvent e) { ft.possiblyDisposeOfTipWindow(); } }); ft.removeListeners(); if (e == null) { // Didn't get here via our mouseover timer requestFocus(); } } }
private void setBottomPanel() { final JPanel panel = new JPanel(new BorderLayout()); panel.add(new JSeparator(), BorderLayout.NORTH); boolean focusable = getFocusableWindowState(); if (focusable) { SizeGrip sg = new SizeGrip(); sg.applyComponentOrientation(sg.getComponentOrientation()); // Workaround panel.add(sg, BorderLayout.LINE_END); MouseInputAdapter adapter = new MouseInputAdapter() { private Point lastPoint; @Override public void mouseDragged(MouseEvent e) { Point p = e.getPoint(); SwingUtilities.convertPointToScreen(p, panel); if (lastPoint == null) { lastPoint = p; } else { int dx = p.x - lastPoint.x; int dy = p.y - lastPoint.y; setLocation(getX() + dx, getY() + dy); lastPoint = p; } } @Override public void mousePressed(MouseEvent e) { lastPoint = e.getPoint(); SwingUtilities.convertPointToScreen(lastPoint, panel); } }; panel.addMouseListener(adapter); panel.addMouseMotionListener(adapter); // Don't add tipListener to the panel or SizeGrip } else { panel.setOpaque(false); JLabel label = new JLabel(FocusableTip.getString("FocusHotkey")); Color fg = UIManager.getColor("Label.disabledForeground"); Font font = textArea.getFont(); font = font.deriveFont(font.getSize2D() - 1.0f); label.setFont(font); if (fg == null) { // Non BasicLookAndFeel-derived Looks fg = Color.GRAY; } label.setOpaque(true); Color bg = TipUtil.getToolTipBackground(); label.setBackground(bg); label.setForeground(fg); label.setHorizontalAlignment(SwingConstants.TRAILING); label.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); panel.add(label); panel.addMouseListener(tipListener); } // Replace the previous SOUTH Component with the new one. Container cp = getContentPane(); if (cp.getComponentCount() == 2) { // Skip first time through Component comp = cp.getComponent(0); cp.remove(0); JScrollPane sp = new JScrollPane(comp); Border emptyBorder = BorderFactory.createEmptyBorder(); sp.setBorder(emptyBorder); sp.setViewportBorder(emptyBorder); sp.setBackground(textArea.getBackground()); sp.getViewport().setBackground(textArea.getBackground()); cp.add(sp); // What was component 1 is now 0. cp.getComponent(0).removeMouseListener(tipListener); cp.remove(0); } cp.add(panel, BorderLayout.SOUTH); }