Java tutorial
/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 1997-2009 Sun Microsystems, Inc. All rights reserved. Portions Copyrighted 2012 Daniel * Huss. * * The contents of this file are subject to the terms of either the GNU General Public License * Version 2 only ("GPL") or the Common Development and Distribution License("CDDL") (collectively, * the "License"). You may not use this file except in compliance with the License. You can obtain a * copy of the License at http://www.netbeans.org/cddl-gplv2.html or nbbuild/licenses/CDDL-GPL-2-CP. * See the License for the specific language governing permissions and limitations under the * License. When distributing the software, include this License Header Notice in each file and * include the License file at nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this particular file * as subject to the "Classpath" exception as provided by Sun in the GPL Version 2 section of the * License file that accompanied this code. If applicable, add the following below the License * Header, with the fields enclosed by brackets [] replaced by your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * Contributor(s): * * The Original Software is NetBeans. The Initial Developer of the Original Software is Sun * Microsystems, Inc. Portions Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. * * If you wish your version of this file to be governed by only the CDDL or only the GPL Version 2, * indicate your decision by adding "[Contributor] elects to include this software in this * distribution under the [CDDL or GPL Version 2] license." If you do not indicate a single choice * of license, a recipient has the option to distribute your version of this file under either the * CDDL, the GPL Version 2 or to extend the choice of license to its licensees as provided above. * However, if you add GPL Version 2 code and therefore, elected the GPL Version 2 license, then the * option applies only if the new code is made subject to such option by the copyright holder. */ package de.unentscheidbar.validation.swing.trigger; import java.awt.Color; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.Callable; import javax.swing.JColorChooser; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.JSpinner; import javax.swing.JTable; import javax.swing.table.DefaultTableModel; import javax.swing.text.BadLocationException; import javax.swing.text.JTextComponent; import javax.swing.text.PlainDocument; import junit.framework.Assert; import org.apache.commons.lang3.ClassUtils; import org.apache.commons.lang3.RandomStringUtils; import com.google.common.base.Equivalence; import com.google.common.base.Equivalence.Wrapper; import com.google.common.base.Throwables; public class ChangeTriggerTest extends TriggerTestCase<JComponent> { private final Map<Wrapper<?>, Callable<Void>> changers = new HashMap<>(); private final String exoticKey = "exotic"; private final String veryExoticKey = "veryExotic"; public static class ExoticComponent extends JPanel { private PlainDocument document = new PlainDocument(); public PlainDocument getDocument() { return document; } } public static class VeryExoticComponent extends JPanel { private static final long serialVersionUID = 1L; private Color value; public void setValue(Color value) { Object oldValue = this.value; this.value = value; if (value != oldValue) this.firePropertyChange("value", oldValue, value); setBackground(value); } public Color getValue() { return value; } } private final class ValueChanger implements Callable<Void> { private final JComponent c; public ValueChanger(JComponent c) { this.c = c; } @Override public Void call() throws Exception { if (c instanceof JTable) { changeTable((JTable) c); } else if (c instanceof JComboBox<?>) { changeCombo((JComboBox<?>) c); } else if (c instanceof JTextComponent) { changeText((JTextComponent) c); } else if (c instanceof JSlider) { changeSlider((JSlider) c); } else if (c instanceof JColorChooser) { changeColor((JColorChooser) c); } else if (c instanceof JSpinner) { changeSpinner((JSpinner) c); } else if (c instanceof VeryExoticComponent) { changeVeryExotic((VeryExoticComponent) c); } else if (c instanceof ExoticComponent) { changeExotic((ExoticComponent) c); } else { Assert.fail("Don't know how to change " + ClassUtils.getSimpleName(c, "NULL")); } return null; } private void changeExotic(ExoticComponent c2) { try { c2.getDocument().insertString(0, "_", null); } catch (BadLocationException e) { throw Throwables.propagate(e); } } private void changeTable(JTable c2) { DefaultTableModel tm = (DefaultTableModel) c2.getModel(); if (rnd.nextInt(3) == 0 || tm.getRowCount() == 0) { tm.addRow(new Object[] { String.valueOf(rnd.nextInt()), String.valueOf(rnd.nextInt()) }); } else if (rnd.nextBoolean()) { tm.removeRow(rnd.nextInt(tm.getRowCount())); } else { tm.setValueAt(UUID.randomUUID().toString(), rnd.nextInt(tm.getRowCount()), rnd.nextInt(tm.getColumnCount())); } } private void changeCombo(JComboBox<?> c2) { if (rnd.nextBoolean()) { Object newItem; while ((newItem = c2.getItemAt(rnd.nextInt(c2.getItemCount()))).equals(c2.getSelectedItem())) ; c2.setSelectedItem(newItem); } else if (rnd.nextBoolean()) { int newIndex; while ((newIndex = rnd.nextInt(c2.getItemCount())) == c2.getSelectedIndex()) ; c2.setSelectedIndex(newIndex); } else { c2.setSelectedItem(UUID.randomUUID().toString()); } } private void changeVeryExotic(VeryExoticComponent c2) { Color col; while ((col = new Color(rnd.nextInt())).equals(c2.getValue())) ; c2.setValue(col); } private void changeText(JTextComponent c2) { String text; while ((text = RandomStringUtils.randomAlphanumeric(100)).equals(c2.getText())) ; c2.setText(text); } private void changeSlider(JSlider c2) { int range = 1 + c2.getMaximum() - c2.getMinimum(); int v; while ((v = c2.getMinimum() + rnd.nextInt(range)) == c2.getValue()) ; c2.setValue(v); } private void changeColor(JColorChooser c2) { Color col; while ((col = new Color(rnd.nextInt())).equals(c2.getColor())) ; c2.setColor(col); } private void changeSpinner(JSpinner c2) { Object o = c2.getNextValue(); if (o == null) o = c2.getPreviousValue(); if (o == null) Assert.fail("Cannot change spinner, needs at least 2 valid values: " + c2.getModel()); c2.setValue(o); } } @Override protected void onSetUp() { gui.add(exoticKey, new ExoticComponent()); gui.add(veryExoticKey, new VeryExoticComponent()); changers.clear(); } private void putValueChanger(String id) { JComponent cmp = gui.<JComponent>get(id); changers.put(Equivalence.identity().wrap(cmp), new ValueChanger(cmp)); } @Override protected void provokeTrigger(Iterable<JComponent> components) { for (JComponent c : components) { Callable<Void> setter = changers.get(Equivalence.identity().wrap(c)); if (setter == null) { Assert.fail("No value changer for " + c); } runInEdt(setter); } drainEventQueue(); } @Override protected void doNotProvokeTrigger(Iterable<JComponent> components) { for (final JComponent c : components) { robot.focusAndWaitForFocusGain(c); robot.focusAndWaitForFocusGain(gui.get(dummyKey)); runInEdt(new Runnable() { @Override public void run() { Color col; while ((col = new Color(rnd.nextInt())).equals(c.getForeground())) ; c.setForeground(col); c.setBackground(col); } }); } } @Override protected Trigger<? super JComponent> getTriggerUnderTest(JComponent c) { if (rnd.nextBoolean()) { return Triggers.onChange(c); } else { return Triggers.onChange(c.getClass()); } } @Override protected List<JComponent> getObservableComponents() { List<JComponent> list = new ArrayList<>(); for (String key : new String[] { spinnerDateKey, spinnerListKey, spinnerNumberKey, colorChooserKey, textAreaKey, textFieldKey, sliderKey, comboKey, tableKey, exoticKey, veryExoticKey }) { list.add(gui.get(key)); putValueChanger(key); } return list; } }