!7 concept TestImage { new Ref pngFile; S imageMD5; int width, height; bool textKnown; S text; } p-subst { new SimpleCRUD(TestImage) { @Override JComponent fieldComponent(TestImage c, S field) { if (eq(field, "pngFile")) ret new ImageChooser((PNGFile) cget(c, "pngFile")); ret super.fieldComponent(c, field); } @Override void makeComponents(TestImage c, Map map) { for (S field : listMinus((L) conceptFieldsInOrder(cc), "width", "height", "imageMD5")) map.put(field, fieldComponent(c, field)); } @Override void saveData(TestImage c, Map components) { super.saveData(c, components); BufferedImage img = c.pngFile.has() ? c.pngFile->getImage() : null; if (img == null) csetAll(c, imageMD5 := null, width := 0, height := 0); else cset(c, imageMD5 := md5OfBufferedImage(img), width := img.getWidth(), height := img.getHeight()); } }.show("OCR Test Images"); }