⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plugintabbedpaneui.java

📁 具有不同语法高亮的编辑器实例
💻 JAVA
字号:
/*
 * 10/21/2005
 *
 * PluginTabbedPaneUI.java - UI used by the tabbed panes holding plugins in an
 * AbstractPluggableGUIApplication.
 * Copyright (C) 2005 Robert Futrell
 * email@address.com
 * www.website.com
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
package org.fife.ui.app;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.KeyboardFocusManager;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
import javax.swing.text.View;


/**
 * The UI for tabbed panes holding plugins in an
 * <code>AbstractPluggableGUIApplication</code>.  This UI is designed to
 * resemble tabbed panes in Microsoft Visual Studio .NET.
 *
 * @author Robert Futrell
 * @version 1.0
 */
class PluginTabbedPaneUI extends BasicTabbedPaneUI {

	private List croppedTitlesList;


/*****************************************************************************/


	/**
	 * Cosntructor.
	 */
	protected PluginTabbedPaneUI() {
		croppedTitlesList = new ArrayList();
	}


/*****************************************************************************/


	/**
	 * Invoked by <code>installUI</code> to create a layout manager
	 * object to manage the <code>JTabbedPane</code>.
	 *
	 * @return A layout manager object.
	 * @see TabbedPaneLayout
	 * @see javax.swing.JTabbedPane#getTabLayoutPolicy
	 */
	protected LayoutManager createLayoutManager() {
		return new PluginTabbedPaneLayout();
	}


/*****************************************************************************/


	/**
	 * Returns an instance of this UI for the specified tabbed pane.
	 *
	 * @param c The tabbed pane.
	 * @return An instance of this UI.
	 */
	public static ComponentUI createUI(JComponent c) {
		return new PluginTabbedPaneUI();
	}


/*****************************************************************************/


	/**
	 * Returns the minimum size for the tabbed pane.  This is overridden so
	 * that the tabbed pane can be given a very small width.  Tabbed panes'
	 * layout managers by default give them a minimum width equal to one of
	 * their tabs' widths, but we don't want to do that.
	 *
	 * @param c The tabbed pane.
	 * @return The minimum size for this tabbed pane.
	 */
	public Dimension getMinimumSize(JComponent c) {
		return new Dimension(60, 64);
	}


/*****************************************************************************/


	/**
	 * Caches insets, colors, fonts, etc.  This method is overridden so we
	 * can set custom values for insets.
	 */
	protected void installDefaults() {
		super.installDefaults();
		contentBorderInsets = new Insets(0,0,2,0);
		tabAreaInsets = new Insets(2, 4, 0, 4);
	}


/*****************************************************************************/


	/**
	 * Arranges the text, icon, etc. on a tab, and caches the "cropped"
	 * version of the tab's title, if necessary.
	 */
	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);

		String croppedTitle = SwingUtilities.layoutCompoundLabel(
											tabPane,
											metrics, title, icon,
											SwingUtilities.CENTER,
											SwingUtilities.CENTER,
											SwingUtilities.CENTER,
											SwingUtilities.TRAILING,
											tabRect,
											iconRect,
											textRect,
											textIconGap);

		int croppedCount = croppedTitlesList.size();
		int tabCount = tabPane.getTabCount();
		if (croppedCount<tabCount) {
			for (int i=croppedCount; i<tabCount; i++)
				croppedTitlesList.add("");
		}
		croppedTitlesList.set(tabIndex, croppedTitle);

		tabPane.putClientProperty("html", null);

	}


/*****************************************************************************/


	protected void paintContentBorderTopEdge(Graphics g, int tabPlacement,
									int selectedIndex, 
									int x, int y, int w, int h) {
	}


/*****************************************************************************/


	protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement,
									int selectedIndex, 
									int x, int y, int w, int h) {

		//g.setColor(UIManager.getColor("TabbedPane.shadow"));
		g.setColor(UIManager.getColor("TabbedPane.foreground"));
		y = y+h-1;
		if ((selectedIndex<0)) {
			g.drawLine(x+1,y, x+w-2,y);
		}
		else {
			// Break line to show visual connection to selected tab
			Rectangle selRect = getTabBounds(selectedIndex, calcRect);
			g.drawLine(x+1,y, selRect.x,y);
			if (selRect.x+selRect.width-1 < x+w-2)
				g.drawLine(selRect.x+selRect.width-1,y, x+w-2,y);
		}
	}


/*****************************************************************************/


	protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement,
										int selectedIndex, 
										int x, int y, int w, int h) {
	}


/*****************************************************************************/


	protected void paintContentBorderRightEdge(Graphics g, int tabPlacement,
										int selectedIndex, 
										int x, int y, int w, int h) {
	}


/*****************************************************************************/


	/**
	 * Paints the background of a tab.
	 */
	protected void paintTabBackground(Graphics g, int tabPlacement,
			int tabIndex, int x, int y, int w, int h, boolean isSelected) {
		if (isSelected) {
			g.setColor(UIManager.getColor("TabbedPane.highlight"));
			//g.setColor(UIManager.getColor("Panel.background"));
			g.fillRect(x,y, w,h);
		}
	}


/*****************************************************************************/


	/**
	 * Paints the border of a tab.
	 */
	protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex,
						int x, int y, int w, int h, boolean isSelected) {
		// NOTE: We assume the tab placement is JTabbedPane.BOTTOM.
		//g.setColor(UIManager.getColor("TabbedPane.shadow"));
		int x2 = x + w - 1;
		if (isSelected) {
			g.setColor(UIManager.getColor("TabbedPane.foreground"));
			int y2 = y + h - 1;
			g.drawLine(x,y2, x2,y2);
			g.drawLine(x2,y2, x2,y);
		}
		else if (tabPane.getSelectedIndex()!=tabIndex+1) {
			g.setColor(UIManager.getColor("TabbedPane.shadow"));
			g.drawLine(x2,y+2, x2,y+h-3);
		}
	}


/*****************************************************************************/


	/**
	 * Paints the text on a tab (the tab's title).
	 */
	protected void paintText(Graphics g, int tabPlacement,
						Font font, FontMetrics metrics, int tabIndex,
						String title, Rectangle textRect, 
						boolean isSelected) {
		// Get our (probably) cropped title; don't use the uncropped one.
		title = (String)croppedTitlesList.get(tabIndex);
		g.setFont(font);
		Color fg = tabPane.getForegroundAt(tabIndex);
//		if (isSelected && (fg instanceof UIResource)) {
if (isSelected) {
			Color selectedFG = UIManager.getColor(
								"TabbedPane.selectedForeground");
			if (selectedFG != null)
				fg = selectedFG;
		}
else {
	fg = UIManager.getColor("TabbedPane.shadow");
}
		g.setColor(fg);
		g.drawString(title, textRect.x, textRect.y+metrics.getAscent());
	} 


/*****************************************************************************/
/******************** INNER CLASSES ******************************************/
/*****************************************************************************/


	/**
	 * Tab layout for a plugin tabbed pane.  All tabs area always in a single
	 * run (row).  If there is not enough room for all of the tabs in one run,
	 * the space available is divided equally among all of the tabs.<p>
	 *
	 * Much of this code is stolen from <code>BasicTabbedPaneUI</code>'s
	 * layout subclasses.
	 */
	class PluginTabbedPaneLayout extends TabbedPaneLayout {

		public PluginTabbedPaneLayout() {
		}

		protected int preferredTabAreaHeight(int tabPlacement, int width) {
			return calculateMaxTabHeight(tabPlacement);
		}

		protected int preferredTabAreaWidth(int tabPlacement, int height) {
			return calculateMaxTabWidth(tabPlacement);
		}

		public void layoutContainer(Container parent) {

			int tabPlacement = tabPane.getTabPlacement();
			int tabCount = tabPane.getTabCount();
			Insets insets = tabPane.getInsets();
			int selectedIndex = tabPane.getSelectedIndex();
			Component visibleComponent = getVisibleComponent();

			calculateLayoutInfo();

			if (selectedIndex < 0) {
				if (visibleComponent != null) {
					// The last tab was removed, so remove the component
					setVisibleComponent(null);
				}
			}
			else {
				Component selectedComponent = tabPane.getComponentAt(selectedIndex);
				boolean shouldChangeFocus = false;

				// In order to allow programs to use a single component
				// as the display for multiple tabs, we will not change
				// the visible compnent if the currently selected tab
				// has a null component.  This is a bit dicey, as we don't
				// explicitly state we support this in the spec, but since
				// programs are now depending on this, we're making it work.
				if (selectedComponent != null) {
					if (selectedComponent != visibleComponent &&
										visibleComponent != null) {
						if (KeyboardFocusManager.
							getCurrentKeyboardFocusManager().getFocusOwner() != null)
							shouldChangeFocus = true;
					}                   
					setVisibleComponent(selectedComponent);
				}

				int tx, ty, tw, th; // tab area bounds
				int cx, cy, cw, ch; // content area bounds
				Insets contentInsets = getContentBorderInsets(tabPlacement);
				Rectangle bounds = tabPane.getBounds();
				int numChildren = tabPane.getComponentCount();

				if (numChildren > 0) {

					// NOTE: Here we're assuming tabs are on the bottom.
					// Calculate tab area bounds
					tw = bounds.width - insets.left - insets.right;
					th = calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight);
					tx = insets.left;
					ty = bounds.height - insets.bottom - th;

					// calculate content area bounds
					cx = insets.left + contentInsets.left;
					cy = insets.top + contentInsets.top;
					cw = bounds.width - insets.left - insets.right - 
						contentInsets.left - contentInsets.right;
					ch = bounds.height - insets.top - insets.bottom - th -
						contentInsets.top - contentInsets.bottom;

					for (int i=0; i < numChildren; i++) {
						Component child = tabPane.getComponent(i);
						child.setBounds(cx, cy, cw, ch);
					}

				}

			}

		}

		/**
		 * Calculates the bounds for each tab.
		 *
		 * @param tabPlacement Always <code>JTabbedPane.BOTTOM</code>.
		 * @param tabCount The number of tabs.
		 */
		protected void calculateTabRects(int tabPlacement, int tabCount) {

			FontMetrics metrics = getFontMetrics();
			Dimension size = tabPane.getSize();
			Insets insets = tabPane.getInsets(); 
			Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
			int fontHeight = metrics.getHeight();
			int selectedIndex = tabPane.getSelectedIndex();
			boolean leftToRight = tabPane.getComponentOrientation().isLeftToRight();

			// Since we'll only ever have one run of tabs, the tab area's
			// height should be the height of the tallest tab.
			maxTabHeight = calculateMaxTabHeight(tabPlacement);

			// Get the starting x and y for the tab run.
			int x = tabAreaInsets.left;
			int y = size.height - insets.bottom - tabAreaInsets.bottom - maxTabHeight;

			runCount = 1;	// Always 1 run count (needed by other methods).

			if (tabCount == 0)
				return;

			// Compute the width of the area in which to put the tabs.
			int tabAreaWidth = size.width - insets.left - insets.right -
							tabAreaInsets.left - tabAreaInsets.right;

			// Compute the width the tabs will take up if they all get the
			// amount of space they want.
			int allTabsPreferredWidth = 0;
			for (int i=0; i<tabCount; i++) {
				allTabsPreferredWidth += calculateTabWidth(tabPlacement, i, metrics);
			}

			// First check to see whether all tabs fit in the tab area
			// width fully.  If they do, give them all the space they need.
			if (allTabsPreferredWidth <= tabAreaWidth) {
				for (int i=0; i<tabCount; i++) {
					Rectangle rect = rects[i];
					if (i > 0) {
						rect.x = rects[i-1].x + rects[i-1].width;
					}
					else {
						tabRuns[0] = 0;
						maxTabWidth = 0;
						rect.x = x;
					}
					rect.width = calculateTabWidth(tabPlacement, i, metrics);
					maxTabWidth = Math.max(maxTabWidth, rect.width);
					rect.y = y;
					rect.height = maxTabHeight;
				}
			}

			// If they all don't fit, make each tab have an equal share of
			// the space available.
			else {
				maxTabWidth = tabAreaWidth/tabCount;
				for (int i=0; i<tabCount; i++) {
					Rectangle rect = rects[i];
					rect.x = x + i*maxTabWidth;
					rect.y = y;
					rect.width = maxTabWidth;
					rect.height = maxTabHeight;
				}
			}

			// If right to left, flip x positions and adjust by widths
			if (!leftToRight) {
				int rightMargin = size.width 
							- (insets.right + tabAreaInsets.right);
				for (int i=0; i<tabCount; i++)
					rects[i].x = rightMargin - rects[i].x - rects[i].width;
			}

		}

	}


/*****************************************************************************/

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -