/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at legal-notices/CDDLv1_0.txt. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2008 Sun Microsystems, Inc. * Portions Copyright 2014-2015 ForgeRock AS */ package org.opends.guitools.controlpanel.ui.components; import static com.forgerock.opendj.util.OperatingSystem.isMacOS; import java.awt.Graphics; import java.awt.Insets; import java.awt.Rectangle; import java.awt.event.InputEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.HashSet; import java.util.Set; import javax.swing.JPopupMenu; import javax.swing.JTree; import javax.swing.tree.TreePath; import org.opends.guitools.controlpanel.ui.renderer.TreeCellRenderer; /** * The tree that is used in different places in the Control Panel (schema * browser, index browser or the LDAP entries browser). It renders in a * different manner than the default tree (selection takes the whole width * of the tree, in a similar manner as happens with trees in Mac OS). * */ public class CustomTree extends JTree { private static final long serialVersionUID = -8351107707374485555L; private Set mouseListeners; private JPopupMenu popupMenu; private final int MAX_ICON_HEIGHT = 18; /** * Internal enumeration used to translate mouse events. * */ private enum NewEventType { MOUSE_PRESSED, MOUSE_CLICKED, MOUSE_RELEASED } /** {@inheritDoc} */ public void paintComponent(Graphics g) { int[] selectedRows = getSelectionRows(); if (selectedRows == null) { selectedRows = new int[] {}; } Insets insets = getInsets(); int w = getWidth( ) - insets.left - insets.right; int h = getHeight( ) - insets.top - insets.bottom; int x = insets.left; int y = insets.top; int nRows = getRowCount(); for ( int i = 0; i < nRows; i++) { int rowHeight = getRowBounds( i ).height; if (isRowSelected(selectedRows, i)) { g.setColor(TreeCellRenderer.selectionBackground); } else { g.setColor(TreeCellRenderer.nonselectionBackground); } g.fillRect( x, y, w, rowHeight ); y += rowHeight; } final int remainder = insets.top + h - y; if ( remainder > 0 ) { g.setColor(TreeCellRenderer.nonselectionBackground); g.fillRect(x, y, w, remainder); } boolean isOpaque = isOpaque(); setOpaque(false); super.paintComponent(g); setOpaque(isOpaque); } private boolean isRowSelected(int[] selectedRows, int i) { for (int j=0; j(mouseListeners)) { if (mouseListener != this) { switch (type) { case MOUSE_RELEASED: mouseListener.mouseReleased(newEvent); break; case MOUSE_CLICKED: mouseListener.mouseClicked(newEvent); break; default: mouseListener.mousePressed(newEvent); } } } ignoreEvents = false; } private MouseEvent getTranslatedEvent(MouseEvent ev) { MouseEvent newEvent = null; int x = ev.getPoint().x; int y = ev.getPoint().y; if (getPathForLocation(x, y) == null) { TreePath path = getWidePathForLocation(x, y); if (path != null) { Rectangle r = getPathBounds(path); if (r != null) { int newX = r.x + r.width / 2; int newY = r.y + r.height / 2; // Simulate an event newEvent = new MouseEvent( ev.getComponent(), ev.getID(), ev.getWhen(), ev.getModifiersEx(), newX, newY, ev.getClickCount(), ev.isPopupTrigger(), ev.getButton()); } } } return newEvent; } }; addMouseListener(mouseListener); if (getRowHeight() <= MAX_ICON_HEIGHT) { setRowHeight(MAX_ICON_HEIGHT + 1); } } /** {@inheritDoc} */ public void addMouseListener(MouseListener mouseListener) { super.addMouseListener(mouseListener); if (mouseListeners == null) { mouseListeners = new HashSet<>(); } mouseListeners.add(mouseListener); } /** {@inheritDoc} */ public void removeMouseListener(MouseListener mouseListener) { super.removeMouseListener(mouseListener); mouseListeners.remove(mouseListener); } private TreePath getWidePathForLocation(int x, int y) { TreePath path = null; TreePath closestPath = getClosestPathForLocation(x, y); if (closestPath != null) { Rectangle pathBounds = getPathBounds(closestPath); if (pathBounds != null && x >= pathBounds.x && x < getX() + getWidth() && y >= pathBounds.y && y < pathBounds.y + pathBounds.height) { path = closestPath; } } return path; } }