📄 tabbedpaneui.java
字号:
package com.digitprop.tonic;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import java.util.Vector;
import java.util.Hashtable;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.plaf.*;
import javax.swing.plaf.basic.*;
import javax.swing.text.View;
/** UI delegate for JTabbedPanes..
*
* @author Markus Fischer
*
* <p>This software is under the <a href="http://www.gnu.org/copyleft/lesser.html" target="_blank">GNU Lesser General Public License</a>
*/
/*
* ------------------------------------------------------------------------
* Copyright (C) 2004 Markus Fischer
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
* You can contact the author at:
* Markus Fischer
* www.digitprop.com
* info@digitprop.com
* ------------------------------------------------------------------------
*/
public class TabbedPaneUI extends BasicTabbedPaneUI implements SwingConstants
{
/** The associated JTabbedPane */
protected JTabbedPane tabPane;
/** Highlight color */
protected Color highlight;
/** The border color */
protected Color borderColor;
/** The color of the selected tab */
private Color selectedColor;
/** If true, draw a 2-pixel instead of 1-pixel border around the selected tab */
private boolean drawThickBorder=false;
/** Gap width between text and icons */
protected int textIconGap;
protected int tabRunOverlay;
/** Insets for the tabs */
protected Insets tabInsets;
/** Insets for the selected tab */
protected Insets selectedTabPadInsets;
/** Insets for the whole tab area */
protected Insets tabAreaInsets;
/** Insets for the content border */
protected Insets contentBorderInsets;
/** As of Java 2 platform v1.3 this previously undocumented field is no
* longer used. Key bindings are now defined by the LookAndFeel, please
* refer to the key bindings specification for further details.
*
* @deprecated As of Java 2 platform v1.3.
*/
protected KeyStroke upKey;
/** As of Java 2 platform v1.3 this previously undocumented field is no
* longer used. Key bindings are now defined by the LookAndFeel, please
* refer to the key bindings specification for further details.
*
* @deprecated As of Java 2 platform v1.3.
*/
protected KeyStroke downKey;
/** As of Java 2 platform v1.3 this previously undocumented field is no
* longer used. Key bindings are now defined by the LookAndFeel, please
* refer to the key bindings specification for further details.
*
* @deprecated As of Java 2 platform v1.3.
*/
protected KeyStroke leftKey;
/** As of Java 2 platform v1.3 this previously undocumented field is no
* longer used. Key bindings are now defined by the LookAndFeel, please
* refer to the key bindings specification for further details.
*
* @deprecated As of Java 2 platform v1.3.
*/
protected KeyStroke rightKey;
/** Transient variable (recalculated each time TabbedPane is layed out) */
protected int tabRuns[]= new int[10];
/** Transient variable (recalculated each time TabbedPane is layed out) */
protected int runCount= 0;
/** Transient variable (recalculated each time TabbedPane is layed out) */
protected int selectedRun= -1;
/** Transient variable (recalculated each time TabbedPane is layed out) */
protected Rectangle rects[]= new Rectangle[0];
/** Transient variable (recalculated each time TabbedPane is layed out) */
protected int maxTabHeight;
/** Transient variable (recalculated each time TabbedPane is layed out) */
protected int maxTabWidth;
/** Listener registered with the associated JTabbedPane */
protected ChangeListener tabChangeListener;
/** Listener registered with the associated JTabbedPane */
protected PropertyChangeListener propertyChangeListener;
/** Listener registered with the associated JTabbedPane */
protected MouseListener mouseListener;
/** Listener registered with the associated JTabbedPane */
protected FocusListener focusListener;
/** Listener registered with the associated JTabbedPane */
private ContainerListener containerListener;
// Private instance data
private Insets currentPadInsets= new Insets(0, 0, 0, 0);
private Insets currentTabAreaInsets= new Insets(0, 0, 0, 0);
private Component visibleComponent;
// PENDING(api): See comment for ContainerHandler
private Vector htmlViews;
private Hashtable mnemonicToIndexMap;
/**
* InputMap used for mnemonics. Only non-null if the JTabbedPane has
* mnemonics associated with it. Lazily created in initMnemonics.
*/
private InputMap mnemonicInputMap;
// For use when tabLayoutPolicy = SCROLL_TAB_LAYOUT
private ScrollableTabSupport tabScroller;
/**
* A rectangle used for general layout calculations in order
* to avoid constructing many new Rectangles on the fly.
*/
protected transient Rectangle calcRect= new Rectangle(0, 0, 0, 0);
/**
* Number of tabs. When the count differs, the mnemonics are updated.
*/
// PENDING: This wouldn't be necessary if JTabbedPane had a better
// way of notifying listeners when the count changed.
private int tabCount;
/** Creates an instance */
public TabbedPaneUI()
{
drawThickBorder=UIManager.getBoolean("TabbedPane.thickBorders");
}
/** Creates and returns a UI delegate for the specified component */
public static ComponentUI createUI(JComponent c)
{
return new TabbedPaneUI();
}
/** Installs the UI settings for the specified component */
public void installUI(JComponent c)
{
this.tabPane= (JTabbedPane) c;
c.setLayout(createLayoutManager());
installComponents();
installDefaults();
installListeners();
installKeyboardActions();
}
/** Uninstalls the UI settings for the specified component */
public void uninstallUI(JComponent c)
{
uninstallKeyboardActions();
uninstallListeners();
uninstallDefaults();
uninstallComponents();
c.setLayout(null);
this.tabPane= null;
}
/**
* Invoked by <code>installUI</code> to create
* a layout manager object to manage
* the <code>JTabbedPane</code>.
*
* @return a layout manager object
*
* @see TabbedPaneLayout
* @see javax.swing.JTabbedPane#getTabLayoutPolicy
*/
protected LayoutManager createLayoutManager()
{
if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT)
{
return new TabbedPaneScrollLayout();
}
else
{ /* WRAP_TAB_LAYOUT */
return new TabbedPaneLayout();
}
}
/* In an attempt to preserve backward compatibility for programs
* which have extended BasicTabbedPaneUI to do their own layout, the
* UI uses the installed layoutManager (and not tabLayoutPolicy) to
* determine if scrollTabLayout is enabled.
*/
private boolean scrollableTabLayoutEnabled()
{
return (tabPane.getLayout() instanceof TabbedPaneScrollLayout);
}
/**
* Creates and installs any required subcomponents for the JTabbedPane.
* Invoked by installUI.
*
* @since 1.4
*/
protected void installComponents()
{
if (scrollableTabLayoutEnabled())
{
if (tabScroller == null)
{
tabScroller= new ScrollableTabSupport(tabPane.getTabPlacement());
tabPane.add(tabScroller.viewport);
tabPane.add(tabScroller.scrollForwardButton);
tabPane.add(tabScroller.scrollBackwardButton);
}
}
}
/**
* Removes any installed subcomponents from the JTabbedPane.
* Invoked by uninstallUI.
*
* @since 1.4
*/
protected void uninstallComponents()
{
if (scrollableTabLayoutEnabled())
{
tabPane.remove(tabScroller.viewport);
tabPane.remove(tabScroller.scrollForwardButton);
tabPane.remove(tabScroller.scrollBackwardButton);
tabScroller= null;
}
}
protected void installDefaults()
{
LookAndFeel.installColorsAndFont(
tabPane,
"TabbedPane.background",
"TabbedPane.foreground",
"TabbedPane.font");
highlight= UIManager.getColor("TabbedPane.light");
lightHighlight= UIManager.getColor("TabbedPane.highlight");
shadow= UIManager.getColor("TabbedPane.shadow");
darkShadow= UIManager.getColor("TabbedPane.darkShadow");
focus= UIManager.getColor("TabbedPane.focus");
selectedColor= UIManager.getColor("TabbedPane.selected");
borderColor=UIManager.getColor("Button.borderColor");
textIconGap= UIManager.getInt("TabbedPane.textIconGap");
tabInsets= UIManager.getInsets("TabbedPane.tabInsets");
selectedTabPadInsets=
UIManager.getInsets("TabbedPane.selectedTabPadInsets");
tabAreaInsets= UIManager.getInsets("TabbedPane.tabAreaInsets");
contentBorderInsets=
UIManager.getInsets("TabbedPane.contentBorderInsets");
tabRunOverlay= UIManager.getInt("TabbedPane.tabRunOverlay");
}
protected void uninstallDefaults()
{
highlight= null;
lightHighlight= null;
shadow= null;
darkShadow= null;
focus= null;
tabInsets= null;
selectedTabPadInsets= null;
tabAreaInsets= null;
contentBorderInsets= null;
}
protected void installListeners()
{
if ((propertyChangeListener= createPropertyChangeListener()) != null)
{
tabPane.addPropertyChangeListener(propertyChangeListener);
}
if ((tabChangeListener= createChangeListener()) != null)
{
tabPane.addChangeListener(tabChangeListener);
}
if ((mouseListener= createMouseListener()) != null)
{
if (scrollableTabLayoutEnabled())
{
tabScroller.tabPanel.addMouseListener(mouseListener);
}
else
{ // WRAP_TAB_LAYOUT
tabPane.addMouseListener(mouseListener);
}
}
if ((focusListener= createFocusListener()) != null)
{
tabPane.addFocusListener(focusListener);
}
// PENDING(api) : See comment for ContainerHandler
if ((containerListener= new ContainerHandler()) != null)
{
tabPane.addContainerListener(containerListener);
if (tabPane.getTabCount() > 0)
{
htmlViews= createHTMLVector();
}
}
}
protected void uninstallListeners()
{
if (mouseListener != null)
{
if (scrollableTabLayoutEnabled())
{ // SCROLL_TAB_LAYOUT
tabScroller.tabPanel.removeMouseListener(mouseListener);
}
else
{ // WRAP_TAB_LAYOUT
tabPane.removeMouseListener(mouseListener);
}
mouseListener= null;
}
if (focusListener != null)
{
tabPane.removeFocusListener(focusListener);
focusListener= null;
}
// PENDING(api): See comment for ContainerHandler
if (containerListener != null)
{
tabPane.removeContainerListener(containerListener);
containerListener= null;
if (htmlViews != null)
{
htmlViews.removeAllElements();
htmlViews= null;
}
}
if (tabChangeListener != null)
{
tabPane.removeChangeListener(tabChangeListener);
tabChangeListener= null;
}
if (propertyChangeListener != null)
{
tabPane.removePropertyChangeListener(propertyChangeListener);
propertyChangeListener= null;
}
}
protected MouseListener createMouseListener()
{
return new MouseHandler();
}
protected FocusListener createFocusListener()
{
return new FocusHandler();
}
protected ChangeListener createChangeListener()
{
return new TabSelectionHandler();
}
protected PropertyChangeListener createPropertyChangeListener()
{
return new PropertyChangeHandler();
}
protected void installKeyboardActions()
{
InputMap km= getMyInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
SwingUtilities.replaceUIInputMap(
tabPane,
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
km);
km= getMyInputMap(JComponent.WHEN_FOCUSED);
SwingUtilities.replaceUIInputMap(tabPane, JComponent.WHEN_FOCUSED, km);
ActionMap am= getMyActionMap();
SwingUtilities.replaceUIActionMap(tabPane, am);
if (scrollableTabLayoutEnabled())
{
tabScroller.scrollForwardButton.setAction(
am.get("scrollTabsForwardAction"));
tabScroller.scrollBackwardButton.setAction(
am.get("scrollTabsBackwardAction"));
}
}
InputMap getMyInputMap(int condition)
{
if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
{
return (InputMap) UIManager.get("TabbedPane.ancestorInputMap");
}
else if (condition == JComponent.WHEN_FOCUSED)
{
return (InputMap) UIManager.get("TabbedPane.focusInputMap");
}
return null;
}
ActionMap getMyActionMap()
{
ActionMap map= (ActionMap) UIManager.get("TabbedPane.actionMap");
if (map == null)
{
map= createMyActionMap();
if (map != null)
{
UIManager.getLookAndFeelDefaults().put("TabbedPane.actionMap", map);
}
}
return map;
}
ActionMap createMyActionMap()
{
ActionMap map= new ActionMapUIResource();
map.put("navigateNext", new NextAction());
map.put("navigatePrevious", new PreviousAction());
map.put("navigateRight", new RightAction());
map.put("navigateLeft", new LeftAction());
map.put("navigateUp", new UpAction());
map.put("navigateDown", new DownAction());
map.put("navigatePageUp", new PageUpAction());
map.put("navigatePageDown", new PageDownAction());
map.put("requestFocus", new RequestFocusAction());
map.put(
"requestFocusForVisibleComponent",
new RequestFocusForVisibleAction());
map.put("setSelectedIndex", new SetSelectedIndexAction());
map.put("scrollTabsForwardAction", new ScrollTabsForwardAction());
map.put("scrollTabsBackwardAction", new ScrollTabsBackwardAction());
return map;
}
protected void uninstallKeyboardActions()
{
SwingUtilities.replaceUIActionMap(tabPane, null);
SwingUtilities.replaceUIInputMap(
tabPane,
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
null);
SwingUtilities.replaceUIInputMap(tabPane, JComponent.WHEN_FOCUSED, null);
}
/**
* Reloads the mnemonics. This should be invoked when a memonic changes,
* when the title of a mnemonic changes, or when tabs are added/removed.
*/
private void updateMnemonics()
{
resetMnemonics();
for (int counter= tabPane.getTabCount() - 1; counter >= 0; counter--)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -