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
*
* - Image transparency and backgrounds
*
- Rotating icons and text
*
- Animated GIFs
*
* 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