basictabbedpaneui.java
来自「Mac OS X 10.4.9 for x86 Source Code gcc」· Java 代码 · 共 2,129 行 · 第 1/5 页
JAVA
2,129 行
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(); Insets tabAreaInsets = getTabAreaInsets(tabPlacement); Insets insets = tabPane.getInsets(); height -= tabAreaInsets.top + tabAreaInsets.bottom + insets.top + insets.bottom; int fontHeight = fm.getHeight(); for (int i = 0; i < tabPane.getTabCount(); i++) { tabHeight = calculateTabHeight(tabPlacement, i, fontHeight); if (runHeight + tabHeight > height) { runHeight = tabHeight; runs++; } else runHeight += tabHeight; } runs++; int maxTabWidth = calculateMaxTabWidth(tabPlacement); int tabAreaWidth = calculateTabAreaWidth(tabPlacement, runs, maxTabWidth); return tabAreaWidth; } /** * This method rotates the places each run in the correct place the * tabRuns array. See the comment for tabRuns for how the runs are placed * in the array. * * @param tabPlacement The JTabbedPane's tab placement. * @param selectedRun The run the current selection is in. */ protected void rotateTabRuns(int tabPlacement, int selectedRun) { if (runCount == 1 || selectedRun == 1 || selectedRun == -1) return; int[] newTabRuns = new int[tabRuns.length]; int currentRun = selectedRun; int i = 1; do { newTabRuns[i] = tabRuns[currentRun]; currentRun = getNextTabRun(currentRun); i++; } while (i < runCount); if (runCount > 1) newTabRuns[0] = tabRuns[currentRun]; tabRuns = newTabRuns; BasicTabbedPaneUI.this.selectedRun = 1; } /** * This method is called when a component is removed from the * JTabbedPane. * * @param comp The component removed. */ public void removeLayoutComponent(Component comp) { // Do nothing. } } /** * This class acts as the LayoutManager for the JTabbedPane in * SCROLL_TAB_MODE. */ private class TabbedPaneScrollLayout extends TabbedPaneLayout
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?