/*
* $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.Color;
import java.awt.Font;
import java.net.URL;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.FontUIResource;
import javax.swing.plaf.IconUIResource;
import junit.framework.TestCase;
import org.jdesktop.swingx.test.XTestUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/**
* Unit test for <code>JXHeader</code>.
* <p>
*
* All test methods in this class are expected to pass.
*
* PENDING JW: some of the tests are dirty in that they rely on hidden (from the
* perspective of the JXHeader) implementation
* details of BasicHeaderUI (like how the different parts are implemented).
* What/How else to test that? A minor improvement could be reached by testing
* the ui delegate directly, as the children are visible to subclasses. So we
* would end up testing its contract to extension.
*
* @author Jeanette Winzenburg
*/
@RunWith(JUnit4.class)
public class JXHeaderTest extends TestCase {
//---------------- testing icon property, similar to #925
// except that it's not a property normally controlled by the ui defaults.
/**
* Test that header's icon property set to default value, if any.
*/
@Test
public void testIconDefaultA() {
Icon icon = XTestUtils.loadDefaultIcon();
assertNotNull("sanity: default icon loaded", icon);
UIManager.put("Header.defaultIcon", icon);
JXHeader header = new JXHeader();
try {
assertSame(icon, header.getIcon());
} finally {
UIManager.put("Header.defaultIcon", null);
}
}
/**
* Test that header's icon property set to default value, if any.
*/
@Test
public void testIconLabelDefaultB() {
Icon icon = XTestUtils.loadDefaultIcon();
assertNotNull("sanity: default icon loaded", icon);
UIManager.put("Header.defaultIcon", icon);
JXHeader header = new JXHeader();
try {
assertSame(icon, getIconLabel(header).getIcon());
} finally {
UIManager.put("Header.defaultIcon", null);
}
}
/**
* Test that header's icon property set to default value, if any.
*/
@Test
public void testIconLabelCustomC() {
Icon icon = XTestUtils.loadDefaultIcon();
assertNotNull("sanity: default icon loaded", icon);
JXHeader header = new JXHeader();
header.setIcon(icon);
SwingUtilities.updateComponentTreeUI(header);
assertSame(icon, header.getIcon());
assertSame(icon, getIconLabel(header).getIcon());
}
/**
* Test that header's icon property set to default value, if any.
*/
@Test
public void testIconLabelDefaultUpdateD() {
Icon uiDefault = UIManager.getIcon("Header.defaultIcon");
Icon icon = new IconUIResource(XTestUtils.loadDefaultIcon());
assertNotNull("sanity: default icon loaded", icon);
JXHeader header = new JXHeader();
header.setIcon(icon);
assertSame(icon, getIconLabel(header).getIcon());
SwingUtilities.updateComponentTreeUI(header);
assertSame(uiDefault, header.getIcon());
assertSame(uiDefault, getIconLabel(header).getIcon());
}
/*
* ----------- start testing #925-swingx
*
* there are several sub-issues: A - property on JXHeader must be set to
* defaults B - corresponding property on the appropriate child must be set C -
* (sanity) custom property must be kept on both header and child after laf
* change D - property on both header and child must be updated to defaults on
* laf change if not custom
*
* The critical (child) properties are those which have default ui properties
* controlled by the header, that is font and foreground of description and
* title label. So we have one group comprised of tests A-D for each of them,
* denoted by the respective postfix.
*
* PENDING JW: any way to auto-create this tests? The groups are created by c&p
* and replace ... error-prone and in fact, introduced testing errors. Which
* passed accidentally because the tested properties had the same default value
* (f.i. Color.BLACK or so).
*
*/
//-------- property: description font
/**
* Issue #925-swingx: custom properties lost on updateUI.
* Header property set to uimanager setting.
*/
@Test
public void testUpdateUIDescriptionFontA() {
Font color = UIManager.getFont("JXHeader.descriptionFont");
assertNotNull("sanity: description font available", color);
JXHeader header = new JXHeader();
assertEquals(color, header.getDescriptionFont());
}
/**
* Issue #925-swingx: custom properties lost on updateUI.
* Description label property set to uimanager setting.
*/
@Test
public void testUpdateUIDescriptionLabelFontB() {
Font color = UIManager.getFont("JXHeader.descriptionFont");
assertNotNull("sanity: description font available", color);
JXHeader header = new JXHeader();
assertEquals(color, getDescriptionLabel(header).getFont());
}
/**
* Issue #925-swingx: custom properties lost on updateUI.
* Description label custom property kept on LAF change.
*/
@Test
public void testUpdateUICustomDescriptionLabelFontC() {
Font color = new Font("serif", Font.BOLD, 36);
JXHeader header = new JXHeader();
header.setDescriptionFont(color);
assertEquals("sanity: description color taken", color, getDescriptionLabel(header).getFont());
SwingUtilities.updateComponentTreeUI(header);
assertEquals(color, header.getDescriptionFont());
assertEquals(color, getDescriptionLabel(header).getFont());
}
/**
* Issue #925-swingx: custom properties lost on updateUI.
* Title label property updated to ui default on laf change.
*/
@Test
public void testUpdateUIDefaultDescriptionLabelFontD() {
Font uiDefault = new FontUIResource("serif", Font.PLAIN, 36);
UIManager.put("JXHeader.descriptionFont", uiDefault);
Font color = new FontUIResource("serif", Font.ITALIC, 20);
JXHeader header = new JXHeader();
header.setDescriptionFont(color);
try {
assertEquals(color, header.getDescriptionFont());
assertEquals(color, getDescriptionLabel(header).getFont());
SwingUtilities.updateComponentTreeUI(header);
assertEquals(uiDefault, header.getDescriptionFont());
assertEquals(uiDefault, getDescriptionLabel(header).getFont());
} finally {
// reset custom property
UIManager.put("JXHeader.descriptionFont", null);
}
}
//-------------- property: description foreground
/**
* Issue #925-swingx: custom properties lost on updateUI.
* Header property set to uimanager setting.
*/
@Test
public void testUpdateUIDescriptionForegroundA() {
Color color = UIManager.getColor("JXHeader.descriptionForeground");
assertNotNull("sanity: description font available", color);
JXHeader header = new JXHeader();
assertEquals(color, header.getDescriptionForeground());
}
/**
* Issue #925-swingx: custom properties lost on updateUI.
* Description label property set to uimanager setting.
*/
@Test
public void testUpdateUIDescriptionLabelForegroundB() {
Color color = UIManager.getColor("JXHeader.descriptionForeground");
assertNotNull("sanity: description font available", color);
JXHeader header = new JXHeader();
assertEquals(color, getDescriptionLabel(header).getForeground());
}
/**
* Issue #925-swingx: custom properties lost on updateUI.
* Description label custom property kept on LAF change.
*/
@Test
public void testUpdateUICustomDescriptionLabelForegroundC() {
Color color = Color.PINK;
JXHeader header = new JXHeader();
header.setDescriptionForeground(color);
assertEquals("sanity: description color taken", color, getDescriptionLabel(header).getForeground());
SwingUtilities.updateComponentTreeUI(header);
assertEquals(color, header.getDescriptionForeground());
assertEquals(color, getDescriptionLabel(header).getForeground());
}
/**
* Issue #925-swingx: custom properties lost on updateUI.
* Description label property updated to ui default on laf change.
*/
@Test
public void testUpdateUIDefaultDescriptionLabelForegroundD() {
Color uiDefault = new ColorUIResource(Color.BLUE);
UIManager.put("JXHeader.descriptionForeground", uiDefault);
Color color = new ColorUIResource(Color.PINK);
JXHeader header = new JXHeader();
header.setDescriptionForeground(color);
SwingUtilities.updateComponentTreeUI(header);
try {
assertEquals(uiDefault, header.getDescriptionForeground());
assertEquals(uiDefault, getDescriptionLabel(header).getForeground());
} finally {
// reset custom property
UIManager.put("JXHeader.descriptionForeground", null);
}
}
//----------- property title foreground
/**
* Issue #925-swingx: custom properties lost on updateUI.
* Header property set to uimanager setting.
*/
@Test
public void testUpdateUITitleForegroundA() {
Color color = UIManager.getColor("JXHeader.titleForeground");
assertNotNull("sanity: title foreground available", color);
JXHeader header = new JXHeader();
assertEquals(color, header.getTitleForeground());
}
/**
* Issue #925-swingx: custom properties lost on updateUI.
* Title label property set to uimanager setting.
*/
@Test
public void testUpdateUITitleLabelForegroundB() {
Color color = UIManager.getColor("JXHeader.titleForeground");
assertNotNull("sanity: title foreground available", color);
JXHeader header = new JXHeader();
assertEquals(color, getTitleLabel(header).getForeground());
}
/**
* Issue #925-swingx: custom properties lost on updateUI.
* Title label custom property kept on LAF change.
*/
@Test
public void testUpdateUICustomTitleLabelForegroundC() {
Color color = Color.PINK;
JXHeader header = new JXHeader();
header.setTitleForeground(color);
assertEquals("sanity: title foreground taken", color, getTitleLabel(header).getForeground());
SwingUtilities.updateComponentTreeUI(header);
assertEquals(color, header.getTitleForeground());
assertEquals(color, getTitleLabel(header).getForeground());
}
/**
* Issue #925-swingx: custom properties lost on updateUI.
* Title label property updated to ui default on laf change.
*/
@Test
public void testUpdateUIDefaultTitleLabelForegroundD() {
Color uiDefault = new ColorUIResource(Color.BLUE);
UIManager.put("JXHeader.titleForeground", uiDefault);
Color color = new ColorUIResource(Color.PINK);
JXHeader header = new JXHeader();
header.setTitleForeground(color);
SwingUtilities.updateComponentTreeUI(header);
try {
assertEquals(uiDefault, header.getTitleForeground());
assertEquals(uiDefault, getTitleLabel(header).getForeground());
} finally {
// reset custom property
UIManager.put("JXHeader.titleForeground", null);
}
}
//---------- property: title font
/**
* Issue #925-swingx: custom properties lost on updateUI.
* Header property set to uimanager setting.
*/
@Test
public void testUpdateUITitleFontA() {
Font font = UIManager.getFont("JXHeader.titleFont");
assertNotNull("sanity: title font available", font);
JXHeader header = new JXHeader();
assertEquals(font, header.getTitleFont());
}
/**
* Issue #925-swingx: custom properties lost on updateUI.
* Test title label property set to UIManager prop
*/
@Test
public void testUpdateUITitleLabelFontB() {
Font font = UIManager.getFont("JXHeader.titleFont");
assertNotNull("sanity: title font available", font);
JXHeader header = new JXHeader();
assertEquals(font, getTitleLabel(header).getFont());
}
/**
* Issue #925-swingx: custom properties lost on updateUI.
* Title label custom property kept on LAF change.
*/
@Test
public void testUpdateUICustomTitleLabelFontC() {
Font color = new Font("serif", Font.BOLD, 36);
JXHeader header = new JXHeader();
header.setTitleFont(color);
assertEquals("sanity: title color taken", color, getTitleLabel(header).getFont());
SwingUtilities.updateComponentTreeUI(header);
assertEquals(color, header.getTitleFont());
assertEquals(color, getTitleLabel(header).getFont());
}
/**
* Issue #925-swingx: custom properties lost on updateUI.
* Title label property updated to ui default on laf change.
*/
@Test
public void testUpdateUIDefaultTitleLabelFontD() {
Font uiDefault = new FontUIResource("serif", Font.PLAIN, 36);
UIManager.put("JXHeader.titleFont", uiDefault);
Font color = new FontUIResource("serif", Font.ITALIC, 20);
JXHeader header = new JXHeader();
header.setTitleFont(color);
try {
assertEquals(color, header.getTitleFont());
assertEquals(color, getTitleLabel(header).getFont());
SwingUtilities.updateComponentTreeUI(header);
assertEquals(uiDefault, header.getTitleFont());
assertEquals(uiDefault, getTitleLabel(header).getFont());
} finally {
// reset custom property
UIManager.put("JXHeader.titleFont", null);
}
}
//--------- end testing #925
/**
* Issue #695-swingx: not-null default values break class invariant.
* Here initial empty constructor.
*/
@Test
public void testTitleSynchInitialEmpty() {
JXHeader header = new JXHeader();
assertEquals(header.getTitle(), getTitleLabel(header).getText());
}
/**
* Issue #695-swingx: not-null default values break invariant.
* Here: initial not-null explicitly set to null and updateUI (to
* simulate LF toggle).
*/
@Test
public void testTitleSynchUpdateUI() {
JXHeader header = new JXHeader("dummy", null);
header.setTitle(null);
header.updateUI();
assertEquals(header.getTitle(), getTitleLabel(header).getText());
}
/**
* Issue #695-swingx: not-null default values break invariant.
* Here: initial null params constructor.
*/
@Test
public void testTitleSynchInitialNull() {
JXHeader header = new JXHeader(null, null);
header.setTitle(null);
assertEquals(header.getTitle(), getTitleLabel(header).getText());
}
/**
* Issue #403-swingx: JXHeader doesn't show custom values.
*
*/
@Test
public void testIconSet() {
URL url = getClass().getResource("resources/images/wellTop.gif");
Icon icon = new ImageIcon(url);
assertNotNull(url);
JXHeader header = new JXHeader();
header.setIcon(icon);
// sanity: the property is set
assertEquals(icon, header.getIcon());
// fishing in the internals ... not really safe, there are 2 labels and 1 jxlabel ... indeed not safe!
assertEquals("the label's text must be equal to the headers title",
header.getIcon(), getIconLabel(header).getIcon());
}
/**
* Issue #403-swingx: JXHeader doesn't show custom values.
*
*/
@Test
public void testTitleSet() {
JXHeader header = new JXHeader();
String title = "customTitle";
header.setTitle(title);
// sanity: the property is set
assertEquals(title, header.getTitle());
assertEquals("the label's text must be equal to the headers title",
header.getTitle(), getTitleLabel(header).getText());
}
/**
* Issue #403-swingx: JXHeader doesn't show custom values.
* <p>
*
* Breaking if values are passed in the constructor.
*/
@Test
public void testTitleInContructor() {
String title = "customTitle";
JXHeader header = new JXHeader(title, null);
// sanity: the property is set
assertEquals(title, header.getTitle());
assertEquals("the label's text must be equal to the headers title",
header.getTitle(), getTitleLabel(header).getText());
}
/**
* Issue swingx-900 NPE when top level ancestor is not available, while "some" ancestor is.
*/
@Test
public void testNPE() {
JXHeader header = new JXHeader();
JPanel panel = new JPanel();
panel.add( header );
panel.setBounds( 0, 0, 200, 200 );
}
// ----------------- private helpers (dirty!)
/**
* Returns the label used for painting the title. Implemented to
* return the first child of type JLabel. <p>
*
* NOTE: this is fishing in implementation details of BasicHeaderUI!
*
* @return the label used for painting the title.
*/
private JLabel getTitleLabel(JXHeader header) {
for (int i = 0; i < header.getComponentCount(); i++) {
if (header.getComponent(i) instanceof JLabel) {
return (JLabel) header.getComponent(i);
}
}
return null;
}
/**
* Returns the label used for painting the description. Implemented to
* return the first child of type JXLabel. <p>
*
* NOTE: this is fishing in implementation details of BasicHeaderUI!
*
* @return the label used for painting the description.
*/
private JLabel getDescriptionLabel(JXHeader header) {
for (int i = 0; i < header.getComponentCount(); i++) {
if (header.getComponent(i) instanceof JXLabel) {
return (JLabel) header.getComponent(i);
}
}
return null;
}
/**
* Returns the label used for painting the icon. Implemented to
* return the second child of type JLabel and not of type JXLabel. <p>
*
* NOTE: this is fishing in implementation details of BasicHeaderUI!
*
* @return the label used for painting the icon.
*/
private JLabel getIconLabel(JXHeader header) {
JLabel label = null;
for (int i = 0; i < header.getComponentCount(); i++) {
if (header.getComponent(i) instanceof JLabel && !(header.getComponent(i) instanceof JXLabel)) {
boolean second = label != null;
label = (JLabel) header.getComponent(i);
if (second) {
return label;
}
}
}
return null;
}
@Override
protected void setUp() throws Exception {
// forcing load of headerAddon
new JXHeader();
}
}