📄 closeabletabbedpane.java
字号:
/* * JMule - Java file sharing client * Copyright (C) 2007-2008 JMule team ( jmule@jmule.org / http://jmule.org ) * * Any parts of this program derived from other projects, or contributed * by third-party developers are copyrighted by their respective authors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */package org.jmule.ui.swing.common;import java.awt.Color;import java.awt.Component;import java.awt.FontMetrics;import java.awt.Graphics;import java.awt.Point;import java.awt.Rectangle;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.awt.event.MouseMotionListener;import javax.swing.Icon;import javax.swing.JComponent;import javax.swing.JTabbedPane;import javax.swing.JViewport;import javax.swing.SwingUtilities;import javax.swing.event.EventListenerList;import javax.swing.plaf.basic.BasicTabbedPaneUI;import javax.swing.plaf.metal.MetalTabbedPaneUI;/** * * Created on Sep 7, 2008 * @author javajox * @version $Revision: 1.1 $ * Last changed by $Author: javajox $ on $Date: 2008/09/07 16:52:15 $ */public class CloseableTabbedPane extends JTabbedPane implements MouseListener, MouseMotionListener {/** * The <code>EventListenerList</code>. */private EventListenerList listenerList = null;/** * The viewport of the scrolled tabs. */private JViewport headerViewport = null;/** * The normal closeicon. */private Icon normalCloseIcon = null;/** * The closeicon when the mouse is over. */private Icon hooverCloseIcon = null;/** * The closeicon when the mouse is pressed. */private Icon pressedCloseIcon = null;/** * Creates a new instance of <code>CloseableTabbedPane</code> */public CloseableTabbedPane() { super(); init(SwingUtilities.LEFT);}/** * Creates a new instance of <code>CloseableTabbedPane</code> * @param horizontalTextPosition the horizontal position of the text (e.g. * SwingUtilities.TRAILING or SwingUtilities.LEFT) */public CloseableTabbedPane(int horizontalTextPosition) { super(); init(horizontalTextPosition);}/** * Initializes the <code>CloseableTabbedPane</code> * @param horizontalTextPosition the horizontal position of the text (e.g. * SwingUtilities.TRAILING or SwingUtilities.LEFT) */private void init(int horizontalTextPosition) { listenerList = new EventListenerList(); addMouseListener(this); addMouseMotionListener(this); if (getUI() instanceof MetalTabbedPaneUI) setUI(new CloseableMetalTabbedPaneUI(horizontalTextPosition)); else setUI(new CloseableTabbedPaneUI(horizontalTextPosition));}/** * Allows setting own closeicons. * @param normal the normal closeicon * @param hoover the closeicon when the mouse is over * @param pressed the closeicon when the mouse is pressed */public void setCloseIcons(Icon normal, Icon hoover, Icon pressed) { normalCloseIcon = normal; hooverCloseIcon = hoover; pressedCloseIcon = pressed;}/** * Adds a <code>Component</code> represented by a title and no icon. * @param title the title to be displayed in this tab * @param component the component to be displayed when this tab is clicked */public void addTab(String title, Component component) { addTab(title, component, null);}/** * Adds a <code>Component</code> represented by a title and an icon. * @param title the title to be displayed in this tab * @param component the component to be displayed when this tab is clicked * @param extraIcon the icon to be displayed in this tab */public void addTab(String title, Component component, Icon extraIcon) { boolean doPaintCloseIcon = true; try { Object prop = null; if ((prop = ((JComponent) component). getClientProperty("isClosable")) != null) { doPaintCloseIcon = (Boolean) prop; } } catch (Exception ignored) {/*Could probably be a ClassCastException*/} super.addTab(title, doPaintCloseIcon ? new CloseTabIcon(extraIcon) : null, component); if (headerViewport == null) { for (Component c : getComponents()) { if ("TabbedPane.scrollableViewport".equals(c.getName())) headerViewport = (JViewport) c; } }}/** * Invoked when the mouse button has been clicked (pressed and released) on * a component. * @param e the <code>MouseEvent</code> */public void mouseClicked(MouseEvent e) { processMouseEvents(e);}/** * Invoked when the mouse enters a component. * @param e the <code>MouseEvent</code> */public void mouseEntered(MouseEvent e) { }/** * Invoked when the mouse exits a component. * @param e the <code>MouseEvent</code> */public void mouseExited(MouseEvent e) { for (int i=0; i<getTabCount(); i++) { CloseTabIcon icon = (CloseTabIcon) getIconAt(i); if (icon != null) icon.mouseover = false; } repaint();}/** * Invoked when a mouse button has been pressed on a component. * @param e the <code>MouseEvent</code> */public void mousePressed(MouseEvent e) { processMouseEvents(e);}/** * Invoked when a mouse button has been released on a component. * @param e the <code>MouseEvent</code> */public void mouseReleased(MouseEvent e) { }/** * Invoked when a mouse button is pressed on a component and then dragged. * <code>MOUSE_DRAGGED</code> events will continue to be delivered to the * component where the drag originated until the mouse button is released * (regardless of whether the mouse position is within the bounds of the * component).<br/> * <br/> * Due to platform-dependent Drag&Drop implementations, * <code>MOUSE_DRAGGED</code> events may not be delivered during a native * Drag&Drop operation. * @param e the <code>MouseEvent</code> */public void mouseDragged(MouseEvent e) { processMouseEvents(e);}/** * Invoked when the mouse cursor has been moved onto a component but no * buttons have been pushed. * @param e the <code>MouseEvent</code> */public void mouseMoved(MouseEvent e) { processMouseEvents(e);}/** * Processes all caught <code>MouseEvent</code>s. * @param e the <code>MouseEvent</code> */private void processMouseEvents(MouseEvent e) { int tabNumber = getUI().tabForCoordinate(this, e.getX(), e.getY()); if (tabNumber < 0) return; CloseTabIcon icon = (CloseTabIcon) getIconAt(tabNumber); if (icon != null) { Rectangle rect= icon.getBounds(); Point pos = headerViewport == null ? new Point() : headerViewport.getViewPosition(); Rectangle drawRect = new Rectangle( rect.x - pos.x, rect.y - pos.y, rect.width, rect.height); if (e.getID() == e.MOUSE_PRESSED) { icon.mousepressed = e.getModifiers() == e.BUTTON1_MASK; repaint(drawRect); } else if (e.getID() == e.MOUSE_MOVED || e.getID() == e.MOUSE_DRAGGED || e.getID() == e.MOUSE_CLICKED) { pos.x += e.getX(); pos.y += e.getY(); if (rect.contains(pos)) { if (e.getID() == e.MOUSE_CLICKED) { int selIndex = getSelectedIndex(); if (fireCloseTab(selIndex)) { if (selIndex > 0) { // to prevent uncatchable null-pointers Rectangle rec = getUI().getTabBounds(this, selIndex - 1); MouseEvent event = new MouseEvent((Component) e.getSource(), e.getID() + 1, System.currentTimeMillis(), e.getModifiers(), rec.x, rec.y, e.getClickCount(), e.isPopupTrigger(), e.getButton()); dispatchEvent(event); } //the tab is being closed //removeTabAt(tabNumber); remove(selIndex); } else { icon.mouseover = false; icon.mousepressed = false; repaint(drawRect); } } else { icon.mouseover = true; icon.mousepressed = e.getModifiers() == e.BUTTON1_MASK; } } else { icon.mouseover = false; } repaint(drawRect); } }}/** * Adds an <code>CloseableTabbedPaneListener</code> to the tabbedpane. * @param l the <code>CloseableTabbedPaneListener</code> to be added */public void addCloseableTabbedPaneListener(CloseableTabbedPaneListener l) { listenerList.add(CloseableTabbedPaneListener.class, l);}/** * Removes an <code>CloseableTabbedPaneListener</code> from the tabbedpane. * @param l the listener to be removed */public void removeCloseableTabbedPaneListener(CloseableTabbedPaneListener l) { listenerList.remove(CloseableTabbedPaneListener.class, l);}/** * Returns an array of all the <code>SearchListener</code>s added to this * <code>SearchPane</code> with addSearchListener(). * @return all of the <code>SearchListener</code>s added or an empty array if * no listeners have been added */public CloseableTabbedPaneListener[] getCloseableTabbedPaneListener() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -