metacity.java

来自「JAVA 所有包」· Java 代码 · 共 2,097 行 · 第 1/5 页

JAVA
2,097
字号
/* * @(#)Metacity.java	1.37 06/07/19 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.java.swing.plaf.gtk;import sun.swing.SwingUtilities2;import com.sun.java.swing.plaf.gtk.GTKConstants.ArrowType;import com.sun.java.swing.plaf.gtk.GTKConstants.ShadowType;import javax.swing.plaf.ColorUIResource;import javax.swing.plaf.synth.*;import java.awt.*;import java.awt.geom.*;import java.awt.image.*;import java.io.*;import java.net.*;import java.security.*;import java.util.*;import javax.swing.*;import javax.swing.border.*;import javax.xml.parsers.*;import org.xml.sax.SAXException;import org.w3c.dom.*;/** * @version 1.37, 07/19/06 */class Metacity implements SynthConstants {    // Tutorial:    // http://developer.gnome.org/doc/tutorials/metacity/metacity-themes.html    // Themes:    // http://art.gnome.org/theme_list.php?category=metacity    static Metacity INSTANCE;    private static final String[] themeNames = {        getUserTheme(),        "blueprint",    	"Bluecurve",        "Crux",        "SwingFallbackTheme"    };    static {        for (String themeName : themeNames) {            if (themeName != null) {            try {                INSTANCE = new Metacity(themeName);            } catch (FileNotFoundException ex) {            } catch (IOException ex) {                logError(themeName, ex);            } catch (ParserConfigurationException ex) {                logError(themeName, ex);            } catch (SAXException ex) {                logError(themeName, ex);            }            }            if (INSTANCE != null) {            break;            }        }        if (INSTANCE == null) {            throw new Error("Could not find any installed metacity theme, and fallback failed");        }    }    private static boolean errorLogged = false;    private static DocumentBuilder documentBuilder;    private static Document xmlDoc;    private static String userHome;    private Node frame_style_set;    private Map<String, Object> frameGeometry;    private Map<String, Map<String, Object>> frameGeometries;    private LayoutManager titlePaneLayout = new TitlePaneLayout();    private ColorizeImageFilter imageFilter = new ColorizeImageFilter();    private URL themeDir = null;    private SynthContext context;    private String themeName;    private ArithmeticExpressionEvaluator aee = new ArithmeticExpressionEvaluator();    private Map<String, Integer> variables;    // Reusable clip shape object    private RoundRectClipShape roundedClipShape;    protected Metacity(String themeName) throws IOException, ParserConfigurationException, SAXException {	this.themeName = themeName;	themeDir = getThemeDir(themeName);	if (themeDir != null) {	    URL themeURL = new URL(themeDir, "metacity-theme-1.xml");	    xmlDoc = getXMLDoc(themeURL);	    if (xmlDoc == null) {		throw new IOException(themeURL.toString());	    }	} else {	    throw new FileNotFoundException(themeName);	}	// Initialize constants	variables = new HashMap();	NodeList nodes = xmlDoc.getElementsByTagName("constant");	int n = nodes.getLength();	for (int i = 0; i < n; i++) {	    Node node = nodes.item(i);	    String name = getStringAttr(node, "name");	    if (name != null) {		String value = getStringAttr(node, "value");		if (value != null) {		    try {			variables.put(name, Integer.parseInt(value));		    } catch (NumberFormatException ex) {			logError(themeName, ex);			// Ignore bad value		    }		}	    }	}	// Cache frame geometries	frameGeometries = new HashMap();	nodes = xmlDoc.getElementsByTagName("frame_geometry");	n = nodes.getLength();	for (int i = 0; i < n; i++) {	    Node node = nodes.item(i);	    String name = getStringAttr(node, "name");	    if (name != null) {		HashMap<String, Object> gm = new HashMap();		frameGeometries.put(name, gm);		String parentGM = getStringAttr(node, "parent");		if (parentGM != null) {		    gm.putAll(frameGeometries.get(parentGM));		}		gm.put("has_title",		       Boolean.valueOf(getBooleanAttr(node, "has_title",            true)));		gm.put("rounded_top_left",		       Boolean.valueOf(getBooleanAttr(node, "rounded_top_left",     false)));		gm.put("rounded_top_right",		       Boolean.valueOf(getBooleanAttr(node, "rounded_top_right",    false)));		gm.put("rounded_bottom_left",		       Boolean.valueOf(getBooleanAttr(node, "rounded_bottom_left",  false)));		gm.put("rounded_bottom_right",		       Boolean.valueOf(getBooleanAttr(node, "rounded_bottom_right", false)));				NodeList childNodes = node.getChildNodes();		int nc = childNodes.getLength();		for (int j = 0; j < nc; j++) {		    Node child = childNodes.item(j);		    if (child.getNodeType() == Node.ELEMENT_NODE) {			name = child.getNodeName();			Object value = null;			if ("distance".equals(name)) {			    value = new Integer(getIntAttr(child, "value", 0));			} else if ("border".equals(name)) {				    value = new Insets(getIntAttr(child, "top", 0),					       getIntAttr(child, "left", 0),					       getIntAttr(child, "bottom", 0),					       getIntAttr(child, "right", 0));			} else if ("aspect_ratio".equals(name)) {			    value = new Float(getFloatAttr(child, "value", 1.0F));			} else {			    logError(themeName, "Unknown Metacity frame geometry value type: "+name);			}			String childName = getStringAttr(child, "name");			if (childName != null && value != null) {			    gm.put(childName, value);			}		    }		}	    }	}	frameGeometry = frameGeometries.get("normal");    }    public static LayoutManager getTitlePaneLayout() {	return INSTANCE.titlePaneLayout;    }    private Shape getRoundedClipShape(int x, int y, int w, int h,				      int arcw, int arch, int corners) {	if (roundedClipShape == null) {	    roundedClipShape = new RoundRectClipShape();	}	roundedClipShape.setRoundedRect(x, y, w, h, arcw, arch, corners);	return roundedClipShape;    }    void paintButtonBackground(SynthContext context, Graphics g, int x, int y, int w, int h) {	updateFrameGeometry(context);	this.context = context;	JButton button = (JButton)context.getComponent();	String buttonName = button.getName();	int buttonState = context.getComponentState();	JComponent titlePane = (JComponent)button.getParent();	Container titlePaneParent = titlePane.getParent();	JInternalFrame jif;	if (titlePaneParent instanceof JInternalFrame) {	    jif = (JInternalFrame)titlePaneParent;	} else if (titlePaneParent instanceof JInternalFrame.JDesktopIcon) {	    jif = ((JInternalFrame.JDesktopIcon)titlePaneParent).getInternalFrame();	} else {	    return;	}	boolean active = jif.isSelected();	button.setOpaque(false);	String state = "normal";	if ((buttonState & PRESSED) != 0) {	    state = "pressed";	} else if ((buttonState & MOUSE_OVER) != 0) {	    state = "prelight";	}	String function = null;	String location = null;	boolean left_corner  = false;	boolean right_corner = false;	if (buttonName == "InternalFrameTitlePane.menuButton") {	    function = "menu";	    location = "left_left";	    left_corner = true;	} else if (buttonName == "InternalFrameTitlePane.iconifyButton") {	    function = "minimize";	    int nButtons = ((jif.isIconifiable() ? 1 : 0) +			    (jif.isMaximizable() ? 1 : 0) +			    (jif.isClosable() ? 1 : 0));	    right_corner = (nButtons == 1);	    switch (nButtons) {	      case 1: location = "right_right"; break;	      case 2: location = "right_middle"; break;	      case 3: location = "right_left"; break;	    }	} else if (buttonName == "InternalFrameTitlePane.maximizeButton") {	    function = "maximize";	    right_corner = !jif.isClosable();	    location = jif.isClosable() ? "right_middle" : "right_right";	} else if (buttonName == "InternalFrameTitlePane.closeButton") {	    function = "close";	    right_corner = true;	    location = "right_right";	}	Node frame = getNode(frame_style_set, "frame", new String[] {	    "focus", (active ? "yes" : "no"),	    "state", (jif.isMaximum() ? "maximized" : "normal")	});	if (function != null && frame != null) {	    Node frame_style = getNode("frame_style", new String[] {		"name", getStringAttr(frame, "style")	    });	    if (frame_style != null) {		Shape oldClip = g.getClip();		if ((right_corner && getBoolean("rounded_top_right", false)) ||		    (left_corner  && getBoolean("rounded_top_left", false))) { 		    Point buttonLoc = button.getLocation();		    if (right_corner) { 			g.setClip(getRoundedClipShape(0, 0, w, h,						      12, 12, RoundRectClipShape.TOP_RIGHT));		    } else {			g.setClip(getRoundedClipShape(0, 0, w, h,						      11, 11, RoundRectClipShape.TOP_LEFT));		    }                    Rectangle clipBounds = oldClip.getBounds();                    g.clipRect(clipBounds.x, clipBounds.y,                                clipBounds.width, clipBounds.height);		}		drawButton(frame_style, location+"_background", state, g, w, h, jif);		drawButton(frame_style, function, state, g, w, h, jif);		g.setClip(oldClip);	    }	}    }    protected void drawButton(Node frame_style, String function, String state,			    Graphics g, int w, int h, JInternalFrame jif) {	Node buttonNode = getNode(frame_style, "button",				  new String[] { "function", function, "state", state });	if (buttonNode == null && !state.equals("normal")) {	    buttonNode = getNode(frame_style, "button",				 new String[] { "function", function, "state", "normal" });	}	if (buttonNode != null) {	    Node draw_ops;	    String draw_ops_name = getStringAttr(buttonNode, "draw_ops");	    if (draw_ops_name != null) {		draw_ops = getNode("draw_ops", new String[] { "name", draw_ops_name });	    } else {		draw_ops = getNode(buttonNode, "draw_ops", null);	    }	    variables.put("width",  w);	    variables.put("height", h);	    draw(draw_ops, g, jif);	}    }    void paintFrameBorder(SynthContext context, Graphics g, int x0, int y0, int width, int height) {	updateFrameGeometry(context);	this.context = context;	JComponent comp = context.getComponent();	JComponent titlePane = findChild(comp, "InternalFrame.northPane");	if (titlePane == null) {	    return;	}        JInternalFrame jif = null;        if (comp instanceof JInternalFrame) {            jif = (JInternalFrame)comp;	} else if (comp instanceof JInternalFrame.JDesktopIcon) {	    jif = ((JInternalFrame.JDesktopIcon)comp).getInternalFrame();	} else {	    assert false : "component is not JInternalFrame or JInternalFrame.JDesktopIcon";	    return;        }	boolean active = jif.isSelected();	Font oldFont = g.getFont();	g.setFont(titlePane.getFont());	g.translate(x0, y0);	Rectangle titleRect = calculateTitleArea(jif);	JComponent menuButton = findChild(titlePane, "InternalFrameTitlePane.menuButton");	Icon frameIcon = jif.getFrameIcon();	variables.put("mini_icon_width",		      (frameIcon != null) ? frameIcon.getIconWidth()  : 0);	variables.put("mini_icon_height",		      (frameIcon != null) ? frameIcon.getIconHeight() : 0);	variables.put("title_width",  calculateTitleTextWidth(g, jif));	FontMetrics fm = SwingUtilities2.getFontMetrics(jif, g);	variables.put("title_height", fm.getAscent() + fm.getDescent());	// These don't seem to apply here, but the Galaxy theme uses them. Not sure why.	variables.put("icon_width",  32);	variables.put("icon_height", 32);	if (frame_style_set != null) {	    Node frame = getNode(frame_style_set, "frame", new String[] {		"focus", (active ? "yes" : "no"),		"state", (jif.isMaximum() ? "maximized" : "normal")	    });	    if (frame != null) {		Node frame_style = getNode("frame_style", new String[] {		    "name", getStringAttr(frame, "style")		});		if (frame_style != null) {		    Shape oldClip = g.getClip();		    boolean roundTopLeft     = getBoolean("rounded_top_left",     false);		    boolean roundTopRight    = getBoolean("rounded_top_right",    false);		    boolean roundBottomLeft  = getBoolean("rounded_bottom_left",  false);		    boolean roundBottomRight = getBoolean("rounded_bottom_right", false);		    if (roundTopLeft || roundTopRight || roundBottomLeft || roundBottomRight) {			jif.setOpaque(false);			g.setClip(getRoundedClipShape(0, 0, width, height, 12, 12,					(roundTopLeft     ? RoundRectClipShape.TOP_LEFT     : 0) |					(roundTopRight    ? RoundRectClipShape.TOP_RIGHT    : 0) |					(roundBottomLeft  ? RoundRectClipShape.BOTTOM_LEFT  : 0) |					(roundBottomRight ? RoundRectClipShape.BOTTOM_RIGHT : 0)));		    }                                    Rectangle clipBounds = oldClip.getBounds();                    g.clipRect(clipBounds.x, clipBounds.y,                               clipBounds.width, clipBounds.height);		    int titleHeight = titlePane.getHeight();		    boolean minimized = jif.isIcon();		    Insets insets = getBorderInsets(context, null);		    int leftTitlebarEdge   = getInt("left_titlebar_edge");		    int rightTitlebarEdge  = getInt("right_titlebar_edge");		    int topTitlebarEdge    = getInt("top_titlebar_edge");		    int bottomTitlebarEdge = getInt("bottom_titlebar_edge");		    if (!minimized) {			drawPiece(frame_style, g, "entire_background",				  0, 0, width, height, jif);		    }		    drawPiece(frame_style, g, "titlebar",			      0, 0, width, titleHeight, jif);		    drawPiece(frame_style, g, "titlebar_middle",			      leftTitlebarEdge, topTitlebarEdge,			      width - leftTitlebarEdge - rightTitlebarEdge,			      titleHeight - topTitlebarEdge - bottomTitlebarEdge,			      jif);		    drawPiece(frame_style, g, "left_titlebar_edge",			      0, 0, leftTitlebarEdge, titleHeight, jif);		    drawPiece(frame_style, g, "right_titlebar_edge",			      width - rightTitlebarEdge, 0,			      rightTitlebarEdge, titleHeight, jif);		    drawPiece(frame_style, g, "top_titlebar_edge",			      0, 0, width, topTitlebarEdge, jif);		    drawPiece(frame_style, g, "bottom_titlebar_edge",			      0, titleHeight - bottomTitlebarEdge,

⌨️ 快捷键说明

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