diff --git a/java_tools/ts_screenshots/.gitignore b/java_tools/ts_screenshots/.gitignore index 2b9be8fb3c..e72f0e6eb6 100644 --- a/java_tools/ts_screenshots/.gitignore +++ b/java_tools/ts_screenshots/.gitignore @@ -1,4 +1,5 @@ inc config TunerStudio.properties -lib \ No newline at end of file +lib +images diff --git a/java_tools/ts_screenshots/screen/src/ScreenGenerator.java b/java_tools/ts_screenshots/screen/src/ScreenGenerator.java index 5e053c3346..3f237d0032 100644 --- a/java_tools/ts_screenshots/screen/src/ScreenGenerator.java +++ b/java_tools/ts_screenshots/screen/src/ScreenGenerator.java @@ -3,11 +3,14 @@ import javax.imageio.ImageIO; import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; +import java.awt.image.RasterFormatException; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; +import java.util.*; import java.util.List; +import java.util.concurrent.atomic.AtomicReference; public class ScreenGenerator { public static final String TS_DIALOG = "com.efiAnalytics.ui.dg"; @@ -30,7 +33,7 @@ public class ScreenGenerator { Frame mainFrame = findMainFrame(); while (topLevelButtons.isEmpty()) { - visitComponent(mainFrame, null, "", (parent, component) -> { + visitComponents(mainFrame, "", (parent, component) -> { if (component instanceof AbstractButton) { AbstractButton ab = (AbstractButton) component; System.out.println("topLevelButton " + ab.getText()); @@ -67,22 +70,42 @@ public class ScreenGenerator { void onComponent(Component parent, Component component); } - public static void visitComponent(Component cmp, Component parent, String prefix, Callback callback) { - System.out.println(prefix + " I see " + cmp.getClass()); - callback.onComponent(parent, cmp); - Container container = (Container) cmp; + public static void visitComponents(Component cmp, String prefix, Callback callback) { + visitComponents(cmp, null, prefix, callback); + } + + public static void visitComponents(Component component, Component parent, String prefix, Callback callback) { + if (component == null) + throw new NullPointerException("component"); + if (component instanceof AbstractButton) { + AbstractButton ab = (AbstractButton) component; + System.out.println("[button " + ab.getText() + "]"); + } else if (component instanceof JLabel) { + JLabel ab = (JLabel) component; + System.out.println("[label " + ab.getText() + "]"); + } else if (component instanceof JComboBox) { + JComboBox ab = (JComboBox) component; + System.out.println("[combo " + ab.getSelectedItem() + "]"); + } + + + System.out.println(prefix + " I see " + component.getClass()); + callback.onComponent(parent, component); + Container container = (Container) component; if (container == null) { // Not a container, return return; } // Go visit and add all children for (Component subComponent : container.getComponents()) { - visitComponent(subComponent, cmp, prefix + " " + subComponent.getClass().getSimpleName(), callback); + if (subComponent == null) + continue; + visitComponents(subComponent, component, prefix + " " + subComponent.getClass().getSimpleName(), callback); } } - private static boolean isTopLevelMenuButton(Component cmp) { - return cmp instanceof bi.b; + private static boolean isTopLevelMenuButton(Component component) { + return component instanceof bi.b; } private static void doJob(Frame frame) throws InterruptedException, InvocationTargetException, IOException, AWTException { @@ -106,41 +129,132 @@ public class ScreenGenerator { List menuItems = findMenuItems(frame); for (JMenuItem menuItem : menuItems) { + handleMenuItem(menuItem); + } + } - SwingUtilities.invokeAndWait(() -> { - try { + private static void handleMenuItem(JMenuItem menuItem) throws InterruptedException, InvocationTargetException { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + menuItem.doClick(); + } + }); - menuItem.doClick(); - Thread.sleep(MENU_CLICK_DELAY); + Thread.sleep(MENU_CLICK_DELAY); - JDialog dialog = findDynamicDialog(); - if (dialog == null) { - // this happens for example for disabled menu items - return; + + AtomicReference ref = new AtomicReference<>(); + SwingUtilities.invokeAndWait(() -> { + ref.set(findDynamicDialog()); + }); + // let's give it time to appear on the screen + Thread.sleep(MENU_CLICK_DELAY); + JDialog dialog = ref.get(); + if (dialog == null) { + System.out.println("Not found for " + menuItem); + return; + } + + SwingUtilities.invokeAndWait(() -> { + try { + Map yCoordinates = new TreeMap<>(); + + findSlices(dialog, yCoordinates); + + if (dialog == null) { + // this happens for example for disabled menu items + return; + } + + + System.out.println("Label Y coordinates: " + yCoordinates); + int topY = dialog.getLocationOnScreen().y; + yCoordinates.put(topY, "top"); + yCoordinates.put(topY + dialog.getSize().height, "bottom"); + + List sorted = new ArrayList<>(yCoordinates.keySet()); + + BufferedImage dialogScreenShot = getScreenShot(dialog); + + for (int i = 0; i < sorted.size() - 1; i++) { + Integer fromYScreen = sorted.get(i); + int fromY = fromYScreen - topY; + int toY = sorted.get(i + 1) - topY; + + String sectionNameWithSpecifalCharacters = yCoordinates.get(fromYScreen); + String sectionName = cleanName(sectionNameWithSpecifalCharacters); + + BufferedImage slice; + try { + slice = dialogScreenShot.getSubimage(0, fromY, dialogScreenShot.getWidth(), toY - fromY); + } catch (RasterFormatException e) { + System.out.printf("Dialog does not fit screen? " + sectionNameWithSpecifalCharacters); + continue; } + if (slice == null) { + System.out.println("Weird"); + continue; + } + String fileName = cleanName(dialog.getTitle()) + "_slice_" + fromY + "_" + sectionName + ".png"; + File output = new File(DESTINATION + fileName); + if (output == null) { + System.out.println(sectionName + " in " + fileName + " was not a success"); + continue; + } + try { + ImageIO.write(slice, PNG, output); + } catch (NullPointerException | FileNotFoundException e) { + System.out.println(sectionName + " in " + fileName + " was not a success?"); + continue; + } + } + + // Robot robot = new Robot(); // Rectangle captureRect = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()); // BufferedImage screenFullImage = robot.createScreenCapture(captureRect); // ImageIO.write(screenFullImage, PNG, new File(DESTINATION + "full_" + d.getTitle() + ".png")); - ImageIO.write( - getScreenShot(dialog), - PNG, - new File(DESTINATION + cleanName(dialog.getTitle()) + ".png")); - dialog.setVisible(false); - dialog.dispose(); - } catch (Exception e) { - throw new IllegalStateException(e); + ImageIO.write( + dialogScreenShot, + PNG, + new File(DESTINATION + cleanName(dialog.getTitle()) + ".png")); + dialog.setVisible(false); + dialog.dispose(); + } catch (Exception e) { + throw new IllegalStateException(e); + } + }); + } + + private static void findSlices(JDialog dialog, Map yCoordinates) { + visitComponents(dialog, "Dynamic dialog", new Callback() { + @Override + public void onComponent(Component parent, Component component) { + if (component instanceof JLabel) { + JLabel label = (JLabel) component; + if (!label.isVisible() || label.getSize().width == 0) + return; + String labelText = label.getText(); + if (labelText.length() > 0) { + System.out.println("Looking at " + label); + try { + yCoordinates.put(label.getLocationOnScreen().y, labelText); + } catch (IllegalComponentStateException e) { + System.out.printf("Did not go well for " + label); + } + } } - }); - } - Thread.sleep(1000); + + } + }); } private static List findMenuItems(Frame frame) { List menuItems = new ArrayList<>(); - visitComponent(frame, null, "Just clicked ", (parent, component) -> { + visitComponents(frame, "Just clicked ", (parent, component) -> { if (component instanceof JMenuItem && component.getClass().getName().endsWith("aH.gc")) { JMenuItem menuItem = (JMenuItem) component; System.out.println("Menu item " + menuItem.getText()); @@ -153,6 +267,10 @@ public class ScreenGenerator { private static String cleanName(String title) { title = title.replace(' ', '_'); title = title.replace(")", ""); + title = title.replace("%", ""); + title = title.replace(">", ""); + title = title.replace("<", ""); + title = title.replace("?", ""); title = title.replace("(", ""); title = title.replace('/', '_'); title = title.replace('\\', '_');