1 /* 2 * 3 * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * - Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * - Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * - Neither the name of Oracle nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 21 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 package java2d; 33 34 35 import java.awt.BorderLayout; 36 import java.awt.Component; 37 import java.awt.Dimension; 38 import java.awt.Font; 39 import java.awt.GridBagLayout; 40 import java.awt.GridLayout; 41 import java.awt.Image; 42 import java.awt.event.ActionEvent; 43 import java.awt.event.ActionListener; 44 import java.awt.event.MouseAdapter; 45 import java.awt.event.MouseEvent; 46 import java.awt.event.WindowAdapter; 47 import java.awt.event.WindowEvent; 48 import javax.swing.JButton; 49 import javax.swing.JCheckBox; 50 import javax.swing.JCheckBoxMenuItem; 51 import javax.swing.JFrame; 52 import javax.swing.JPanel; 53 import javax.swing.JTabbedPane; 54 import javax.swing.JToggleButton; 55 import javax.swing.border.BevelBorder; 56 import javax.swing.border.CompoundBorder; 57 import javax.swing.border.EmptyBorder; 58 import javax.swing.border.SoftBevelBorder; 59 import javax.swing.event.ChangeEvent; 60 import javax.swing.event.ChangeListener; 61 62 63 /** 64 * DemoGroup handles multiple demos inside of a panel. Demos are loaded 65 * from the demos[][] string as listed in J2Ddemo.java. 66 * Demo groups can be loaded individually, for example : 67 * java DemoGroup Fonts 68 * Loads all the demos found in the demos/Fonts directory. 69 */ 70 @SuppressWarnings("serial") 71 public class DemoGroup extends JPanel 72 implements ChangeListener, ActionListener { 73 private final DemoInstVarsAccessor demoInstVars; 74 public int columns = 2; 75 private static final Font font = new Font(Font.SERIF, Font.PLAIN, 10); 76 private final EmptyBorder emptyB = new EmptyBorder(5, 5, 5, 5); 77 private final BevelBorder bevelB = new BevelBorder(BevelBorder.LOWERED); 78 private String groupName; 79 public JPanel clonePanels[]; 80 public JTabbedPane tabbedPane; 81 82 public DemoGroup(String name, DemoInstVarsAccessor demoInstVars) { 83 84 groupName = name; 85 this.demoInstVars = demoInstVars; 86 87 setLayout(new BorderLayout()); 88 89 JPanel p = new JPanel(new GridLayout(0, 2)); 90 p.setBorder(new CompoundBorder(emptyB, bevelB)); 91 92 // Find the named demo group in J2Ddemo.demos[]. 93 int ind = -1; 94 while (!name.equals(J2Ddemo.demos[++ind][0])) { 95 } 96 String[] demos = J2Ddemo.demos[ind]; 97 98 // If there are an odd number of demos, use GridBagLayout. 99 // Note that we don't use the first entry. 100 int numDemos = demos.length - 1; 101 if (numDemos % 2 == 1) { 102 p.setLayout(new GridBagLayout()); 103 } 104 105 MouseAdapter mouseListener = new MouseAdapter() { 106 107 @Override 108 public void mouseClicked(MouseEvent e) { 109 DemoGroup.this.mouseClicked(e.getComponent()); 110 } 111 }; 112 113 // For each demo in the group, prepare a DemoPanel. 114 for (int i = 1; i <= numDemos; i++) { 115 DemoPanel dp = 116 new DemoPanel("java2d.demos." + name + "." + demos[i], demoInstVars); 117 dp.setDemoBorder(p); 118 if (dp.surface != null) { 119 dp.surface.addMouseListener(mouseListener); 120 dp.surface.setMonitor(demoInstVars.getPerformanceMonitor() != null); 121 } 122 if (p.getLayout() instanceof GridBagLayout) { 123 int x = p.getComponentCount() % 2; 124 int y = p.getComponentCount() / 2; 125 int w = (i == numDemos) ? 2 : 1; 126 J2Ddemo.addToGridBag(p, dp, x, y, w, 1, 1, 1); 127 } else { 128 p.add(dp); 129 } 130 } 131 132 add(p); 133 } 134 135 public void mouseClicked(Component component) { 136 String className = component.toString(); 137 138 if (tabbedPane == null) { 139 shutDown(getPanel()); 140 JPanel p = new JPanel(new BorderLayout()); 141 p.setBorder(new CompoundBorder(emptyB, bevelB)); 142 143 tabbedPane = new JTabbedPane(); 144 tabbedPane.setFont(font); 145 146 JPanel tmpP = (JPanel) getComponent(0); 147 tabbedPane.addTab(groupName, tmpP); 148 149 clonePanels = new JPanel[tmpP.getComponentCount()]; 150 for (int i = 0; i < clonePanels.length; i++) { 151 clonePanels[i] = new JPanel(new BorderLayout()); 152 DemoPanel dp = (DemoPanel) tmpP.getComponent(i); 153 DemoPanel c = new DemoPanel(dp.className, demoInstVars); 154 c.setDemoBorder(clonePanels[i]); 155 if (c.surface != null) { 156 c.surface.setMonitor(demoInstVars.getPerformanceMonitor() != null); 157 Image cloneImg = DemoImages.getImage("clone.gif", this); 158 c.tools.cloneB = c.tools.addTool(cloneImg, 159 "Clone the Surface", this); 160 Dimension d = c.tools.toolbar.getPreferredSize(); 161 c.tools.toolbar.setPreferredSize( 162 new Dimension(d.width + 27, d.height)); 163 if (demoInstVars.getBackgroundColor() != null) { 164 c.surface.setBackground(demoInstVars.getBackgroundColor()); 165 } 166 } 167 clonePanels[i].add(c); 168 String s = dp.className.substring(dp.className.indexOf('.') + 1); 169 tabbedPane.addTab(s, clonePanels[i]); 170 } 171 p.add(tabbedPane); 172 remove(tmpP); 173 add(p); 174 175 tabbedPane.addChangeListener(this); 176 revalidate(); 177 } 178 179 className = className.substring(0, className.indexOf('[')); 180 181 for (int i = 0; i < tabbedPane.getTabCount(); i++) { 182 String s1 = className.substring(className.indexOf('.') + 1); 183 if (tabbedPane.getTitleAt(i).equals(s1)) { 184 tabbedPane.setSelectedIndex(i); 185 break; 186 } 187 } 188 189 revalidate(); 190 } 191 192 @Override 193 public void actionPerformed(ActionEvent e) { 194 JButton b = (JButton) e.getSource(); 195 if (b.getToolTipText().startsWith("Clone")) { 196 cloneDemo(); 197 } else { 198 removeClone(b.getParent().getParent().getParent().getParent()); 199 } 200 } 201 private int index; 202 203 @Override 204 public void stateChanged(ChangeEvent e) { 205 shutDown((JPanel) tabbedPane.getComponentAt(index)); 206 index = tabbedPane.getSelectedIndex(); 207 setup(false); 208 } 209 210 public JPanel getPanel() { 211 if (tabbedPane != null) { 212 return (JPanel) tabbedPane.getSelectedComponent(); 213 } else { 214 return (JPanel) getComponent(0); 215 } 216 } 217 218 public void setup(boolean issueRepaint) { 219 220 JPanel p = getPanel(); 221 222 // Let PerformanceMonitor know which demos are running 223 if (demoInstVars.getPerformanceMonitor() != null) { 224 demoInstVars.getPerformanceMonitor().surf.setPanel(p); 225 demoInstVars.getPerformanceMonitor().surf.setSurfaceState(); 226 } 227 228 GlobalControls c = demoInstVars.getControls(); 229 // .. tools check against global controls settings .. 230 // .. & start demo & custom control thread if need be .. 231 for (int i = 0; i < p.getComponentCount(); i++) { 232 DemoPanel dp = (DemoPanel) p.getComponent(i); 233 if (dp.surface != null && c != null) { 234 Tools t = dp.tools; 235 t.setVisible(isValid()); 236 t.issueRepaint = issueRepaint; 237 JToggleButton b[] = { t.toggleB, t.aliasB, t.renderB, 238 t.textureB, t.compositeB }; 239 JCheckBox cb[] = { c.toolBarCB, c.aliasCB, c.renderCB, 240 c.textureCB, c.compositeCB }; 241 for (int j = 0; j < b.length; j++) { 242 if (c.obj != null && c.obj.equals(cb[j])) { 243 if (b[j].isSelected() != cb[j].isSelected()) { 244 b[j].doClick(); 245 } 246 } else if (c.obj == null) { 247 if (b[j].isSelected() != cb[j].isSelected()) { 248 b[j].doClick(); 249 } 250 } 251 } 252 t.setVisible(true); 253 if (c.screenCombo.getSelectedIndex() 254 != t.screenCombo.getSelectedIndex()) { 255 t.screenCombo.setSelectedIndex(c.screenCombo. 256 getSelectedIndex()); 257 } 258 if (demoInstVars.getVerboseCB().isSelected()) { 259 dp.surface.verbose(c); 260 } 261 dp.surface.setSleepAmount(c.slider.getValue()); 262 if (demoInstVars.getBackgroundColor() != null) { 263 dp.surface.setBackground(demoInstVars.getBackgroundColor()); 264 } 265 t.issueRepaint = true; 266 } 267 dp.start(); 268 } 269 revalidate(); 270 } 271 272 public void shutDown(JPanel p) { 273 for (int i = 0; i < p.getComponentCount(); i++) { 274 ((DemoPanel) p.getComponent(i)).stop(); 275 } 276 System.gc(); 277 } 278 279 public void cloneDemo() { 280 JPanel panel = clonePanels[tabbedPane.getSelectedIndex() - 1]; 281 if (panel.getComponentCount() == 1) { 282 panel.invalidate(); 283 panel.setLayout(new GridLayout(0, columns, 5, 5)); 284 panel.revalidate(); 285 } 286 DemoPanel original = (DemoPanel) getPanel().getComponent(0); 287 DemoPanel clone = new DemoPanel(original.className, demoInstVars); 288 if (columns == 2) { 289 clone.setDemoBorder(panel); 290 } 291 Image removeImg = DemoImages.getImage("remove.gif", this); 292 clone.tools.cloneB = 293 clone.tools.addTool(removeImg, "Remove the Surface", this); 294 Dimension d = clone.tools.toolbar.getPreferredSize(); 295 clone.tools.toolbar.setPreferredSize( 296 new Dimension(d.width + 27, d.height)); 297 if (demoInstVars.getBackgroundColor() != null) { 298 clone.surface.setBackground(demoInstVars.getBackgroundColor()); 299 } 300 if (demoInstVars.getControls() != null) { 301 if (clone.tools.isExpanded 302 != demoInstVars.getControls().toolBarCB.isSelected()) { 303 clone.tools.toggleB.doClick(); 304 } 305 } 306 clone.start(); 307 clone.surface.setMonitor(demoInstVars.getPerformanceMonitor() != null); 308 panel.add(clone); 309 panel.repaint(); 310 panel.revalidate(); 311 } 312 313 public void removeClone(Component theClone) { 314 JPanel panel = clonePanels[tabbedPane.getSelectedIndex() - 1]; 315 if (panel.getComponentCount() == 2) { 316 Component cmp = panel.getComponent(0); 317 panel.removeAll(); 318 panel.setLayout(new BorderLayout()); 319 panel.revalidate(); 320 panel.add(cmp); 321 } else { 322 panel.remove(theClone); 323 int cmpCount = panel.getComponentCount(); 324 for (int j = 1; j < cmpCount; j++) { 325 int top = (j + 1 >= 3) ? 0 : 5; 326 int left = ((j + 1) % 2) == 0 ? 0 : 5; 327 EmptyBorder eb = new EmptyBorder(top, left, 5, 5); 328 SoftBevelBorder sbb = new SoftBevelBorder(BevelBorder.RAISED); 329 JPanel p = (JPanel) panel.getComponent(j); 330 p.setBorder(new CompoundBorder(eb, sbb)); 331 } 332 } 333 panel.repaint(); 334 panel.revalidate(); 335 } 336 337 public static void main(String args[]) { 338 class DemoInstVarsAccessorImpl extends DemoInstVarsAccessorImplBase { 339 private volatile JCheckBoxMenuItem ccthreadCB; 340 341 public void setCcthreadCB(JCheckBoxMenuItem ccthreadCB) { 342 this.ccthreadCB = ccthreadCB; 343 } 344 345 @Override 346 public JCheckBoxMenuItem getCcthreadCB() { 347 return ccthreadCB; 348 } 349 } 350 DemoInstVarsAccessorImpl demoInstVars = new DemoInstVarsAccessorImpl(); 351 final DemoGroup group = new DemoGroup(args[0], demoInstVars); 352 JFrame f = new JFrame("Java2D(TM) Demo - DemoGroup"); 353 f.addWindowListener(new WindowAdapter() { 354 355 @Override 356 public void windowClosing(WindowEvent e) { 357 System.exit(0); 358 } 359 360 @Override 361 public void windowDeiconified(WindowEvent e) { 362 group.setup(false); 363 } 364 365 @Override 366 public void windowIconified(WindowEvent e) { 367 group.shutDown(group.getPanel()); 368 } 369 }); 370 f.getContentPane().add("Center", group); 371 f.pack(); 372 int FRAME_WIDTH = 620; 373 int FRAME_HEIGHT = 530; 374 f.setSize(FRAME_WIDTH, FRAME_HEIGHT); 375 f.setLocationRelativeTo(null); // centers f on screen 376 f.setVisible(true); 377 for (String arg : args) { 378 if (arg.startsWith("-ccthread")) { 379 demoInstVars.setCcthreadCB(new JCheckBoxMenuItem("CCThread", true)); 380 } 381 } 382 group.setup(false); 383 } 384 }