📄 basictabbedpaneui.java
字号:
for(int i = 1; i < tabCount; i++) { if (getBaseline(i) != baseline) { baseline = -1; break; } } } else { // left/right, tabs may be different sizes. FontMetrics fontMetrics = getFontMetrics(); int fontHeight = fontMetrics.getHeight(); int height = calculateTabHeight(tabPlacement, 0, fontHeight); for(int i = 1; i < tabCount; i++) { int newHeight = calculateTabHeight(tabPlacement, i,fontHeight); if (height != newHeight) { // assume different baseline baseline = -1; break; } } } }// 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; 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); if (tabPane.getTabComponentAt(tabIndex) == null) { String clippedTitle = title; if (scrollableTabLayoutEnabled() && tabScroller.croppedEdge.isParamsSet() && tabScroller.croppedEdge.getTabIndex() == tabIndex && isHorizontalTabPlacement()) { int availTextWidth = tabScroller.croppedEdge.getCropline() - (textRect.x - tabRect.x) - tabScroller.croppedEdge.getCroppedSideWidth(); clippedTitle = SwingUtilities2.clipStringIfNecessary(null, metrics, title, availTextWidth); } paintText(g, tabPlacement, font, metrics, tabIndex, clippedTitle, textRect, isSelected); paintIcon(g, tabPlacement, tabIndex, icon, iconRect, isSelected); } paintFocusIndicator(g, tabPlacement, rects, tabIndex, iconRect, textRect, isSelected); } private boolean isHorizontalTabPlacement() { return tabPane.getTabPlacement() == TOP || tabPane.getTabPlacement() == BOTTOM; } /* 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 static int xCropLen[] = {1,1,0,0,1,1,2,2}; private static int yCropLen[] = {0,3,3,6,6,9,9,12}; private static final int CROP_SEGMENT = 12; private static Polygon createCroppedTabShape(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 + tabRect.height; break; case TOP: case BOTTOM: default: rlen = tabRect.height; start = tabRect.y; end = tabRect.y + tabRect.height; ostart = tabRect.x + tabRect.width; } 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; yp[pcnt++] = end; xp[pcnt] = ostart; yp[pcnt++] = start; for(int i = 0; i < rcnt; i++) { for(int j = 0; j < xCropLen.length; j++) { xp[pcnt] = cropline - xCropLen[j]; yp[pcnt] = start + (i*CROP_SEGMENT) + yCropLen[j]; if (yp[pcnt] >= end) { yp[pcnt] = end; pcnt++; break; } pcnt++; } } if (tabPlacement == JTabbedPane.TOP || tabPlacement == JTabbedPane.BOTTOM) { return new Polygon(xp, yp, pcnt); } else { // LEFT or RIGHT return new Polygon(yp, xp, pcnt); } } /* If tabLayoutPolicy == SCROLL_TAB_LAYOUT, this method will paint an edge * indicating the tab is cropped in the viewport display */ private void paintCroppedTabEdge(Graphics g) { int tabIndex = tabScroller.croppedEdge.getTabIndex(); int cropline = tabScroller.croppedEdge.getCropline(); int x,y; switch(tabPane.getTabPlacement()) { case LEFT: case RIGHT: x = rects[tabIndex].x; y = cropline; int xx = x; g.setColor(shadow); while(xx <= x+rects[tabIndex].width) { for (int i=0; i < xCropLen.length; i+=2) { g.drawLine(xx+yCropLen[i],y-xCropLen[i], xx+yCropLen[i+1]-1,y-xCropLen[i+1]); } xx+=CROP_SEGMENT; } break; case TOP: case BOTTOM: default: x = cropline; y = rects[tabIndex].y; int yy = y; g.setColor(shadow); while(yy <= y+rects[tabIndex].height) { for (int i=0; i < xCropLen.length; i+=2) { g.drawLine(x-xCropLen[i],yy+yCropLen[i], x-xCropLen[i+1],yy+yCropLen[i+1]-1); } yy+=CROP_SEGMENT; } } } protected void layoutLabel(int tabPlacement, FontMetrics metrics, int tabIndex, String title, Icon icon, Rectangle tabRect, Rectangle iconRect, Rectangle textRect, boolean isSelected ) { textRect.x = textRect.y = iconRect.x = iconRect.y = 0; View v = getTextViewForTab(tabIndex); if (v != null) { tabPane.putClientProperty("html", v); } SwingUtilities.layoutCompoundLabel((JComponent) tabPane, metrics, title, icon, SwingUtilities.CENTER, SwingUtilities.CENTER, SwingUtilities.CENTER, SwingUtilities.TRAILING, tabRect, iconRect, textRect, textIconGap); tabPane.putClientProperty("html", null); int xNudge = getTabLabelShiftX(tabPlacement, tabIndex, isSelected); int yNudge = getTabLabelShiftY(tabPlacement, tabIndex, isSelected); iconRect.x += xNudge; iconRect.y += yNudge; textRect.x += xNudge; textRect.y += yNudge; } protected void paintIcon(Graphics g, int tabPlacement, int tabIndex, Icon icon, Rectangle iconRect, boolean isSelected ) { if (icon != null) { icon.paintIcon(tabPane, g, iconRect.x, iconRect.y); } } protected void paintText(Graphics g, int tabPlacement, Font font, FontMetrics metrics, int tabIndex, String title, Rectangle textRect, boolean isSelected) { g.setFont(font); View v = getTextViewForTab(tabIndex); if (v != null) { // html v.paint(g, textRect); } else { // plain text int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex); if (tabPane.isEnabled() && tabPane.isEnabledAt(tabIndex)) { Color fg = tabPane.getForegroundAt(tabIndex); if (isSelected && (fg instanceof UIResource)) { Color selectedFG = UIManager.getColor( "TabbedPane.selectedForeground"); if (selectedFG != null) { fg = selectedFG; } } g.setColor(fg); SwingUtilities2.drawStringUnderlineCharAt(tabPane, g, title, mnemIndex, textRect.x, textRect.y + metrics.getAscent()); } else { // tab disabled g.setColor(tabPane.getBackgroundAt(tabIndex).brighter()); SwingUtilities2.drawStringUnderlineCharAt(tabPane, g, title, mnemIndex, textRect.x, textRect.y + metrics.getAscent()); g.setColor(tabPane.getBackgroundAt(tabIndex).darker()); SwingUtilities2.drawStringUnderlineCharAt(tabPane, g, title, mnemIndex, textRect.x - 1, textRect.y + metrics.getAscent() - 1); } } } protected int getTabLabelShiftX(int tabPlacement, int tabIndex, boolean isSelected) { Rectangle tabRect = rects[tabIndex]; int nudge = 0; switch(tabPlacement) { case LEFT: nudge = isSelected? -1 : 1; break; case RIGHT: nudge = isSelected? 1 : -1; break; case BOTTOM: case TOP: default: nudge = tabRect.width % 2; } return nudge; } protected int getTabLabelShiftY(int tabPlacement, int tabIndex, boolean isSelected) { Rectangle tabRect = rects[tabIndex]; int nudge = 0; switch(tabPlacement) { case BOTTOM: nudge = isSelected? 1 : -1; break; case LEFT:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -