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 + -
显示快捷键?