diff -r fd16c54261b3 -r 90ce3da70b43 jdk/test/java/awt/MultipleGradientPaint/MultiGradientTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/awt/MultipleGradientPaint/MultiGradientTest.java Sat Dec 01 00:00:00 2007 +0000 @@ -0,0 +1,434 @@ +/* + * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +/* + * @test + * @bug 6296064 6521533 + * @summary A simple manual test for visual verification of GradientPaint + * LinearGradientPaint, and RadialGradientPaint. + * @run main/manual MultiGradientTest + * @author campbelc + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.LinearGradientPaint; +import java.awt.MultipleGradientPaint.ColorSpaceType; +import java.awt.MultipleGradientPaint.CycleMethod; +import java.awt.Paint; +import java.awt.Polygon; +import java.awt.RadialGradientPaint; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.geom.AffineTransform; +import java.awt.geom.NoninvertibleTransformException; +import java.awt.geom.Point2D; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.EnumSet; +import java.util.List; +import javax.swing.AbstractListModel; +import javax.swing.BoxLayout; +import javax.swing.ComboBoxModel; +import javax.swing.JCheckBox; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JSpinner; +import javax.swing.SpinnerNumberModel; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; + +public class MultiGradientTest extends JPanel { + + private static final Color[] COLORS = { + new Color(0, 0, 0), + new Color(128, 128, 128), + new Color(255, 0, 0), + new Color(255, 255, 0), + new Color(0, 255, 0), + new Color(0, 255, 255), + new Color(128, 0, 255), + new Color(128, 128, 128), + }; + + private static enum PaintType {BASIC, LINEAR, RADIAL}; + private static enum ShapeType {RECT, ELLIPSE, MULTIPLE}; + private static enum XformType {IDENTITY, TRANSLATE, SCALE, SHEAR, ROTATE}; + + private PaintType paintType = PaintType.LINEAR; + private ShapeType shapeType = ShapeType.RECT; + private XformType xformType = XformType.IDENTITY; + private CycleMethod cycleMethod = CycleMethod.NO_CYCLE; + private ColorSpaceType colorSpace = ColorSpaceType.SRGB; + private Object antialiasHint = RenderingHints.VALUE_ANTIALIAS_OFF; + private Object renderHint = RenderingHints.VALUE_RENDER_SPEED; + private AffineTransform transform = new AffineTransform(); + + private int numColors; + + private GradientPanel gradientPanel; + private ControlsPanel controlsPanel; + + private MultiGradientTest() { + numColors = COLORS.length; + + setLayout(new BorderLayout()); + gradientPanel = new GradientPanel(); + add(gradientPanel, BorderLayout.CENTER); + controlsPanel = new ControlsPanel(); + add(controlsPanel, BorderLayout.SOUTH); + } + + private class GradientPanel extends JPanel { + private int startX, startY, endX, endY; + private int ctrX, ctrY, focusX, focusY; + private float radius; + private Paint paint; + + private GradientPanel() { + startX = 20; + startY = 20; + endX = 100; + endY = 100; + ctrX = 100; + ctrY = 100; + focusX = 100; + focusY = 100; + radius = 100.0f; + + makeNewPaint(); + + MouseAdapter l = new MyMouseAdapter(); + addMouseListener(l); + addMouseMotionListener(l); + } + + public void paintComponent(Graphics g) { + Graphics2D g2d = (Graphics2D)g.create(); + + int w = getWidth(); + int h = getHeight(); + g2d.setColor(Color.black); + g2d.fillRect(0, 0, w, h); + + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + antialiasHint); + g2d.setRenderingHint(RenderingHints.KEY_RENDERING, + renderHint); + + g2d.transform(transform); + g2d.setPaint(paint); + + switch (shapeType) { + default: + case RECT: + g2d.fillRect(0, 0, w, h); + break; + + case ELLIPSE: + g2d.fillOval(0, 0, w, h); + break; + + case MULTIPLE: + g2d.fillRect(0, 0, w/2, h/2); + g2d.fillOval(w/2, 0, w/2, h/2); + g2d.drawOval(0, h/2, w/2, h/2); + g2d.drawLine(0, h/2, w/2, h); + g2d.drawLine(0, h, w/2, h/2); + Polygon p = new Polygon(); + p.addPoint(w/2, h); + p.addPoint(w, h); + p.addPoint(3*w/4, h/2); + g2d.fillPolygon(p); + break; + } + + switch (paintType) { + default: + case BASIC: + case LINEAR: + g2d.setColor(Color.white); + g2d.fillRect(startX-1, startY-1, 2, 2); + g2d.drawString("1", startX, startY + 12); + g2d.fillRect(endX-1, endY-1, 2, 2); + g2d.drawString("2", endX, endY + 12); + break; + + case RADIAL: + g2d.setColor(Color.white); + g2d.fillRect(ctrX-1, ctrY-1, 2, 2); + g2d.drawString("C", ctrX, ctrY + 12); + g2d.fillRect(focusX-1, focusY-1, 2, 2); + g2d.drawString("F", focusX, focusY + 12); + break; + } + + g2d.dispose(); + } + + private void updatePoints(int x, int y) { + Point2D inv = new Point2D.Double(x, y); + + try { + inv = transform.inverseTransform(inv, null); + } catch (NoninvertibleTransformException e) { + e.printStackTrace(); + } + + x = (int)inv.getX(); + y = (int)inv.getY(); + + switch (paintType) { + default: + case BASIC: + case LINEAR: + // pick the closest point to move + if (inv.distance(startX, startY) < inv.distance(endX, endY)) { + startX = x; + startY = y; + } else { + endX = x; + endY = y; + } + break; + + case RADIAL: + // pick the closest point to move + if (inv.distance(ctrX, ctrY) < inv.distance(focusX, focusY)) { + ctrX = x; + ctrY = y; + } else { + focusX = x; + focusY = y; + } + break; + } + + updatePaint(); + } + + private void makeNewPaint() { + Color[] colors = Arrays.copyOf(COLORS, numColors); + float[] fractions = new float[colors.length]; + for (int i = 0; i < fractions.length; i++) { + fractions[i] = ((float)i) / (fractions.length-1); + } + + switch (paintType) { + case BASIC: + boolean cyclic = (cycleMethod != CycleMethod.NO_CYCLE); + paint = new GradientPaint(startX, startY, Color.RED, + endX, endY, Color.BLUE, cyclic); + break; + + default: + case LINEAR: + paint = + new LinearGradientPaint(new Point2D.Float(startX, startY), + new Point2D.Float(endX, endY), + fractions, colors, + cycleMethod, colorSpace, + new AffineTransform()); + break; + + case RADIAL: + paint = + new RadialGradientPaint(new Point2D.Float(ctrX, ctrY), + radius, + new Point2D.Float(focusX, focusY), + fractions, colors, + cycleMethod, colorSpace, + new AffineTransform()); + break; + } + + switch (xformType) { + default: + case IDENTITY: + transform = new AffineTransform(); + break; + case TRANSLATE: + transform = AffineTransform.getTranslateInstance(2, 2); + break; + case SCALE: + transform = AffineTransform.getScaleInstance(1.2, 1.4); + break; + case SHEAR: + transform = AffineTransform.getShearInstance(0.1, 0.1); + break; + case ROTATE: + transform = AffineTransform.getRotateInstance(Math.PI / 4, + getWidth()/2, + getHeight()/2); + break; + } + } + + public void updatePaint() { + makeNewPaint(); + repaint(); + } + + private class MyMouseAdapter extends MouseAdapter { + @Override + public void mouseClicked(MouseEvent e) { + updatePoints(e.getX(), e.getY()); + } + + @Override + public void mouseDragged(MouseEvent e) { + updatePoints(e.getX(), e.getY()); + } + } + + public Dimension getPreferredSize() { + return new Dimension(400, 400); + } + } + + private class ControlsPanel extends JPanel implements ActionListener { + private JComboBox cmbPaint, cmbCycle, cmbSpace, cmbShape, cmbXform; + private JCheckBox cbAntialias, cbRender; + private JSpinner spinNumColors; + + private ControlsPanel() { + cmbPaint = createCombo(this, paintType); + cmbPaint.setSelectedIndex(1); + cmbCycle = createCombo(this, cycleMethod); + cmbSpace = createCombo(this, colorSpace); + cmbShape = createCombo(this, shapeType); + cmbXform = createCombo(this, xformType); + + int max = COLORS.length; + SpinnerNumberModel model = new SpinnerNumberModel(max, 2, max, 1); + spinNumColors = new JSpinner(model); + spinNumColors.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + numColors = ((Integer)spinNumColors.getValue()).intValue(); + gradientPanel.updatePaint(); + } + }); + add(spinNumColors); + + cbAntialias = createCheck(this, "Antialiasing"); + cbRender = createCheck(this, "Render Quality"); + } + + private JComboBox createCombo(JPanel panel, Enum e) { + JComboBox cmb = new JComboBox(); + cmb.setModel(new EnumComboBoxModel(e.getClass())); + cmb.addActionListener(this); + panel.add(cmb); + return cmb; + } + + private JCheckBox createCheck(JPanel panel, String name) { + JCheckBox cb = new JCheckBox(name); + cb.addActionListener(this); + panel.add(cb); + return cb; + } + + public void actionPerformed(ActionEvent e) { + Object source = e.getSource(); + + if (source == cmbPaint) { + paintType = (PaintType)cmbPaint.getSelectedItem(); + } else if (source == cmbCycle) { + cycleMethod = (CycleMethod)cmbCycle.getSelectedItem(); + } else if (source == cmbSpace) { + colorSpace = (ColorSpaceType)cmbSpace.getSelectedItem(); + } else if (source == cmbShape) { + shapeType = (ShapeType)cmbShape.getSelectedItem(); + } else if (source == cmbXform) { + xformType = (XformType)cmbXform.getSelectedItem(); + } else if (source == cbAntialias) { + antialiasHint = cbAntialias.isSelected() ? + RenderingHints.VALUE_ANTIALIAS_ON : + RenderingHints.VALUE_ANTIALIAS_OFF; + } else if (source == cbRender) { + renderHint = cbRender.isSelected() ? + RenderingHints.VALUE_RENDER_QUALITY : + RenderingHints.VALUE_RENDER_SPEED; + } + + gradientPanel.updatePaint(); + } + } + + private static class EnumComboBoxModel> + extends AbstractListModel + implements ComboBoxModel + { + private E selected = null; + private List list; + + public EnumComboBoxModel(Class en) { + EnumSet ens = EnumSet.allOf(en); + list = new ArrayList(ens); + selected = list.get(0); + } + + public int getSize() { + return list.size(); + } + + public E getElementAt(int index) { + return list.get(index); + } + + public void setSelectedItem(Object anItem) { + selected = (E)anItem; + this.fireContentsChanged(this, 0, getSize()); + } + + public E getSelectedItem() { + return selected; + } + } + + public static void main(String[] args) { + final JFrame frame = new JFrame("Multistop Gradient Demo"); + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + frame.dispose(); + } + }); + frame.add(new MultiGradientTest()); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } +}