Author: echatellier Date: 2010-03-25 10:51:44 +0100 (Thu, 25 Mar 2010) New Revision: 251 Log: Add datatips code with nimbus fix. Added: trunk/src/main/java/org/nuiton/widget/datatips/ trunk/src/main/java/org/nuiton/widget/datatips/DataTipCell.java trunk/src/main/java/org/nuiton/widget/datatips/DataTipComponent.java trunk/src/main/java/org/nuiton/widget/datatips/DataTipListener.java trunk/src/main/java/org/nuiton/widget/datatips/DataTipManager.java trunk/src/main/java/org/nuiton/widget/datatips/DataTipPopup.java trunk/src/main/java/org/nuiton/widget/datatips/ListDataTipCell.java trunk/src/main/java/org/nuiton/widget/datatips/ListDataTipListener.java trunk/src/main/java/org/nuiton/widget/datatips/TableDataTipCell.java trunk/src/main/java/org/nuiton/widget/datatips/TableDataTipListener.java trunk/src/main/java/org/nuiton/widget/datatips/TreeDataTipCell.java trunk/src/main/java/org/nuiton/widget/datatips/TreeDataTipListener.java trunk/src/main/java/org/nuiton/widget/datatips/package-info.java Added: trunk/src/main/java/org/nuiton/widget/datatips/DataTipCell.java =================================================================== --- trunk/src/main/java/org/nuiton/widget/datatips/DataTipCell.java (rev 0) +++ trunk/src/main/java/org/nuiton/widget/datatips/DataTipCell.java 2010-03-25 09:51:44 UTC (rev 251) @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2002 - 2005, Stephen Kelvin Friedrich. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the name of the copyright holder nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.nuiton.widget.datatips; + +import java.awt.*; + +interface DataTipCell { + + boolean isSet(); + + Component getRendererComponent(); + + Rectangle getCellBounds(); + + /** + * 'Null' value for cells (location is outside of any cell bounds). + */ + DataTipCell NONE = new DataTipCell() { + + public boolean isSet() { + return false; + } + + public Component getRendererComponent() { + return null; + } + + public Rectangle getCellBounds() { + return null; + } + + public boolean equals(Object obj) { + return false; + } + + public int hashCode() { + return 0; + } + }; +} Property changes on: trunk/src/main/java/org/nuiton/widget/datatips/DataTipCell.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/src/main/java/org/nuiton/widget/datatips/DataTipComponent.java =================================================================== --- trunk/src/main/java/org/nuiton/widget/datatips/DataTipComponent.java (rev 0) +++ trunk/src/main/java/org/nuiton/widget/datatips/DataTipComponent.java 2010-03-25 09:51:44 UTC (rev 251) @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2002 - 2005, Stephen Kelvin Friedrich. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the name of the copyright holder nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.nuiton.widget.datatips; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; + +/** + * Note: It's important to inherit from JToolTip: Mouse events get dispatched to the parent.<br/> + * I do not really know why this is so. At least PopupFactory creates a different type of popup + * if the content is instance of JToolTip. + */ +class DataTipComponent extends JToolTip { + private DataTipCell cell; + private CellRendererPane rendererPane; + private Rectangle withoutBorderRectangle; + private Color backgroundColor; + private boolean isHeavyWeight; + + DataTipComponent(DataTipCell cell, Rectangle withoutBorderRectangle, Color backgroundColor) { + this.cell = cell; + this.withoutBorderRectangle = withoutBorderRectangle; + this.backgroundColor = backgroundColor; + rendererPane = new CellRendererPane(); + add(rendererPane); + setFocusable(false); + setBorder(null); + enableEvents(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_WHEEL_EVENT_MASK); + } + + /** + * Overriden, so that Swing does not create a ToolTipUI. + */ + public void updateUI() { + } + + /** + * Overriden to always return false, so that no component ever receives mouse events. + * Instead a mouse press will be caught on the popup's window ancestor, the popup will be hidden and the mouse press redispatched + * to the underlying component. + */ + public boolean contains(int x, int y) { + return isHeavyWeight; + } + + protected void processMouseEvent(MouseEvent e) { + DataTipManager.get().handleEventFromDataTipComponent(e); + } + + protected void processMouseMotionEvent(MouseEvent e) { + DataTipManager.get().handleEventFromDataTipComponent(e); + } + + protected void processMouseWheelEvent(MouseWheelEvent e) { + DataTipManager.get().handleEventFromDataTipComponent(e); + } + + public void paintComponent(Graphics g) { + Component component = cell.getRendererComponent(); + + // Leave the component's opacity settings as is, just paint the background myself. + // This seems to be the only viable solution: DefaultTableCellRenderer overrides isOpaque() and returns + // true only if renderer color does not equal parent color. The problem is that rendererPane.paintComponent() + // re-parents the renderer. + g.setColor(backgroundColor); + int width = getWidth(); + int height = getHeight(); + g.fillRect(0, 0, width, height); + + g.setColor(Color.black); + g.drawRect(0, 0, width - 1, height - 1); + + if (withoutBorderRectangle != null) { + Shape oldClip = g.getClip(); + g.setClip(withoutBorderRectangle); + g.setColor(backgroundColor); + g.fillRect(0, 0, width, height); + g.setClip(oldClip); + } + + g.setClip(1, 1, width - 2, height - 2); + rendererPane.paintComponent(g, component, this, 0, 0, width, height); + g.setClip(withoutBorderRectangle); + rendererPane.paintComponent(g, component, this, 0, 0, width, height); + } + + public void setHeavyWeight(boolean isHeavyWeight) { + this.isHeavyWeight = isHeavyWeight; + } +} Property changes on: trunk/src/main/java/org/nuiton/widget/datatips/DataTipComponent.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/src/main/java/org/nuiton/widget/datatips/DataTipListener.java =================================================================== --- trunk/src/main/java/org/nuiton/widget/datatips/DataTipListener.java (rev 0) +++ trunk/src/main/java/org/nuiton/widget/datatips/DataTipListener.java 2010-03-25 09:51:44 UTC (rev 251) @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2002 - 2005, Stephen Kelvin Friedrich. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the name of the copyright holder nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.nuiton.widget.datatips; + +import javax.swing.*; +import javax.swing.event.MouseInputAdapter; +import java.awt.*; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.awt.event.MouseEvent; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +abstract class DataTipListener extends MouseInputAdapter implements ComponentListener { + private DataTipPopup dataTipPopup; + + // When running under JDK 1.5 (or higher) DataTipListener will check if the tip must be updated when the parent + // component changes size or moves. + // With JDK 1.4 or earlier this does not work, because no mouse event gets posted (even though the relative mouse + // position changes) - yet to be able to compile with 1.4 the necessary JDK 1.5 methods are called by reflection. + // On JDK 1.4 the popup is just always hidden qwhen the component changes (and reshown when the user first moves + // the mouse again). + private static final Class[] NO_PARAMETERS = new Class[0]; + private static final Object[] NO_ARGUMENTS = new Object[0]; + private static Class mouseInfoClass; + private static Method getPointerInfoMethod; + private static Class pointerInfoClass; + private static Method getLocationMethod; + + static { + try { + mouseInfoClass = Class.forName("java.awt.MouseInfo"); + getPointerInfoMethod = mouseInfoClass.getMethod("getPointerInfo", NO_PARAMETERS); + pointerInfoClass = Class.forName("java.awt.PointerInfo"); + getLocationMethod = pointerInfoClass.getMethod("getLocation", NO_PARAMETERS); + } + catch(NoSuchMethodException e) { + // fine probably running on pre-1.5-JDK + } + catch(ClassNotFoundException e) { + // fine probably running on pre-1.5-JDK + } + } + + DataTipListener() { + } + + /** + * @return the cell that is at position 'point' in the component or DataTipCell.NONE if there isn't a cell at that + * point. + */ + abstract DataTipCell getCell(JComponent component, Point point); + + /** + * If the user presses a mouse button on a popup, Swing's behaviour depends on the popup type: + * - lightweight popup: + * This case is handled here. Because the TipComponent.contains(int x, int y) is overriden to always return false + * Swing will dispath the event directly to the parent component. + * - heavyweight popup: + * Swing will dispatch the event to the popup's window, which is handled in DataTipPopup. + */ + public void mousePressed(MouseEvent e) { + //hideTip(); Can't: Double click would not work. Click count of the second click would be '1', because it would + // go to a different window (for heavyweight datatips). + } + + public void mouseEntered(MouseEvent event) { + checkShowOrHide(event); + } + + public void mouseExited(MouseEvent event) { + checkShowOrHide(event); + } + + public void mouseDragged(MouseEvent event) { + checkShowOrHide(event); + } + + public void mouseMoved(MouseEvent event) { + checkShowOrHide(event); + } + + private void checkShowOrHide(MouseEvent event) { + JComponent component = (JComponent) event.getSource(); + Point mousePosition = event.getPoint(); + checkShowOrHide(component, mousePosition); + } + + private void checkShowOrHide(JComponent component, Point mousePosition) { + Window windowAncestor = SwingUtilities.getWindowAncestor(component); + if (windowAncestor == null || !windowAncestor.isActive()) { + hideTip(); + return; + } + + DataTipCell dataTipCell = getCell(component, mousePosition); + Rectangle visRect = component.getVisibleRect(); + + if(!visRect.contains(mousePosition)) { + dataTipCell = DataTipCell.NONE; + } + + DataTipCell currentPopupCell = getCurrentPopupCell(); + if(dataTipCell.equals(currentPopupCell)) { + return; + } + + hideTip(); + if(!dataTipCell.isSet()) { + return; + } + + dataTipPopup = createPopup(component, mousePosition, dataTipCell); + } + + private DataTipCell getCurrentPopupCell() { + if(!isTipShown()) { + return DataTipCell.NONE; + } + return dataTipPopup.getCell(); + } + + private DataTipPopup createPopup(JComponent component, Point mousePosition, DataTipCell dataTipCell) { + Rectangle cellBounds = dataTipCell.getCellBounds(); + + Rectangle visRect = component.getVisibleRect(); + Rectangle visibleCellRectangle = cellBounds.intersection(visRect); + if (!visibleCellRectangle.contains(mousePosition)) { + return null; + } + + Component rendererComponent = dataTipCell.getRendererComponent(); + Dimension rendCompDim = rendererComponent.getMinimumSize(); + Rectangle rendCompBounds = new Rectangle(cellBounds.getLocation(), rendCompDim); + if(cellBounds.contains(rendCompBounds) && visRect.contains(rendCompBounds)) { + return null; + } + + Dimension preferredSize = rendererComponent.getPreferredSize(); + Point tipPosition = cellBounds.getLocation(); + int width = Math.max(cellBounds.width, preferredSize.width); + int height = Math.max(cellBounds.height, preferredSize.height); + Dimension tipDimension = new Dimension(width, height); + DataTipPopup dataTipPopup = new DataTipPopup(component, dataTipCell, tipPosition, tipDimension); + + return dataTipPopup; + } + + private boolean isTipShown() { + return dataTipPopup != null && dataTipPopup.isTipShown(); + } + + private void hideTip() { + if (dataTipPopup != null) { + dataTipPopup.hideTip(); + dataTipPopup = null; + } + } + + public void componentResized(ComponentEvent e) { + checkShowOrHide(e); + } + + public void componentMoved(ComponentEvent e) { + checkShowOrHide(e); + } + + public void componentShown(ComponentEvent e) { + checkShowOrHide(e); + } + + public void componentHidden(ComponentEvent e) { + hideTip(); + } + + private void checkShowOrHide(ComponentEvent e) { + JComponent component = (JComponent) e.getSource(); + Point mousePosition = getCurrentMousePosition(); + if(mousePosition == null) { + hideTip(); + } + else { + SwingUtilities.convertPointFromScreen(mousePosition, component); + checkShowOrHide(component, mousePosition); + } + } + + private static Point getCurrentMousePosition() { + if(mouseInfoClass == null) { + return null; + } + try { + Object pointerInfo = getPointerInfoMethod.invoke(null, NO_ARGUMENTS); + Point mousePosition = (Point) getLocationMethod.invoke(pointerInfo, NO_ARGUMENTS); + return mousePosition; + } + catch(IllegalAccessException e) { + // strange, but nothing I can do here + } + catch(InvocationTargetException e) { + // strange, but nothing I can do here + } + + return null; + } +} Property changes on: trunk/src/main/java/org/nuiton/widget/datatips/DataTipListener.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/src/main/java/org/nuiton/widget/datatips/DataTipManager.java =================================================================== --- trunk/src/main/java/org/nuiton/widget/datatips/DataTipManager.java (rev 0) +++ trunk/src/main/java/org/nuiton/widget/datatips/DataTipManager.java 2010-03-25 09:51:44 UTC (rev 251) @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2002 - 2005, Stephen Kelvin Friedrich. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the name of the copyright holder nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.nuiton.widget.datatips; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.AWTEventListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; +import java.security.AccessControlException; + +/** + * <code>DataTipManager</code> provides data tips for tree, table and list components. Whenever the mouse cursor is + * over a cell whose content is partially hidden a popup with the complete cell content is shown. + * The cell content can be hidden because it is clipped at either the parent component bounds (e.g. scrollpane) or at + * the cell bounds (e.g. table row height is too small). + */ +public class DataTipManager { + private static DataTipManager instance; + + private ListDataTipListener listMouseListener = new ListDataTipListener(); + private TableDataTipListener tableMouseListener = new TableDataTipListener(); + private TreeDataTipListener treeMouseListener = new TreeDataTipListener(); + private Component parentComponent; + private Window tipComponentWindow; + private MouseEvent lastMouseEvent; + private static boolean allowUntrustedUsage; + + private DataTipManager() { + try { + long eventMask = AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.MOUSE_WHEEL_EVENT_MASK; + Toolkit.getDefaultToolkit().addAWTEventListener(new MouseEventModifier(), eventMask); + } + catch(AccessControlException e) { + if(!allowUntrustedUsage) { + throw new RuntimeException("DataTipManager needs to run in a trusted application", e); + } + } + } + + static void enableUntrustedUsage(boolean enable) { + allowUntrustedUsage = enable; + } + + /** + * @return the single, shared instance of the DataTipmanager + */ + public static synchronized DataTipManager get() { + if(instance == null) { + instance = new DataTipManager(); + } + return instance; + } + + /** + * Enable data tips for a list component. + * @param list the list which should be enhanced with data tips. + */ + public synchronized void register(JList list) { + list.addMouseListener(listMouseListener); + list.addMouseMotionListener(listMouseListener); + list.addComponentListener(listMouseListener); + } + + /** + * Enable data tips for a tree component. + * @param tree the tree which should be enhanced with data tips. + */ + public synchronized void register(JTree tree) { + tree.addMouseListener(treeMouseListener); + tree.addMouseMotionListener(treeMouseListener); + tree.addComponentListener(treeMouseListener); + } + + /** + * Enable data tips for a list component. + * @param table the table which should be enhanced with data tips. + */ + public synchronized void register(JTable table) { + table.addMouseListener(tableMouseListener); + table.addMouseMotionListener(tableMouseListener); + table.addComponentListener(tableMouseListener); + } + + void setTipWindow(Component parentComponent, Window dataTipComponent) { + this.parentComponent = parentComponent; + tipComponentWindow = dataTipComponent; + } + + public boolean handleEventFromParentComponent(MouseEvent mouseEvent) { + // filter out events that come from client explicitly calling this method, but we have already handled in awt event listener + if(mouseEvent == lastMouseEvent) { + return false; + } + Object source = mouseEvent.getSource(); + if(source != parentComponent) { + return false; + } + int id = mouseEvent.getID(); + int x = mouseEvent.getX(); + int y = mouseEvent.getY(); + long when = mouseEvent.getWhen(); + int modifiers = mouseEvent.getModifiers(); + int clickCount = mouseEvent.getClickCount(); + boolean isPopupTrigger = mouseEvent.isPopupTrigger(); + if(id == MouseEvent.MOUSE_EXITED) { + Point point = SwingUtilities.convertPoint(parentComponent, x, y, tipComponentWindow); + if(tipComponentWindow.contains(point)) { + MouseEvent newEvent = new MouseEvent(parentComponent, MouseEvent.MOUSE_MOVED, when, modifiers, + x, y, clickCount, isPopupTrigger); + parentComponent.dispatchEvent(newEvent); + // If the datatip has been hidden as a result, then process the exit event, too, so that + // e.g. tooltips will hide. + boolean stillVisible = parentComponent != null; + return stillVisible; + } + } + return false; + } + + public void handleEventFromDataTipComponent(MouseEvent mouseEvent) { + mouseEvent.consume(); + int id = mouseEvent.getID(); + if(id != MouseEvent.MOUSE_ENTERED) { + int x = mouseEvent.getX(); + int y = mouseEvent.getY(); + Point point = SwingUtilities.convertPoint(mouseEvent.getComponent(), x, y, parentComponent); + + if(id == MouseEvent.MOUSE_EXITED && parentComponent.contains(point)) { + return; + } + long when = mouseEvent.getWhen(); + int modifiers = mouseEvent.getModifiers(); + int clickCount = mouseEvent.getClickCount(); + boolean isPopupTrigger = mouseEvent.isPopupTrigger(); + MouseEvent newEvent; + if(id == MouseEvent.MOUSE_WHEEL) { + MouseWheelEvent mouseWheelEvent = (MouseWheelEvent) mouseEvent; + int scrollType = mouseWheelEvent.getScrollType(); + int scrollAmount = mouseWheelEvent.getScrollAmount(); + int wheelRotation = mouseWheelEvent.getWheelRotation(); + newEvent = new MouseWheelEvent(parentComponent, id, when, modifiers, point.x, point.y, + clickCount, isPopupTrigger, scrollType, scrollAmount, + wheelRotation); + } + else { + newEvent = new MouseEvent(parentComponent, id, when, modifiers, point.x, point.y, + clickCount, isPopupTrigger); + } + Component parentComponentBackup = parentComponent; + parentComponent.dispatchEvent(newEvent); + if(parentComponent == null && id != MouseEvent.MOUSE_EXITED) { + MouseEvent exitEvent = new MouseEvent(parentComponentBackup, MouseEvent.MOUSE_EXITED, when, + modifiers, point.x, point.y, clickCount, isPopupTrigger); + parentComponentBackup.dispatchEvent(exitEvent); + } + if(tipComponentWindow != null && id != MouseEvent.MOUSE_MOVED) { + // mouse click might have changed appearance (e.g. selection color) + tipComponentWindow.repaint(); + } + } + } + + private class MouseEventModifier implements AWTEventListener { + private MouseEventModifier() { + } + + public void eventDispatched(AWTEvent event) { + if(tipComponentWindow == null) { + return; + } + Object source = event.getSource(); + + if(source == parentComponent) { + MouseEvent mouseEvent = (MouseEvent) event; + boolean filter = handleEventFromParentComponent(mouseEvent); + if(filter) { + mouseEvent.consume(); + } + else { + lastMouseEvent = mouseEvent; + } + } + } + } +} + Property changes on: trunk/src/main/java/org/nuiton/widget/datatips/DataTipManager.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/src/main/java/org/nuiton/widget/datatips/DataTipPopup.java =================================================================== --- trunk/src/main/java/org/nuiton/widget/datatips/DataTipPopup.java (rev 0) +++ trunk/src/main/java/org/nuiton/widget/datatips/DataTipPopup.java 2010-03-25 09:51:44 UTC (rev 251) @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2002 - 2005, Stephen Kelvin Friedrich. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the name of the copyright holder nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.nuiton.widget.datatips; + +import javax.swing.*; +import java.awt.*; + +class DataTipPopup { + private Popup popup; + private DataTipCell cell; + + DataTipPopup(JComponent parent, DataTipCell cell, Point tipPosition, Dimension tipDimension) { + this.cell = cell; + Rectangle parentVisibleRect = parent.getVisibleRect(); + Rectangle withoutBorderRectangle = parentVisibleRect.intersection(new Rectangle(tipPosition, tipDimension)); + withoutBorderRectangle.translate(-tipPosition.x, -tipPosition.y); + + DataTipComponent dataTipComponent = new DataTipComponent(cell, withoutBorderRectangle, parent.getBackground()); + + Dimension tipDimensionClipped = new Dimension(tipDimension.width, tipDimension.height); + Window windowAncestor = SwingUtilities.getWindowAncestor(parent); + GraphicsConfiguration gc = windowAncestor.getGraphicsConfiguration(); + Rectangle screenBounds = gc.getBounds(); + Point tipScreenPosition = new Point(tipPosition.x, tipPosition.y); + SwingUtilities.convertPointToScreen(tipScreenPosition, parent); + Point tipPositionClipped = new Point(); + tipPositionClipped.x = Math.max(tipScreenPosition.x, screenBounds.x); + tipPositionClipped.y = Math.max(tipScreenPosition.y, screenBounds.y); + tipDimensionClipped.width = Math.min(screenBounds.x + screenBounds.width - tipPositionClipped.x, tipDimensionClipped.width); + tipDimensionClipped.height = Math.min(screenBounds.y + screenBounds.height - tipPositionClipped.y, tipDimensionClipped.height); + SwingUtilities.convertPointFromScreen(tipPositionClipped, parent); + dataTipComponent.setPreferredSize(tipDimensionClipped); + SwingUtilities.convertPointToScreen(tipPosition, parent); + + PopupFactory popupFactory = PopupFactory.getSharedInstance(); + popup = popupFactory.getPopup(parent, dataTipComponent, tipPosition.x, tipPosition.y); + popup.show(); + Window componentWindow = SwingUtilities.windowForComponent(parent); + Window tipWindow = SwingUtilities.windowForComponent(dataTipComponent); + //noinspection ObjectEquality + boolean isHeavyWeight = tipWindow != null && tipWindow != componentWindow; + dataTipComponent.setHeavyWeight(isHeavyWeight); + if (isHeavyWeight) { +// ToolTipManager.sharedInstance().registerComponent(dataTipComponent); + DataTipManager.get().setTipWindow(parent, tipWindow); + } + } + + DataTipCell getCell() { + return cell; + } + + void hideTip() { + if (popup != null) { + popup.hide(); + popup = null; + + DataTipManager.get().setTipWindow(null, null); + } + } + + public boolean isTipShown() { + return popup != null; + } +} Property changes on: trunk/src/main/java/org/nuiton/widget/datatips/DataTipPopup.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/src/main/java/org/nuiton/widget/datatips/ListDataTipCell.java =================================================================== --- trunk/src/main/java/org/nuiton/widget/datatips/ListDataTipCell.java (rev 0) +++ trunk/src/main/java/org/nuiton/widget/datatips/ListDataTipCell.java 2010-03-25 09:51:44 UTC (rev 251) @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2002 - 2005, Stephen Kelvin Friedrich. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the name of the copyright holder nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.nuiton.widget.datatips; + +import org.nuiton.widget.datatips.DataTipCell; + +import javax.swing.*; +import java.awt.*; + +class ListDataTipCell implements DataTipCell { + private final JList list; + private final int rowIndex; + + ListDataTipCell(JList list, int rowIndex) { + this.list = list; + this.rowIndex = rowIndex; + } + + public boolean isSet() { + return rowIndex >= 0; + } + + public Rectangle getCellBounds() { + Rectangle cellRect = list.getCellBounds(rowIndex, rowIndex); + return cellRect; + } + + public Component getRendererComponent() { + Object item = list.getModel().getElementAt(rowIndex); + boolean isSelected = list.isSelectedIndex(rowIndex); + boolean isFocussed = list.hasFocus() && rowIndex == list.getLeadSelectionIndex(); + ListCellRenderer renderer = list.getCellRenderer(); + Component component = renderer.getListCellRendererComponent(list, item, rowIndex, isSelected, isFocussed); + return component; + } + + public boolean equals(Object o) { + if(this == o) { + return true; + } + if(o == null || getClass() != o.getClass()) { + return false; + } + + ListDataTipCell listDataTipCell = (ListDataTipCell) o; + + if(rowIndex != listDataTipCell.rowIndex) { + return false; + } + + return true; + } + + public int hashCode() { + return rowIndex; + } +} Property changes on: trunk/src/main/java/org/nuiton/widget/datatips/ListDataTipCell.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/src/main/java/org/nuiton/widget/datatips/ListDataTipListener.java =================================================================== --- trunk/src/main/java/org/nuiton/widget/datatips/ListDataTipListener.java (rev 0) +++ trunk/src/main/java/org/nuiton/widget/datatips/ListDataTipListener.java 2010-03-25 09:51:44 UTC (rev 251) @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2002 - 2005, Stephen Kelvin Friedrich. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the name of the copyright holder nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.nuiton.widget.datatips; + +import org.nuiton.widget.datatips.DataTipCell; +import org.nuiton.widget.datatips.DataTipListener; +import org.nuiton.widget.datatips.ListDataTipCell; + +import javax.swing.*; +import java.awt.*; + +class ListDataTipListener extends DataTipListener { + ListDataTipListener() { + } + + DataTipCell getCell(JComponent component, Point point) { + JList list = (JList) component; + int index = list.locationToIndex(point); + if (index < 0) { + return DataTipCell.NONE; + } + return new ListDataTipCell(list, index); + } +} Property changes on: trunk/src/main/java/org/nuiton/widget/datatips/ListDataTipListener.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/src/main/java/org/nuiton/widget/datatips/TableDataTipCell.java =================================================================== --- trunk/src/main/java/org/nuiton/widget/datatips/TableDataTipCell.java (rev 0) +++ trunk/src/main/java/org/nuiton/widget/datatips/TableDataTipCell.java 2010-03-25 09:51:44 UTC (rev 251) @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2002 - 2005, Stephen Kelvin Friedrich. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the name of the copyright holder nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.nuiton.widget.datatips; + +import org.nuiton.widget.datatips.DataTipCell; + +import javax.swing.*; +import javax.swing.table.TableCellRenderer; +import java.awt.*; + +class TableDataTipCell implements DataTipCell { + private final JTable table; + private final int rowIndex; + private final int columnIndex; + + TableDataTipCell(JTable table, int rowIndex, int columnIndex) { + this.table = table; + this.rowIndex = rowIndex; + this.columnIndex = columnIndex; + } + + public boolean isSet() { + return rowIndex >= 0 && columnIndex >= 0; + } + + public Rectangle getCellBounds() { + Rectangle cellRect = table.getCellRect(rowIndex, columnIndex, false); + return cellRect; + } + + public Component getRendererComponent() { + TableCellRenderer cellRenderer = table.getCellRenderer(rowIndex, columnIndex); + Component component = table.prepareRenderer(cellRenderer, rowIndex, columnIndex); + return component; + } + + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + TableDataTipCell cellPosition = (TableDataTipCell) o; + + if (columnIndex != cellPosition.columnIndex) { + return false; + } + if (rowIndex != cellPosition.rowIndex) { + return false; + } + + return true; + } + + public int hashCode() { + int result; + result = rowIndex; + result = 29 * result + columnIndex; + return result; + } +} Property changes on: trunk/src/main/java/org/nuiton/widget/datatips/TableDataTipCell.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/src/main/java/org/nuiton/widget/datatips/TableDataTipListener.java =================================================================== --- trunk/src/main/java/org/nuiton/widget/datatips/TableDataTipListener.java (rev 0) +++ trunk/src/main/java/org/nuiton/widget/datatips/TableDataTipListener.java 2010-03-25 09:51:44 UTC (rev 251) @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2002 - 2005, Stephen Kelvin Friedrich. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the name of the copyright holder nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.nuiton.widget.datatips; + +import org.nuiton.widget.datatips.DataTipCell; +import org.nuiton.widget.datatips.DataTipListener; +import org.nuiton.widget.datatips.TableDataTipCell; + +import javax.swing.*; +import java.awt.*; + +class TableDataTipListener extends DataTipListener { + TableDataTipListener() { + } + + DataTipCell getCell(JComponent component, Point point) { + JTable table = (JTable) component; + int rowIndex = table.rowAtPoint(point); + int columnIndex = table.columnAtPoint(point); + if (rowIndex < 0 || columnIndex < 0) { + return DataTipCell.NONE; + } + TableDataTipCell cellPosition = new TableDataTipCell(table, rowIndex, columnIndex); + return cellPosition; + } +} Property changes on: trunk/src/main/java/org/nuiton/widget/datatips/TableDataTipListener.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/src/main/java/org/nuiton/widget/datatips/TreeDataTipCell.java =================================================================== --- trunk/src/main/java/org/nuiton/widget/datatips/TreeDataTipCell.java (rev 0) +++ trunk/src/main/java/org/nuiton/widget/datatips/TreeDataTipCell.java 2010-03-25 09:51:44 UTC (rev 251) @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2002 - 2005, Stephen Kelvin Friedrich. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the name of the copyright holder nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.nuiton.widget.datatips; + +import java.awt.Component; +import java.awt.Rectangle; + +import javax.swing.JTree; +import javax.swing.UIManager; +import javax.swing.tree.TreeCellRenderer; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreePath; + +class TreeDataTipCell implements DataTipCell { + private final JTree tree; + private final int rowIndex; + + public TreeDataTipCell(JTree tree, int rowIndex) { + this.tree = tree; + this.rowIndex = rowIndex; + } + + public boolean isSet() { + return rowIndex >= 0; + } + + public Rectangle getCellBounds() { + TreePath treePath = tree.getPathForRow(rowIndex); + Rectangle cellRect = tree.getPathBounds(treePath); + return cellRect; + } + + public Component getRendererComponent() { + TreeModel treeModel = tree.getModel(); + TreePath treePath = tree.getPathForRow(rowIndex); + TreeCellRenderer renderer = tree.getCellRenderer(); + boolean isSelected = tree.isPathSelected(treePath); + boolean isExpanded = tree.isExpanded(treePath); + boolean hasFocus = tree.hasFocus() && rowIndex == tree.getLeadSelectionRow(); + Object item = treePath.getLastPathComponent(); + boolean isLeaf = treeModel.isLeaf(item); + Component component = renderer.getTreeCellRendererComponent(tree, item, isSelected, isExpanded, isLeaf, rowIndex, hasFocus); + component.setFont(tree.getFont()); + + // FIX Nimbus white foreground on white background + if (isSelected) { + component.setForeground(UIManager.getColor("Tree.textForeground")); + } + + return component; + } + + public boolean equals(Object o) { + if(this == o) { + return true; + } + if(o == null || getClass() != o.getClass()) { + return false; + } + + TreeDataTipCell treeDataTipCell = (TreeDataTipCell) o; + + if(rowIndex != treeDataTipCell.rowIndex) { + return false; + } + + return true; + } + + public int hashCode() { + return rowIndex; + } +} + Property changes on: trunk/src/main/java/org/nuiton/widget/datatips/TreeDataTipCell.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/src/main/java/org/nuiton/widget/datatips/TreeDataTipListener.java =================================================================== --- trunk/src/main/java/org/nuiton/widget/datatips/TreeDataTipListener.java (rev 0) +++ trunk/src/main/java/org/nuiton/widget/datatips/TreeDataTipListener.java 2010-03-25 09:51:44 UTC (rev 251) @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2002 - 2005, Stephen Kelvin Friedrich. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the name of the copyright holder nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.nuiton.widget.datatips; + +import org.nuiton.widget.datatips.DataTipCell; +import org.nuiton.widget.datatips.DataTipListener; +import org.nuiton.widget.datatips.TreeDataTipCell; + +import javax.swing.*; +import java.awt.*; + +class TreeDataTipListener extends DataTipListener { + TreeDataTipListener() { + } + + DataTipCell getCell(JComponent component, Point point) { + JTree tree = (JTree) component; + int rowIndex = tree.getRowForLocation(point.x, point.y); + if (rowIndex < 0) { + return DataTipCell.NONE; + } + return new TreeDataTipCell(tree, rowIndex); + } +} Property changes on: trunk/src/main/java/org/nuiton/widget/datatips/TreeDataTipListener.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: trunk/src/main/java/org/nuiton/widget/datatips/package-info.java =================================================================== --- trunk/src/main/java/org/nuiton/widget/datatips/package-info.java (rev 0) +++ trunk/src/main/java/org/nuiton/widget/datatips/package-info.java 2010-03-25 09:51:44 UTC (rev 251) @@ -0,0 +1,8 @@ +/** + * Add data tips to your Swing table, tree or list. + * + * Those classes has been copied from original project : + * https://datatips.dev.java.net/ and just contains some bugfixes + * for nimbus look'n'feel. + */ +package org.nuiton.widget.datatips; Property changes on: trunk/src/main/java/org/nuiton/widget/datatips/package-info.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL