import java.util.*;
import java.util.zip.*;
import java.util.List;
import java.util.regex.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.concurrent.locks.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import javax.swing.table.*;
import java.io.*;
import java.net.*;
import java.lang.reflect.*;
import java.lang.ref.*;
import java.lang.management.*;
import java.security.*;
import java.security.spec.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.imageio.*;
import java.math.*;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import javax.swing.event.AncestorListener;
import javax.swing.event.AncestorEvent;
import javax.swing.Timer;
import javax.swing.Timer;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
public class main {
public static void main(String[] args) throws Exception {
showFullScreenImageSurface(invertedImage(shootScreen2()));
}
static void showFullScreenImageSurface(BufferedImage img) {
showFullScreen(jscroll(disposeFrameOnClick(new ImageSurface(img))));
}
static BufferedImage shootScreen2() {
return shootScreen2(screenRectangle());
}
static BufferedImage shootScreen2(Rectangle area) { try {
return new Robot().createScreenCapture(area);
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static BufferedImage shootScreen2(Rect area) {
return shootScreen2(area.getRectangle());
}
static BufferedImage shootScreen2(int x, int y, int w, int h) {
return shootScreen2(new Rectangle(x, y, w, h));
}
static BufferedImage invertedImage(BufferedImage img) {
img = cloneBufferedImage(img);
invertImage(img);
return img;
}
static JFrame showFullScreen(final JComponent c) {
return (JFrame) swingAndWait(new Object() { Object get() {
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice();
if (!gd.isFullScreenSupported())
throw fail("No full-screen mode supported!");
boolean dec = JFrame.isDefaultLookAndFeelDecorated();
if (dec)
JFrame.setDefaultLookAndFeelDecorated(false);
final JFrame window = new JFrame();
if (dec)
JFrame.setDefaultLookAndFeelDecorated(true);
registerEscape(window, new Runnable() { public void run() { try { window.dispose() ;
} catch (Exception __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); } } public String toString() { return "window.dispose()"; }});
window.add(wrap(c));
gd.setFullScreenWindow(window);
return window;
}
public String toString() { return "GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment()\r\n .getDefaultScreenDevice();\r\n if (!gd.isFullScreenSupported())\r\n fail(\"No full-screen mode supported!\");\r\n bool dec = JFrame.isDefaultLookAndFeelDecorated();\r\n if (dec)\r\n JFrame.setDefaultLookAndFeelDecorated(false);\r\n final new JFrame window;\r\n if (dec)\r\n JFrame.setDefaultLookAndFeelDecorated(true);\r\n registerEscape(window, r { window.dispose() });\r\n window.add(wrap(c));\r\n gd.setFullScreenWindow(window);\r\n ret window;"; }});
}
static BufferedImage cloneBufferedImage(BufferedImage image) {
return copyImage(image);
}
static Rectangle screenRectangle() {
return new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
}
static void invertImage(BufferedImage img) {
int w = img.getWidth(), h = img.getHeight();
for (int x = 0; x < w; x++)
for (int y = 0; y < h; y++) {
int rgba = img.getRGB(x, y);
Color col = new Color(rgba, true);
col = new Color(
255 - col.getRed(),
255 - col.getGreen(),
255 - col.getBlue());
img.setRGB(x, y, col.getRGB());
}
}
static JScrollPane jscroll(Component c) {
return new JScrollPane(c);
}
static A disposeFrameOnClick(final A c) {
onClick(c, new Runnable() { public void run() { try { disposeFrame(c) ;
} catch (Exception __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); } } public String toString() { return "disposeFrame(c)"; }});
return c;
}
static void onClick(JComponent c, final Object runnable) {
c.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
callF(runnable, e);
}
});
}
static BufferedImage copyImage(BufferedImage bi) {
ColorModel cm = bi.getColorModel();
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
WritableRaster raster = bi.copyData(bi.getRaster().createCompatibleWritableRaster());
return new BufferedImage(cm, raster, isAlphaPremultiplied, null);
}
static RuntimeException fail() {
throw new RuntimeException("fail");
}
static RuntimeException fail(Object msg) {
throw new RuntimeException(String.valueOf(msg));
}
static RuntimeException fail(String msg) {
throw new RuntimeException(unnull(msg));
}
static RuntimeException fail(String msg, Throwable innerException) {
throw new RuntimeException(msg, innerException);
}
// disabled for now to shorten some programs
/*static RuntimeException fail(S msg, O... args) {
throw new RuntimeException(format(msg, args));
}*/
static void disposeFrame(final Component c) {
swingNowOrLater(new Runnable() { public void run() { try {
Frame f = getFrame(c);
if (f != null)
f.dispose();
} catch (Exception __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); } } public String toString() { return "Frame f = getFrame(c);\r\n if (f != null)\r\n f.dispose();"; }});
}
// c = JComponent or something implementing swing()
static JComponent wrap(Object swingable) {
JComponent c = (JComponent) ( swingable instanceof JComponent ? swingable : callOpt(swingable, "swing"));
if (c instanceof JTable || c instanceof JList
|| c instanceof JTextArea || c instanceof JEditorPane
|| c instanceof JTextPane)
return new JScrollPane(c);
return c;
}
static void swingAndWait(Runnable r) { try {
if (isAWTThread())
r.run();
else
EventQueue.invokeAndWait(r);
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static Object swingAndWait(final Object f) {
if (isAWTThread())
return callF(f);
else {
final Var result = new Var();
swingAndWait(new Runnable() { public void run() { try {
result.set(callF(f));
} catch (Exception __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); } } public String toString() { return "result.set(callF(f));"; }});
return result.get();
}
}
static void registerEscape(JFrame frame, final Runnable r) {
String name = "Escape";
Action action = abstractAction(name, r);
JComponent pnl = frame.getRootPane();
KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
pnl.getActionMap().put(name, action);
pnl.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(keyStroke, name);
}
static Object callOpt(Object o) {
if (o == null) return null;
return callF(o);
}
static Object callOpt(Object o, String method, Object... args) {
try {
if (o == null) return null;
if (o instanceof Class) {
Method m = callOpt_findStaticMethod((Class) o, method, args, false);
if (m == null) return null;
m.setAccessible(true);
return m.invoke(null, args);
} else {
Method m = callOpt_findMethod(o, method, args, false);
if (m == null) return null;
m.setAccessible(true);
return m.invoke(o, args);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Method callOpt_findStaticMethod(Class c, String method, Object[] args, boolean debug) {
Class _c = c;
while (c != null) {
for (Method m : c.getDeclaredMethods()) {
if (debug)
System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");;
if (!m.getName().equals(method)) {
if (debug) System.out.println("Method name mismatch: " + method);
continue;
}
if ((m.getModifiers() & Modifier.STATIC) == 0 || !callOpt_checkArgs(m, args, debug))
continue;
return m;
}
c = c.getSuperclass();
}
return null;
}
static Method callOpt_findMethod(Object o, String method, Object[] args, boolean debug) {
Class c = o.getClass();
while (c != null) {
for (Method m : c.getDeclaredMethods()) {
if (debug)
System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");;
if (m.getName().equals(method) && callOpt_checkArgs(m, args, debug))
return m;
}
c = c.getSuperclass();
}
return null;
}
private static boolean callOpt_checkArgs(Method m, Object[] args, boolean debug) {
Class>[] types = m.getParameterTypes();
if (types.length != args.length) {
if (debug)
System.out.println("Bad parameter length: " + args.length + " vs " + types.length);
return false;
}
for (int i = 0; i < types.length; i++)
if (!(args[i] == null || isInstanceX(types[i], args[i]))) {
if (debug)
System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]);
return false;
}
return true;
}
static AbstractAction abstractAction(String name, final Object runnable) {
return new AbstractAction(name) {
public void actionPerformed(ActionEvent evt) {
pcallF(runnable);
}
};
}
static JFrame getFrame(Object o) {
if (!(o instanceof Component)) return null;
Component c = (Component) o;
while (c != null) {
if (c instanceof JFrame) return (JFrame) c;
c = c.getParent();
}
return null;
}
static Object callF(Object f, Object... args) {
return callFunction(f, args);
}
static String unnull(String s) {
return s == null ? "" : s;
}
static List unnull(List l) {
return l == null ? emptyList() : l;
}
static Iterable unnull(Iterable i) {
return i == null ? emptyList() : i;
}
static Object[] unnull(Object[] a) {
return a == null ? new Object[0] : a;
}
static BitSet unnull(BitSet b) {
return b == null ? new BitSet() : b;
}
static boolean isAWTThread() {
if (isAndroid()) return false;
if (isHeadless()) return false;
return isTrue(callOpt(getClass("javax.swing.SwingUtilities"), "isEventDispatchThread"));
}
static Class> getClass(String name) {
try {
return Class.forName(name);
} catch (ClassNotFoundException e) {
return null;
}
}
static Class getClass(Object o) {
return o instanceof Class ? (Class) o : o.getClass();
}
static Class getClass(Object realm, String name) { try {
try {
return getClass(realm).getClassLoader().loadClass(classNameToVM(name));
} catch (ClassNotFoundException e) {
return null;
}
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static Boolean isHeadless_cache;
static boolean isHeadless() {
if (isHeadless_cache != null) return isHeadless_cache;
if (GraphicsEnvironment.isHeadless()) return isHeadless_cache = true;
// Also check if AWT actually works.
// If DISPLAY variable is set but no X server up, this will notice.
try {
callOpt(getClass("javax.swing.SwingUtilities"), "isEventDispatchThread");
return isHeadless_cache = false;
} catch (Throwable e) { return isHeadless_cache = true; }
}
static Object pcallF(Object f, Object... args) {
return pcallFunction(f, args);
}
static Object callFunction(Object f, Object... args) {
if (f == null) return null;
if (f instanceof Runnable) {
((Runnable) f).run();
return null;
} else if (f instanceof String)
return call(mc(), (String) f, args);
else
return call(f, "get", args);
//else throw fail("Can't call a " + getClassName(f));
}
static List emptyList() {
return new ArrayList();
//ret Collections.emptyList();
}
// extended over Class.isInstance() to handle primitive types
static boolean isInstanceX(Class type, Object arg) {
if (type == boolean.class) return arg instanceof Boolean;
if (type == int.class) return arg instanceof Integer;
if (type == long.class) return arg instanceof Long;
if (type == float.class) return arg instanceof Float;
if (type == short.class) return arg instanceof Short;
if (type == char.class) return arg instanceof Character;
if (type == byte.class) return arg instanceof Byte;
if (type == double.class) return arg instanceof Double;
return type.isInstance(arg);
}
// hmm, this shouldn't call functions really. That was just
// for coroutines.
static boolean isTrue(Object o) {
if (o instanceof Boolean)
return ((Boolean) o).booleanValue();
if (o == null) return false;
return ((Boolean) callF(o)).booleanValue();
}
static boolean isTrue(Object pred, Object arg) {
return booleanValue(callF(pred, arg));
}
static int isAndroid_flag;
static boolean isAndroid() {
if (isAndroid_flag == 0)
isAndroid_flag = System.getProperty("java.vendor").toLowerCase().indexOf("android") >= 0 ? 1 : -1;
return isAndroid_flag > 0;
}
static Object mc() {
return getMainClass();
}
static String classNameToVM(String name) {
return name.replace(".", "$");
}
static Object call(Object o) {
return callFunction(o);
}
// varargs assignment fixer for a single string array argument
static Object call(Object o, String method, String[] arg) {
return call(o, method, new Object[] {arg});
}
static Object call(Object o, String method, Object... args) {
try {
if (o instanceof Class) {
Method m = call_findStaticMethod((Class) o, method, args, false);
m.setAccessible(true);
return m.invoke(null, args);
} else {
Method m = call_findMethod(o, method, args, false);
m.setAccessible(true);
return m.invoke(o, args);
}
} catch (Exception e) {
throw e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e);
}
}
static Method call_findStaticMethod(Class c, String method, Object[] args, boolean debug) {
Class _c = c;
while (c != null) {
for (Method m : c.getDeclaredMethods()) {
if (debug)
System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");;
if (!m.getName().equals(method)) {
if (debug) System.out.println("Method name mismatch: " + method);
continue;
}
if ((m.getModifiers() & Modifier.STATIC) == 0 || !call_checkArgs(m, args, debug))
continue;
return m;
}
c = c.getSuperclass();
}
throw new RuntimeException("Method '" + method + "' (static) with " + args.length + " parameter(s) not found in " + _c.getName());
}
static Method call_findMethod(Object o, String method, Object[] args, boolean debug) {
Class c = o.getClass();
while (c != null) {
for (Method m : c.getDeclaredMethods()) {
if (debug)
System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");;
if (m.getName().equals(method) && call_checkArgs(m, args, debug))
return m;
}
c = c.getSuperclass();
}
throw new RuntimeException("Method '" + method + "' (non-static) with " + args.length + " parameter(s) not found in " + o.getClass().getName());
}
private static boolean call_checkArgs(Method m, Object[] args, boolean debug) {
Class>[] types = m.getParameterTypes();
if (types.length != args.length) {
if (debug)
System.out.println("Bad parameter length: " + args.length + " vs " + types.length);
return false;
}
for (int i = 0; i < types.length; i++)
if (!(args[i] == null || isInstanceX(types[i], args[i]))) {
if (debug)
System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]);
return false;
}
return true;
}
static Object pcallFunction(Object f, Object... args) {
try { /* pcall 1*/ return callFunction(f, args); /* pcall 2 */ } catch (Throwable __e) { printStackTrace(__e); }
return null;
}
static boolean booleanValue(Object o) {
return eq(true, o);
}
static Class getMainClass() {
return main.class;
}
static Class getMainClass(Object o) { try {
return (o instanceof Class ? (Class) o : o.getClass()).getClassLoader().loadClass("main");
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static boolean eq(Object a, Object b) {
if (a == null) return b == null;
if (a.equals(b)) return true;
if (a instanceof BigInteger) {
if (b instanceof Integer) return a.equals(BigInteger.valueOf((Integer) b));
if (b instanceof Long) return a.equals(BigInteger.valueOf((Long) b));
}
return false;
}
static class Rect {
int x, y, w, h;
Rect() {}
Rect(Rectangle r) {
x = r.x;
y = r.y;
w = r.width;
h = r.height;
}
Rect(int x, int y, int w, int h) {
this.h = h;
this.w = w;
this.y = y;
this.x = x;}
Rectangle getRectangle() {
return new Rectangle(x, y, w, h);
}
public boolean equals(Object o) { return stdEq2(this, o); }
public int hashCode() { return stdHash2(this); }
public String toString() {
return x + "," + y + " / " + w + "," + h;
}
int x2() { return x + w; }
int y2() { return y + h; }
boolean contains(Pt p) {
return contains(p.x, p.y);
}
boolean contains(int _x, int _y) {
return _x >= x && _y >= y && _x < x+w && _y < y+h;
}
}
static class ImageSurface extends Surface {
private BufferedImage image;
private double zoomX = 1, zoomY = 1;
private Rectangle selection;
List tools = new ArrayList();
Object overlay; // voidfunc(Graphics2D)
Runnable onSelectionChange;
static boolean verbose;
public ImageSurface() {
this(new RGBImage(1, 1, new int[] { 0xFFFFFF }));
}
public ImageSurface(RGBImage image) {
this(image.getBufferedImage());
}
public ImageSurface(BufferedImage image) {
clearSurface = false;
this.image = image;
componentPopupMenu(this, new Object() { void get(JPopupMenu menu) {
Point p = pointFromEvent(componentPopupMenu_mouseEvent.get()).getPoint();
fillPopupMenu(menu, p);
}
public String toString() { return "Point p = pointFromEvent(componentPopupMenu_mouseEvent.get()).getPoint();\r\n fillPopupMenu(menu, p);"; }});
new ImageSurfaceSelector(this);
jHandleFileDrop(this, new Object() { void get(File f) { setImage(loadBufferedImage(f)) ; }
public String toString() { return "setImage(loadBufferedImage(f))"; }});
}
public ImageSurface(RGBImage image, double zoom) {
this(image);
setZoom(zoom);
}
// point is already in image coordinates
protected void fillPopupMenu(JPopupMenu menu, final Point point) {
JMenuItem miZoomReset = new JMenuItem("Zoom 100%");
miZoomReset.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
setZoom(1.0);
centerPoint(point);
}
});
menu.add(miZoomReset);
JMenuItem miZoomIn = new JMenuItem("Zoom in");
miZoomIn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
setZoom(getZoomX()*2.0, getZoomY()*2.0);
centerPoint(point);
}
});
menu.add(miZoomIn);
JMenuItem miZoomOut = new JMenuItem("Zoom out");
miZoomOut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
setZoom(getZoomX()*0.5, getZoomY()*0.5);
centerPoint(point);
}
});
menu.add(miZoomOut);
JMenuItem miZoomToWindow = new JMenuItem("Zoom to window");
miZoomToWindow.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
zoomToDisplaySize();
}
});
menu.add(miZoomToWindow);
addMenuItem(menu, "Show full screen", new Runnable() { public void run() { try { showFullScreen() ;
} catch (Exception __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); } } public String toString() { return "showFullScreen()"; }});
menu.addSeparator();
addMenuItem(menu, "Save image...", new Runnable() { public void run() { try { saveImage() ;
} catch (Exception __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); } } public String toString() { return "saveImage()"; }});
addMenuItem(menu, "Upload image...", new Runnable() { public void run() { try { uploadImage() ;
} catch (Exception __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); } } public String toString() { return "uploadImage()"; }});
addMenuItem(menu, "Copy image to clipboard", new Runnable() { public void run() { try {
copyImageToClipboard(getImage());
} catch (Exception __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); } } public String toString() { return "copyImageToClipboard(getImage());"; }});
addMenuItem(menu, "Paste image from clipboard", new Runnable() { public void run() { try {
loadFromClipboard();
} catch (Exception __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); } } public String toString() { return "loadFromClipboard();"; }});
}
void loadFromClipboard() {
BufferedImage img = getImageFromClipboard();
if (img != null)
setImage(img);
}
void saveImage() {
RGBImage image = new RGBImage(getImage(), null);
JFileChooser fileChooser = new JFileChooser(getProgramDir());
if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
try {
image.save(fileChooser.getSelectedFile());
} catch (IOException e) {
popup(e);
}
}
}
public void render(int w, int h, Graphics2D g) {
if (verbose) main.print("render");
g.setColor(Color.white);
if (image == null)
g.fillRect(0, 0, w, h);
else {
int iw = getZoomedWidth(), ih = getZoomedHeight();
g.drawImage(image, 0, 0, iw, ih, null);
g.fillRect(iw, 0, w-iw, h);
g.fillRect(0, ih, iw, h-ih);
}
if (verbose) main.print("render overlay");
if (overlay != null) pcallF(overlay, g);
if (verbose) main.print("render selection");
if (selection != null) {
// drawRect is inclusive, selection is exclusive, so... whatever, tests show it's cool.
drawSelectionRect(g, selection, Color.green, Color.white);
}
}
public void drawSelectionRect(Graphics2D g, Rectangle selection, Color green, Color white) {
g.setColor(green);
int top = (int) (selection.y * zoomY);
int bottom = (int) ((selection.y+selection.height) * zoomY);
int left = (int) (selection.x * zoomX);
int right = (int) ((selection.x+selection.width) * zoomX);
g.drawRect(left-1, top-1, right-left+1, bottom-top+1);
g.setColor(white);
g.drawRect(left - 2, top - 2, right - left + 3, bottom - top + 3);
}
public void setZoom(double zoom) {
setZoom(zoom, zoom);
}
public void setZoom(double zoomX, double zoomY) {
this.zoomX = zoomX;
this.zoomY = zoomY;
revalidate();
repaint();
}
public Dimension getMinimumSize() {
int w = getZoomedWidth();
int h = getZoomedHeight();
Dimension min = super.getMinimumSize();
return new Dimension(Math.max(w, min.width), Math.max(h, min.height));
}
private int getZoomedHeight() {
return (int) (image.getHeight() * zoomY);
}
private int getZoomedWidth() {
return (int) (image.getWidth() * zoomX);
}
public void setImage(RGBImage image) {
setImage(image.getBufferedImage());
}
public void setImage(BufferedImage image) {
this.image = image;
revalidate();
repaint();
}
public BufferedImage getImage() {
return image;
}
public double getZoomX() {
return zoomX;
}
public double getZoomY() {
return zoomY;
}
public Dimension getPreferredSize() {
return new Dimension(getZoomedWidth(), getZoomedHeight());
}
/** returns a scrollpane with the scroll-mode prevent-garbage-drawing fix applied */
public JScrollPane makeScrollPane() {
JScrollPane scrollPane = new JScrollPane(this);
scrollPane.getViewport().setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE);
return scrollPane;
}
public void zoomToWindow() { zoomToDisplaySize(); }
public void zoomToDisplaySize() {
if (image == null) return;
Dimension display = getDisplaySize();
double xRatio = display.width/(double) image.getWidth();
double yRatio = display.height/(double) image.getHeight();
setZoom(Math.min(xRatio, yRatio));
revalidate();
}
/** tricky magic to get parent scroll pane */
private Dimension getDisplaySize() {
Container c = getParent();
while (c != null) {
if (c instanceof JScrollPane)
return c.getSize();
c = c.getParent();
}
return getSize();
}
public void setSelection(Rectangle r) {
if (neq(selection, r)) {
selection = r;
pcallF(onSelectionChange);
repaint();
}
}
public Rectangle getSelection() {
return selection;
}
public RGBImage getRGBImage() {
return new RGBImage(getImage());
}
// p is in image coordinates
void centerPoint(Point p) {
//_print("centerPoint " + p);
if (!(getParent() instanceof JViewport))
return;
p = new Point((int) (p.x*getZoomX()), (int) (p.y*getZoomY()));
final JViewport viewport = (JViewport) ( getParent());
Dimension viewSize = viewport.getExtentSize();
//_print("centerPoint " + p);
int x = max(0, p.x-viewSize.width/2);
int y = max(0, p.y-viewSize.height/2);
p = new Point(x,y);
//_print("centerPoint " + p);
final Point _p = p;
awtLater(new Runnable() { public void run() { try {
viewport.setViewPosition(_p);
} catch (Exception __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); } } public String toString() { return "viewport.setViewPosition(_p);"; }});
}
Pt pointFromEvent(MouseEvent e) {
return new Pt((int) (e.getX()/zoomX), (int) (e.getY()/zoomY));
}
void uploadImage() {
final BufferedImage img = getImage();
final JTextField tf = new JTextField();
showFormTitled("Upload Image",
"Image title (optional)", tf, new Runnable() { public void run() { try {
messageBox("Image uploaded as " + main.uploadImage(tf.getText().trim(), toPNG(img)))
;
} catch (Exception __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); } } public String toString() { return "messageBox(\"Image uploaded as \" + main.uploadImage(tf.getText().trim(), toPNG(img)))"; }});
}
void showFullScreen() {
showFullScreenImageSurface(getImage());
}
}
abstract static class Surface extends JPanel {
public Object AntiAlias = RenderingHints.VALUE_ANTIALIAS_ON;
public Object Rendering = RenderingHints.VALUE_RENDER_SPEED;
public AlphaComposite composite;
public Paint texture;
public BufferedImage bimg;
public int imageType;
public String name;
public boolean clearSurface = true;
// Demos using animated gif's that implement ImageObserver set dontThread.
public boolean dontThread;
protected long sleepAmount = 50; // max20 fps
private long orig, start, frame;
private Toolkit toolkit;
private boolean perfMonitor, outputPerf;
private int biw, bih;
private boolean clearOnce;
private boolean toBeInitialized = true;
public Surface() {
setDoubleBuffered(false);
toolkit = getToolkit();
name = this.getClass().getName();
name = name.substring(name.indexOf(".", 7)+1);
setImageType(0);
// To launch an individual demo with the performance str output :
// java -Djava2demo.perf= -cp Java2Demo.jar demos.Clipping.ClipAnim
try {
if (System.getProperty("java2demo.perf") != null) {
perfMonitor = outputPerf = true;
}
} catch (Exception ex) { }
}
/*protected Image getImage(String name) {
return DemoImages.getImage(name, this);
}
protected Font getFont(String name) {
return DemoFonts.getFont(name);
}*/
public int getImageType() {
return imageType;
}
public void setImageType(int imgType) {
if (imgType == 0) {
imageType = 1;
} else {
imageType = imgType;
}
bimg = null;
}
public void setAntiAlias(boolean aa) {
AntiAlias = aa
? RenderingHints.VALUE_ANTIALIAS_ON
: RenderingHints.VALUE_ANTIALIAS_OFF;
}
public void setRendering(boolean rd) {
Rendering = rd
? RenderingHints.VALUE_RENDER_QUALITY
: RenderingHints.VALUE_RENDER_SPEED;
}
public void setTexture(Object obj) {
if (obj instanceof GradientPaint) {
texture = new GradientPaint(0, 0, Color.white,
getSize().width*2, 0, Color.green);
} else {
texture = (Paint) obj;
}
}
public void setComposite(boolean cp) {
composite = cp
? AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f)
: null;
}
public void setMonitor(boolean pm) {
perfMonitor = pm;
}
public void setSleepAmount(long amount) {
sleepAmount = amount;
}
public long getSleepAmount() {
return sleepAmount;
}
public BufferedImage createBufferedImage(Graphics2D g2,
int w,
int h,
int imgType) {
BufferedImage bi = null;
if (imgType == 0) {
bi = (BufferedImage) g2.getDeviceConfiguration().
createCompatibleImage(w, h);
} else if (imgType > 0 && imgType < 14) {
bi = new BufferedImage(w, h, imgType);
} else if (imgType == 14) {
bi = createBinaryImage(w, h, 2);
} else if (imgType == 15) {
bi = createBinaryImage(w, h, 4);
} else if (imgType == 16) {
bi = createSGISurface(w, h, 32);
} else if (imgType == 17) {
bi = createSGISurface(w, h, 16);
}
biw = w;
bih = h;
return bi;
}
// Lookup tables for BYTE_BINARY 1, 2 and 4 bits.
static byte[] lut1Arr = new byte[] {0, (byte)255 };
static byte[] lut2Arr = new byte[] {0, (byte)85, (byte)170, (byte)255};
static byte[] lut4Arr = new byte[] {0, (byte)17, (byte)34, (byte)51,
(byte)68, (byte)85,(byte) 102, (byte)119,
(byte)136, (byte)153, (byte)170, (byte)187,
(byte)204, (byte)221, (byte)238, (byte)255};
private BufferedImage createBinaryImage(int w, int h, int pixelBits) {
int bytesPerRow = w * pixelBits / 8;
if (w * pixelBits % 8 != 0) {
bytesPerRow++;
}
byte[] imageData = new byte[h * bytesPerRow];
IndexColorModel cm = null;
switch (pixelBits) {
case 1:
cm = new IndexColorModel(pixelBits, lut1Arr.length,
lut1Arr, lut1Arr, lut1Arr);
break;
case 2:
cm = new IndexColorModel(pixelBits, lut2Arr.length,
lut2Arr, lut2Arr, lut2Arr);
break;
case 4:
cm = new IndexColorModel(pixelBits, lut4Arr.length,
lut4Arr, lut4Arr, lut4Arr);
break;
default:
{new Exception("Invalid # of bit per pixel").printStackTrace();}
}
DataBuffer db = new DataBufferByte(imageData, imageData.length);
WritableRaster r = Raster.createPackedRaster(db, w, h, pixelBits, null);
return new BufferedImage(cm, r, false, null);
}
private BufferedImage createSGISurface(int w, int h, int pixelBits) {
int rMask32 = 0xFF000000;
int rMask16 = 0xF800;
int gMask32 = 0x00FF0000;
int gMask16 = 0x07C0;
int bMask32 = 0x0000FF00;
int bMask16 = 0x003E;
DirectColorModel dcm = null;
DataBuffer db = null;
WritableRaster wr = null;
switch (pixelBits) {
case 16:
short[] imageDataUShort = new short[w * h];
dcm = new DirectColorModel(16, rMask16, gMask16, bMask16);
db = new DataBufferUShort(imageDataUShort, imageDataUShort.length);
wr = Raster.createPackedRaster(db, w, h, w,
new int[] {rMask16, gMask16, bMask16},
null);
break;
case 32:
int[] imageDataInt = new int[w * h];
dcm = new DirectColorModel(32, rMask32, gMask32, bMask32);
db = new DataBufferInt(imageDataInt, imageDataInt.length);
wr = Raster.createPackedRaster(db, w, h, w,
new int[] {rMask32, gMask32, bMask32},
null);
break;
default:
{new Exception("Invalid # of bit per pixel").printStackTrace();}
}
return new BufferedImage(dcm, wr, false, null);
}
public Graphics2D createGraphics2D(int width,
int height,
BufferedImage bi,
Graphics g) {
Graphics2D g2 = null;
if (bi != null) {
g2 = bi.createGraphics();
} else {
g2 = (Graphics2D) g;
}
g2.setBackground(getBackground());
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, AntiAlias);
g2.setRenderingHint(RenderingHints.KEY_RENDERING, Rendering);
if (clearSurface || clearOnce) {
g2.clearRect(0, 0, width, height);
clearOnce = false;
}
if (texture != null) {
// set composite to opaque for texture fills
g2.setComposite(AlphaComposite.SrcOver);
g2.setPaint(texture);
g2.fillRect(0, 0, width, height);
}
if (composite != null) {
g2.setComposite(composite);
}
return g2;
}
public abstract void render(int w, int h, Graphics2D g);
/**
* It's possible to turn off double-buffering for just the repaint
* calls invoked directly on the non double buffered component.
* This can be done by overriding paintImmediately() (which is called
* as a result of repaint) and getting the current RepaintManager and
* turning off double buffering in the RepaintManager before calling
* super.paintImmediately(g).
*/
public void paintImmediately(int x,int y,int w, int h) {
RepaintManager repaintManager = null;
boolean save = true;
if (!isDoubleBuffered()) {
repaintManager = RepaintManager.currentManager(this);
save = repaintManager.isDoubleBufferingEnabled();
repaintManager.setDoubleBufferingEnabled(false);
}
super.paintImmediately(x, y, w, h);
if (repaintManager != null) {
repaintManager.setDoubleBufferingEnabled(save);
}
}
public void paint(Graphics g) {
Dimension d = getSize();
if (imageType == 1)
bimg = null;
else if (bimg == null || biw != d.width || bih != d.height) {
bimg = createBufferedImage((Graphics2D)g,
d.width, d.height, imageType-2);
clearOnce = true;
toBeInitialized = true;
}
if (toBeInitialized) {
toBeInitialized = false;
startClock();
}
Graphics2D g2 = createGraphics2D(d.width, d.height, bimg, g);
render(d.width, d.height, g2);
g2.dispose();
if (bimg != null) {
g.drawImage(bimg, 0, 0, null);
toolkit.sync();
}
}
public void startClock() {
orig = System.currentTimeMillis();
start = orig;
frame = 0;
}
private static final int REPORTFRAMES = 30;
public static void setAlpha(Graphics2D g, float alpha) {
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
}
}
static class Var {
A v; // you can access this directly if you use one thread
Var() {}
Var(A v) {
this.v = v;}
synchronized void set(A a) {
if (v != a) {
v = a;
notifyAll();
}
}
synchronized A get() { return v; }
synchronized boolean has() { return v != null; }
synchronized void clear() { v = null; }
}
static class RGB {
public float r, g, b; // can't be final cause persistence
RGB() {}
public RGB(float r, float g, float b) {
this.r = r;
this.g = g;
this.b = b;
}
public RGB(double r, double g, double b) {
this.r = (float) r;
this.g = (float) g;
this.b = (float) b;
}
public RGB(double brightness) {
this.r = this.g = this.b = (float) brightness;
}
public RGB(Color color) {
this.r = color.getRed()/255f;
this.g = color.getGreen()/255f;
this.b = color.getBlue()/255f;
}
public RGB(String hex) {
r = Integer.parseInt(hex.substring(0, 2), 16)/255f;
g = Integer.parseInt(hex.substring(2, 4), 16)/255f;
b = Integer.parseInt(hex.substring(4, 6), 16)/255f;
}
public float getComponent(int i) {
return i == 0 ? r : i == 1 ? g : b;
}
public Color getColor() {
return new Color(r, g, b);
}
public static RGB newSafe(float r, float g, float b) {
return new RGB(Math.max(0, Math.min(1, r)), Math.max(0, Math.min(1, g)), Math.max(0, Math.min(1, b)));
}
public int asInt() {
return getColor().getRGB() & 0xFFFFFF;
}
public float getBrightness() {
return (r+g+b)/3.0f;
}
public String getHexString() {
return Integer.toHexString(asInt() | 0xFF000000).substring(2).toUpperCase();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof RGB)) return false;
RGB rgb = (RGB) o;
if (Float.compare(rgb.b, b) != 0) return false;
if (Float.compare(rgb.g, g) != 0) return false;
if (Float.compare(rgb.r, r) != 0) return false;
return true;
}
@Override
public int hashCode() {
int result = (r != +0.0f ? Float.floatToIntBits(r) : 0);
result = 31 * result + (g != +0.0f ? Float.floatToIntBits(g) : 0);
result = 31 * result + (b != +0.0f ? Float.floatToIntBits(b) : 0);
return result;
}
public boolean isBlack() {
return r == 0f && g == 0f && b == 0f;
}
public boolean isWhite() {
return r == 1f && g == 1f && b == 1f;
}
public String toString() {
return getHexString();
}
}
static class RGBImage {
transient BufferedImage bufferedImage;
File file;
int width, height;
int[] pixels;
RGBImage() {}
RGBImage(BufferedImage image) {
this(image, null);
}
RGBImage(BufferedImage image, File file) {
this.file = file;
bufferedImage = image;
width = image.getWidth();
height = image.getHeight();
pixels = new int[width*height];
PixelGrabber pixelGrabber = new PixelGrabber(image, 0, 0, width, height, pixels, 0, width);
try {
if (!pixelGrabber.grabPixels())
throw new RuntimeException("Could not grab pixels");
cleanPixels(); // set upper byte to 0
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
/** We assume it's a file name to load from */
RGBImage(String file) throws IOException {
this(new File(file));
}
RGBImage(Dimension size, Color color) {
this(size.width, size.height, color);
}
RGBImage(Dimension size, RGB color) {
this(size.width, size.height, color);
}
private void cleanPixels() {
for (int i = 0; i < pixels.length; i++)
pixels[i] &= 0xFFFFFF;
}
RGBImage(int width, int height, int[] pixels) {
this.width = width;
this.height = height;
this.pixels = pixels;
}
RGBImage(int w, int h, RGB[] pixels) {
this.width = w;
this.height = h;
this.pixels = asInts(pixels);
}
public static int[] asInts(RGB[] pixels) {
int[] ints = new int[pixels.length];
for (int i = 0; i < pixels.length; i++)
ints[i] = pixels[i] == null ? 0 : pixels[i].getColor().getRGB();
return ints;
}
public RGBImage(int w, int h) {
this(w, h, Color.black);
}
RGBImage(int w, int h, RGB rgb) {
this.width = w;
this.height = h;
this.pixels = new int[w*h];
int col = rgb.asInt();
if (col != 0)
for (int i = 0; i < pixels.length; i++)
pixels[i] = col;
}
RGBImage(RGBImage image) {
this(image.width, image.height, copyPixels(image.pixels));
}
RGBImage(int width, int height, Color color) {
this(width, height, new RGB(color));
}
RGBImage(File file) throws IOException {
this(javax.imageio.ImageIO.read(file));
}
private static int[] copyPixels(int[] pixels) {
int[] copy = new int[pixels.length];
System.arraycopy(pixels, 0, copy, 0, pixels.length);
return copy;
}
public int getIntPixel(int x, int y) {
if (inRange(x, y))
return pixels[y * width + x];
else
return 0xFFFFFF;
}
public static RGB asRGB(int packed) {
int r = (packed >> 16) & 0xFF;
int g = (packed >> 8) & 0xFF;
int b = packed & 0xFF;
return new RGB(r / 255f, g / 255f, b / 255f);
}
public RGB getRGB(int x, int y) {
if (inRange(x, y))
return asRGB(pixels[y * width + x]);
else
return new RGB(0xFFFFFF);
}
/** alias of getRGB - I kept typing getPixel instead of getRGB all the time, so I finally created it */
public RGB getPixel(int x, int y) {
return getRGB(x, y);
}
int getWidth() { return width; }
int getHeight() { return height; }
int w() { return width; }
int h() { return height; }
/** Attention: cached, i.e. does not change when image itself changes */
/** @NotNull */
public BufferedImage getBufferedImage() {
if (bufferedImage == null) {
bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//bufferedImage.setData(Raster.createRaster(new SampleModel()));
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
bufferedImage.setRGB(x, y, pixels[y*width+x]);
}
return bufferedImage;
}
RGBImage clip(Rect r) {
return r == null ? null : clip(r.getRectangle());
}
RGBImage clip(Rectangle r) {
r = fixClipRect(r);
int[] newPixels;
try {
newPixels = new int[r.width*r.height];
} catch (RuntimeException e) {
System.out.println(r);
throw e;
}
for (int y = 0; y < r.height; y++) {
System.arraycopy(pixels, (y+r.y)*width+r.x, newPixels, y*r.width, r.width);
}
return new RGBImage(r.width, r.height, newPixels);
}
private Rectangle fixClipRect(Rectangle r) {
r = r.intersection(new Rectangle(0, 0, width, height));
if (r.isEmpty())
r = new Rectangle(r.x, r.y, 0, 0);
return r;
}
public File getFile() {
return file;
}
/** can now also do GIF (not just JPEG) */
public static RGBImage load(String fileName) {
return load(new File(fileName));
}
/** can now also do GIF (not just JPEG) */
public static RGBImage load(File file) {
try {
BufferedImage bufferedImage = javax.imageio.ImageIO.read(file);
return new RGBImage(bufferedImage);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public int getInt(int x, int y) {
return pixels[y * width + x];
}
public void save(File file) throws IOException {
String name = file.getName().toLowerCase();
String type;
if (name.endsWith(".png")) type = "png";
else if (name.endsWith(".jpg") || name.endsWith(".jpeg")) type = "jpeg";
else throw new IOException("Unknown image extension: " + name);
javax.imageio.ImageIO.write(getBufferedImage(), type, file);
}
public static RGBImage dummyImage() {
return new RGBImage(1, 1, new int[] {0xFFFFFF});
}
public int[] getPixels() {
return pixels;
}
public void setPixel(int x, int y, RGB rgb) {
if (x >= 0 && y >= 0 && x < width && y < height)
pixels[y*width+x] = rgb.asInt();
}
public void setPixel(int x, int y, Color color) {
setPixel(x, y, new RGB(color));
}
public void setPixel(int x, int y, int rgb) {
if (x >= 0 && y >= 0 && x < width && y < height)
pixels[y*width+x] = rgb;
}
public RGBImage copy() {
return new RGBImage(this);
}
public boolean inRange(int x, int y) {
return x >= 0 && y >= 0 && x < width && y < height;
}
public Dimension getSize() {
return new Dimension(width, height);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
RGBImage rgbImage = (RGBImage) o;
if (height != rgbImage.height) return false;
if (width != rgbImage.width) return false;
if (!Arrays.equals(pixels, rgbImage.pixels)) return false;
return true;
}
@Override
public int hashCode() {
int result = width;
result = 31 * result + height;
result = 31 * result + Arrays.hashCode(pixels);
return result;
}
public String getHex(int x, int y) {
return getPixel(x, y).getHexString();
}
public RGBImage clip(int x, int y, int width, int height) {
return clip(new Rectangle(x, y, width, height));
}
public RGBImage clipLine(int y) {
return clip(0, y, width, 1);
}
public int numPixels() {
return width*height;
}
}
// independent timer
static void awtLater(int delay, final Object r) {
swingLater(delay, r);
}
static void awtLater(Object r) {
swingLater(r);
}
// dependent timer (runs only when component is visible)
static void awtLater(JComponent component, int delay, Object r) {
installTimer(component, r, delay, delay, false);
}
static BufferedImage getImageFromClipboard() { try {
Transferable transferable = Toolkit.getDefaultToolkit().getSystemClipboard().getContents(null);
if (transferable != null && transferable.isDataFlavorSupported(DataFlavor.imageFlavor))
return (BufferedImage) transferable.getTransferData(DataFlavor.imageFlavor);
return null;
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static String uploadImage(String title, byte[] imgData) { try {
return uploadImage(programID(), title, imgData);
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static String uploadImage(String gummipw, String title, byte[] imgData) { try {
if (gummipw == null || gummipw.length() == 0)
throw new RuntimeException("Need gummi password.");
System.out.println("Uploading:");
System.out.println(" gummipw: " + gummipw);
System.out.println(" " + title);
int displayLength = 40;
System.out.println(" " + imgData.length + " bytes of image data");
URL url = new URL("http://tinybrain.de:8080/tb-int/add_snippet.php");
String postData =
"gummipw=" + URLEncoder.encode(unnull(gummipw), "UTF-8")
+ "&blob=" + URLEncoder.encode(base64encode(imgData), "UTF-8")
+ "&name=" + URLEncoder.encode(unnull(title), "UTF-8")
+ "&type=" + 23 /* SN_IMAGE */
+ "&high=1&public=1";
//System.out.println(postData);
String contents = doPost(postData, url.openConnection(), url);
System.out.println(contents);
if (isInteger(contents)) {
long id = parseSnippetID(contents);
System.out.println("=> #" + id);
return "#" + id;
} else
throw new RuntimeException("Server error: " + contents);
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static boolean neq(Object a, Object b) {
return !eq(a, b);
}
static void printStackTrace(Throwable e) {
// we go to system.out now - system.err is nonsense
print(getStackTrace(e));
}
static void printStackTrace() {
printStackTrace(new Throwable());
}
static void printStackTrace(String indent, Throwable e) {
if (endsWithLetter(indent)) indent += " ";
printIndent(indent, getStackTrace(e));
}
static boolean contains(Collection c, Object o) {
return c != null && c.contains(o);
}
static boolean contains(Object[] x, Object o) {
if (x != null)
for (Object a : x)
if (eq(a, o))
return true;
return false;
}
static boolean contains(String s, char c) {
return s != null && s.indexOf(c) >= 0;
}
static boolean contains(String s, String b) {
return s != null && s.indexOf(b) >= 0;
}
static void revalidate(Component c) {
if (c == null || !c.isShowing()) return;
// magic combo to actually relayout and repaint
c.revalidate();
c.repaint();
}
static void addMenuItem(JPopupMenu menu, String text, Runnable action) {
menu.add(jmenuItem(text, action));
}
static byte[] toPNG(BufferedImage img) {
return convertToPNG(img);
}
static void swingNowOrLater(Runnable r) {
if (isAWTThread())
r.run();
else
swingLater(r);
}
static void copyImageToClipboard(Image img) {
TransferableImage trans = new TransferableImage(img);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents( trans, null);
print("Copied image to clipboard (" + img.getWidth(null) + "*" + img.getHeight(null) + " px)");
}
static boolean inRange(int x, int n) {
return x >= 0 && x < n;
}
static int asInt(Object o) {
return toInt(o);
}
static class componentPopupMenu_Maker {
List menuMakers = new ArrayList();
}
static Map componentPopupMenu_map = new WeakHashMap();
static ThreadLocal componentPopupMenu_mouseEvent = new ThreadLocal();
// menuMaker = voidfunc(JPopupMenu)
static void componentPopupMenu(final JComponent component, final Object menuMaker) {
swingNowOrLater(new Runnable() { public void run() { try {
componentPopupMenu_Maker maker = componentPopupMenu_map.get(component);
if (maker == null) {
componentPopupMenu_map.put(component, maker = new componentPopupMenu_Maker());
final componentPopupMenu_Maker _maker = maker;
component.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) { displayMenu(e); }
public void mouseReleased(MouseEvent e) { displayMenu(e); }
void displayMenu(MouseEvent e) {
if (e.isPopupTrigger()) {
JPopupMenu menu = new JPopupMenu();
int emptyCount = menu.getComponentCount();
componentPopupMenu_mouseEvent.set(e);
for (Object menuMaker : _maker.menuMakers)
pcallF(menuMaker, menu);
// show menu if any items in it
if (menu.getComponentCount() != emptyCount)
menu.show(e.getComponent(), e.getX(), e.getY());
}
}
});
}
maker.menuMakers.add(menuMaker);
} catch (Exception __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); } } public String toString() { return "componentPopupMenu_Maker maker = componentPopupMenu_map.get(component);\n if (maker == null) {\n componentPopupMenu_map.put(component, maker = new componentPopupMenu_Maker);\n final componentPopupMenu_Maker _maker = maker;\n component.addMouseListener(new MouseAdapter {\n public void mousePressed(MouseEvent e) { displayMenu(e); }\n public void mouseReleased(MouseEvent e) { displayMenu(e); }\n \n void displayMenu(MouseEvent e) {\n if (e.isPopupTrigger()) {\n new JPopupMenu menu;\n int emptyCount = menu.getComponentCount();\n \n componentPopupMenu_mouseEvent.set(e);\n for (Object menuMaker : _maker.menuMakers)\n pcallF(menuMaker, menu);\n \n // show menu if any items in it\n if (menu.getComponentCount() != emptyCount)\n menu.show(e.getComponent(), e.getX(), e.getY());\n }\n }\n });\n }\n maker.menuMakers.add(menuMaker);"; }});
}
// get purpose 1: access a list/array (safer version of x.get(y))
static A get(List l, int idx) {
return l != null && idx >= 0 && idx < l(l) ? l.get(idx) : null;
}
static A get(A[] l, int idx) {
return idx >= 0 && idx < l(l) ? l[idx] : null;
}
// default to false
static boolean get(boolean[] l, int idx) {
return idx >= 0 && idx < l(l) ? l[idx] : false;
}
static Class get_dynamicObject = DynamicObject.class;
// get purpose 2: access a field by reflection or a map
static Object get(Object o, String field) {
try {
if (o instanceof Class) return get((Class) o, field);
if (o instanceof Map)
return ((Map) o).get(field);
Field f = getOpt_findField(o.getClass(), field);
if (f != null) {
f.setAccessible(true);
return f.get(o);
}
if (get_dynamicObject != null && get_dynamicObject.isInstance(o))
return call(get_raw(o, "fieldValues"), "get", field);
} catch (Exception e) {
throw asRuntimeException(e);
}
throw new RuntimeException("Field '" + field + "' not found in " + o.getClass().getName());
}
static Object get_raw(Object o, String field) {
try {
Field f = get_findField(o.getClass(), field);
f.setAccessible(true);
return f.get(o);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Object get(Class c, String field) {
try {
Field f = get_findStaticField(c, field);
f.setAccessible(true);
return f.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Field get_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0)
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Static field '" + field + "' not found in " + c.getName());
}
static Field get_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
throw new RuntimeException("Field '" + field + "' not found in " + c.getName());
}
//please include function withMargin.
static int showForm_defaultGap = 4;
static JComponent showFormTitled(String title, Object... _parts) {
List l = new ArrayList();
final Var frame = new Var();
List parts = asList(_parts);
Runnable submit = null;
for (int i = 0; i < l(parts); i++) {
final Object o = parts.get(i), next = get(parts, i+1);
if (o instanceof Runnable)
l.add(ll(null, jbutton("Submit", submit = new Runnable() { public void run() { try {
Object result = call(o);
if (neq(Boolean.FALSE, result))
disposeFrame(frame.get());
} catch (Exception __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); } } public String toString() { return "Object result = call(o);\r\n if (neq(Boolean.FALSE, result))\r\n disposeFrame(frame.get());"; }})));
else if (o instanceof Component || o instanceof String || next instanceof Component) { // smartAdd accepts strings
l.add(ll(o == null ? new JPanel() : o, next));
if (next instanceof JButton && submit == null)
submit = new Runnable() { public void run() { try { ((JButton) next).doClick() ;
} catch (Exception __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); } } public String toString() { return "((JButton) next).doClick()"; }};
i++;
}
else print("showForm: Unknown element type: " + getClassName(o));
}
if (submit != null) {
List textFields = collectInstances(flattenList(l), JTextField.class);
for (JTextField textField : textFields) onEnter(textField, submit);
}
JPanel panel = hvgrid((List) l, showForm_defaultGap);
frame.set(minFrameWidth(showPackedFrame(title, withMargin(panel)), 400));
return panel;
}
// onDrop: voidfunc(File)
static void jHandleFileDrop(JComponent c, final Object onDrop) {
new DropTarget(c, new DropTargetAdapter() {
public void drop(DropTargetDropEvent e) {
try { /* pcall 1*/
Transferable tr = e.getTransferable();
DataFlavor[] flavors = tr.getTransferDataFlavors();
for (DataFlavor flavor : flavors) {
if (flavor.isFlavorJavaFileListType()) {
e.acceptDrop(e.getDropAction());
File file = first((List) tr.getTransferData(flavor));
if (file != null && !isFalse(callF(onDrop, file)))
e.dropComplete(true);
return;
}
}
/* pcall 2 */ } catch (Throwable __e) { printStackTrace(__e); }
e.rejectDrop();
}
});
}
static int max(int a, int b) {
return Math.max(a, b);
}
static int max(int a, int b, int c) {
return max(max(a, b), c);
}
static long max(int a, long b) {
return Math.max((long) a, b);
}
static long max(long a, long b) {
return Math.max(a, b);
}
static double max(int a, double b) {
return Math.max((double) a, b);
}
static float max(float a, float b) {
return Math.max(a, b);
}
static int max(Collection c) {
int x = Integer.MIN_VALUE;
for (int i : c) x = max(x, i);
return x;
}
static double max(double[] c) {
if (c.length == 0) return Double.MIN_VALUE;
double x = c[0];
for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]);
return x;
}
static float max(float[] c) {
if (c.length == 0) return Float.MAX_VALUE;
float x = c[0];
for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]);
return x;
}
static byte max(byte[] c) {
byte x = -128;
for (byte d : c) if (d > x) x = d;
return x;
}
static File getProgramDir() {
return programDir();
}
static File getProgramDir(String snippetID) {
return programDir(snippetID);
}
static void popup(final Throwable throwable) {
popupError(throwable);
}
static void popup(final String msg) {
print(msg);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JOptionPane.showMessageDialog(null, msg);
}
});
}
static volatile StringBuffer local_log = new StringBuffer(); // not redirected
static volatile StringBuffer print_log = local_log; // might be redirected, e.g. to main bot
// in bytes - will cut to half that
static volatile int print_log_max = 1024*1024;
static volatile int local_log_max = 100*1024;
//static int print_maxLineLength = 0; // 0 = unset
static boolean print_silent; // total mute if set
static volatile ThreadLocal print_byThread; // special handling by thread
static void print() {
print("");
}
// slightly overblown signature to return original object...
static A print(A o) {
ping();
if (print_silent) return o;
String s = String.valueOf(o) + "\n";
print_noNewLine(s);
return o;
}
static void print_noNewLine(String s) {
if (print_byThread != null) {
Object f = print_byThread.get();
if (f != null)
if (isFalse(callF(f, s))) return;
}
print_raw(s);
}
static void print_raw(String s) {
// TODO if (print_maxLineLength != 0)
StringBuffer loc = local_log;
StringBuffer buf = print_log;
int loc_max = print_log_max;
if (buf != loc && buf != null) {
print_append(buf, s, print_log_max);
loc_max = local_log_max;
}
if (loc != null)
print_append(loc, s, loc_max);
System.out.print(s);
}
static void print(long l) {
print(String.valueOf(l));
}
static void print(char c) {
print(String.valueOf(c));
}
static void print_append(StringBuffer buf, String s, int max) {
synchronized(buf) {
buf.append(s);
max /= 2;
if (buf.length() > max) try {
int newLength = max/2;
int ofs = buf.length()-newLength;
String newString = buf.substring(ofs);
buf.setLength(0);
buf.append("[...] ").append(newString);
} catch (Exception e) {
buf.setLength(0);
}
}
}
static boolean loadBufferedImage_useImageCache = true;
static BufferedImage loadBufferedImage(String snippetIDOrURL) { try {
if (snippetIDOrURL == null) return null;
if (isURL(snippetIDOrURL))
return ImageIO.read(new URL(snippetIDOrURL));
if (!isSnippetID(snippetIDOrURL)) throw fail("Not a URL or snippet ID: " + snippetIDOrURL);
String snippetID = "" + parseSnippetID(snippetIDOrURL);
try {
File dir = getCacheProgramDir("Image-Snippets");
if (loadBufferedImage_useImageCache) {
dir.mkdirs();
File file = new File(dir, snippetID + ".png");
if (file.exists() && file.length() != 0)
try {
return ImageIO.read(file);
} catch (Throwable e) {
e.printStackTrace();
// fall back to loading from sourceforge
}
}
String imageURL = snippetImageURL(snippetID);
System.err.println("Loading image: " + imageURL);
BufferedImage image = ImageIO.read(new URL(imageURL));
if (loadBufferedImage_useImageCache) {
File tempFile = new File(dir, snippetID + ".tmp." + System.currentTimeMillis());
ImageIO.write(image, "png", tempFile);
tempFile.renameTo(new File(dir, snippetID + ".png"));
//Log.info("Cached image.");
}
//Log.info("Loaded image.");
return image;
} catch (IOException e) {
throw new RuntimeException(e);
}
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static BufferedImage loadBufferedImage(File file) { try {
return file.isFile() ? ImageIO.read(file) : null;
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static boolean equals(Object a, Object b) {
return a == null ? b == null : a.equals(b);
}
static void messageBox(final String msg) {
swingAndWait(new Runnable() { public void run() { try {
JOptionPane.showMessageDialog(null, msg, "JavaX", JOptionPane.INFORMATION_MESSAGE);
} catch (Exception __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); } } public String toString() { return "JOptionPane.showMessageDialog(null, msg, \"JavaX\", JOptionPane.INFORMATION_MESSAGE);"; }});
}
static void printIndent(Object o) {
print(indentx(str(o)));
}
static void printIndent(String indent, Object o) {
print(indentx(indent, str(o)));
}
static void printIndent(int indent, Object o) {
print(indentx(indent, str(o)));
}
static ArrayList asList(A[] a) {
return new ArrayList(Arrays.asList(a));
}
static ArrayList asList(int[] a) {
ArrayList l = new ArrayList();
for (int i : a) l.add(i);
return l;
}
static ArrayList asList(Iterable s) {
if (s instanceof ArrayList) return (ArrayList) s;
ArrayList l = new ArrayList();
if (s != null)
for (A a : s)
l.add(a);
return l;
}
static List collectInstances(Iterable i, Class c) {
List l = new ArrayList();
for (Object o : i)
if (isInstanceX(c, o))
l.add(o);
return l;
}
static void popupError(final Throwable throwable) {
throwable.printStackTrace(); // print stack trace to console for the experts
SwingUtilities.invokeLater(new Runnable() {
public void run() {
String text = throwable.toString();
//text = cutPrefix(text, "java.lang.RuntimeException: ");
JOptionPane.showMessageDialog(null, text);
}
});
}
static void swingLater(long delay, final Object r) {
javax.swing.Timer timer = new javax.swing.Timer(toInt(delay), actionListener(r));
timer.setRepeats(false);
timer.start();
}
static void swingLater(Object r) {
SwingUtilities.invokeLater(toRunnable(r));
}
static boolean isURL(String s) {
return s.startsWith("http://") || s.startsWith("https://");
}
static JMenuItem jmenuItem(String text, final Object r) {
JMenuItem mi = new JMenuItem(text);
mi.addActionListener(actionListener(r));
return mi;
}
static JButton jbutton(String text, Object action) {
return newButton(text, action);
}
// button without action
static JButton jbutton(String text) {
return newButton(text, null);
}
static String doPost(Map urlParameters, String url) {
return doPost(makePostData(urlParameters), url);
}
static String doPost(String urlParameters, String url) { try {
URL _url = new URL(url);
return doPost(urlParameters, _url.openConnection(), _url);
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static String doPost(String urlParameters, URLConnection conn, URL url) { try {
setHeaders(conn);
print("Sending POST request: " + url);
// connect and do POST
conn.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(urlParameters);
writer.flush();
String contents = loadPage(conn, url);
writer.close();
return contents;
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static List flattenList(List a) {
List l = new ArrayList();
for (Object x : a)
if (x instanceof List)
l.addAll(flattenList((List) x));
else
l.add(x);
return l;
}
static volatile boolean ping_pauseAll;
static int ping_sleep = 100; // poll pauseAll flag every 100
static volatile boolean ping_anyActions;
static Map ping_actions = synchroMap(new WeakHashMap());
// returns true if it did anything
static boolean ping() { try {
if (ping_pauseAll && !isAWTThread()) {
do
Thread.sleep(ping_sleep);
while (ping_pauseAll);
return true;
}
if (ping_anyActions) {
Object action;
synchronized(mc()) {
action = ping_actions.get(currentThread());
if (action instanceof Runnable)
ping_actions.remove(currentThread());
if (ping_actions.isEmpty()) ping_anyActions = false;
}
if (action instanceof Runnable)
((Runnable) action).run();
else if (eq(action, "cancelled"))
throw fail("Thread cancelled.");
}
return false;
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static File getCacheProgramDir() {
return getCacheProgramDir(getProgramID());
}
static File getCacheProgramDir(String snippetID) {
return new File(userHome(), "JavaX-Caches/" + formatSnippetIDOpt(snippetID));
}
public static boolean isSnippetID(String s) {
try {
parseSnippetID(s);
return true;
} catch (RuntimeException e) {
return false;
}
}
static boolean endsWithLetter(String s) {
return nempty(s) && isLetter(last(s));
}
static int l(Object[] a) { return a == null ? 0 : a.length; }
static int l(boolean[] a) { return a == null ? 0 : a.length; }
static int l(byte[] a) { return a == null ? 0 : a.length; }
static int l(int[] a) { return a == null ? 0 : a.length; }
static int l(float[] a) { return a == null ? 0 : a.length; }
static int l(char[] a) { return a == null ? 0 : a.length; }
static int l(Collection c) { return c == null ? 0 : c.size(); }
static int l(Map m) { return m == null ? 0 : m.size(); }
static int l(CharSequence s) { return s == null ? 0 : s.length(); }
static int l(Object o) {
return o instanceof String ? l((String) o)
: l((Collection) o); // incomplete
}
static JFrame minFrameWidth(JFrame frame, int w) {
if (frame.getWidth() < w)
frame.setSize(w, frame.getHeight());
return frame;
}
// TODO: all the fringe cases (?)
static JPanel hvgrid(List> components) {
if (empty(components)) return new JPanel();
int h = l(components), w = l(first(components));
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(h, w));
for (List row : components)
smartAdd(panel, row);
return panel;
}
static JPanel hvgrid(List> components, int gap) {
JPanel panel = hvgrid(components);
GridLayout g = (GridLayout) ( panel.getLayout());
g.setHgap(gap);
g.setVgap(gap);
return panel;
}
static Object getOpt(Object o, String field) {
return getOpt_cached(o, field);
}
static Object getOpt_raw(Object o, String field) {
try {
Field f = getOpt_findField(o.getClass(), field);
if (f == null) return null;
f.setAccessible(true);
return f.get(o);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Object getOpt(Class c, String field) {
try {
if (c == null) return null;
Field f = getOpt_findStaticField(c, field);
if (f == null) return null;
f.setAccessible(true);
return f.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
static Field getOpt_findStaticField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0)
return f;
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
static Field getOpt_findField(Class> c, String field) {
Class _c = c;
do {
for (Field f : _c.getDeclaredFields())
if (f.getName().equals(field))
return f;
_c = _c.getSuperclass();
} while (_c != null);
return null;
}
static Object first(Object list) {
return ((List) list).isEmpty() ? null : ((List) list).get(0);
}
static A first(List list) {
return list.isEmpty() ? null : list.get(0);
}
static A first(A[] bla) {
return bla == null || bla.length == 0 ? null : bla[0];
}
static A first(Iterable i) {
if (i == null) return null;
Iterator it = i.iterator();
return it.hasNext() ? it.next() : null;
}
static List ll(A... a) {
return litlist(a);
}
static boolean isInteger(String s) {
if (s == null) return false;
int n = l(s);
if (n == 0) return false;
int i = 0;
if (s.charAt(0) == '-')
if (++i >= n) return false;
while (i < n) {
char c = s.charAt(i);
if (c < '0' || c > '9') return false;
++i;
}
return true;
}
static RuntimeException asRuntimeException(Throwable t) {
return t instanceof RuntimeException ? (RuntimeException) t : new RuntimeException(t);
}
static String getStackTrace(Throwable throwable) {
StringWriter writer = new StringWriter();
throwable.printStackTrace(new PrintWriter(writer));
return writer.toString();
}
static File programDir_mine; // set this to relocate program's data
static File programDir() {
return programDir(getProgramID());
}
static File programDir(String snippetID) {
if (programDir_mine != null && sameSnippetID(snippetID, programID()))
return programDir_mine;
return new File(javaxDataDir(), formatSnippetID(snippetID));
}
static int withMargin_defaultWidth = 6;
static JPanel withMargin(Component c) {
JPanel p = new JPanel(new BorderLayout());
int w = withMargin_defaultWidth;
p.setBorder(BorderFactory.createEmptyBorder(w, w, w, w));
p.add(c);
return p;
}
static byte[] convertToPNG(BufferedImage img) { try {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ImageIO.write(img, "png", stream);
return stream.toByteArray();
} catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }}
static String base64encode(byte[] a) {
int aLen = a.length;
int numFullGroups = aLen/3;
int numBytesInPartialGroup = aLen - 3*numFullGroups;
int resultLen = 4*((aLen + 2)/3);
StringBuffer result = new StringBuffer(resultLen);
char[] intToAlpha = intToBase64;
// Translate all full groups from byte array elements to Base64
int inCursor = 0;
for (int i=0; i> 2]);
result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
result.append(intToAlpha[(byte1 << 2)&0x3f | (byte2 >> 6)]);
result.append(intToAlpha[byte2 & 0x3f]);
}
// Translate partial group if present
if (numBytesInPartialGroup != 0) {
int byte0 = a[inCursor++] & 0xff;
result.append(intToAlpha[byte0 >> 2]);
if (numBytesInPartialGroup == 1) {
result.append(intToAlpha[(byte0 << 4) & 0x3f]);
result.append("==");
} else {
// assert numBytesInPartialGroup == 2;
int byte1 = a[inCursor++] & 0xff;
result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
result.append(intToAlpha[(byte1 << 2)&0x3f]);
result.append('=');
}
}
// assert inCursor == a.length;
// assert result.length() == resultLen;
return result.toString();
}
/**
* This array is a lookup table that translates 6-bit positive integer
* index values into their "Base64 Alphabet" equivalents as specified
* in Table 1 of RFC 2045.
*/
static final char intToBase64[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
};
static boolean isFalse(Object o) {
return eq(false, o);
}
static String snippetImageURL(String snippetID) {
long id = parseSnippetID(snippetID);
String url;
if (id == 1000010 || id == 1000012)
url = "http://tinybrain.de:8080/tb/show-blobimage.php?id=" + id;
else
url = "http://eyeocr.sourceforge.net/filestore/filestore.php?cmd=serve&file=blob_" + id
+ "&contentType=image/png";
return url;
}
static JTextField onEnter(JTextField tf, final Object action) {
if (action == null || tf == null) return tf;
tf.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
pcallF(action);
}
});
return tf;
}
static JList onEnter(JList list, final Object action) {
list.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent ke) {
if (ke.getKeyCode() == KeyEvent.VK_ENTER)
pcallF(action);
}
});
return list;
}
static String getClassName(Object o) {
return o == null ? "null" : o.getClass().getName();
}
public static long parseSnippetID(String snippetID) {
long id = Long.parseLong(shortenSnippetID(snippetID));
if (id == 0) throw fail("0 is not a snippet ID");
return id;
}
// first delay = delay
static Timer installTimer(JComponent component, Object r, long delay) {
return installTimer(component, r, delay, delay);
}
// first delay = delay
static Timer installTimer(RootPaneContainer frame, long delay, Object r) {
return installTimer(frame.getRootPane(), r, delay, delay);
}
// first delay = delay
static Timer installTimer(JComponent component, long delay, Object r) {
return installTimer(component, r, delay, delay);
}
static void installTimer(JComponent component, long delay, long firstDelay, Object r) {
installTimer(component, r, delay, firstDelay);
}
static Timer installTimer(final JComponent component, final Object r, final long delay, final long firstDelay) {
return installTimer(component, r, delay, firstDelay, true);
}
static Timer installTimer(final JComponent component, final Object r, final long delay, final long firstDelay, final boolean repeats) {
return (Timer) swingAndWait(new Object() { Object get() {
Timer timer = new Timer(toInt(delay), new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent _evt) {
try { /* pcall 1*/
if (!allPaused())
callF(r);
/* pcall 2 */ } catch (Throwable __e) { printStackTrace(__e); }
}});
timer.setInitialDelay(toInt(firstDelay));
timer.setRepeats(repeats);
bindTimerToComponent(timer, component);
return timer;
}
public String toString() { return "Timer timer = new Timer(toInt(delay), actionListener {\r\n pcall {\r\n if (!allPaused())\r\n callF(r);\r\n }\r\n });\r\n timer.setInitialDelay(toInt(firstDelay));\r\n timer.setRepeats(repeats);\r\n bindTimerToComponent(timer, component);\r\n ret timer;"; }});
}
static Timer installTimer(JFrame frame, long delay, long firstDelay, Object r) {
return installTimer(frame.getRootPane(), r, delay, firstDelay);
}
static String programID() {
return getProgramID();
}
static JFrame showPackedFrame(String title, Component contents) {
return packFrame(showFrame(title, contents));
}
static JFrame showPackedFrame(Component contents) {
return packFrame(showFrame(contents));
}
static int toInt(Object o) {
if (o == null) return 0;
if (o instanceof Number)
return ((Number) o).intValue();
if (o instanceof String)
return parseInt((String) o);
throw fail("woot not int: " + getClassName(o));
}
static int toInt(long l) {
if (l != (int) l) throw fail("Too large for int: " + l);
return (int) l;
}
static String shortenSnippetID(String snippetID) {
if (snippetID.startsWith("#"))
snippetID = snippetID.substring(1);
String httpBlaBla = "http://tinybrain.de/";
if (snippetID.startsWith(httpBlaBla))
snippetID = snippetID.substring(httpBlaBla.length());
return "" + parseLong(snippetID);
}
static Thread currentThread() {
return Thread.currentThread();
}
static int packFrame_minw = 150, packFrame_minh = 50;
static JFrame packFrame(Component c) {
JFrame frame = getFrame(c);
if (frame == null) return null;
frame.pack();
int maxW = getScreenWidth()-50, maxH = getScreenHeight()-50;
frame.setSize(
min(maxW, max(frame.getWidth(), packFrame_minw)),
min(maxH, max(frame.getHeight(), packFrame_minh)));
return frame;
}
static JPanel smartAdd(JPanel panel, List parts) {
for (Object o : parts) {
Component c;
if (o == null)
c = new JPanel();
else if (o instanceof String)
c = jlabel((String) o);
else
c = wrap(o);
panel.add(c);
}
return panel;
}
static JPanel smartAdd(JPanel panel, Object... parts) {
return smartAdd(panel, asList(parts));
}
static String str(Object o) {
return String.valueOf(o);
}
static String str(char[] c) {
return new String(c);
}
static boolean allPaused() {
return ping_pauseAll;
}
static void bindTimerToComponent(final Timer timer, JFrame f) {
bindTimerToComponent(timer, f.getRootPane());
}
static void bindTimerToComponent(final Timer timer, JComponent c) {
if (c.isShowing())
timer.start();
c.addAncestorListener(new AncestorListener() {
public void ancestorAdded(AncestorEvent event) {
timer.start();
}
public void ancestorRemoved(AncestorEvent event) {
timer.stop();
}
public void ancestorMoved(AncestorEvent event) {
}
});
}
static String programID;
static String getProgramID() {
return nempty(programID) ? formatSnippetIDOpt(programID) : "?";
}
// TODO: ask JavaX instead
static String getProgramID(Class c) {
String id = (String) getOpt(c, "programID");
if (nempty(id))
return formatSnippetID(id);
return "?";
}
static String getProgramID(Object o) {
return getProgramID(getMainClass(o));
}
static ActionListener actionListener(final Object runnable) {
return new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent _evt) { pcallF(runnable); }};
}
static String _userHome;
static String userHome() {
if (_userHome == null) {
if (isAndroid())
_userHome = "/storage/sdcard0/";
else
_userHome = System.getProperty("user.home");
//System.out.println("userHome: " + _userHome);
}
return _userHome;
}
static File userHome(String path) {
return new File(userDir(), path);
}
static ArrayList litlist(A... a) {
return new ArrayList(Arrays.asList(a));
}
static JFrame showFrame() {
return makeFrame();
}
static JFrame showFrame(Object content) {
return makeFrame(content);
}
static JFrame showFrame(String title) {
return makeFrame(title);
}
static JFrame showFrame(String title, Object content) {
return makeFrame(title, content);
}
static JFrame showFrame(JFrame frame) {
if (frameTooSmall(frame)) frameStandardSize(frame);
frame.setVisible(true);
return frame;
}
// make or update frame
static JFrame showFrame(String title, Object content, JFrame frame) {
if (frame == null)
return showFrame(title, content);
else {
frame.setTitle(title);
setFrameContents(frame, content);
return frame;
}
}
static void setHeaders(URLConnection con) throws IOException {
String computerID = getComputerID();
if (computerID != null) try {
con.setRequestProperty("X-ComputerID", computerID);
con.setRequestProperty("X-OS", System.getProperty("os.name") + " " + System.getProperty("os.version"));
} catch (Throwable e) {
//printShortException(e);
}
}
static ThreadLocal loadPage_charset = new ThreadLocal();
static boolean loadPage_allowGzip = true, loadPage_debug;
static boolean loadPage_anonymous; // don't send computer ID
static int loadPage_verboseness = 100000;
static int loadPage_retries = 60; // seconds
public static String loadPageSilently(String url) {
try {
return loadPageSilently(new URL(loadPage_preprocess(url)));
} catch (IOException e) { throw new RuntimeException(e); }
}
public static String loadPageSilently(URL url) {
try {
IOException e = null;
for (int tries = 0; tries < loadPage_retries; tries++)
try {
URLConnection con = openConnection(url);
return loadPage(con, url);
} catch (IOException _e) {
e = _e;
if (loadPageThroughProxy_enabled) {
print("Trying proxy because of: " + e);
try {
return loadPageThroughProxy(str(url));
} catch (Throwable e2) {
print(" " + exceptionToStringShort(e2));
}
}
sleepSeconds(1);
}
throw e;
} catch (IOException e) { throw new RuntimeException(e); }
}
static String loadPage_preprocess(String url) {
if (url.startsWith("tb/"))
url = "tinybrain.de:8080/" + url;
if (url.indexOf("://") < 0)
url = "http://" + url;
return url;
}
public static String loadPage(String url) {
try {
url = loadPage_preprocess(url);
print("Loading: " + hideCredentials(url));
return loadPageSilently(new URL(url));
} catch (IOException e) { throw new RuntimeException(e); }
}
public static String loadPage(URL url) {
print("Loading: " + hideCredentials(url.toExternalForm()));
return loadPageSilently(url);
}
public static String loadPage(URLConnection con, URL url) throws IOException {
try {
if (!loadPage_anonymous)
setHeaders(con);
if (loadPage_allowGzip)
con.setRequestProperty("Accept-Encoding", "gzip");
} catch (Throwable e) {} // fails if within doPost
String contentType = con.getContentType();
if (contentType == null)
throw new IOException("Page could not be read: " + url);
//print("Content-Type: " + contentType);
String charset = loadPage_charset == null ? null : loadPage_charset.get();
if (charset == null) charset = loadPage_guessCharset(contentType);
InputStream in = con.getInputStream();
if ("gzip".equals(con.getContentEncoding())) {
if (loadPage_debug)
print("loadPage: Using gzip.");
in = new GZIPInputStream(in);
}
Reader r = new InputStreamReader(in, charset);
StringBuilder buf = new StringBuilder();
int n = 0;
while (true) {
int ch = r.read();
if (ch < 0)
break;
buf.append((char) ch);
++n;
if ((n % loadPage_verboseness) == 0) print(" " + n + " chars read");
}
return buf.toString();
}
static String loadPage_guessCharset(String contentType) {
Pattern p = Pattern.compile("text/[a-z]+;\\s+charset=([^\\s]+)\\s*");
Matcher m = p.matcher(contentType);
String match = m.matches() ? m.group(1) : null;
if (loadPage_debug)
print("loadPage: contentType=" + contentType + ", match: " + match);
/* If Content-Type doesn't match this pre-conception, choose default and hope for the best. */
return or(match, "ISO-8859-1");
}
static boolean sameSnippetID(String a, String b) {
return a != null && b != null && parseSnippetID(a) == parseSnippetID(b);
}
// action can be Runnable or a function name
static JButton newButton(String text, final Object action) {
JButton btn = new JButton(text);
if (action != null)
btn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent _evt) {
callFunction(action);
}});
return btn;
}
static Runnable toRunnable(final Object o) {
if (o instanceof Runnable) return (Runnable) o;
return new Runnable() { public void run() { try { callF(o) ;
} catch (Exception __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); } } public String toString() { return "callF(o)"; }};
}
static boolean empty(Collection c) {
return isEmpty(c);
}
static boolean empty(String s) {
return isEmpty(s);
}
static boolean empty(Map map) {
return map == null || map.isEmpty();
}
static boolean empty(Object[] o) {
return o == null || o.length == 0;
}
static boolean empty(Object o) {
if (o instanceof Collection) return empty((Collection) o);
if (o instanceof String) return empty((String) o);
if (o instanceof Map) return empty((Map) o);
if (o instanceof Object[]) return empty((Object[]) o);
throw fail("unknown type for 'empty': " + getType(o));
}
static boolean empty(float[] a) { return a == null || a.length == 0; }
static String makePostData(Map