1 /* 2 * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package javax.swing.plaf.nimbus; 26 27 import javax.swing.Painter; 28 import sun.swing.plaf.synth.SynthIcon; 29 30 import javax.swing.plaf.synth.SynthContext; 31 import javax.swing.*; 32 import java.awt.*; 33 import java.awt.image.BufferedImage; 34 import javax.swing.plaf.UIResource; 35 36 /** 37 * An icon that delegates to a painter. 38 * @author rbair 39 */ 40 class NimbusIcon extends SynthIcon { 41 private int width; 42 private int height; 43 private String prefix; 44 private String key; 45 46 NimbusIcon(String prefix, String key, int w, int h) { 47 this.width = w; 48 this.height = h; 49 this.prefix = prefix; 50 this.key = key; 51 } 52 53 @SuppressWarnings("unchecked") 54 private static Painter<JComponent> paintFilter(@SuppressWarnings("rawtypes") Painter painter) { 55 return (Painter<JComponent>) painter; 56 } 57 58 @Override 59 public void paintIcon(SynthContext context, Graphics g, int x, int y, 60 int w, int h) { 61 Painter<JComponent> painter = null; 62 if (context != null) { 63 painter = paintFilter((Painter)context.getStyle().get(context, key)); 64 } 65 if (painter == null){ 66 painter = paintFilter((Painter)UIManager.get(prefix + "[Enabled]." + key)); 67 } 68 69 if (painter != null && context != null) { 70 JComponent c = context.getComponent(); 71 boolean rotate = false; 72 boolean flip = false; 73 //translatex and translatey are additional translations that 74 //must occur on the graphics context when rendering a toolbar 75 //icon 76 int translatex = 0; 77 int translatey = 0; 78 if (c instanceof JToolBar) { 79 JToolBar toolbar = (JToolBar)c; 80 rotate = toolbar.getOrientation() == JToolBar.VERTICAL; 81 flip = !toolbar.getComponentOrientation().isLeftToRight(); 82 Object o = NimbusLookAndFeel.resolveToolbarConstraint(toolbar); 83 //we only do the +1 hack for UIResource borders, assuming 84 //that the border is probably going to be our border 85 if (toolbar.getBorder() instanceof UIResource) { 86 if (o == BorderLayout.SOUTH) { 87 translatey = 1; 88 } else if (o == BorderLayout.EAST) { 89 translatex = 1; 90 } 91 } 92 } else if (c instanceof JMenu) { 93 flip = ! c.getComponentOrientation().isLeftToRight(); 94 } 95 if (g instanceof Graphics2D){ 96 Graphics2D gfx = (Graphics2D)g; 97 gfx.translate(x, y); 98 gfx.translate(translatex, translatey); 99 if (rotate) { 100 gfx.rotate(Math.toRadians(90)); 101 gfx.translate(0, -w); 102 painter.paint(gfx, context.getComponent(), h, w); 103 gfx.translate(0, w); 104 gfx.rotate(Math.toRadians(-90)); 105 } else if (flip){ 106 gfx.scale(-1, 1); 107 gfx.translate(-w,0); 108 painter.paint(gfx, context.getComponent(), w, h); 109 gfx.translate(w,0); 110 gfx.scale(-1, 1); 111 } else { 112 painter.paint(gfx, context.getComponent(), w, h); 113 } 114 gfx.translate(-translatex, -translatey); 115 gfx.translate(-x, -y); 116 } else { 117 // use image if we are printing to a Java 1.1 PrintGraphics as 118 // it is not a instance of Graphics2D 119 BufferedImage img = new BufferedImage(w,h, 120 BufferedImage.TYPE_INT_ARGB); 121 Graphics2D gfx = img.createGraphics(); 122 if (rotate) { 123 gfx.rotate(Math.toRadians(90)); 124 gfx.translate(0, -w); 125 painter.paint(gfx, context.getComponent(), h, w); 126 } else if (flip){ 127 gfx.scale(-1, 1); 128 gfx.translate(-w,0); 129 painter.paint(gfx, context.getComponent(), w, h); 130 } else { 131 painter.paint(gfx, context.getComponent(), w, h); 132 } 133 gfx.dispose(); 134 g.drawImage(img,x,y,null); 135 img = null; 136 } 137 } 138 } 139 140 /** 141 * Implements the standard Icon interface's paintIcon method as the standard 142 * synth stub passes null for the context and this will cause us to not 143 * paint any thing, so we override here so that we can paint the enabled 144 * state if no synth context is available 145 */ 146 @Override 147 public void paintIcon(Component c, Graphics g, int x, int y) { 148 Painter<JComponent> painter = 149 paintFilter((Painter)UIManager.get(prefix + "[Enabled]." + key)); 150 if (painter != null){ 151 JComponent jc = (c instanceof JComponent) ? (JComponent)c : null; 152 Graphics2D gfx = (Graphics2D)g; 153 gfx.translate(x, y); 154 painter.paint(gfx, jc , width, height); 155 gfx.translate(-x, -y); 156 } 157 } 158 159 @Override 160 public int getIconWidth(SynthContext context) { 161 if (context == null) { 162 return width; 163 } 164 JComponent c = context.getComponent(); 165 if (c instanceof JToolBar && ((JToolBar)c).getOrientation() == JToolBar.VERTICAL) { 166 //we only do the -1 hack for UIResource borders, assuming 167 //that the border is probably going to be our border 168 if (c.getBorder() instanceof UIResource) { 169 return c.getWidth() - 1; 170 } else { 171 return c.getWidth(); 172 } 173 } else { 174 return scale(context, width); 175 } 176 } 177 178 @Override 179 public int getIconHeight(SynthContext context) { 180 if (context == null) { 181 return height; 182 } 183 JComponent c = context.getComponent(); 184 if (c instanceof JToolBar){ 185 JToolBar toolbar = (JToolBar)c; 186 if (toolbar.getOrientation() == JToolBar.HORIZONTAL) { 187 //we only do the -1 hack for UIResource borders, assuming 188 //that the border is probably going to be our border 189 if (toolbar.getBorder() instanceof UIResource) { 190 return c.getHeight() - 1; 191 } else { 192 return c.getHeight(); 193 } 194 } else { 195 return scale(context, width); 196 } 197 } else { 198 return scale(context, height); 199 } 200 } 201 202 /** 203 * Scale a size based on the "JComponent.sizeVariant" client property of the 204 * component that is using this icon 205 * 206 * @param context The synthContext to get the component from 207 * @param size The size to scale 208 * @return The scaled size or original if "JComponent.sizeVariant" is not 209 * set 210 */ 211 private int scale(SynthContext context, int size) { 212 if (context == null || context.getComponent() == null){ 213 return size; 214 } 215 // The key "JComponent.sizeVariant" is used to match Apple's LAF 216 String scaleKey = (String) context.getComponent().getClientProperty( 217 "JComponent.sizeVariant"); 218 if (scaleKey != null) { 219 if (NimbusStyle.LARGE_KEY.equals(scaleKey)) { 220 size *= NimbusStyle.LARGE_SCALE; 221 } else if (NimbusStyle.SMALL_KEY.equals(scaleKey)) { 222 size *= NimbusStyle.SMALL_SCALE; 223 } else if (NimbusStyle.MINI_KEY.equals(scaleKey)) { 224 // mini is not quite as small for icons as full mini is 225 // just too tiny 226 size *= NimbusStyle.MINI_SCALE + 0.07; 227 } 228 } 229 return size; 230 } 231 }