/* * * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Oracle nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package java2d; import static java.awt.Color.BLACK; import static java.awt.Color.GREEN; import static java.awt.Color.LIGHT_GRAY; import static java.awt.Color.WHITE; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Graphics; import java.awt.Image; import java.awt.Insets; import java.awt.RenderingHints; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.print.PrinterJob; import java.text.DecimalFormat; import java.util.logging.Level; import java.util.logging.Logger; import javax.print.attribute.HashPrintRequestAttributeSet; import javax.print.attribute.PrintRequestAttributeSet; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.JToggleButton; import javax.swing.JToolBar; import javax.swing.SwingConstants; import javax.swing.border.EtchedBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; /** * Tools to control individual demo graphic attributes. Also, control for * start & stop on animated demos; control for cloning the demo; control for * printing the demo. Expand and collapse the Tools panel with ToggleIcon. */ @SuppressWarnings("serial") public final class Tools extends JPanel implements ActionListener, ChangeListener, Runnable { private final DemoInstVarsAccessor demoInstVars; private ImageIcon stopIcon, startIcon; private Font font = new Font(Font.SERIF, Font.PLAIN, 10); private Color roColor = new Color(187, 213, 238); private Surface surface; private Thread thread; private JPanel toolbarPanel; private JPanel sliderPanel; private JLabel label; private ToggleIcon bumpyIcon, rolloverIcon; private DecimalFormat decimalFormat = new DecimalFormat("000"); protected boolean focus; public JToggleButton toggleB; public JButton printB; public JComboBox screenCombo; public JToggleButton renderB, aliasB; public JToggleButton textureB, compositeB; public JButton startStopB; public JButton cloneB; public boolean issueRepaint = true; public JToolBar toolbar; public JSlider slider; public boolean doSlider; public boolean isExpanded; @SuppressWarnings("LeakingThisInConstructor") public Tools(Surface surface, DemoInstVarsAccessor demoInstVars) { this.surface = surface; this.demoInstVars = demoInstVars; setLayout(new BorderLayout()); stopIcon = new ImageIcon(DemoImages.getImage("stop.gif", this)); startIcon = new ImageIcon(DemoImages.getImage("start.gif", this)); bumpyIcon = new ToggleIcon(this, LIGHT_GRAY); rolloverIcon = new ToggleIcon(this, roColor); toggleB = new JToggleButton(bumpyIcon); toggleB.addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { focus = true; bumpyIcon.start(); } @Override public void mouseExited(MouseEvent e) { focus = false; bumpyIcon.stop(); } }); isExpanded = false; toggleB.addActionListener(this); toggleB.setMargin(new Insets(0, 0, -4, 0)); toggleB.setBorderPainted(false); toggleB.setFocusPainted(false); toggleB.setContentAreaFilled(false); toggleB.setRolloverIcon(rolloverIcon); add("North", toggleB); toolbar = new JToolBar(); toolbar.setPreferredSize(new Dimension(5*25, 26)); toolbar.setFloatable(false); String s = surface.AntiAlias == RenderingHints.VALUE_ANTIALIAS_ON ? "On" : "Off"; aliasB = addTool("A", "Antialiasing " + s, this); s = surface.Rendering == RenderingHints.VALUE_RENDER_SPEED ? "Speed" : "Quality"; renderB = addTool("R", "Rendering " + s, this); s = surface.texture != null ? "On" : "Off"; textureB = addTool("T", "Texture " + s, this); s = surface.composite != null ? "On" : "Off"; compositeB = addTool("C", "Composite " + s, this); Image printBImg = DemoImages.getImage("print.gif", this); printB = addTool(printBImg, "Print the Surface", this); if (surface instanceof AnimatingSurface) { Image stopImg = DemoImages.getImage("stop.gif", this); startStopB = addTool(stopImg, "Stop Animation", this); toolbar.setPreferredSize(new Dimension(6*25, 26)); } screenCombo = new JComboBox<>(); screenCombo.setPreferredSize(new Dimension(100, 18)); screenCombo.setFont(font); for (String name : GlobalControls.screenNames) { screenCombo.addItem(name); } screenCombo.addActionListener(this); toolbarPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0)); toolbarPanel.setLocation(0, 6); toolbarPanel.setVisible(false); toolbarPanel.add(toolbar); toolbarPanel.add(screenCombo); toolbarPanel.setBorder(new EtchedBorder()); add(toolbarPanel); setPreferredSize(new Dimension(200, 8)); if (surface instanceof AnimatingSurface) { sliderPanel = new JPanel(new BorderLayout()); label = new JLabel(" Sleep = 030 ms"); label.setForeground(BLACK); sliderPanel.add(label, BorderLayout.WEST); slider = new JSlider(SwingConstants.HORIZONTAL, 0, 200, 30); slider.addChangeListener(this); sliderPanel.setBorder(new EtchedBorder()); sliderPanel.add(slider); addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { if (toolbarPanel.isVisible()) { invalidate(); if ((doSlider = !doSlider)) { remove(toolbarPanel); add(sliderPanel); } else { remove(sliderPanel); add(toolbarPanel); } validate(); repaint(); } } }); } } public JButton addTool(Image img, String toolTip, ActionListener al) { JButton b = new JButton(new ImageIcon(img)) { Dimension prefSize = new Dimension(25, 22); @Override public Dimension getPreferredSize() { return prefSize; } @Override public Dimension getMaximumSize() { return prefSize; } @Override public Dimension getMinimumSize() { return prefSize; } }; toolbar.add(b); b.setFocusPainted(false); b.setSelected(true); b.setToolTipText(toolTip); b.addActionListener(al); return b; } public JToggleButton addTool(String name, String toolTip, ActionListener al) { JToggleButton b = new JToggleButton(name) { Dimension prefSize = new Dimension(25, 22); @Override public Dimension getPreferredSize() { return prefSize; } @Override public Dimension getMaximumSize() { return prefSize; } @Override public Dimension getMinimumSize() { return prefSize; } }; toolbar.add(b); b.setFocusPainted(false); if (toolTip.equals("Rendering Quality") || toolTip.equals( "Antialiasing On") || toolTip.equals("Texture On") || toolTip. equals("Composite On")) { b.setSelected(true); } else { b.setSelected(false); } b.setToolTipText(toolTip); b.addActionListener(al); return b; } @Override public void actionPerformed(ActionEvent e) { Object obj = e.getSource(); if (obj instanceof JButton) { JButton b = (JButton) obj; b.setSelected(!b.isSelected()); if (b.getIcon() == null) { b.setBackground(b.isSelected() ? GREEN : LIGHT_GRAY); } } if (obj.equals(toggleB)) { isExpanded = !isExpanded; if (isExpanded) { setPreferredSize(new Dimension(200, 38)); } else { setPreferredSize(new Dimension(200, 6)); } toolbarPanel.setVisible(isExpanded); if (sliderPanel != null) { sliderPanel.setVisible(isExpanded); } getParent().validate(); toggleB.getModel().setRollover(false); return; } if (obj.equals(printB)) { start(); return; } if (obj.equals(startStopB)) { if (startStopB.getToolTipText().equals("Stop Animation")) { startStopB.setIcon(startIcon); startStopB.setToolTipText("Start Animation"); surface.animating.stop(); } else { startStopB.setIcon(stopIcon); startStopB.setToolTipText("Stop Animation"); surface.animating.start(); } } else if (obj.equals(aliasB)) { if (aliasB.getToolTipText().equals("Antialiasing On")) { aliasB.setToolTipText("Antialiasing Off"); } else { aliasB.setToolTipText("Antialiasing On"); } surface.setAntiAlias(aliasB.isSelected()); } else if (obj.equals(renderB)) { if (renderB.getToolTipText().equals("Rendering Quality")) { renderB.setToolTipText("Rendering Speed"); } else { renderB.setToolTipText("Rendering Quality"); } surface.setRendering(renderB.isSelected()); } else if (obj.equals(textureB)) { if (textureB.getToolTipText().equals("Texture On")) { textureB.setToolTipText("Texture Off"); surface.setTexture(null); surface.clearSurface = true; } else { textureB.setToolTipText("Texture On"); surface.setTexture(demoInstVars.getControls().texturechooser.texture); } } else if (obj.equals(compositeB)) { if (compositeB.getToolTipText().equals("Composite On")) { compositeB.setToolTipText("Composite Off"); } else { compositeB.setToolTipText("Composite On"); } surface.setComposite(compositeB.isSelected()); } else if (obj.equals(screenCombo)) { surface.setImageType(screenCombo.getSelectedIndex()); } if (issueRepaint && surface.animating != null) { if (surface.getSleepAmount() != 0) { if (surface.animating.running()) { surface.animating.doRepaint(); } } } else if (issueRepaint) { surface.repaint(); } } @Override public void stateChanged(ChangeEvent e) { int value = slider.getValue(); label.setText(" Sleep = " + decimalFormat.format(value) + " ms"); label.repaint(); surface.setSleepAmount(value); } public void start() { thread = new Thread(this); thread.setPriority(Thread.MAX_PRIORITY); thread.setName("Printing " + surface.name); thread.start(); } public synchronized void stop() { thread = null; notifyAll(); } @Override public void run() { boolean stopped = false; if (surface.animating != null && surface.animating.running()) { stopped = true; startStopB.doClick(); } try { PrinterJob printJob = PrinterJob.getPrinterJob(); printJob.setPrintable(surface); boolean pDialogState = true; PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet(); if (!demoInstVars.getPrintCB().isSelected()) { pDialogState = printJob.printDialog(aset); } if (pDialogState) { printJob.print(aset); } } catch (java.security.AccessControlException ace) { String errmsg = "Applet access control exception; to allow " + "access to printer, set\n" + "permission for \"queuePrintJob\" in " + "RuntimePermission."; JOptionPane.showMessageDialog(this, errmsg, "Printer Access Error", JOptionPane.ERROR_MESSAGE); } catch (Exception ex) { Logger.getLogger(Tools.class.getName()).log(Level.SEVERE, null, ex); } if (stopped) { startStopB.doClick(); } thread = null; } /** * Expand and Collapse the Tools Panel with this bumpy button. */ static class ToggleIcon implements Icon, Runnable { private Color shadowColor = new Color(102, 102, 153); private Color fillColor; private Tools tools; private Thread thread; public ToggleIcon(Tools tools, Color fillColor) { this.tools = tools; this.fillColor = fillColor; } @Override public void paintIcon(Component c, Graphics g, int x, int y) { int w = getIconWidth(); int h = getIconHeight(); g.setColor(fillColor); g.fillRect(0, 0, w, h); for (; x < w - 2; x += 4) { g.setColor(WHITE); g.fillRect(x, 1, 1, 1); g.fillRect(x + 2, 3, 1, 1); g.setColor(shadowColor); g.fillRect(x + 1, 2, 1, 1); g.fillRect(x + 3, 4, 1, 1); } } @Override public int getIconWidth() { return tools.getSize().width; } @Override public int getIconHeight() { return 6; } public void start() { thread = new Thread(this); thread.setPriority(Thread.MIN_PRIORITY); thread.setName("ToggleIcon"); thread.start(); } public synchronized void stop() { if (thread != null) { thread.interrupt(); } thread = null; } @Override public void run() { try { Thread.sleep(400); } catch (InterruptedException e) { } if (tools.focus && thread != null) { tools.toggleB.doClick(); } thread = null; } } } // End Tools class