diff --git a/src/share/classes/javax/swing/plaf/basic/BasicColorChooserUI.java b/src/share/classes/javax/swing/plaf/basic/BasicColorChooserUI.java
index acd141c1c4ad04b10d4329d1641b4c1564815290..f8c163d5d2d00054bed3ae11521c5d6353be18ab 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicColorChooserUI.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicColorChooserUI.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2010, Oracle and/or its affiliates. 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
@@ -113,7 +113,6 @@ public class BasicColorChooserUI extends ColorChooserUI
previewPanelHolder.setBorder(new TitledBorder(previewString));
}
previewPanelHolder.setInheritsPopupMenu(true);
- chooser.add(previewPanelHolder, BorderLayout.SOUTH);
installPreviewPanel();
chooser.applyComponentOrientation(c.getComponentOrientation());
@@ -126,13 +125,9 @@ public class BasicColorChooserUI extends ColorChooserUI
uninstallDefaultChoosers();
uninstallListeners();
+ uninstallPreviewPanel();
uninstallDefaults();
- previewPanelHolder.remove(previewPanel);
- if (previewPanel instanceof UIResource) {
- chooser.setPreviewPanel(null);
- }
-
previewPanelHolder = null;
previewPanel = null;
defaultChoosers = null;
@@ -143,29 +138,37 @@ public class BasicColorChooserUI extends ColorChooserUI
}
protected void installPreviewPanel() {
- if (previewPanel != null) {
- previewPanelHolder.remove(previewPanel);
- previewPanel.removeMouseListener(getHandler());
+ JComponent previewPanel = this.chooser.getPreviewPanel();
+ if (previewPanel == null) {
+ previewPanel = ColorChooserComponentFactory.getPreviewPanel();
}
-
- previewPanel = chooser.getPreviewPanel();
- Dimension layoutSize = new Dimension(); // fix for bug 4759306
- if (previewPanel != null) {
- layoutSize = new BorderLayout().minimumLayoutSize(previewPanel);
- if ((previewPanelHolder != null) && (chooser != null) &&
- (layoutSize.getWidth() + layoutSize.getHeight() == 0)) {
- chooser.remove(previewPanelHolder);
- return;
+ else {
+ Dimension size = new BorderLayout().minimumLayoutSize(previewPanel);
+ if ((size.width == 0) && (size.height == 0)) {
+ previewPanel = null;
}
}
- if (previewPanel == null || previewPanel instanceof UIResource) {
- previewPanel = ColorChooserComponentFactory.getPreviewPanel(); // get from table?
- chooser.setPreviewPanel(previewPanel);
+ this.previewPanel = previewPanel;
+ if (previewPanel != null) {
+ chooser.add(previewPanelHolder, BorderLayout.SOUTH);
+ previewPanel.setForeground(chooser.getColor());
+ previewPanelHolder.add(previewPanel);
+ previewPanel.addMouseListener(getHandler());
+ previewPanel.setInheritsPopupMenu(true);
}
- previewPanel.setForeground(chooser.getColor());
- previewPanelHolder.add(previewPanel);
- previewPanel.addMouseListener(getHandler());
- previewPanel.setInheritsPopupMenu(true);
+ }
+
+ /**
+ * Removes installed preview panel from the UI delegate.
+ *
+ * @since 1.7
+ */
+ protected void uninstallPreviewPanel() {
+ if (this.previewPanel != null) {
+ this.previewPanel.removeMouseListener(getHandler());
+ this.previewPanelHolder.remove(this.previewPanel);
+ }
+ this.chooser.remove(this.previewPanelHolder);
}
protected void installDefaults() {
@@ -209,7 +212,6 @@ public class BasicColorChooserUI extends ColorChooserUI
chooser.removePropertyChangeListener( propertyChangeListener );
chooser.getSelectionModel().removeChangeListener(previewListener);
previewListener = null;
- previewPanel.removeMouseListener(getHandler());
}
private void selectionChanged(ColorSelectionModel model) {
@@ -312,9 +314,8 @@ public class BasicColorChooserUI extends ColorChooserUI
}
}
else if (prop == JColorChooser.PREVIEW_PANEL_PROPERTY) {
- if (evt.getNewValue() != previewPanel) {
- installPreviewPanel();
- }
+ uninstallPreviewPanel();
+ installPreviewPanel();
}
else if (prop == JColorChooser.SELECTION_MODEL_PROPERTY) {
ColorSelectionModel oldModel = (ColorSelectionModel) evt.getOldValue();
@@ -352,5 +353,4 @@ public class BasicColorChooserUI extends ColorChooserUI
super("color");
}
}
-
}
diff --git a/src/share/classes/javax/swing/plaf/basic/BasicComboPopup.java b/src/share/classes/javax/swing/plaf/basic/BasicComboPopup.java
index 077c15b9d4a9c73e8fb092ed99fdccc42e03e580..803e4d01bda8dd082f56c9c76798a8c2c8eac6c8 100644
--- a/src/share/classes/javax/swing/plaf/basic/BasicComboPopup.java
+++ b/src/share/classes/javax/swing/plaf/basic/BasicComboPopup.java
@@ -202,8 +202,8 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup {
* Implementation of ComboPopup.show().
*/
public void show() {
+ comboBox.firePopupMenuWillBecomeVisible();
setListSelection(comboBox.getSelectedIndex());
-
Point location = getPopupLocation();
show( comboBox, location.x, location.y );
}
@@ -344,7 +344,8 @@ public class BasicComboPopup extends JPopupMenu implements ComboPopup {
protected void firePopupMenuWillBecomeVisible() {
super.firePopupMenuWillBecomeVisible();
- comboBox.firePopupMenuWillBecomeVisible();
+ // comboBox.firePopupMenuWillBecomeVisible() is called from BasicComboPopup.show() method
+ // to let the user change the popup menu from the PopupMenuListener.popupMenuWillBecomeVisible()
}
protected void firePopupMenuWillBecomeInvisible() {
diff --git a/src/share/classes/javax/swing/text/DefaultFormatter.java b/src/share/classes/javax/swing/text/DefaultFormatter.java
index d6e47c5fdf91b2892fd0320d22076745a84be168..75c3481678ef1a562c50216ce9478adc3781209c 100644
--- a/src/share/classes/javax/swing/text/DefaultFormatter.java
+++ b/src/share/classes/javax/swing/text/DefaultFormatter.java
@@ -570,7 +570,9 @@ public class DefaultFormatter extends JFormattedTextField.AbstractFormatter
direction = -1;
}
- if (getOverwriteMode() && rh.text != null) {
+ if (getOverwriteMode() && rh.text != null &&
+ getFormattedTextField().getSelectedText() == null)
+ {
rh.length = Math.min(Math.max(rh.length, rh.text.length()),
rh.fb.getDocument().getLength() - rh.offset);
}
diff --git a/src/share/classes/javax/swing/text/InternationalFormatter.java b/src/share/classes/javax/swing/text/InternationalFormatter.java
index c511b20e281f07191f92a66a21b53dc8ca332cf5..b49fed2e3ce54b0298c2fa0f9de2954935579b8c 100644
--- a/src/share/classes/javax/swing/text/InternationalFormatter.java
+++ b/src/share/classes/javax/swing/text/InternationalFormatter.java
@@ -622,18 +622,8 @@ public class InternationalFormatter extends DefaultFormatter {
/**
* Overriden in an attempt to honor the literals.
- *
- * If we do
- * not allow invalid values and are in overwrite mode, this does the
- * following for each character in the replacement range:
- *
- * - If the character is a literal, add it to the string to replace
- * with. If there is text to insert and it doesn't match the
- * literal, then insert the literal in the the middle of the insert
- * text. This allows you to either paste in literals or not and
- * get the same behavior.
- *
- If there is no text to insert, replace it with ' '.
- *
+ * If we do not allow invalid values and are in overwrite mode, this
+ * {@code rh.length} is corrected as to preserve trailing literals.
* If not in overwrite mode, and there is text to insert it is
* inserted at the next non literal index going forward. If there
* is only text to remove, it is removed from the next non literal
@@ -643,61 +633,27 @@ public class InternationalFormatter extends DefaultFormatter {
if (!getAllowsInvalid()) {
String text = rh.text;
int tl = (text != null) ? text.length() : 0;
+ JTextComponent c = getFormattedTextField();
- if (tl == 0 && rh.length == 1 && getFormattedTextField().
- getSelectionStart() != rh.offset) {
+ if (tl == 0 && rh.length == 1 && c.getSelectionStart() != rh.offset) {
// Backspace, adjust to actually delete next non-literal.
rh.offset = getNextNonliteralIndex(rh.offset, -1);
- }
- if (getOverwriteMode()) {
- StringBuffer replace = null;
-
- for (int counter = 0, textIndex = 0,
- max = Math.max(tl, rh.length); counter < max;
- counter++) {
- if (isLiteral(rh.offset + counter)) {
- if (replace != null) {
- replace.append(getLiteral(rh.offset +
- counter));
- }
- if (textIndex < tl && text.charAt(textIndex) ==
- getLiteral(rh.offset + counter)) {
- textIndex++;
- }
- else if (textIndex == 0) {
- rh.offset++;
- rh.length--;
- counter--;
- max--;
- }
- else if (replace == null) {
- replace = new StringBuffer(max);
- replace.append(text.substring(0, textIndex));
- replace.append(getLiteral(rh.offset +
- counter));
- }
- }
- else if (textIndex < tl) {
- if (replace != null) {
- replace.append(text.charAt(textIndex));
- }
- textIndex++;
- }
- else {
- // Nothing to replace it with, assume ' '
- if (replace == null) {
- replace = new StringBuffer(max);
- if (textIndex > 0) {
- replace.append(text.substring(0, textIndex));
- }
- }
- if (replace != null) {
- replace.append(' ');
- }
+ } else if (getOverwriteMode()) {
+ int pos = rh.offset;
+ int textPos = pos;
+ boolean overflown = false;
+
+ for (int i = 0; i < rh.length; i++) {
+ while (isLiteral(pos)) pos++;
+ if (pos >= string.length()) {
+ pos = textPos;
+ overflown = true;
+ break;
}
+ textPos = ++pos;
}
- if (replace != null) {
- rh.text = replace.toString();
+ if (overflown || c.getSelectedText() == null) {
+ rh.length = pos - rh.offset;
}
}
else if (tl > 0) {
diff --git a/test/java/beans/XMLEncoder/Test4631471.java b/test/java/beans/XMLEncoder/Test4631471.java
index 9c67e60e3d981a74c43bc43e48dbfb57ac684332..0b3b107f7c69dde0b7ea6e5963b483f5a4929792 100644
--- a/test/java/beans/XMLEncoder/Test4631471.java
+++ b/test/java/beans/XMLEncoder/Test4631471.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. 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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4631471
+ * @bug 4631471 6972468
* @summary Tests DefaultTreeModel encoding
* @author Sergey Malenkov, Mark Davidson
*/
@@ -37,6 +37,12 @@ import javax.swing.tree.TreeNode;
public abstract class Test4631471 extends AbstractTest {
public static void main(String[] args) throws Exception {
+ main();
+ System.setSecurityManager(new SecurityManager());
+ main();
+ }
+
+ private static void main() throws Exception {
// the DefaultMutableTreeNode will archive correctly
new Test4631471() {
protected Object getObject() {
diff --git a/test/java/beans/XMLEncoder/Test4903007.java b/test/java/beans/XMLEncoder/Test4903007.java
index 82583720934be58f8ab09011c5cd933647aebf95..02ba9a6a939414e71e00ddbfacbd1059bfed61e4 100644
--- a/test/java/beans/XMLEncoder/Test4903007.java
+++ b/test/java/beans/XMLEncoder/Test4903007.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. 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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 4903007
+ * @bug 4903007 6972468
* @summary Tests encoding of container with boxes and BoxLayout
* @author Sergey Malenkov, Mark Davidson
*/
@@ -36,7 +36,7 @@ import javax.swing.JPanel;
public class Test4903007 extends AbstractTest {
public static void main(String[] args) throws Exception {
- new Test4903007().test(false); // TODO: could not encode with security manager
+ new Test4903007().test(true);
}
protected JPanel getObject() {
diff --git a/test/java/beans/XMLEncoder/javax_swing_JLayeredPane.java b/test/java/beans/XMLEncoder/javax_swing_JLayeredPane.java
index 05c90ba15dc9e77a9c3dcbd8b8a10d74d37e02ad..1e41bc41e7bccbefa20b30c3371b7aea31d21949 100644
--- a/test/java/beans/XMLEncoder/javax_swing_JLayeredPane.java
+++ b/test/java/beans/XMLEncoder/javax_swing_JLayeredPane.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. 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
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 5023552
+ * @bug 5023552 6972468
* @summary Tests JLayeredPane encoding
* @author Sergey Malenkov
*/
@@ -35,7 +35,7 @@ import javax.swing.JPanel;
public final class javax_swing_JLayeredPane extends AbstractTest {
public static void main(String[] args) {
- new javax_swing_JLayeredPane().test(false); // TODO: could not encode with security manager
+ new javax_swing_JLayeredPane().test(true);
}
private static void init(JLayeredPane pane, int layer, int x, int y, int w, int h, Color color) {
diff --git a/test/javax/swing/JColorChooser/Test6199676.java b/test/javax/swing/JColorChooser/Test6199676.java
new file mode 100644
index 0000000000000000000000000000000000000000..19bb68b49005cd5cb68f2b1d24c71fbc0f6a3160
--- /dev/null
+++ b/test/javax/swing/JColorChooser/Test6199676.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 6199676
+ * @summary Tests preview panel after L&F changing
+ * @author Sergey Malenkov
+ */
+
+import java.awt.Component;
+import java.awt.Container;
+import javax.swing.JColorChooser;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.UIManager.LookAndFeelInfo;
+
+public class Test6199676 implements Runnable {
+ public static void main(String[] args) {
+ SwingUtilities.invokeLater(new Test6199676());
+ }
+
+ private static void exit(String error) {
+ if (error != null) {
+ System.err.println(error);
+ System.exit(1);
+ }
+ else {
+ System.exit(0);
+ }
+ }
+
+ private static Component getPreview(Container container) {
+ String name = "ColorChooser.previewPanelHolder";
+ for (Component component : container.getComponents()) {
+ if (!name.equals(component.getName())) {
+ component = (component instanceof Container)
+ ? getPreview((Container) component)
+ : null;
+ }
+ if (component instanceof Container) {
+ container = (Container) component;
+ return 1 == container.getComponentCount()
+ ? container.getComponent(0)
+ : null;
+ }
+ }
+ return null;
+ }
+
+ private static boolean isShowing(Component component) {
+ return (component != null) && component.isShowing();
+ }
+
+ private int index;
+ private boolean updated;
+ private JColorChooser chooser;
+
+ public synchronized void run() {
+ if (this.chooser == null) {
+ this.chooser = new JColorChooser();
+
+ JFrame frame = new JFrame(getClass().getName());
+ frame.add(this.chooser);
+ frame.setVisible(true);
+ }
+ else if (this.updated) {
+ if (isShowing(this.chooser.getPreviewPanel())) {
+ exit("custom preview panel is showing");
+ }
+ exit(null);
+ }
+ else {
+ Component component = this.chooser.getPreviewPanel();
+ if (component == null) {
+ component = getPreview(this.chooser);
+ }
+ if (!isShowing(component)) {
+ exit("default preview panel is not showing");
+ }
+ this.updated = true;
+ this.chooser.setPreviewPanel(new JPanel());
+ }
+ LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels();
+ LookAndFeelInfo info = infos[++this.index % infos.length];
+ try {
+ UIManager.setLookAndFeel(info.getClassName());
+ }
+ catch (Exception exception) {
+ exit("could not change L&F");
+ }
+ SwingUtilities.updateComponentTreeUI(this.chooser);
+ SwingUtilities.invokeLater(this);
+ }
+}
diff --git a/test/javax/swing/JComboBox/4743225/bug4743225.java b/test/javax/swing/JComboBox/4743225/bug4743225.java
new file mode 100644
index 0000000000000000000000000000000000000000..2a41b3075acf97dbe9f348f2598a592598562517
--- /dev/null
+++ b/test/javax/swing/JComboBox/4743225/bug4743225.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 4743225
+ * @summary Size of JComboBox list is wrong when list is populated via PopupMenuListener
+ * @author Alexander Potochkin
+ */
+
+import sun.awt.SunToolkit;
+
+import javax.accessibility.AccessibleContext;
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+import javax.swing.event.PopupMenuEvent;
+import javax.swing.event.PopupMenuListener;
+import javax.swing.plaf.basic.BasicComboPopup;
+import java.awt.FlowLayout;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.Toolkit;
+import java.awt.event.InputEvent;
+
+public class bug4743225 extends JFrame {
+
+ private static JComboBox cb;
+ private static volatile boolean flag;
+
+ public bug4743225() {
+ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ setLayout(new FlowLayout());
+ cb = new JComboBox(new Object[] {"one", "two", "three"});
+ cb.addPopupMenuListener(new PopupMenuListener() {
+ public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
+ cb.addItem("Test");
+ }
+
+ public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
+ }
+
+ public void popupMenuCanceled(PopupMenuEvent e) {
+ }
+ });
+ add(cb);
+ pack();
+ }
+
+ public static BasicComboPopup getPopup() {
+ AccessibleContext c = cb.getAccessibleContext();
+ for(int i = 0; i < c.getAccessibleChildrenCount(); i ++) {
+ if (c.getAccessibleChild(i) instanceof BasicComboPopup) {
+ return (BasicComboPopup) c.getAccessibleChild(i);
+ }
+ }
+ throw new AssertionError("No BasicComboPopup found");
+ }
+
+ public static void main(String... args) throws Exception {
+
+ Robot robot = new Robot();
+ robot.setAutoDelay(20);
+ SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ new bug4743225().setVisible(true);
+ }
+ });
+ toolkit.realSync();
+
+ // calling this method from main thread is ok
+ Point point = cb.getLocationOnScreen();
+ robot.mouseMove(point.x + 10, point.y + 10);
+ robot.mousePress(InputEvent.BUTTON1_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_MASK);
+ toolkit.realSync();
+
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ if(getPopup().getList().getLastVisibleIndex() == 3) {
+ flag = true;
+ }
+ }
+ });
+
+ if (!flag) {
+ throw new RuntimeException("The ComboBox popup wasn't correctly updated");
+ }
+ }
+}
diff --git a/test/javax/swing/JFormattedTextField/Test6462562.java b/test/javax/swing/JFormattedTextField/Test6462562.java
new file mode 100644
index 0000000000000000000000000000000000000000..0696a016fba475ebced6f6147ec05919c4907ac1
--- /dev/null
+++ b/test/javax/swing/JFormattedTextField/Test6462562.java
@@ -0,0 +1,360 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. 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 6462562
+ @summary Tests text input into JFormattedTextField
+ with an InternationalFormatter
+ @author Peter Zhelezniakov
+ @run main Test6462562
+*/
+
+import java.awt.event.ActionEvent;
+import java.text.DateFormat;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import javax.swing.Action;
+import javax.swing.JFormattedTextField;
+import javax.swing.SwingUtilities;
+import javax.swing.text.Caret;
+import javax.swing.text.DateFormatter;
+import javax.swing.text.DefaultEditorKit;
+import javax.swing.text.InternationalFormatter;
+import javax.swing.text.NumberFormatter;
+
+
+public class Test6462562
+{
+ static final String BACKSPACE = new String("backspace");
+ static final String DELETE = new String("delete");
+
+ boolean failed = false;
+
+ void test() {
+ testPercentFormat();
+ testCurrencyFormat();
+ testIntegerFormat();
+ testDateFormat();
+
+ if (failed) {
+ throw new RuntimeException("Some testcases failed, see output above");
+ }
+ System.err.println("(-; All testcases passed ;-)");
+ }
+
+ TestFormattedTextField create(NumberFormat format) {
+ format.setMaximumFractionDigits(0);
+ NumberFormatter fmt = new NumberFormatter(format);
+ return new TestFormattedTextField(fmt);
+ }
+
+ TestFormattedTextField create(DateFormat format) {
+ DateFormatter fmt = new DateFormatter(format);
+ return new TestFormattedTextField(fmt);
+ }
+
+ public static void main(String[] args) throws Exception {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ public void run() {
+ new Test6462562().test();
+ }
+ });
+ }
+
+ class TestFormattedTextField extends JFormattedTextField
+ {
+ final Action backspace;
+ final Action delete;
+ final Action insert;
+
+ final ActionEvent dummyEvent;
+
+ public TestFormattedTextField(InternationalFormatter fmt) {
+ super(fmt);
+ fmt.setAllowsInvalid(false);
+ fmt.setOverwriteMode(true);
+
+ backspace = getActionMap().get(DefaultEditorKit.deletePrevCharAction);
+ delete = getActionMap().get(DefaultEditorKit.deleteNextCharAction);
+ insert = getActionMap().get(DefaultEditorKit.insertContentAction);
+ dummyEvent = new ActionEvent(this, 0, null);
+ }
+
+ public boolean test(int pos, int selectionLength, String todo, Object expectedResult) {
+ Object v0 = getValue();
+
+ Caret caret = getCaret();
+ caret.setDot(pos);
+ if (selectionLength > 0) {
+ caret.moveDot(pos + selectionLength);
+ }
+
+ String desc = todo;
+ if (todo == BACKSPACE) {
+ backspace.actionPerformed(dummyEvent);
+ } else if (todo == DELETE) {
+ delete.actionPerformed(dummyEvent);
+ } else {
+ desc = "insert('" + todo + "')";
+ insert.actionPerformed(new ActionEvent(this, 0, todo));
+ }
+
+ try {
+ commitEdit();
+ } catch (ParseException e) {
+ e.printStackTrace();
+ failed = true;
+ return false;
+ }
+
+ Object v1 = getValue();
+ if (! v1.equals(expectedResult)) {
+ System.err.printf("Failure: value='%s', mark=%d, dot=%d, action=%s\n",
+ v0, pos, pos + selectionLength, desc);
+ System.err.printf(" Result: '%s', expected: '%s'\n", v1, expectedResult);
+ failed = true;
+ return false;
+ }
+ return true;
+ }
+ }
+
+ void testPercentFormat() {
+ NumberFormat format = NumberFormat.getPercentInstance(Locale.US);
+ TestFormattedTextField ftf = create(format);
+ ftf.setValue(.34);
+
+ System.err.println("Testing NumberFormat.getPercentInstance(Locale.US)");
+
+ // test inserting individual characters
+ ftf.test(0, 0, "1", .14);
+ ftf.test(2, 0, "2", 1.42);
+ ftf.test(1, 0, "0", 1.02);
+
+ // test inserting several characters at once - e.g. from clipboard
+ ftf.test(0, 0, "1024", 10.24);
+ ftf.test(3, 0, "333", 103.33);
+ ftf.test(6, 0, "77", 10333.77);
+ ftf.test(4, 0, "99", 10399.77);
+ ftf.test(6, 0, "00", 10390.07);
+
+ // test inserting strings that contain some formatting
+ ftf.test(0, 0, "2,2", 2290.07);
+ ftf.test(2, 0, "2,2", 222.27);
+ ftf.test(4, 0, "2,2", 222.22);
+ ftf.test(6, 0, "33,33", 2222233.33);
+
+ // test delete
+ ftf.test(0, 0, DELETE, 222233.33);
+ ftf.test(10, 0, DELETE, 222233.33);
+ ftf.test(5, 0, DELETE, 22223.33);
+ ftf.test(6, 0, DELETE, 2222.33);
+
+ // test backspace
+ ftf.test(0, 0, BACKSPACE, 2222.33);
+ ftf.test(7, 0, BACKSPACE, 222.23);
+ ftf.test(4, 0, BACKSPACE, 22.23);
+ ftf.test(2, 0, BACKSPACE, 2.23);
+
+ // test replacing selection
+ ftf.test(0, 1, "555", 555.23);
+ ftf.test(4, 2, "555", 5555.55);
+ ftf.test(2, 3, "1", 551.55);
+ ftf.test(3, 2, "6", 55.65);
+ ftf.test(4, 2, "12", 556.12);
+ ftf.test(3, 4, "0", 5.5);
+ ftf.test(0, 3, "111222333444555", 1112223334445.55);
+
+ // test deleting selection
+ ftf.test(0, 2, DELETE, 12223334445.55);
+ ftf.test(0, 3, BACKSPACE, 223334445.55);
+ ftf.test(12, 2, DELETE, 2233344.45);
+ ftf.test(9, 2, BACKSPACE, 22333.44);
+ ftf.test(4, 3, DELETE, 223.44);
+ ftf.test(1, 2, BACKSPACE, 23.44);
+ ftf.test(3, 3, DELETE, .23);
+ ftf.test(1, 2, BACKSPACE, .02);
+ }
+
+ void testCurrencyFormat() {
+ NumberFormat format = NumberFormat.getCurrencyInstance(Locale.US);
+ TestFormattedTextField ftf = create(format);
+ ftf.setValue(56L);
+
+ System.err.println("Testing NumberFormat.getCurrencyInstance(Locale.US)");
+
+ // test inserting individual characters
+ ftf.test(1, 0, "1", 16L);
+ ftf.test(3, 0, "2", 162L);
+ ftf.test(2, 0, "0", 102L);
+
+ // test inserting several characters at once - e.g. from clipboard
+ ftf.test(1, 0, "1024", 1024L);
+ ftf.test(4, 0, "333", 10333L);
+ ftf.test(7, 0, "77", 1033377L);
+ ftf.test(5, 0, "99", 1039977L);
+ ftf.test(7, 0, "00", 1039007L);
+
+ // test inserting strings that contain some formatting
+ ftf.test(1, 0, "2,2", 229007L);
+ ftf.test(3, 0, "2,2", 22227L);
+ ftf.test(4, 0, "2,2", 2222L);
+ ftf.test(6, 0, "33,33", 22223333L);
+
+ // test delete
+ ftf.test(1, 0, DELETE, 2223333L);
+ ftf.test(10, 0, DELETE, 2223333L);
+ ftf.test(5, 0, DELETE, 222333L);
+ ftf.test(5, 0, DELETE, 22233L);
+
+ // test backspace
+ ftf.test(1, 0, BACKSPACE, 22233L);
+ ftf.test(7, 0, BACKSPACE, 2223L);
+ ftf.test(4, 0, BACKSPACE, 223L);
+ ftf.test(2, 0, BACKSPACE, 23L);
+
+ // test replacing selection
+ ftf.test(1, 1, "555", 5553L);
+ ftf.test(4, 2, "555", 55555L);
+ ftf.test(2, 3, "1", 5155L);
+ ftf.test(3, 2, "6", 565L);
+ ftf.test(1, 3, "111222333444555", 111222333444555L);
+
+ // test deleting selection
+ ftf.test(1, 2, DELETE, 1222333444555L);
+ ftf.test(1, 3, BACKSPACE, 22333444555L);
+ ftf.test(13, 2, DELETE, 223334445L);
+ ftf.test(10, 2, BACKSPACE, 2233344L);
+ ftf.test(4, 4, DELETE, 2244L);
+ ftf.test(1, 4, BACKSPACE, 4L);
+ }
+
+ void testIntegerFormat() {
+ NumberFormat format = NumberFormat.getIntegerInstance(Locale.US);
+ TestFormattedTextField ftf = create(format);
+ ftf.setValue(56L);
+
+ System.err.println("Testing NumberFormat.getIntegerInstance(Locale.US)");
+
+ // test inserting individual characters
+ ftf.test(0, 0, "1", 16L);
+ ftf.test(2, 0, "2", 162L);
+ ftf.test(1, 0, "0", 102L);
+
+ // test inserting several characters at once - e.g. from clipboard
+ ftf.test(0, 0, "1024", 1024L);
+ ftf.test(3, 0, "333", 10333L);
+ ftf.test(6, 0, "77", 1033377L);
+ ftf.test(4, 0, "99", 1039977L);
+ ftf.test(6, 0, "00", 1039007L);
+
+ // test inserting strings that contain some formatting
+ ftf.test(0, 0, "2,2", 229007L);
+ ftf.test(2, 0, "2,2", 22227L);
+ ftf.test(3, 0, "2,2", 2222L);
+ ftf.test(5, 0, "33,33", 22223333L);
+
+ // test delete
+ ftf.test(0, 0, DELETE, 2223333L);
+ ftf.test(9, 0, DELETE, 2223333L);
+ ftf.test(4, 0, DELETE, 222333L);
+ ftf.test(4, 0, DELETE, 22233L);
+
+ // test backspace
+ ftf.test(0, 0, BACKSPACE, 22233L);
+ ftf.test(6, 0, BACKSPACE, 2223L);
+ ftf.test(2, 0, BACKSPACE, 223L);
+ ftf.test(2, 0, BACKSPACE, 23L);
+
+ // test replacing selection
+ ftf.test(0, 1, "555", 5553L);
+ ftf.test(3, 2, "555", 55555L);
+ ftf.test(1, 3, "1", 5155L);
+ ftf.test(2, 2, "6", 565L);
+ ftf.test(0, 3, "111222333444555", 111222333444555L);
+
+ // test deleting selection
+ ftf.test(0, 2, DELETE, 1222333444555L);
+ ftf.test(0, 3, BACKSPACE, 22333444555L);
+ ftf.test(12, 2, DELETE, 223334445L);
+ ftf.test(9, 2, BACKSPACE, 2233344L);
+ ftf.test(3, 4, DELETE, 2244L);
+ ftf.test(0, 4, BACKSPACE, 4L);
+ }
+
+ Date date(DateFormat format, String spec) {
+ try {
+ return format.parse(spec);
+ } catch (ParseException e) {
+ throw new Error("Error in test");
+ }
+ }
+
+ void testDateFormat() {
+ DateFormat format = new SimpleDateFormat("MM/dd/yyyy", Locale.US);
+ TestFormattedTextField ftf = create(format);
+ ftf.setValue(date(format, "12/05/2005"));
+
+ System.err.println("Testing SimpleDateFormat(\"MM/dd/yyyy\", Locale.US)");
+
+ // test inserting individual characters
+ ftf.test(0, 0, "0", date(format, "02/05/2005"));
+ ftf.test(4, 0, "4", date(format, "02/04/2005"));
+ ftf.test(6, 0, "1", date(format, "02/04/1005"));
+ ftf.test(9, 0, "9", date(format, "02/04/1009"));
+
+ // test inserting several characters at once - e.g. from clipboard
+ ftf.test(0, 0, "11", date(format, "11/04/1009"));
+ ftf.test(3, 0, "23", date(format, "11/23/1009"));
+ ftf.test(6, 0, "191", date(format, "11/23/1919"));
+
+ // test delete
+ ftf.test(0, 0, DELETE, date(format, "01/23/1919"));
+ ftf.test(3, 0, DELETE, date(format, "01/03/1919"));
+ ftf.test(10, 0, DELETE, date(format, "01/03/1919"));
+ ftf.test(1, 0, DELETE, date(format, "12/03/1918"));
+ ftf.test(4, 0, DELETE, date(format, "11/30/1918"));
+
+ // test backspace
+ ftf.test(0, 0, BACKSPACE, date(format, "11/30/1918"));
+ ftf.test(1, 0, BACKSPACE, date(format, "01/30/1918"));
+ ftf.test(4, 0, BACKSPACE, date(format, "12/31/1917"));
+ ftf.test(10, 0, BACKSPACE, date(format, "12/31/0191"));
+ ftf.test(3, 0, BACKSPACE, date(format, "01/31/0191"));
+ ftf.test(5, 0, BACKSPACE, date(format, "01/03/0191"));
+
+ // test replacing selection
+ ftf.test(0, 1, "1", date(format, "11/03/0191"));
+ ftf.test(3, 1, "2", date(format, "11/23/0191"));
+ ftf.test(6, 2, "20", date(format, "11/23/2091"));
+
+ // test deleting selection
+ ftf.test(0, 1, BACKSPACE, date(format, "01/23/2091"));
+ ftf.test(3, 1, DELETE, date(format, "01/03/2091"));
+ ftf.test(6, 2, BACKSPACE, date(format, "01/03/0091"));
+ ftf.test(8, 1, DELETE, date(format, "01/03/0001"));
+ }
+}