001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2009 Sun Microsystems, Inc. 025 * Portions Copyright 2015 ForgeRock AS 026 */ 027 028package org.opends.guitools.controlpanel.event; 029 030import java.awt.Component; 031import java.awt.Dimension; 032import java.awt.Point; 033import java.awt.Rectangle; 034import java.awt.event.MouseAdapter; 035import java.awt.event.MouseEvent; 036 037import javax.swing.JComponent; 038import javax.swing.JTable; 039import javax.swing.JToolTip; 040import javax.swing.Popup; 041import javax.swing.PopupFactory; 042import javax.swing.table.TableCellRenderer; 043 044/** 045 * This class listens to events and displays a tooltip when the user clicks on 046 * the object that registered this listener. 047 * 048 */ 049public class ClickTooltipDisplayer extends MouseAdapter 050{ 051 private boolean isTooltipVisible; 052 private Popup tipWindow; 053 054 /** {@inheritDoc} */ 055 public void mouseExited(MouseEvent event) 056 { 057 hideToolTip(event); 058 } 059 060 /** {@inheritDoc} */ 061 public void mousePressed(MouseEvent event) 062 { 063 if (isTooltipVisible) 064 { 065 hideToolTip(event); 066 } 067 else 068 { 069 displayToolTip(event); 070 } 071 } 072 073 /** 074 * Displays a tooltip depending on the MouseEvent received. 075 * @param event the mouse event. 076 */ 077 private void displayToolTip(MouseEvent event) 078 { 079 JComponent component = (JComponent)event.getSource(); 080 String toolTipText; 081 if (component instanceof JTable) 082 { 083 JTable table = (JTable)component; 084 int row = table.rowAtPoint(event.getPoint()); 085 int column = table.columnAtPoint(event.getPoint()); 086 if (row != -1 && column != -1) 087 { 088 TableCellRenderer renderer = table.getCellRenderer(row, column); 089 Component comp = renderer.getTableCellRendererComponent(table, 090 table.getValueAt(row, column), true, true, row, column); 091 if (comp instanceof JComponent) 092 { 093 // The coordinates must be translated. 094 Rectangle rect = table.getCellRect(row, column, true); 095 int x = event.getPoint().x - rect.x; 096 int y = event.getPoint().y - rect.y; 097 MouseEvent tEv = new MouseEvent(table, event.getID(), 098 event.getWhen(), event.getModifiers(), x, y, 099 event.getClickCount(), event.isPopupTrigger(), event.getButton()); 100 toolTipText = ((JComponent)comp).getToolTipText(tEv); 101 } 102 else 103 { 104 toolTipText = null; 105 } 106 } 107 else 108 { 109 toolTipText = null; 110 } 111 } 112 else 113 { 114 toolTipText = component.getToolTipText(); 115 } 116 if (toolTipText != null) 117 { 118 Point preferredLocation = component.getToolTipLocation(event); 119 Rectangle sBounds = component.getGraphicsConfiguration(). 120 getBounds(); 121 122 JToolTip tip = component.createToolTip(); 123 tip.setTipText(toolTipText); 124 Dimension size = tip.getPreferredSize(); 125 Point location = new Point(); 126 127 Point screenLocation = component.getLocationOnScreen(); 128 if(preferredLocation != null) 129 { 130 location.x = screenLocation.x + preferredLocation.x; 131 location.y = screenLocation.y + preferredLocation.y; 132 } 133 else 134 { 135 location.x = screenLocation.x + event.getX(); 136 location.y = screenLocation.y + event.getY() + 20; 137 } 138 139 if (location.x < sBounds.x) { 140 location.x = sBounds.x; 141 } 142 else if (location.x - sBounds.x + size.width > sBounds.width) { 143 location.x = sBounds.x + Math.max(0, sBounds.width - size.width); 144 } 145 if (location.y < sBounds.y) { 146 location.y = sBounds.y; 147 } 148 else if (location.y - sBounds.y + size.height > sBounds.height) { 149 location.y = sBounds.y + Math.max(0, sBounds.height - size.height); 150 } 151 152 PopupFactory popupFactory = PopupFactory.getSharedInstance(); 153 tipWindow = popupFactory.getPopup(component, tip, location.x, location.y); 154 tipWindow.show(); 155 isTooltipVisible = true; 156 } 157 } 158 159 /** 160 * Hides the tooltip if we are displaying it. 161 * @param event the mouse event. 162 */ 163 private void hideToolTip(MouseEvent event) 164 { 165 if (tipWindow != null) 166 { 167 tipWindow.hide(); 168 tipWindow = null; 169 isTooltipVisible = false; 170 } 171 } 172}