package jmri.jmrit.display; import static jmri.util.JUnitSwingUtil.assertImageNinePoints; import static jmri.util.JUnitSwingUtil.assertPixel; import static jmri.util.JUnitSwingUtil.getDisplayedContent; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertTrue; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.Point; import java.awt.event.ActionEvent; import java.io.File; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.SwingUtilities; import jmri.*; import jmri.jmrit.catalog.NamedIcon; import jmri.util.JUnitSwingUtil; import jmri.util.JUnitSwingUtil.Pixel; import jmri.util.JUnitUtil; import jmri.util.JmriJFrame; import jmri.util.junit.annotations.DisabledIfHeadless; import org.junit.jupiter.api.*; import org.netbeans.jemmy.ComponentChooser; import org.netbeans.jemmy.QueueTool; import org.netbeans.jemmy.operators.JLabelOperator; /** * Test of PositionableLabel *

* Includes tests *

* along with some combinations * * @author Bob Jacobsen Copyright 2015 */ @DisabledIfHeadless public class PositionableLabelTest extends PositionableTestBase { protected PositionableLabel to = null; @Test public void testSmallPanel() throws Positionable.DuplicateIdException { JFrame jf = new JFrame(); JPanel jpanel = new JPanel(); jf.getContentPane().add(jpanel); jpanel.setPreferredSize(new Dimension(200, 200)); jpanel.setLayout(null); // test button in upper left JButton doButton = new JButton("change label"); doButton.addActionListener((ActionEvent e) -> { if (to.getText().equals("one")) { to.setText("two"); } else { to.setText("one"); } }); doButton.setBounds(0, 0, 120, 40); jpanel.add(doButton); to = new PositionableLabel("one", editor); to.setBounds(80, 80, 40, 40); editor.putItem(to); to.setDisplayLevel(Editor.LABELS); Assertions.assertEquals(Editor.LABELS, to.getDisplayLevel(), "Display Level "); jpanel.add(to); jf.pack(); jf.setVisible(true); } // Load file showing four labels with backgrounds and make sure they have right color // The file used was written with 4.0.1, and behaves as expected from panel names @Test public void testBackgroundColorFile() throws JmriException { // make four windows assertTrue(InstanceManager.getDefault(ConfigureManager.class) .load(new File("java/test/jmri/jmrit/display/configurexml/valid/backgrounds.xml"))); new QueueTool().waitEmpty(); // Find color in label by frame name int color1 = getColor("F Bkg none, label Bkg none"); // transparent background int color2 = getColor("F Bkg blue, label Bkg none"); // transparent background shows blue int color3 = getColor("F Bkg none, label Bkg yellow"); // yellow int color4 = getColor("F Bkg blue, label Bkg yellow"); assertPixel("F Bkg none, label Bkg none color", Pixel.TRANSPARENT, color1); // transparent shows neutral frame background assertPixel("F Bkg blue, label Bkg none color", Pixel.TRANSPARENT, color2); // no blue, looking at transparent label assertPixel("F Bkg none, label Bkg yellow color", Pixel.YELLOW, color3); assertPixel("F Bkg blue, label Bkg yellow color", Pixel.YELLOW, color4); } int getColor(String name) { new QueueTool().waitEmpty(); // Find window by name JmriJFrame frame = JmriJFrame.getFrame(name); assertNotNull( frame, () -> "frame: " + name); // find label within that JLabel jl = JLabelOperator.findJLabel(frame, new ComponentChooser() { @Override public boolean checkComponent(Component comp) { if (comp == null) { return false; } else { return (comp instanceof JLabel); } } @Override public String getDescription() { return "find the first JLabel"; } }); int[] content = JUnitSwingUtil.getDisplayedContent(jl, jl.getSize(), new Point(0, 0)); int color = content[0]; // Unless in demo mode, close table window if (System.getProperty("jmri.demo", "false").equals("false")) { frame.setVisible(false); } return color; } // Explicit tests of PositionableLabel features @Test public void testDisplayTransparent() { JFrame f = new JFrame(); f.getContentPane().setBackground(Color.blue); f.setUndecorated(true); // skip frame decoration, which can force a min size. NamedIcon icon = new NamedIcon("resources/icons/redTransparentBox.gif", "box"); // 13x13 PositionableLabel label = new PositionableLabel(icon, editor); f.add(label); f.pack(); new QueueTool().waitEmpty(); assertEquals( new Dimension(13, 13).toString(), label.getSize().toString(), "icon size"); int[] val = getDisplayedContent(label, label.getSize(), new Point(0, 0)); assertEquals( 13 * 13, val.length, "icon arraylength"); assertImageNinePoints("icon", val, label.getSize(), Pixel.RED, Pixel.RED, Pixel.RED, Pixel.RED, Pixel.TRANSPARENT, Pixel.RED, Pixel.RED, Pixel.RED, Pixel.RED); // now check that background shows through // Need to find the icon location first Point point = SwingUtilities.convertPoint(label, 0, 0, f.getContentPane()); val = getDisplayedContent(f.getContentPane(), label.getSize(), point); assertEquals( 13 * 13, val.length, "frame arraylength"); assertImageNinePoints("icon", val, label.getSize(), Pixel.RED, Pixel.RED, Pixel.RED, Pixel.RED, Pixel.BLUE, Pixel.RED, Pixel.RED, Pixel.RED, Pixel.RED); JUnitUtil.dispose(f); } @Test public void testDisplayTransparent45degrees() { JFrame f = new JFrame(); f.getContentPane().setBackground(Color.blue); f.setUndecorated(true); // skip frame decoration, which can force a min size. NamedIcon icon = new NamedIcon("resources/icons/redTransparentBox.gif", "box"); // 13x13 PositionableLabel label = new PositionableLabel(icon, editor); f.add(label); f.pack(); new QueueTool().waitEmpty(); assertEquals( new Dimension(13, 13).toString(), label.getSize().toString(), "icon size"); // do the rotation, which transforms 13x13 to sqrt(2) bigger, 19x19 label.rotate(45); assertEquals( new Dimension(19, 19).toString(), label.getSize().toString(), "icon size"); f.pack(); new QueueTool().waitEmpty(); assertEquals( new Dimension(19, 19).toString(), label.getSize().toString(), "icon size"); // and check int[] val = getDisplayedContent(label, label.getSize(), new Point(0, 0)); assertEquals( 19 * 19, val.length, "icon arraylength"); assertImageNinePoints("icon", val, label.getSize(), Pixel.TRANSPARENT, Pixel.RED, Pixel.TRANSPARENT, Pixel.RED, Pixel.TRANSPARENT, Pixel.TRANSPARENT, // not sure why mid-right is TRANSPARENT; misaligned? Clipping? Pixel.TRANSPARENT, Pixel.TRANSPARENT, Pixel.TRANSPARENT); // not sure why bottom mid is TRANSPARENT; misaligned? Clipping? // now check that background shows through // Need to find the icon location first Point point = SwingUtilities.convertPoint(label, 0, 0, f.getContentPane()); val = getDisplayedContent(f.getContentPane(), label.getSize(), point); assertEquals( 19 * 19, val.length, "frame arraylength"); assertImageNinePoints("icon", val, label.getSize(), Pixel.BLUE, Pixel.RED, Pixel.BLUE, Pixel.RED, Pixel.BLUE, Pixel.BLUE, Pixel.BLUE, Pixel.BLUE, Pixel.BLUE); JUnitUtil.dispose(f); } // c.f. http://www.ssec.wisc.edu/~tomw/java/unicode.html#x2580 static final String SAMPLE_TEXT_U25CF = " \u25CF "; // note spaces // FULL BLOCK \u2588 // BLACK SQUARE \u25A0 // BLACK CIRCLE \u25CF // BLACK SMALL SQUARE \u25AA // BLACK DIAMOND \u25C6 // HEAVY MULTIPLICATION X \u2716 @Test public void testDisplayText() { JFrame f = new JFrame(); f.getContentPane().setBackground(Color.blue); f.setUndecorated(true); // skip frame decoration, which can force a min size. PositionableLabel label = new PositionableLabel(SAMPLE_TEXT_U25CF, editor); label.setForeground(Color.black); // this is a direct set, not through the UI label.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12)); f.add(label); f.pack(); new QueueTool().waitEmpty(); assertTrue( label.getSize().width > label.getSize().height, () -> "Expect size " + label.getSize() + " wider than height"); int[] val = getDisplayedContent(label, label.getSize(), new Point(0, 0)); //for (int i=0; i "Expect size " + label.getSize() + " higher than width"); int[] val = getDisplayedContent(label, label.getSize(), new Point(0, 0)); //for (int i=0; i