📄 basictabbedpaneui.java
字号:
{ int maxWidth = calculateMaxTabWidth(tabPlacement); calcRect.height -= tabAreaInsets.top + tabAreaInsets.bottom; max = calcRect.height + tabAreaInsets.top + insets.top; int height = 0; start += tabAreaInsets.top + insets.top; int runHeight = start; int fontHeight = fm.getHeight(); for (int i = 0; i < tabCount; i++) { height = calculateTabHeight(tabPlacement, i, fontHeight); if (runHeight + height > max) { runHeight = tabAreaInsets.top + insets.top + getTabRunIndent(tabPlacement, ++runs); rects[i] = new Rectangle(insets.left + tabAreaInsets.left, runHeight, maxWidth, height); runHeight += height; if (runs > tabRuns.length - 1) expandTabRunsArray(); tabRuns[runs] = i; } else { rects[i] = new Rectangle(insets.left + tabAreaInsets.left, runHeight, maxWidth, height); runHeight += height; } } runs++; tabAreaRect.width = runs * maxTabWidth - (runs - 1) * tabRunOverlay + tabAreaInsets.left + tabAreaInsets.right; tabAreaRect.height = tabPane.getHeight() - insets.top - insets.bottom; tabAreaRect.y = insets.top; contentRect.width = tabPane.getWidth() - insets.left - insets.right - tabAreaRect.width; contentRect.height = tabAreaRect.height; contentRect.y = insets.top; if (tabPlacement == SwingConstants.LEFT) { tabAreaRect.x = insets.left; contentRect.x = tabAreaRect.x + tabAreaRect.width; } else { contentRect.x = insets.left; tabAreaRect.x = contentRect.x + contentRect.width; } } runCount = runs; tabRuns[0] = 0; normalizeTabRuns(tabPlacement, tabCount, start, max); selectedRun = getRunForTab(tabCount, tabPane.getSelectedIndex()); if (shouldRotateTabRuns(tabPlacement)) rotateTabRuns(tabPlacement, selectedRun); // Need to pad the runs and move them to the correct location. for (int i = 0; i < runCount; i++) { int first = lastTabInRun(tabCount, getPreviousTabRun(i)) + 1; if (first == tabCount) first = 0; int last = lastTabInRun(tabCount, i); if (shouldPadTabRun(tabPlacement, i)) padTabRun(tabPlacement, first, last, max); // Done padding, now need to move it. if (tabPlacement == SwingConstants.TOP && i > 0) { for (int j = first; j <= last; j++) rects[j].y += (runCount - i) * maxTabHeight - (runCount - i) * tabRunOverlay; } if (tabPlacement == SwingConstants.BOTTOM) { int height = tabPane.getBounds().height - insets.bottom - tabAreaInsets.bottom; int adjustment; if (i == 0) adjustment = height - maxTabHeight; else adjustment = height - (runCount - i + 1) * maxTabHeight - (runCount - i) * tabRunOverlay; for (int j = first; j <= last; j++) rects[j].y = adjustment; } if (tabPlacement == SwingConstants.LEFT && i > 0) { for (int j = first; j <= last; j++) rects[j].x += (runCount - i) * maxTabWidth - (runCount - i) * tabRunOverlay; } if (tabPlacement == SwingConstants.RIGHT) { int width = tabPane.getBounds().width - insets.right - tabAreaInsets.right; int adjustment; if (i == 0) adjustment = width - maxTabWidth; else adjustment = width - (runCount - i + 1) * maxTabWidth + (runCount - i) * tabRunOverlay; for (int j = first; j <= last; j++) rects[j].x = adjustment; } } padSelectedTab(tabPlacement, tabPane.getSelectedIndex()); } /** * This method is called when the JTabbedPane is laid out in * WRAP_TAB_LAYOUT. It calls calculateLayoutInfo to find the positions * of all its components. * * @param parent The Container to lay out. */ public void layoutContainer(Container parent) { calculateLayoutInfo(); } /** * This method returns the minimum layout size for the given container. * * @param parent The container that is being sized. * * @return The minimum size. */ public Dimension minimumLayoutSize(Container parent) { return calculateSize(false); } // If there is more free space in an adjacent run AND the tab in the run can fit in the // adjacent run, move it. This method is not perfect, it is merely an approximation. // If you play around with Sun's JTabbedPane, you'll see that // it does do some pretty strange things with regards to not moving tabs // that should be moved. // start = the x position where the tabs will begin // max = the maximum position of where the tabs can go to (tabAreaInsets.left + the width of the tab area) /** * This method tries to "even out" the number of tabs in each run based on * their widths. * * @param tabPlacement The JTabbedPane's tab placement. * @param tabCount The number of tabs. * @param start The x position where the tabs will begin. * @param max The maximum x position where the tab can run to. */ protected void normalizeTabRuns(int tabPlacement, int tabCount, int start, int max) { Insets tabAreaInsets = getTabAreaInsets(tabPlacement); if (tabPlacement == SwingUtilities.TOP || tabPlacement == SwingUtilities.BOTTOM) { // We should only do this for runCount - 1, cause we can only shift that many times between // runs. for (int i = 1; i < runCount; i++) { Rectangle currRun = rects[lastTabInRun(tabCount, i)]; Rectangle nextRun = rects[lastTabInRun(tabCount, getNextTabRun(i))]; int spaceInCurr = currRun.x + currRun.width; int spaceInNext = nextRun.x + nextRun.width; int diffNow = spaceInCurr - spaceInNext; int diffLater = (spaceInCurr - currRun.width) - (spaceInNext + currRun.width); while (Math.abs(diffLater) < Math.abs(diffNow) && spaceInNext + currRun.width < max) { tabRuns[i]--; spaceInNext += currRun.width; spaceInCurr -= currRun.width; currRun = rects[lastTabInRun(tabCount, i)]; diffNow = spaceInCurr - spaceInNext; diffLater = (spaceInCurr - currRun.width) - (spaceInNext + currRun.width); } // Fix the bounds. int first = lastTabInRun(tabCount, i) + 1; int last = lastTabInRun(tabCount, getNextTabRun(i)); int currX = tabAreaInsets.left; for (int j = first; j <= last; j++) { rects[j].x = currX; currX += rects[j].width; } } } else { for (int i = 1; i < runCount; i++) { Rectangle currRun = rects[lastTabInRun(tabCount, i)]; Rectangle nextRun = rects[lastTabInRun(tabCount, getNextTabRun(i))]; int spaceInCurr = currRun.y + currRun.height; int spaceInNext = nextRun.y + nextRun.height; int diffNow = spaceInCurr - spaceInNext; int diffLater = (spaceInCurr - currRun.height) - (spaceInNext + currRun.height); while (Math.abs(diffLater) < Math.abs(diffNow) && spaceInNext + currRun.height < max) { tabRuns[i]--; spaceInNext += currRun.height; spaceInCurr -= currRun.height; currRun = rects[lastTabInRun(tabCount, i)]; diffNow = spaceInCurr - spaceInNext; diffLater = (spaceInCurr - currRun.height) - (spaceInNext + currRun.height); } int first = lastTabInRun(tabCount, i) + 1; int last = lastTabInRun(tabCount, getNextTabRun(i)); int currY = tabAreaInsets.top; for (int j = first; j <= last; j++) { rects[j].y = currY; currY += rects[j].height; } } } } /** * This method pads the tab at the selected index by the selected tab pad * insets (so that it looks larger). * * @param tabPlacement The placement of the tabs. * @param selectedIndex The selected index. */ protected void padSelectedTab(int tabPlacement, int selectedIndex) { Insets insets = getSelectedTabPadInsets(tabPlacement); rects[selectedIndex].x -= insets.left; rects[selectedIndex].y -= insets.top; rects[selectedIndex].width += insets.left + insets.right; rects[selectedIndex].height += insets.top + insets.bottom; } // If the tabs on the run don't fill the width of the window, make it fit now. // start = starting index of the run // end = last index of the run // max = tabAreaInsets.left + width (or equivalent) // assert start <= end. /** * This method makes each tab in the run larger so that the tabs expand * to fill the runs width/height (depending on tabPlacement). * * @param tabPlacement The placement of the tabs. * @param start The index of the first tab. * @param end The last index of the tab * @param max The amount of space in the run (width for TOP and BOTTOM * tabPlacement). */ protected void padTabRun(int tabPlacement, int start, int end, int max) { if (tabPlacement == SwingConstants.TOP || tabPlacement == SwingConstants.BOTTOM) { int runWidth = rects[end].x + rects[end].width; int spaceRemaining = max - runWidth; int numTabs = end - start + 1; // now divvy up the space. int spaceAllocated = spaceRemaining / numTabs; int currX = rects[start].x; for (int i = start; i <= end; i++) { rects[i].x = currX; rects[i].width += spaceAllocated; currX += rects[i].width; // This is used because since the spaceAllocated // variable is an int, it rounds down. Sometimes, // we don't fill an entire row, so we make it do // so now. if (i == end && rects[i].x + rects[i].width != max) rects[i].width = max - rects[i].x; } } else { int runHeight = rects[end].y + rects[end].height; int spaceRemaining = max - runHeight; int numTabs = end - start + 1; int spaceAllocated = spaceRemaining / numTabs; int currY = rects[start].y; for (int i = start; i <= end; i++) { rects[i].y = currY; rects[i].height += spaceAllocated; currY += rects[i].height; if (i == end && rects[i].y + rects[i].height != max) rects[i].height = max - rects[i].y; } } } /** * This method returns the preferred layout size for the given container. * * @param parent The container to size. * * @return The preferred layout size. */ public Dimension preferredLayoutSize(Container parent) { return calculateSize(false); } /** * This method returns the preferred tab height given a tabPlacement and * width. * * @param tabPlacement The JTabbedPane's tab placement. * @param width The expected width. * * @return The preferred tab area height. */ protected int preferredTabAreaHeight(int tabPlacement, int width) { if (tabPane.getTabCount() == 0) return calculateTabAreaHeight(tabPlacement, 0, 0); int runs = 0; int runWidth = 0; int tabWidth = 0; FontMetrics fm = getFontMetrics(); Insets tabAreaInsets = getTabAreaInsets(tabPlacement); Insets insets = tabPane.getInsets(); // Only interested in width, this is a messed up rectangle now. width -= tabAreaInsets.left + tabAreaInsets.right + insets.left + insets.right; // The reason why we can't use runCount: // This method is only called to calculate the size request // for the tabbedPane. However, this size request is dependent on // our desired width. We need to find out what the height would // be IF we got our desired width. for (int i = 0; i < tabPane.getTabCount(); i++) { tabWidth = calculateTabWidth(tabPlacement, i, fm); if (runWidth + tabWidth > width) { runWidth = tabWidth; runs++; } else runWidth += tabWidth; } runs++; int maxTabHeight = calculateMaxTabHeight(tabPlacement); int tabAreaHeight = calculateTabAreaHeight(tabPlacement, runs, maxTabHeight); return tabAreaHeight; } /** * This method calculates the preferred tab area width given a tab * placement and height. * * @param tabPlacement The JTabbedPane's tab placement. * @param height The expected height. * * @return The preferred tab area width. */ protected int preferredTabAreaWidth(int tabPlacement, int height) { if (tabPane.getTabCount() == 0) return calculateTabAreaHeight(tabPlacement, 0, 0); int runs = 0; int runHeight = 0; int tabHeight = 0; FontMetrics fm = getFontMetrics();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -