📄 basictabbedpaneui.java
字号:
} if (tabChangeListener != null) { tabPane.removeChangeListener(tabChangeListener); tabChangeListener = null; } if (propertyChangeListener != null) { tabPane.removePropertyChangeListener(propertyChangeListener); propertyChangeListener = null; } handler = null; } protected MouseListener createMouseListener() { return getHandler(); } protected FocusListener createFocusListener() { return getHandler(); } protected ChangeListener createChangeListener() { return getHandler(); } protected PropertyChangeListener createPropertyChangeListener() { return getHandler(); } private Handler getHandler() { if (handler == null) { handler = new Handler(); } return handler; } protected void installKeyboardActions() { InputMap km = getInputMap(JComponent. WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); SwingUtilities.replaceUIInputMap(tabPane, JComponent. WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, km); km = getInputMap(JComponent.WHEN_FOCUSED); SwingUtilities.replaceUIInputMap(tabPane, JComponent.WHEN_FOCUSED, km); LazyActionMap.installLazyActionMap(tabPane, BasicTabbedPaneUI.class, "TabbedPane.actionMap"); } InputMap getInputMap(int condition) { if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) { return (InputMap)DefaultLookup.get(tabPane, this, "TabbedPane.ancestorInputMap"); } else if (condition == JComponent.WHEN_FOCUSED) { return (InputMap)DefaultLookup.get(tabPane, this, "TabbedPane.focusInputMap"); } return null; } 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--) { int mnemonic = tabPane.getMnemonicAt(counter); if (mnemonic > 0) { addMnemonic(counter, mnemonic); } } } /** * Resets the mnemonics bindings to an empty state. */ private void resetMnemonics() { if (mnemonicToIndexMap != null) { mnemonicToIndexMap.clear(); mnemonicInputMap.clear(); } } /** * Adds the specified mnemonic at the specified index. */ private void addMnemonic(int index, int mnemonic) { if (mnemonicToIndexMap == null) { initMnemonics(); } mnemonicInputMap.put(KeyStroke.getKeyStroke(mnemonic, Event.ALT_MASK), "setSelectedIndex"); mnemonicToIndexMap.put(new Integer(mnemonic), new Integer(index)); } /** * Installs the state needed for mnemonics. */ private void initMnemonics() { mnemonicToIndexMap = new Hashtable(); mnemonicInputMap = new ComponentInputMapUIResource(tabPane); mnemonicInputMap.setParent(SwingUtilities.getUIInputMap(tabPane, JComponent.WHEN_IN_FOCUSED_WINDOW)); SwingUtilities.replaceUIInputMap(tabPane, JComponent.WHEN_IN_FOCUSED_WINDOW, mnemonicInputMap); } /** * Sets the tab the mouse is over by location. This is a cover method * for <code>setRolloverTab(tabForCoordinate(x, y, false))</code>. */ private void setRolloverTab(int x, int y) { // NOTE: // This calls in with false otherwise it could trigger a validate, // which should NOT happen if the user is only dragging the // mouse around. setRolloverTab(tabForCoordinate(tabPane, x, y, false)); } /** * Sets the tab the mouse is currently over to <code>index</code>. * <code>index</code> will be -1 if the mouse is no longer over any * tab. No checking is done to ensure the passed in index identifies a * valid tab. * * @param index Index of the tab the mouse is over. * @since 1.5 */ protected void setRolloverTab(int index) { rolloverTabIndex = index; } /** * Returns the tab the mouse is currently over, or -1 if the mouse is no * longer over any tab. * * @param index Index of the tab the mouse is over. * @since 1.5 */ protected int getRolloverTab() { return rolloverTabIndex; } public Dimension getMinimumSize(JComponent c) { // Default to LayoutManager's minimumLayoutSize return null; } public Dimension getMaximumSize(JComponent c) { // Default to LayoutManager's maximumLayoutSize return null; }// UI Rendering public void paint(Graphics g, JComponent c) { int selectedIndex = tabPane.getSelectedIndex(); int tabPlacement = tabPane.getTabPlacement(); ensureCurrentLayout(); // Paint content border and tab area if (tabsOverlapBorder) { paintContentBorder(g, tabPlacement, selectedIndex); } // If scrollable tabs are enabled, the tab area will be // painted by the scrollable tab panel instead. // if (!scrollableTabLayoutEnabled()) { // WRAP_TAB_LAYOUT paintTabArea(g, tabPlacement, selectedIndex); } if (!tabsOverlapBorder) { paintContentBorder(g, tabPlacement, selectedIndex); } } /** * Paints the tabs in the tab area. * Invoked by paint(). * The graphics parameter must be a valid <code>Graphics</code> * object. Tab placement may be either: * <code>JTabbedPane.TOP</code>, <code>JTabbedPane.BOTTOM</code>, * <code>JTabbedPane.LEFT</code>, or <code>JTabbedPane.RIGHT</code>. * The selected index must be a valid tabbed pane tab index (0 to * tab count - 1, inclusive) or -1 if no tab is currently selected. * The handling of invalid parameters is unspecified. * * @param g the graphics object to use for rendering * @param tabPlacement the placement for the tabs within the JTabbedPane * @param selectedIndex the tab index of the selected component * * @since 1.4 */ protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex) { int tabCount = tabPane.getTabCount(); Rectangle iconRect = new Rectangle(), textRect = new Rectangle(); Rectangle clipRect = g.getClipBounds(); // Paint tabRuns of tabs from back to front for (int i = runCount - 1; i >= 0; i--) { int start = tabRuns[i]; int next = tabRuns[(i == runCount - 1)? 0 : i + 1]; int end = (next != 0? next - 1: tabCount - 1); for (int j = start; j <= end; j++) { if (j != selectedIndex && rects[j].intersects(clipRect)) { paintTab(g, tabPlacement, rects, j, iconRect, textRect); } } } // Paint selected tab if its in the front run // since it may overlap other tabs if (selectedIndex >= 0 && rects[selectedIndex].intersects(clipRect)) { paintTab(g, tabPlacement, rects, selectedIndex, iconRect, textRect); } } protected void paintTab(Graphics g, int tabPlacement, Rectangle[] rects, int tabIndex, Rectangle iconRect, Rectangle textRect) { Rectangle tabRect = rects[tabIndex]; int selectedIndex = tabPane.getSelectedIndex(); boolean isSelected = selectedIndex == tabIndex; Graphics2D g2 = null; Polygon cropShape = null; Shape save = null; int cropx = 0; int cropy = 0; if (scrollableTabLayoutEnabled()) { if (g instanceof Graphics2D) { g2 = (Graphics2D)g; // Render visual for cropped tab edge... Rectangle viewRect = tabScroller.viewport.getViewRect(); int cropline; switch(tabPlacement) { case LEFT: case RIGHT: cropline = viewRect.y + viewRect.height; if ((tabRect.y < cropline) && (tabRect.y + tabRect.height > cropline)) { cropShape = createCroppedTabClip(tabPlacement, tabRect, cropline); cropx = tabRect.x; cropy = cropline-1; } break; case TOP: case BOTTOM: default: cropline = viewRect.x + viewRect.width; if ((tabRect.x < cropline) && (tabRect.x + tabRect.width > cropline)) { cropShape = createCroppedTabClip(tabPlacement, tabRect, cropline); cropx = cropline-1; cropy = tabRect.y; } } if (cropShape != null) { save = g2.getClip(); g2.clip(cropShape); } } } if (tabsOpaque || tabPane.isOpaque()) { paintTabBackground(g, tabPlacement, tabIndex, tabRect.x, tabRect.y, tabRect.width, tabRect.height, isSelected); } paintTabBorder(g, tabPlacement, tabIndex, tabRect.x, tabRect.y, tabRect.width, tabRect.height, isSelected); String title = tabPane.getTitleAt(tabIndex); Font font = tabPane.getFont(); FontMetrics metrics = SwingUtilities2.getFontMetrics(tabPane, g, font); Icon icon = getIconForTab(tabIndex); layoutLabel(tabPlacement, metrics, tabIndex, title, icon, tabRect, iconRect, textRect, isSelected); paintText(g, tabPlacement, font, metrics, tabIndex, title, textRect, isSelected); paintIcon(g, tabPlacement, tabIndex, icon, iconRect, isSelected); paintFocusIndicator(g, tabPlacement, rects, tabIndex, iconRect, textRect, isSelected); if (cropShape != null) { paintCroppedTabEdge(g, tabPlacement, tabIndex, isSelected, cropx, cropy); g2.setClip(save); } } /* This method will create and return a polygon shape for the given tab rectangle * which has been cropped at the specified cropline with a torn edge visual. * e.g. A "File" tab which has cropped been cropped just after the "i": * ------------- * | ..... | * | . | * | ... . | * | . . | * | . . | * | . . | * -------------- * * The x, y arrays below define the pattern used to create a "torn" edge * segment which is repeated to fill the edge of the tab. * For tabs placed on TOP and BOTTOM, this righthand torn edge is created by * line segments which are defined by coordinates obtained by * subtracting xCropLen[i] from (tab.x + tab.width) and adding yCroplen[i] * to (tab.y). * For tabs placed on LEFT or RIGHT, the bottom torn edge is created by * subtracting xCropLen[i] from (tab.y + tab.height) and adding yCropLen[i] * to (tab.x). */ private int xCropLen[] = {1,1,0,0,1,1,2,2}; private int yCropLen[] = {0,3,3,6,6,9,9,12}; private static final int CROP_SEGMENT = 12; private Polygon createCroppedTabClip(int tabPlacement, Rectangle tabRect, int cropline) { int rlen = 0; int start = 0; int end = 0; int ostart = 0; switch(tabPlacement) { case LEFT: case RIGHT: rlen = tabRect.width; start = tabRect.x; end = tabRect.x + tabRect.width; ostart = tabRect.y; break; case TOP: case BOTTOM: default: rlen = tabRect.height; start = tabRect.y; end = tabRect.y + tabRect.height; ostart = tabRect.x; } int rcnt = rlen/CROP_SEGMENT; if (rlen%CROP_SEGMENT > 0) { rcnt++; } int npts = 2 + (rcnt*8); int xp[] = new int[npts]; int yp[] = new int[npts]; int pcnt = 0; xp[pcnt] = ostart;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -