/* * $Id$ * * Copyright 2006 Sun Microsystems, Inc., 4150 Network Circle, * Santa Clara, California 95054, U.S.A. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ package org.jdesktop.swingx; import java.awt.Component; import java.awt.GraphicsEnvironment; import java.awt.event.ActionEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Locale; import java.util.logging.Logger; import javax.swing.Action; import javax.swing.JComponent; import org.jdesktop.swingx.action.AbstractActionExt; import org.jdesktop.swingx.plaf.LookAndFeelAddons; import org.jdesktop.swingx.plaf.UIManagerExt; import org.jdesktop.swingx.search.PatternModel; import org.jdesktop.test.PropertyChangeReport; import org.jdesktop.test.TestUtils; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; /** * Test to expose known issues around <code>Locale</code> setting. * * Ideally, there would be at least one failing test method per open * Issue in the issue tracker. Plus additional failing test methods for * not fully specified or not yet decided upon features/behaviour. * * @author Jeanette Winzenburg */ @RunWith(JUnit4.class) public class XLocalizeTest extends InteractiveTestCase { @SuppressWarnings("all") private static final Logger LOG = Logger.getLogger(XLocalizeTest.class .getName()); private static final Locale A_LOCALE = Locale.FRENCH; private static final Locale OTHER_LOCALE = Locale.GERMAN; private Locale originalLocale; // test scope is static anyway... static { // force the addon to load LookAndFeelAddons.getAddon(); } public static void main(String[] args) { // setSystemLF(true); XLocalizeTest test = new XLocalizeTest(); try { test.runInteractiveTests(); // test.runInteractiveTests("interactive.*TwoTable.*"); } catch (Exception e) { System.err.println("exception when executing interactive tests:"); e.printStackTrace(); } } @Override protected void setUp() throws Exception { originalLocale = Locale.getDefault(); super.setUp(); } @Override protected void tearDown() throws Exception { Locale.setDefault(originalLocale); super.tearDown(); } /** * Issue #1394-swingx: missing properties for _en * * fix - added empty properties file named swingx_en */ @Test public void testEnglishLocaleSwingX() { String close = UIManagerExt.getString("Search.close", Locale.US); assertEquals("Close", close); } /** * Issue #1394-swingx: missing properties for _en * * fix - added empty properties file named TipOfTheDay_en */ @Test public void testEnglishLocaleTipOfTheDay() { new JXTipOfTheDay(); String close = UIManagerExt.getString("TipOfTheDay.closeText", Locale.US); assertEquals("Close", close); } /** * Issue #1394-swingx: missing properties for _en * * fix - added empty properties file named LoginPane_en */ @Test public void testEnglishLogin() { new JXLoginPane(); String close = UIManagerExt.getString("JXLoginPane.cancelString", Locale.US); assertEquals("Cancel", close); } /** * Issue #1394-swingx: missing properties for _en * * fix - added empty properties file named ErrorPane_en */ @Test public void testEnglishError() { new JXErrorPane(); String close = UIManagerExt.getString("JXErrorPane.ok_button_text", Locale.US); assertEquals("Close", close); } /** * Issue #1394-swingx: missing properties for _en * * fix - added empty properties file named SearchField_en */ @Test public void testEnglishSearchFile() { new JXSearchField(); String close = UIManagerExt.getString("SearchField.prompt", Locale.US); assertEquals("Search", close); } /** * test correct PropertyChangeNotification: must fire after * all internal state is set ... dooohhh. * * Here: test JXDialog. */ /** * test correct PropertyChangeNotification: must fire after * all internal state is set ... * * Here: test FindPanel */ @Test public void testLocaleDialogPropertyNotificationInListener() { // This test will not work in a headless configuration. if (GraphicsEnvironment.isHeadless()) { LOG.fine("cannot run localeDialogPropertyNotificationInListener - headless environment"); return; } final String prefix = PatternModel.SEARCH_PREFIX; final JXFindPanel findPanel = new JXFindPanel(); final JXDialog dialog = new JXDialog(findPanel); final String titleKey = AbstractPatternPanel.SEARCH_TITLE; // JW: arrrgghh ... dirty! Consequence of dirty initialization // of AbstractPatternPanel subclasses ... findPanel.addNotify(); String name = dialog.getTitle(); String uiValue = UIManagerExt.getString(prefix + titleKey, findPanel .getLocale()); // sanity assertNotNull(uiValue); assertEquals(name, uiValue); final Locale alternative = getAlternativeLocale(dialog); PropertyChangeListener report = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { // sanity // wrong assumption: find widgets name is changed as well // assertTrue("locale property changed, instead: " + evt.getPropertyName(), "locale".equals(evt.getPropertyName())); if (!"locale".equals(evt.getPropertyName())) return; String altUIValue = UIManagerExt.getString(prefix + titleKey, alternative); String altName = dialog.getTitle(); assertEquals("name must be updated before fire propertyChange", altUIValue, altName); }}; dialog.addPropertyChangeListener(report); PropertyChangeReport r = new PropertyChangeReport(); dialog.addPropertyChangeListener(r); dialog.setLocale(alternative); // sanity: guarantee that we got a locale change notification assertEquals(1, r.getEventCount("locale")); } /** * test correct PropertyChangeNotification: must fire after * all internal state is set ... dooohhh. * * Here: test FindBar. */ @Test public void testLocaleFindBarPropertyNotificationInListener() { final String prefix = PatternModel.SEARCH_PREFIX; final JXFindBar findPanel = new JXFindBar(); final String actionCommand = JXFindBar.FIND_NEXT_ACTION_COMMAND; // JW: arrrgghh ... dirty! Consequence of dirty initialization // of AbstractPatternPanel subclasses ... findPanel.addNotify(); final Action action = findPanel.getActionMap().get(actionCommand); String name = (String) action.getValue(Action.NAME); String uiValue = UIManagerExt.getString(prefix + actionCommand, findPanel .getLocale()); // sanity assertNotNull(uiValue); assertEquals(name, uiValue); final Locale alternative = getAlternativeLocale(findPanel); PropertyChangeListener report = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { // sanity // assertTrue("locale property changed", "locale".equals(evt.getPropertyName())); if (!"locale".equals(evt.getPropertyName())) return; String altUIValue = UIManagerExt.getString(prefix + actionCommand, alternative); String altName = (String) action.getValue(Action.NAME); assertEquals("name must be updated before fire propertyChange", altUIValue, altName); }}; PropertyChangeReport r = new PropertyChangeReport(); findPanel.addPropertyChangeListener(r); findPanel.setLocale(alternative); assertEquals(1, r.getEventCount("locale")); } /** * test correct PropertyChangeNotification: must fire after * all internal state is set ... * * Here: test FindPanel */ @Test public void testLocaleFindPanelPropertyNotificationInListener() { final String prefix = PatternModel.SEARCH_PREFIX; final JXFindPanel findPanel = new JXFindPanel(); final String actionCommand = AbstractPatternPanel.MATCH_ACTION_COMMAND; // JW: arrrgghh ... dirty! Consequence of dirty initialization // of AbstractPatternPanel subclasses ... findPanel.addNotify(); final Action action = findPanel.getActionMap().get(actionCommand); String name = (String) action.getValue(Action.NAME); String uiValue = UIManagerExt.getString(prefix + actionCommand, findPanel .getLocale()); // sanity assertNotNull(uiValue); assertEquals(name, uiValue); final Locale alternative = getAlternativeLocale(findPanel); PropertyChangeListener report = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { // sanity // wrong assumption: find widgets name is changed as well // assertTrue("locale property changed, instead: " + evt.getPropertyName(), "locale".equals(evt.getPropertyName())); if (!"locale".equals(evt.getPropertyName())) return; String altUIValue = UIManagerExt.getString(prefix + actionCommand, alternative); String altName = (String) action.getValue(Action.NAME); assertEquals("name must be updated before fire propertyChange", altUIValue, altName); }}; findPanel.addPropertyChangeListener(report); PropertyChangeReport r = new PropertyChangeReport(); findPanel.addPropertyChangeListener(r); findPanel.setLocale(alternative); assertEquals(1, r.getEventCount("locale")); } /** * test correct PropertyChangeNotification: must fire after * all internal state is set ... dooohhh. */ @Test public void testLocaleTablePropertyNotification() { String prefix = "JXTable."; JXTable table = new JXTable(10, 2); String actionCommand = JXTable.HORIZONTALSCROLL_ACTION_COMMAND; Action action = table.getActionMap().get(actionCommand); String name = (String) action.getValue(Action.NAME); String uiValue = UIManagerExt.getString(prefix + actionCommand, table .getLocale()); // sanity assertNotNull(uiValue); assertEquals(name, uiValue); Locale old = table.getLocale(); Locale alternative = getAlternativeLocale(table); PropertyChangeReport report = new PropertyChangeReport(); table.addPropertyChangeListener(report); table.setLocale(alternative); TestUtils.assertPropertyChangeEvent(report, "locale", old, alternative); } /** * test correct PropertyChangeNotification: must fire after * all internal state is set ... * * Here: test JXTable. */ @Test public void testLocaleTablePropertyNotificationInListener() { final String prefix = "JXTable."; final JXTable table = new JXTable(10, 2); final String actionCommand = JXTable.HORIZONTALSCROLL_ACTION_COMMAND; final Action action = table.getActionMap().get(actionCommand); String name = (String) action.getValue(Action.NAME); String uiValue = UIManagerExt.getString(prefix + actionCommand, table .getLocale()); // sanity assertNotNull(uiValue); assertEquals(name, uiValue); final Locale alternative = getAlternativeLocale(table); PropertyChangeListener report = new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { // sanity assertTrue("locale property changed", "locale".equals(evt.getPropertyName())); String altUIValue = UIManagerExt.getString(prefix + actionCommand, alternative); String altName = (String) action.getValue(Action.NAME); assertEquals("name must be updated before fire propertyChange", altUIValue, altName); }}; table.addPropertyChangeListener(report); table.setLocale(alternative); } private Locale getAlternativeLocale(final Component table) { Locale alternative = OTHER_LOCALE; if (alternative.getLanguage().equals(table.getLocale().getLanguage())) { alternative = A_LOCALE; } return alternative; } /** * Issue #635-swingx: find widgets must support dynamic localization * Here: test findPanel's actions (incomplete ..) */ @Test public void testLocaleFindPanel() { JXFindPanel panel = new JXFindPanel(); // JW: arrrgghh ... dirty! Consequence of dirty initialization // of AbstractPatternPanel subclasses ... panel.addNotify(); String prefix = PatternModel.SEARCH_PREFIX; assertLocaleActionUpdate(panel, prefix, AbstractPatternPanel.MATCH_ACTION_COMMAND); assertLocaleActionUpdate(panel, prefix, JXFindPanel.FIND_NEXT_ACTION_COMMAND); assertLocaleActionUpdate(panel, prefix, JXFindPanel.FIND_PREVIOUS_ACTION_COMMAND); } /** * Issue #459-swingx: JXTable setLocale doesn't update localized column * control properties. <p> * * Pass/fail expectation: * <ul> * <li> fails always with jdk5 independent of LookAndFeelAddon resource * bundle registration. * <li> fails with jdk6 and LookAndFeelAddon copy resource bundle values. * <li> passes with jdk6 and LookAndFeelAddon addResourceBundle. * </ul> */ @Test public void testLocaleColumnControl() { String prefix = "JXTable."; JXTable table = new JXTable(10, 2); assertLocaleActionUpdate(table, prefix, JXTable.HORIZONTALSCROLL_ACTION_COMMAND); assertLocaleActionUpdate(table, prefix, JXTable.PACKALL_ACTION_COMMAND); assertLocaleActionUpdate(table, prefix, JXTable.PACKSELECTED_ACTION_COMMAND); } private void assertLocaleActionUpdate(JComponent table, String prefix, String actionCommand) { Action action = table.getActionMap().get(actionCommand); String name = (String) action.getValue(Action.NAME); String uiValue = UIManagerExt.getString(prefix + actionCommand, table .getLocale()); // sanity assertNotNull(uiValue); assertEquals(name, uiValue); Locale alternative = OTHER_LOCALE; if (alternative.getLanguage().equals(table.getLocale().getLanguage())) { alternative = A_LOCALE; } table.setLocale(alternative); String altUIValue = UIManagerExt.getString(prefix + actionCommand, table.getLocale()); // sanity assertNotNull(altUIValue); // sanity to track unexpected failure during refactoring assertFalse("new uiValue must be different: " + uiValue + "/" + altUIValue, uiValue.equals(altUIValue)); String altName = (String) action.getValue(Action.NAME); // here are the real asserts assertFalse("new action name must be different: " + name + "/" + altName, name.equals(altName)); assertEquals(altName, altUIValue); } /** * Issue #466-swingx: locale-dependent values not accessible. This looks * like a side-effect of the first go on #159-swingx (not all values of * resourceBundle available). * <p> * * Could be core problem (in jdk5, fixed in jdk6) around classloader and * ResourceBundle: <a * href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4834404"> * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4834404 </a> * * */ @Test public void testGetLocaleUIDefaults() { String key = "JXTable.column.packAll"; Object alternativeValue = UIManagerExt.getString(key, OTHER_LOCALE); // sanity - the value must be available assertNotNull(alternativeValue); Object defaultValue = UIManagerExt.getString(key, A_LOCALE); // sanity - the value must be available assertNotNull(defaultValue); assertFalse("values must be different: " + defaultValue + "/" + alternativeValue, defaultValue.equals(alternativeValue)); } /** * Issue #459-swingx: columnControl properties not updated on locale setting. * */ public void interactiveLocaleColumnControl() { final JXTable table = new JXTable(10, 4); table.setColumnControlVisible(true); table.getColumnExt(0).setTitle(table.getLocale().getLanguage()); Action toggleLocale = new AbstractActionExt("toggleLocale") { @Override public void actionPerformed(ActionEvent e) { Locale old = table.getLocale(); table.setLocale(old == A_LOCALE ? OTHER_LOCALE : A_LOCALE); table.getColumnExt(0).setTitle(table.getLocale().getLanguage()); } }; JXFrame frame = wrapWithScrollingInFrame(table, "toggle locale on table - column control not updated"); addAction(frame, toggleLocale); frame.setVisible(true); } /** * Issue #459-swingx: columnControl properties not updated on locale setting. * * */ public void interactiveLocaleColumnControlTwoTables() { final JXTable table = new JXTable(10, 4); table.setColumnControlVisible(true); table.getColumnExt(0).setTitle(table.getLocale().getLanguage()); JXTable other = new JXTable(10, 4); other.setColumnControlVisible(true); other.setLocale(A_LOCALE); other.getColumnExt(0).setTitle(other.getLocale().getLanguage()); JXFrame frame = wrapWithScrollingInFrame(table, other, "different locals: de <--> vs fr"); addSearchModeToggle(frame); addMessage(frame, "Find panel/bar should be localized per-table"); frame.pack(); frame.setVisible(true); } }