synthsplitpaneui.java
来自「java jdk 1.4的源码」· Java 代码 · 共 2,043 行 · 第 1/5 页
JAVA
2,043 行
/** * Messaged to reset the preferred sizes. */ public void resetToPreferredSizes(JSplitPane jc) { if(splitPane != null) { LayoutManager layout = jc.getLayout(); if (layout instanceof SplitPaneLayoutManager) { ((SplitPaneLayoutManager)layout).resetToPreferredSizes(); } splitPane.revalidate(); splitPane.repaint(); } } /** * Sets the location of the divider to location. */ public void setDividerLocation(JSplitPane jc, int location) { if (!ignoreDividerLocationChange) { dividerLocationIsSet = true; splitPane.revalidate(); splitPane.repaint(); } else { ignoreDividerLocationChange = false; } } /** * Returns the location of the divider, which may differ from what * the splitpane thinks the location of the divider is. */ public int getDividerLocation(JSplitPane jc) { if(orientation == JSplitPane.HORIZONTAL_SPLIT) return divider.getX(); return divider.getY(); } /** * Gets the minimum location of the divider. */ public int getMinimumDividerLocation(JSplitPane jc) { int minLoc = 0; Component leftC = splitPane.getLeftComponent(); if ((leftC != null) && (leftC.isVisible())) { Insets insets = splitPane.getInsets(); Dimension minSize = leftC.getMinimumSize(); if(orientation == JSplitPane.HORIZONTAL_SPLIT) { minLoc = minSize.width; } else { minLoc = minSize.height; } if(insets != null) { if(orientation == JSplitPane.HORIZONTAL_SPLIT) { minLoc += insets.left; } else { minLoc += insets.top; } } } return minLoc; } /** * Gets the maximum location of the divider. */ public int getMaximumDividerLocation(JSplitPane jc) { Dimension splitPaneSize = splitPane.getSize(); int maxLoc = 0; Component rightC = splitPane.getRightComponent(); if (rightC != null) { Insets insets = splitPane.getInsets(); Dimension minSize = new Dimension(0, 0); if (rightC.isVisible()) { minSize = rightC.getMinimumSize(); } if(orientation == JSplitPane.HORIZONTAL_SPLIT) { maxLoc = splitPaneSize.width - minSize.width; } else { maxLoc = splitPaneSize.height - minSize.height; } maxLoc -= dividerSize; if(insets != null) { if(orientation == JSplitPane.HORIZONTAL_SPLIT) { maxLoc -= insets.right; } else { maxLoc -= insets.top; } } } return Math.max(getMinimumDividerLocation(splitPane), maxLoc); } public void update(Graphics g, JComponent c) { SynthContext context = getContext(c); SynthLookAndFeel.update(context, g); paint(context, g); context.dispose(); } public void paint(Graphics g, JComponent c) { SynthContext context = getContext(c); paint(context, g); context.dispose(); } protected void paint(SynthContext context, Graphics g) { if (!painted && splitPane.getDividerLocation()<0) { ignoreDividerLocationChange = true; splitPane.setDividerLocation(getDividerLocation(splitPane)); } painted = true; } private void paintDragDivider(Graphics g, int x, int y, int w, int h) { SynthContext context = getContext(splitPane,Region.SPLIT_PANE_DIVIDER); context.setComponentState(((context.getComponentState() | MOUSE_OVER) ^ MOUSE_OVER) | PRESSED); SynthPainter painter = (SynthPainter)context.getStyle(). get(context, "SplitPane.dragPainter"); if (painter != null) { painter.paint(context, "foreground", g, x, y, w, h); } context.dispose(); } /** * Messaged after the JSplitPane the receiver is providing the look * and feel for paints its children. */ public void finishedPaintingChildren(JSplitPane jc, Graphics g) { if(jc == splitPane && getLastDragLocation() != -1 && !isContinuousLayout() && !draggingHW) { if(orientation == JSplitPane.HORIZONTAL_SPLIT) { paintDragDivider(g, getLastDragLocation(), 0, dividerSize - 1, splitPane.getHeight() - 1); } else { paintDragDivider(g, 0, lastDragLocation, splitPane.getWidth() - 1, dividerSize - 1); } } } /** * Resets the layout manager based on orientation and messages it * with invalidateLayout to pull in appropriate Components. */ protected void resetLayoutManager() { SplitPaneLayoutManager layoutManager; if(orientation == JSplitPane.HORIZONTAL_SPLIT) { layoutManager = new SplitPaneLayoutManager(0); } else { layoutManager = new SplitPaneLayoutManager(1); } splitPane.setLayout(layoutManager); layoutManager.updateComponents(); splitPane.revalidate(); splitPane.repaint(); } /** * Should be messaged before the dragging session starts, resets * lastDragLocation and dividerSize. */ protected void startDragging() { Component leftC = splitPane.getLeftComponent(); Component rightC = splitPane.getRightComponent(); ComponentPeer cPeer; beginDragDividerLocation = getDividerLocation(splitPane); draggingHW = false; if(leftC != null && (cPeer = leftC.getPeer()) != null && !(cPeer instanceof LightweightPeer)) { draggingHW = true; } else if(rightC != null && (cPeer = rightC.getPeer()) != null && !(cPeer instanceof LightweightPeer)) { draggingHW = true; } if(orientation == JSplitPane.HORIZONTAL_SPLIT) { setLastDragLocation(divider.getBounds().x); dividerSize = divider.getSize().width; if(!isContinuousLayout() && draggingHW) { nonContinuousLayoutDivider.setBounds (getLastDragLocation(), 0, dividerSize, splitPane.getHeight()); addHeavyweightDivider(); } } else { setLastDragLocation(divider.getBounds().y); dividerSize = divider.getSize().height; if(!isContinuousLayout() && draggingHW) { nonContinuousLayoutDivider.setBounds (0, getLastDragLocation(), splitPane.getWidth(), dividerSize); addHeavyweightDivider(); } } } /** * Messaged during a dragging session to move the divider to the * passed in location. If continuousLayout is true the location is * reset and the splitPane validated. */ protected void dragDividerTo(int location) { if(getLastDragLocation() != location) { if(isContinuousLayout()) { splitPane.setDividerLocation(location); setLastDragLocation(location); } else { int lastLoc = getLastDragLocation(); setLastDragLocation(location); if(orientation == JSplitPane.HORIZONTAL_SPLIT) { if(draggingHW) { nonContinuousLayoutDivider.setLocation( getLastDragLocation(), 0); } else { int splitHeight = splitPane.getHeight(); splitPane.repaint(lastLoc, 0, dividerSize, splitHeight); splitPane.repaint(location, 0, dividerSize, splitHeight); } } else { if(draggingHW) { nonContinuousLayoutDivider.setLocation(0, getLastDragLocation()); } else { int splitWidth = splitPane.getWidth(); splitPane.repaint(0, lastLoc, splitWidth, dividerSize); splitPane.repaint(0, location, splitWidth, dividerSize); } } } } } /** * Messaged to finish the dragging session. If not continuous display * the dividers location will be reset. */ protected void finishDraggingTo(int location) { dragDividerTo(location); setLastDragLocation(-1); if(!isContinuousLayout()) { Component leftC = splitPane.getLeftComponent(); Rectangle leftBounds = leftC.getBounds(); if (draggingHW) { if(orientation == JSplitPane.HORIZONTAL_SPLIT) { nonContinuousLayoutDivider.setLocation(-dividerSize, 0); } else { nonContinuousLayoutDivider.setLocation(0, -dividerSize); } splitPane.remove(nonContinuousLayoutDivider); } splitPane.setDividerLocation(location); } } /** * LayoutManager for JSplitPanes that have an orientation of * HORIZONTAL_SPLIT. */ private class SplitPaneLayoutManager implements LayoutManager2,UIResource { /* left, right, divider. (in this exact order) */ protected int[] sizes; protected Component[] components; /** Size of the splitpane the last time laid out. */ private int lastSplitPaneSize; /** True if resetToPreferredSizes has been invoked. */ private boolean doReset; /** Axis, 0 for horizontal, or 1 for veritcal. */ private int axis; SplitPaneLayoutManager(int axis) { this.axis = axis; components = new Component[3]; components[0] = components[1] = components[2] = null; sizes = new int[3]; } // // LayoutManager // /** * Does the actual layout. */ public void layoutContainer(Container container) { Dimension containerSize = container.getSize(); // If the splitpane has a zero size then no op out of here. // If we execute this function now, we're going to cause ourselves // much grief. if (containerSize.height <= 0 || containerSize.width <= 0 ) { lastSplitPaneSize = 0; return; } int spDividerLocation = splitPane.getDividerLocation(); Insets insets = splitPane.getInsets(); int availableSize = getAvailableSize(containerSize, insets); int newSize = getSizeForPrimaryAxis(containerSize); int beginLocation = getDividerLocation(splitPane); int dOffset = getSizeForPrimaryAxis(insets, true); Dimension dSize = (components[2] == null) ? null : components[2].getPreferredSize(); if ((doReset && !dividerLocationIsSet) || spDividerLocation < 0) { resetToPreferredSizes(availableSize); } else if (lastSplitPaneSize <= 0 || availableSize == lastSplitPaneSize || !painted || (dSize != null && getSizeForPrimaryAxis(dSize) != sizes[2])) { if (dSize != null) { sizes[2] = getSizeForPrimaryAxis(dSize); } else { sizes[2] = 0; } setDividerLocation(spDividerLocation - dOffset, availableSize); dividerLocationIsSet = false; } else if (availableSize != lastSplitPaneSize) { distributeSpace(availableSize - lastSplitPaneSize, true); } doReset = false; dividerLocationIsSet = false; lastSplitPaneSize = availableSize; // Reset the bounds of each component int nextLocation = getInitialLocation(insets); int counter = 0; while (counter < 3) { if (components[counter] != null && components[counter].isVisible()) { setComponentToSize(components[counter], sizes[counter], nextLocation, insets, containerSize); nextLocation += sizes[counter]; } switch (counter) { case 0: counter = 2; break; case 2: counter = 1; break; case 1: counter = 3; break; } } if (painted) { // This is tricky, there is never a good time for us // to push the value to the splitpane, painted appears to // the best time to do it. What is really needed is // notification that layout has completed. int newLocation = getDividerLocation(splitPane); if (newLocation != (spDividerLocation - dOffset)) { int lastLocation = splitPane.getLastDividerLocation(); ignoreDividerLocationChange = true; try { splitPane.setDividerLocation(newLocation); // This is not always needed, but is rather tricky // to determine when... The case this is needed for // is if the user sets the divider location to some // bogus value, say 0, and the actual value is 1, the // call to setDividerLocation(1) will preserve the // old value of 0, when we really want the divider // location value before the call. This is needed for // the one touch buttons. splitPane.setLastDividerLocation(lastLocation); } finally { ignoreDividerLocationChange = false; } } } }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?