JAVA SWT Animated GIF - java

I need to add animated gif in form of spinner, into some SWT widget like for example Label. This Label will be as default labelSpiner.setEnabled(false). When I start some long duration operation this Label with spinner will show (labelSpinner.setEnabled(true))in right corner of window.
Normaly Image can be added to Label by labelSpinner.setImage(arg0)
If I add this SPINNER.GIF normal way into Label, it wont animate, its only static Image.
Does anybody know how to add animated gif (for example some spinner) into SWT based JAVA SE app widget? I browsed many examples but many of them were useless, and those good were too complicated.
I would like to do it very simple.
Can somebody help?

Did you try the Eclipse article about SWT Images?
This part will load the image and display it in a Canvas:
ImageLoader loader = new ImageLoader();
loader.load(getClass().getResourceAsStream("Idea_SWT_Animation.gif"));
Canvas canvas = new Canvas(shell,SWT.NONE);
image = new Image(display,loader.data[0]);
int imageNumber;
final GC gc = new GC(image);
canvas.addPaintListener(new PaintListener(){
public void paintControl(PaintEvent event){
event.gc.drawImage(image,0,0);
}
});
And this part updates the gif:
Thread thread = new Thread(){
public void run(){
long currentTime = System.currentTimeMillis();
int delayTime = loader.data[imageNumber].delayTime;
while(currentTime + delayTime * 10 > System.currentTimeMillis()){
// Wait till the delay time has passed
}
display.asyncExec(new Runnable(){
public void run(){
// Increase the variable holding the frame number
imageNumber = imageNumber == loader.data.length-1 ? 0 : imageNumber+1;
// Draw the new data onto the image
ImageData nextFrameData = loader.data[imageNumber];
Image frameImage = new Image(display,nextFrameData);
gc.drawImage(frameImage,nextFrameData.x,nextFrameData.y);
frameImage.dispose();
canvas.redraw();
}
});
}
};
shell.open();
thread.start();

After trying at least 3 different animated GIF examples, none of which worked, I started working on my own, based mainly on the answer above.
Here is a complete running example including:
a base64 decoder (courtesy of http://www.source-code.biz/base64coder/java/ )
spinner GIF
main method
Remove the main method, base64 methods, and image data, and you will have a working animated GIF canvas.
import java.io.IOException;
import java.io.InputStream;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class AnimatedGif extends Canvas {
public static void main(String[] args) throws IOException {
byte[] d = decode(b64.toCharArray(), 0, b64.length());
Display display = new Display ();
Shell shell = new Shell(display);
shell.setBounds(0, 0, 100, 100);
AnimatedGif gif = new AnimatedGif(shell, SWT.NONE);
gif.setLocation(10,10);
gif.setSize(16, 16);
gif.load(new java.io.ByteArrayInputStream(d));
shell.open();
gif.animate();
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ()) display.sleep ();
}
display.dispose ();
}
private final ImageLoader loader = new ImageLoader();
private int img = 0;
private volatile boolean animating = false;
private Thread animateThread;
public AnimatedGif(Composite parent, int style) {
super(parent, style);
}
public void load (InputStream resource) throws IOException {
loader.load(resource);
}
public void animate() {
if (animateThread == null) {
animateThread = createThread();
animateThread.setDaemon(true);
}
if (animateThread.isAlive())
return;
animateThread.start();
}
public void stop() {
animating = false;
if (animateThread != null)
try {
animateThread.join();
animateThread = null;
} catch (InterruptedException e) {
// do nothing
}
}
private Thread createThread() {
return new Thread() {
long currentTime = System.currentTimeMillis();
final Display display = getParent().getDisplay();
public void run() {
animating = true;
while(animating) {
img = (img == loader.data.length-1) ? 0 : img + 1;
int delayTime = Math.max(50, 10*loader.data[img].delayTime);
long now = System.currentTimeMillis();
long ms = Math.max(currentTime + delayTime - now, 5);
currentTime += delayTime;
try {
Thread.sleep(ms);
} catch(Exception e) {
return;
}
if (!display.isDisposed())
display.asyncExec(new Runnable() {
#Override
public void run() {
ImageData nextFrameData = loader.data[img];
Image frameImage = new Image(display, nextFrameData);
new GC(AnimatedGif.this).drawImage(frameImage, nextFrameData.x, nextFrameData.y);
frameImage.dispose();
//canvas.redraw();
}
});
}
Display.getDefault().asyncExec(new Runnable() {
#Override
public void run() {
new GC(AnimatedGif.this).fillRectangle(
0,
0,
getBounds().width,
getBounds().height);
}
});
}
};
}
private static final char[] map1 = new char[64];
static {
int i = 0;
for (char c = 'A'; c <= 'Z'; c++)
map1[i++] = c;
for (char c = 'a'; c <= 'z'; c++)
map1[i++] = c;
for (char c = '0'; c <= '9'; c++)
map1[i++] = c;
map1[i++] = '+';
map1[i++] = '/';
}
private static final byte[] map2 = new byte[128];
static {
for (int i = 0; i < map2.length; i++)
map2[i] = -1;
for (int i = 0; i < 64; i++)
map2[map1[i]] = (byte) i;
}
public static byte[] decode(char[] in, int iOff, int iLen) {
if (iLen % 4 != 0)
throw new IllegalArgumentException(
"Length of Base64 encoded input string is not a multiple of 4.");
while (iLen > 0 && in[iOff + iLen - 1] == '=')
iLen--;
int oLen = (iLen * 3) / 4;
byte[] out = new byte[oLen];
int ip = iOff;
int iEnd = iOff + iLen;
int op = 0;
while (ip < iEnd) {
int i0 = in[ip++];
int i1 = in[ip++];
int i2 = ip < iEnd ? in[ip++] : 'A';
int i3 = ip < iEnd ? in[ip++] : 'A';
if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
throw new IllegalArgumentException(
"Illegal character in Base64 encoded data.");
int b0 = map2[i0];
int b1 = map2[i1];
int b2 = map2[i2];
int b3 = map2[i3];
if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
throw new IllegalArgumentException(
"Illegal character in Base64 encoded data.");
int o0 = (b0 << 2) | (b1 >>> 4);
int o1 = ((b1 & 0xf) << 4) | (b2 >>> 2);
int o2 = ((b2 & 3) << 6) | b3;
out[op++] = (byte) o0;
if (op < oLen)
out[op++] = (byte) o1;
if (op < oLen)
out[op++] = (byte) o2;
}
return out;
}
static String b64 =
"R0lGODlhEAAQAPf/AMra5KO9zOzz9s3b5MDS3aS+zZOwwsrZ4+bt89jm7IKftuLr" +
"8ZCswH6bs9vn7qrD0+Ts8oqnvYKetomlu8PV4t7p79Pg6dzp79vm7q/F1aC6zdTi" +
"6bbL2XqYsdDf55SwxK/H1ajC0Yajudzp7q7E087c59Xi6niWr8XY4qW/0LnM2aO9" +
"zoyov7bK2djk7ICbtIOhtt7p7pq1yc3b5sDU38DR39vm7LDH1afA0Yqovebu85Gt" +
"wouovsvZ5oCdtunv9IaiuXyZscrb5qnC0Zezxdjj64WiuZ65y7vQ3N/p8OLq8avE" +
"1MTX4o6rwJaxxLnN29jm7a7F1dvm7Y2qwH2bs7zQ3Jizx9Df6djj7HmXr+Tt8rvO" +
"26/E1LrO3KC5zKW+z8/e577Q3oCctYShubTK2HyasZGtwHuYsdTg6enw89/p76zE" +
"04iku+Lr8LXJ2JKvw+Xt8tHf583b57vP3pu2ycjY45m0yNvp7qzE1bHI13qZsaK8" +
"zn2aspq0yODp8Nfi6svb5oaiuuDp76vE09Hf6ZWzxMfY4qnC087e5+rx9eLs8pSv" +
"xL/R3rPI2Nfj64ajuq7E1Y2pv7rQ2+Lp8J65yarC1JKvxLzR3nybsrzQ3unw9HmY" +
"sLvR3LPI17nO28rY5Iqlvc3c5urx9Iakus/f53iVrtPi6cnY436btNTi6tfi67PK" +
"1rHI2H6bspy3yJ63ydXi7JezxKjA0ZGuwNjk64CbtazE0Zezx8DR3NXi68TX4Nvn" +
"7e7097vP24CctH2atIqlvN7o7tPh6Nzn7JGvwK/F1MbX4dHg6MfY4b7S3c/e5n2b" +
"srjN2ezy9eDq78rb4svb473R2+Ts8cHV3r7R3eXu8rfN2JSvwo+tv9/p7pSxw6C7" +
"ytbj6cTX36zD1NHg5vL3+KnB0Onx9cPV35y4yLPJ1dnl7LnO2cHU3avD0bnP2sDV" +
"4pKvwdfk7O7z99Xi6XqXsNTi6N3o7sjY4ubv8s7c5qvE0env842svuLs8Z64yJm0" +
"xZq2x46svuLq8P///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQFAAD/ACwAAAAAEAAQ" +
"AAAIvQD/CRR4poEEf0q0DFz478SZFwqAxPC3AAEChqU6GAQSwcHEihcFntAoQUQE" +
"BgkcVKCI4IdAkiYZfCiScmXFfzBzMFhYk6K/jScZ/uspSEFMJ0KxpIxxAQgPBk5k" +
"CDVRBIoDDE8/yNAg1MIGmglkyvDy5cHCEh4smIC14d/WLyGGQGpBA4UQtBYsCDyy" +
"AseDByBaqKhhqAfaKwNTPIiyBAQZFUjqGmY4KEMGEG5UdAlDgYlQgQ9IdOJQhRPD" +
"gAAh+QQFAAD/ACwAAAAAEAAQAAAI1gD/CRR4IkiZBjx0DFwoMIueBj58EBGlRAtD" +
"h1TEKAikgJUOfxAWbsKk0QgbFjmEJEkiEIFAVBLGjMoxZUcfG1AEhvz3YiOoSAz/" +
"3VHzD8EPIxNYMPgQVMqFSRAWsGjyhoidoAmkVFjgb8eHPq80BMWS4I4fQZboaFiB" +
"I6gJFxhGXDiyJ4WsIZUWItrwxwYGF/9ShHjwIEOLGkwAkbJgAgvgwHjwLLnB4QmF" +
"HnI8oNmwYSCJDCDycPBUA8UMMHGuMHxAQvSTTBTqzBASVCCIFlWQ1KDAMCAAIfkE" +
"BQAA/wAsAAAAABAAEAAACMsA/wkUeKZDmSANfAxc+K8BlRe+FNRSMIbKMoYwFCjI" +
"CAOGEY1iqgyMMIHkhJIRgE14JImXEoEMdpiJyYBBpBxN5mjyB+GfEytWiNyyspCR" +
"ohE8f2jQ4GUpw38JLvBE8CVFChxDnkadOmTQoRCQtEqFoKNYlAdrMohNyiVDlBst" +
"5ix0lAAphAX/uNwgoyIMDQpMdJWAgrSNQC6NODyZQ4NJnVAWCFeYNLDFli6MDM3w" +
"gCZXgl0XGFaRVAPFZjQmHEl5KhCaaQ+EKDAMCAAh+QQFAAD/ACwAAAAAEAAQAAAI" +
"2wD/CRRIJUiHLCdODFz47xEMCT5eNOBjMAjDKTkisBFh5J+CiK3KDFy06I2ZJix4" +
"TJggYowCPr8EHqEjg4iTDzuaTGExQYEVQP9WCN3j5cjCKXYuIfihZEiIEDhwMBSo" +
"KMYCLSSiHAqxZKoNB0kW/MvAZQmJDFP/jfi3AMEaEDcacZgqZSACEjfIcOjCZKEL" +
"DGr+IdDxz42KJ0hQCEFkQVUCB34WEP6nYssWGqfkxDH1B8MIfwv8DUQShsKnEoQ2" +
"FMEQI4lohhR6gLFg4q+DCmn/zQBzZUMqGwwDAgAh+QQFAAD/ACwAAAAAEAAQAAAI" +
"uAD/CRTIgAcQBQ06DFz474iMDwVFSEh4gmGKFRoeMogAZGKHUgMHPcDxxYsMJxsl" +
"UhSYIcqDEF8yosyh8sy/BxmWPBjyYGFKCS/OkABBFBLDfxsPNujkhkyLFkchcpTA" +
"QYVVGkeLJHAQw1+VLkhqoDi6tasSTmFoGBJSYuHWCv4WaPlHAUWPEh4smMDyNi4C" +
"gUzu5t2g1QHcBQj+CsSrtwgUw34VD7xiAVZZvz+OCtyQAMMFQf4YBgQAIfkEBQAA" +
"/wAsAAAAABAAEAAACNYA/wkUeMTSDhZGXgxc+C9Fij10PjSZoADVJoYk8IRIoaHP" +
"GxaBJGDKMvBBBjwPZK14RYQBqDFi9AwkAWLJgyE4NNj5EGmUAiokQeTJcyNDJYY5" +
"jMQ80YKD0xYM/01ho6BBkCpPPD2pEfVgIB9lkGSqQYFJ1D45FPhoQBZFD0BRbQhh" +
"RYQHhToz5JBCxBBKEh2idPybAcaDhQ0msCSQcudfEn9KBAqJg8bEHxeLL6gRCEHL" +
"wCsbsNjAcKfCpH8Qov7b4ALDCD8LICD4N1u1iwuC/C34wTAgACH5BAUAAP8ALAAA" +
"AAAQABAAAAjNAP8JFMil2JAvGpwMXPiPC5cMUQal0GCFQQSGLRrdiPLgUAovVnZM" +
"gDGwyhYOZG6sCYFDAxEzERQ0ECipyxMVLTJAGqLhFoMJCqj8o1CD0ZwwcxaGHPni" +
"DAoUhmjQYPjvpwJfHWZoZUKBKkwYCsp4GFunK8NIEWDUCkIIDZpQuqjmAGZEJgUT" +
"uSyUcLSQUROgY8b8c5QACpQEiBErmvMoqEApu0ZIvkD5wghNksQsG3ihgr/PoD/z" +
"qsJwUhsIqFNDUEJV4IIfOhAg+MEwIAAh+QQFAAD/ACwAAAAAEAAQAAAI1wD/CRRI" +
"Yk0GEkNWDFz4T4WbGyC4RAmx4sgihki2qCBzY8khinQWTRlIIcyWJxwakQiBY4+M" +
"NzkeCaRAgQaSLhwyLMHhhYiZCDD+zejx6RQKJguPOGnCRgIVMGBKyBHC8N8HFiJ8" +
"BLligVAcRFV38DDyosMGExtMWajaZMK/BllSuSjyR1XVKRMU8DlhA4PfBC4WTsGq" +
"9cQ/BzFGOMAg5Z+Nf3YmjCkrsEISf37U/FOs6JICBa2CDPS3YMHAJDEQWOFThqE/" +
"HQj+lV7wA9CvqgJhx9aihGFAACH5BAUAAP8ALAAAAAAQABAAAAjAAP8JFMipCodO" +
"JB4MXPiPCYUwXVS4AZEhwyCGJXqgoIFEBRkQS6I8SDHwioeMhmqoaAHiwQMcK44I" +
"tGDhpJCNLSANCfFFg4x/G2CZqFli4YMvXmR8YJAgQZENFhj+87mUBwYHUIqYkCrD" +
"CQMeQC7EcJAAi1SvEUQoEOSvAlmpDCIAkdDA34K2bwcyyPGPbod/CO66dbo0Ld2B" +
"PwLjTRBXhN8TAxEgEDhWrt9SDCXfjQFEwYszkKX+06LEH90zDAMCACH5BAkAAP8A" +
"LAAAAAAQABAAAAjWAP8JFEihBpIqLUAMXPhPyIw6FDI94ZCHxAOGV+KAmYGihieK" +
"IDKQGLhhAxoPcnpQmHhjCR48KQS6wGLCAilATGq0yPDgQYiYLjDY+LMB0cJKQ2Sl" +
"2HPkwggMLkww/IdjhQY6lgT5uZMAy1QNr/p82OFvQQUpCabaIfKmCYsFECZdkDL1" +
"AwMWE4z8QPBPzZ2pkUAFUvBCIASBUGz02TElx6gxElAJ5PsvSRIhOViwMaJADKZN" +
"CyH408FKwWAxVPRkYahFiSgiPnw0UD11oA4eDcoEOcEwIAAh+QQJAAD/ACwAAAAA" +
"EAAQAAAIyAD/CRw4zAYtYdwGKvyXz1m2YAaF1XsGbWE1aW3UQKQVb8CBA8YG3qMH" +
"Z4E8c++OKQMwD9k4XALTpClp7tsxD8oGIOs2DaamRDPbOFMIwBi6ZARwuQMKp83C" +
"fwSiVUEqgKnThdTU9YrWq5nVp73OMWNmzWvQp6tWlUv7j6m4AQpt2Utny1a4tmnc" +
"AQhAaVuAAAUABxaoCdwzfq70UaJEzpUrSo8HQjNQqNC+WLEKZda8cNYsIoWuFTLA" +
"bhaxpwK1EWOADV+/hQEBACH5BAUAAP8ALAAAAAAQABAAAAjcAP8JFGgj1YYrYGYM" +
"XPivggMMLkxYANODAsN//pLEwFBkA6ESnyiEQTLQ3wJ/IzD8MRVHzikaW7aoEKhj" +
"gR8HCVRZQCQEBZInKtz804HAnxqIC5l04UDmBgkEEPxdkHKRQ6MbINYgODkiwcUM" +
"JJZwybA1iQMbF5eEOBSFhJYFMRR5ZYgDR4gQQ5T8QHDJzpSFR7zsWUH4HyArCiaw" +
"mNJkxwcnRGTQOSLwFx8FY0RMmMCDRRMzbxYtGlim1QsfCmAYEcEmQo6/C4N0CMKn" +
"wWkJMB5dFHjiRJbZVBgGBAAh+QQFAAD/ACwAAAAAEAAQAAAIuQD/CRToT9AFDAk2" +
"DFz47weCBf5iOEgAy8IVhgge+qvgAEoRExY8lBiYESLHBEU2hCzRg4lAjSexgBTZ" +
"AwWFf1pMTlxYQoghGmE4KYm4kyGKGki6VCGKkuE/GiqicpAAJAKDD05btCDjplMD" +
"BVUZOIUEoiyJMy8kiLC68MGQB0syPPh3poHaHAycyNDwJcSDKBkEnuhgd21eGV6+" +
"4HgwaGApwlStfti7IgXDwYV5XJVxxKlAwmA1MwwIACH5BAUAAP8ALAAAAAAQABAA" +
"AAjVAP8JFPhjgT9BF1wMXPgPQUMIC/yMwOBiA0OBEP5NqnAHgw0sG64M1JLxn5oL" +
"UhK4+GMCTRwhApX4S/LvTkosJjZY8ABmxj8donQkgcIQESk5M+pQ4EGElRAbFwH1" +
"QEGhRgMfCnL0ucikaiYkZXwEYrHjYo0nnp5UCdJAAZspF1twmNvihB4xRnIwrJTh" +
"Rp48IP5loaJgVKQPdjTgGPJgCQgSA++OAcWAyKsVsh7gyfBgYBZMEsa+6aMhRQg8" +
"kBduQqVgQpMPdPakSHFR4AsjZC0dYRgQACH5BAUAAP8ALAAAAAAQABAAAAjRAP8J" +
"FFgBAQIdP2wMXPhPCYSHECG0GcaQBi9/GDNirNBuIA8xkjSNuEDywoiTuzYIpKLg" +
"0RxFCWLGhAIlgaN/D4womNCE0UJHJSzkMpHphQIjwFgw/KcrFBo0hCTUghHBy1JG" +
"dTx4CNVAAVUiS9cxmTGjRxlfO80spUHDEAoUE17AmLDDysIuYeYwqnHpH8sJDG5p" +
"CFGJSwsVT7pIEtg1ghkiGnCEWHODDIctWwbOreslxaEHUW40usEwAgMrGlIMipKB" +
"y5qlAp1o+DKExBeGAQEAIfkEBQAA/wAsAAAAABAAEAAACNcA/wkUqETLPwQIByr8" +
"xwPQjwUQD+rAsBATHysIYiQZCNHfwBWtFCi4pMjBiH9q/PhLkkBghxdjJtj5Z+Of" +
"FAwmYzj4xyaIDxEsmih0kQCDUSzw+CiYsGPhP1V/irhIlaXBvwmWnFowtcHElTIv" +
"jPD44FRIHEIWrvgESnahEDklwMygIoFNEydHFFJAcepTjzr/YEQwQ8QLjgfeOHRB" +
"QoMCBYFAcryRsQdHCBKNODzZEobDwCmL6KwIcWjJDTIqtiBZaObI6ChcQNxw48ap" +
"wBVDSGRYs2ZhQAA7";
}

here is sample code provided. Basically this is how it works. Unlike other image formats, Animated GIF will have setof ImageData ( like a frame in an animation). You will render this image data on Cavans with the delay that you want.
http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/DisplayananimatedGIF.htm

This one is also working example code based upon Eclipse article about SWT. I was trying to make a slideshow or animated gif dialog from images located in a folder. posted here because it could be useful for somenone.
public class GifDialog extends Dialog {
Shell dialog;
private Canvas canvas;
int numberImage = 1;
private volatile boolean running = true;
final List<Image> imageCollection = new ArrayList<Image>();
DenemeDialog(Shell parent) {
super(parent);
}
public String open() {
Shell parent = getParent();
this.func();
dialog = new Shell(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
dialog.setSize(600, 400);
dialog.setText("Show Begins!!!");
Monitor primary = dialog.getDisplay().getPrimaryMonitor();
Rectangle bounds = primary.getBounds();
Rectangle rect = dialog.getBounds();
int x = bounds.x + (bounds.width - rect.width) / 2;
int y = bounds.y + (bounds.height - rect.height) / 2;
dialog.setLocation(x, y);
dialog.setLayout(new FillLayout());
final Canvas canvas = new Canvas(dialog, SWT.NONE);
final Image image = new Image(dialog.getDisplay(), imageCollection.get(
0).getImageData());
final GC gc = new GC(image);
canvas.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent event) {
event.gc.drawImage(image, 0, 0);
}
});
Thread thread = new Thread() {
public void run() {
while (running) {
dialog.getDisplay().asyncExec(new Runnable() {
public void run() {
numberImage = numberImage == imageCollection.size() - 1
? 0 : numberImage + 1;
ImageData nextFrameData = imageCollection.get(
numberImage).getImageData();
Image frameImage = new Image(dialog.getDisplay(),
nextFrameData);
gc.drawImage(frameImage, nextFrameData.x,
nextFrameData.y);
frameImage.dispose();
canvas.redraw();
if (numberImage == 0)
try {
running = false;
} catch (Exception e) {
e.printStackTrace();
}
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
};
dialog.open();
thread.start();
Display display = parent.getDisplay();
while (!dialog.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
return "After Dialog";
}
public void func() {
File path = new File("..\folder");
File[] files = path.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isFile()) { // this line weeds out other
// directories/folders
try {
ImageData imageData = new ImageData(
new ByteArrayInputStream(loadImage(files[i])));
final Image image = new Image(Display.getDefault(),
imageData);
imageCollection.add(image);
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
public byte[] loadImage(File file) throws IOException {
BufferedImage image = ImageIO.read(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", bos);
return bos.toByteArray();
}
public Canvas getCanvas() {
return canvas;
}
public void setCanvas(Canvas canvas) {
this.canvas = canvas;
}

Note: None of the examples that rely on SWT's ImageLoader.class will work on GTK Linux SWT, as there is currently a bug that hard-codes the maximum frames to 32 and sets the delay between frames incorrectly.
See GTK ImageLoader.java
// Fix the number of GIF frames as GdkPixbufAnimation does not provide an API to
// determine number of frames.
int num_frames = 32;

Related

Signal 7 (SIGBUS), code 1 (BUS_ADRALN), fault addr

I'm trying to do stitching on android. I used Surf algorithm to serve as finder and I got an error like "try enable OPENCV_ENABLED_NONFREE". I use C++ native code on Android Studio and do stitching in background. I solved the surf error but now, when I test this application on real device, I get this error:
I did some research in another forum, and they say that the problem may be caused by a function that doesn't return the value it's supposed to return. Is there anyone who can help me please. This is the code:
private Handler handler = new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message message) {
switch (message.what) {
case HANDLER_START_STITCHING :
{
new Thread()
{
public void run()
{
AsyncTask.execute(new Runnable() {
#Override
public void run() {
String[] source=getDirectoryFilelist("null");
final File resultDir = new File(getApplicationContext().getExternalFilesDir(null).getAbsolutePath() + File.separator + "viewwer");
// if (!resultDir.exists())
// resultDir.mkdir();
final String stitchingResultImagePath = new File(getApplicationContext().getExternalFilesDir(null).getAbsolutePath()) +"/result.jpg"; // + (ANGLE-90) + ".jpg";
if( NativePanorama.jniStitching(source, stitchingResultImagePath, STITCH_IMAGE_SCALE) == 0 )
{
handler.sendMessage(handler.obtainMessage(HANDLER_SET_STITCHING_BUTTON_TEXT,"Stitching success"));
File image = new File(getApplicationContext().getExternalFilesDir(null).getAbsolutePath());
File result_90 = new File(getApplicationContext().getExternalFilesDir(null).getAbsolutePath() + "/result90.jpg");
File result_180 = new File(getApplicationContext().getExternalFilesDir(null).getAbsolutePath() + "/result180.jpg");
File result_270 = new File(getApplicationContext().getExternalFilesDir(null).getAbsolutePath() + "/result270.jpg");
File result_360 = new File(getApplicationContext().getExternalFilesDir(null).getAbsolutePath() + "/result360.jpg");
Log.d("GESTION_STITCHING", result_180.toString());
/*if (ANGLE == 450) {
handler.sendMessage(handler.obtainMessage(HANDLER_FINISH_STITCHING,"Stitching success"));
}*/
if (image.exists()) {
File[] files = image.listFiles();
for (int i=0;i<files.length; i++) {
if (files[i].compareTo(result_90) == 0 || files[i].compareTo(result_180) == 0 || files[i].compareTo(result_270) == 0 || files[i].compareTo(result_360) == 0) {
} else {
files[i].delete();
}
}
}
}
else
{
handler.sendMessage(handler.obtainMessage(HANDLER_SET_STITCHING_BUTTON_TEXT,"Stitching error"));
}
}
});
}
}.start();
break;
}
and the following is the native C++ code:
JNIEXPORT jint JNICALL Java_com_priscilla_viewwer_utils_NativePanorama_jniStitching(JNIEnv *env, jclass clazz, jobjectArray source, jstring result, jdouble scale) {
clock_t beginTime, endTime;
double timeSpent;
beginTime = clock();
//init jni call java method
int i = 0;
bool try_use_gpu = true;
vector<Mat> imgs;
Mat img;
Mat img_scaled;
Mat pano;
Mat pano_tocut;
Mat gray;
const char* result_name = env->GetStringUTFChars(result, JNI_FALSE); //convert result
LOGE("result_name=%s",result_name);
LOGE("scale=%f",scale);
int imgCount = env->GetArrayLength(source); //img count
LOGE("source imgCount=%d",imgCount);
for(i=0;i<imgCount;i++)
{
jstring jsource = (jstring)(env->GetObjectArrayElement(source, i));
const char* source_name = env->GetStringUTFChars(jsource, JNI_FALSE); //convert jsource
LOGE("Add index %d source_name=:%s", i, source_name);
img=imread(source_name);
Size dsize = Size((int)(img.cols*scale),(int)(img.rows*scale));
img_scaled = Mat(dsize,CV_32S);
resize(img,img_scaled,dsize);
imgs.push_back(img_scaled);
env->ReleaseStringUTFChars(jsource, source_name); //release convert jsource
}
img.release();
pano = stitchingImages(imgs);
for(i=0;i<imgs.size();i++)
{
imgs[i].release();
}
//cut black edges
//LOGE("stitching success,cutting black....");
pano_tocut = pano;
cvtColor(pano_tocut, gray, CV_BGR2GRAY);
Rect startROI(0,0,gray.cols,gray.rows); // start as the source image - ROI is the complete SRC-Image
cropLargestPossibleROI(gray,pano_tocut,startROI);
gray.release();
imwrite(result_name, pano_tocut);
pano.release();
pano_tocut.release();
env->ReleaseStringUTFChars(result, result_name); //release convert result
endTime = clock();
timeSpent = (double)(endTime - beginTime) / CLOCKS_PER_SEC;
LOGE("success,total cost time %f seconds",timeSpent);
// env->CallVoidMethod(clazz, javaMethodRef, timeSpent);
return 0;
}
I came cross this issues either, and I found it was violating strict aliasing.
cause by casting~
problem:
uint32_t i32 = *((uint32_t*)m_data);
solution:
uint32_t i32 = 0;
char* p = (char*)&i32;
for(int i =0;i < 4;i++)
{
p[i] = m_data[i];
}

Communication beetwen sockets stops working after one message. BattleShipGame Swing

At the beggining I send string of tables stating where enemy ships are placed. Then in the loop (infinite for now) i try to send one message and listen one depending which turn is. After one message send and recived loops stop looping. I have suspect that it may have something to do with thread but i have no idea how to approach this. I don't expect o anyone dig through all this code but but i think it's better to include more code then less. I mainly looking for some guidance. Code below and thank you for your help.
Main class (i think customMousePressed & actionPerformed could be the main culprits)
public class BattleShipGame extends JFrame implements ActionListener {
//this 268, Draw 112 /////////////////////////////////////
private Optional<Ship> newShip;
private int logicPosX;
private int logicPosY;
private Coordinates start;
static String coordinatesInput = "", coordinatesOutput = "";
static boolean myturn = false;
private static int counter = 0;
static boolean connected = false;
Captain player = new Captain();
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new BattleShipGame());
}
private BattleShipGame()
{
this.setTitle("Battleship Game");
this.setSize(1100, 500);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
this.setResizable(false);
JPanel panel = new JPanel();
player.initializeShips();
Timer timer = new Timer(20, this);
DrawBoardAndShips boardAndShips = new DrawBoardAndShips(player);
timer.start();
//create player
//set your ships (one map & ships to drag from place to place)
//when READY button clicked and all ships are on board ->
//->search for player (Connection - sockets)
//draw 2 maps (one with ships, one to shoot)
//receive coordinates (hit or miss - draw changes to 1 map) - win condition checker (send info to another player about shoot result)
//send coordinates
JButton reset = new JButton("RESET");
reset.addActionListener(e -> {
//set to default position of ships
player.resetPositions();
player.getShips().forEach(ship -> ship.setShipOnBoard(false));
});
JButton ready = new JButton("READY!");
ready.addActionListener((ActionEvent e) -> { //set logic when button ready pressed
//check if all ships are on board
//set ready = true
if (player.getShips().stream().filter(Ship::isShipOnBoard).count() == 10 && e.getSource() == ready) {
//set logic
for (Ship ship : player.getShips()) {
player.setMyBoard(ship);
}
//establish network connection
boolean outcome = serverOrClientDecision(JOptionPane.YES_OPTION, player);
if(outcome) {
panel.remove(reset);
panel.remove(ready);
}
revalidate();
repaint();
}
});
panel.add(reset);
panel.add(ready);
this.add(panel, BorderLayout.SOUTH);
this.add(boardAndShips, BorderLayout.CENTER);
boardAndShips.addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
customMouseDragged(player, e);
}
});
boardAndShips.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {
customMouseClicked(e, player);
}
#Override
public void mousePressed(MouseEvent e) {
customMousePressed(e, player);
}
#Override
public void mouseReleased(MouseEvent e) {
customMouseReleased(player);
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
});
this.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if(!coordinatesInput.isEmpty() && !player.isMyTurn()){
String[] parts = coordinatesInput.split("\\."); //////////////////
logicPosX = Integer.parseInt(parts[0]);
logicPosY = Integer.parseInt(parts[1]);
if (player.getMyBoard()[logicPosX][logicPosY] == 1) {
player.getMyBoard()[logicPosX][logicPosY] = 2;
isSunk(player.getMyBoard());
}
else if(player.getMyBoard()[logicPosX][logicPosY] == 0)
player.getMyBoard()[logicPosX][logicPosY] = -1;
coordinatesInput = "";
player.setMyTurn(true);
}
repaint();
}
public boolean serverOrClientDecision(int decision, Captain player) {
Object[] options = {"CREATE", "JOIN", "EXIT"};
Object[] options2 = {"BACK", "TRY AGAIN", "EXIT"};
if (decision == JOptionPane.YES_OPTION) {
decision = JOptionPane.showOptionDialog(this, "Create game or join one?", "Battleship Game",
JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, null);
}
//
if(decision == JOptionPane.CANCEL_OPTION)
return false;
if (decision == JOptionPane.YES_OPTION) {
//create server
SwingWorker<Void, Void> worker = new SwingWorker<>() {
#Override
protected Void doInBackground() throws Exception {
Server server = new Server(player);
return null;
}
};
worker.execute();
} else if (decision == JOptionPane.NO_OPTION) {
//getting IP
String serversIP = JOptionPane.showInputDialog("Type server's IP");
//creating client
SwingWorker<Void, Boolean> worker1 = new SwingWorker<>() {
#Override
protected Void doInBackground() throws IOException {
Client client = new Client(serversIP, player);
return null;
}
};
worker1.execute();
while (!worker1.isDone()) {
if (connected == true)
break;
}
if (!connected) {
decision = JOptionPane.showOptionDialog(this, "Host not responding", "Join Game",
JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options2, null);
serverOrClientDecision(decision, player);
}
}
return true;
}
public void customMouseDragged(Captain player, MouseEvent e) {
if (player.getReady() == 0) {
newShip.filter(Ship::isHorizontal)
.ifPresent(ship -> ship.setCoordinates(new Coordinates(e.getX() - ship.getSize() * 16, e.getY() - 16)));
newShip.filter(ship -> !ship.isHorizontal())
.ifPresent(ship -> ship.setCoordinates(new Coordinates(e.getX() - 16, e.getY() - ship.getSize() * 16)));
}
}
public void customMouseClicked(MouseEvent e, Captain player) {
if (player.getReady() == 0) {
//ship is in bounds of the BOARD after rotating
player.getShips().stream()
.filter(ship -> ship.getBounds().contains(e.getPoint()))
.filter(ship -> (logicPosX < 11 && logicPosY + ship.getSize() < 11 && ship.isHorizontal())
|| (logicPosX + ship.getSize() < 11 && logicPosY < 11 && !ship.isHorizontal()))
.forEach(ship -> ship.setHorizontal(!ship.isHorizontal()));
//ship don't overlap space of other ship, if does revert rotation to previous state
if(newShip.isPresent()) {
player.getShips().stream()
.filter(ship -> ship.getId() != newShip.get().getId())
.filter(ship -> ship.getBigBounds().intersects(newShip.get().getBounds()))
.forEach(ship -> {
newShip.get().setHorizontal(!newShip.get().isHorizontal());
});
}
}
}
public void customMousePressed(MouseEvent e, Captain player) {
if (player.getReady() == 0) {
logicPosX = logicPosY = -1;
//picking up ship
newShip = player.getShips().stream().
filter(ship -> ship.getBounds().contains(e.getPoint()))
.findAny();
newShip.ifPresent(newShip -> start = newShip.getCoordinates());
} else if (player.getReady() == 2 && player.isMyTurn()) {
//System.out.println(e.getPoint().toString());
//-1 - uncovered (miss)
// 0 - covered (miss)
// 1 - covered (hit)
// 2 - uncovered (hit)
// 3 - uncovered (hit and sunk)
// is shoot in bounds of the enemy BOARD
if ((e.getX() > 600 && e.getX() < 920) && (e.getY() > 50 && e.getY() < 370)){
logicPosX = (e.getX() - 600) / 32;
logicPosY = (e.getY() - 50) / 32;
if (player.getEnemyBoard()[logicPosX][logicPosY] == 1) { // if covered (hit)
player.getEnemyBoard()[logicPosX][logicPosY] = 2;// set as uncovered (hit)
//check if ship sunk
isSunk(player.getEnemyBoard());
coordinatesOutput = Integer.toString(logicPosX) + "." + Integer.toString(logicPosY);
player.setMyTurn(false);
coordinatesOutput = "";
}
else if (player.getEnemyBoard()[logicPosX][logicPosY] == 0) { //if covered (miss)
player.getEnemyBoard()[logicPosX][logicPosY] = -1; // set as uncovered (miss)
coordinatesOutput = Integer.toString(logicPosX) + "." + Integer.toString(logicPosY);
player.setMyTurn(false);
coordinatesOutput = "";
}
}
}
}
public void customMouseReleased(Captain player) {
if (player.getReady() == 0) {
if (newShip.isPresent()) {
logicPosX = (newShip.get().getCoordinates().getX() - 150) / 32;
logicPosY = (newShip.get().getCoordinates().getY() - 50) / 32;
//ship placed on board
if (((logicPosX + newShip.get().getSize() < 11) && (logicPosY < 11) && newShip.get().isHorizontal() && logicPosX > -1 && logicPosY > -1)
|| ((logicPosX < 11) && (logicPosY + newShip.get().getSize() < 11) && !newShip.get().isHorizontal() && logicPosX > -1 && logicPosY > -1)) {
//adjust to grid
newShip.get().getCoordinates().setX(150 + logicPosX * 32);
newShip.get().getCoordinates().setY(50 + logicPosY * 32);
newShip.ifPresent(newShip -> newShip.setShipOnBoard(true));
//ship don't overlap space of other ship, if does revert move
player.getShips().stream()
.filter(ship -> ship.getId() != newShip.get().getId())
.filter(ship -> ship.getBigBounds().intersects(newShip.get().getBounds()))
.forEach(ship -> {
newShip.get().setCoordinates(start);
newShip.get().setShipOnBoard(false);
});
} else {
newShip.get().setHorizontal(true);
newShip.get().setCoordinates(start);
}
}
}
}
private void isSunk(int[][] board) {
int struck = 0;
int notStruck = 0;
Point[] struckPositions = new Point[4];
//checking every direction for not struck poles in ship
for (int n = 0; n < 4; n++) {
if (logicPosY - n > 0){
if (board[logicPosX][logicPosY - n] == 2) {
struckPositions[struck] = new Point(logicPosX, logicPosY);
struck++;
}
else if(board[logicPosX][logicPosY - n] == 1)
notStruck++;
else if(board[logicPosX][logicPosY - n] == 0)
break;
}
else
break;
}
for (int s = 1; s < 4; s++) {
if (logicPosY + s < 10){
if (board[logicPosX][logicPosY + s] == 2) {
struckPositions[struck] = new Point(logicPosX, logicPosY);
struck++;
}
else if(board[logicPosX][logicPosY + s] == 1)
notStruck++;
else if(board[logicPosX][logicPosY + s] == 0)
break;
}
else
break;
}
for (int e = 1; e < 4; e++) {
if (logicPosX + e < 10){
if (board[logicPosX + e][logicPosY] == 2) {
struckPositions[struck] = new Point(logicPosX, logicPosY);
struck++;
}
else if(board[logicPosX + e][logicPosY] == 1)
notStruck++;
else if(board[logicPosX + e][logicPosY] == 0)
break;
}
else
break;
}
for (int w = 1; w < 4; w++) {
if (logicPosX - w > 0){
if (board[logicPosX - w][logicPosY] == 2) {
struckPositions[struck] = new Point(logicPosX, logicPosY);
struck++;
}
else if(board[logicPosX - w][logicPosY] == 1)
notStruck++;
else if(board[logicPosX - w][logicPosY] == 0)
break;
}
else
break;
}
// if sunk change it in logical table
if (notStruck == 0){
for (Point p : struckPositions){
board[p.x][p.y] = 3;
//return int = struck
}
}
//else return -1; - in future to display sunk ships as small squares next to tables
}
}
Server
class Server extends Thread {
ServerSocket serverSocket;
Socket socket;
DataInputStream dataInputStream;
DataOutputStream dataOutputStream;
String sendMessage = "", message1 = "", receivedMessage = "";
public Server(Captain player) throws IOException {
System.out.println("SERVER");
int asd = 0;
player.setReady(1);
serverSocket = new ServerSocket(6666);
socket = serverSocket.accept();
player.setReady(2);
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream = new DataOutputStream(socket.getOutputStream());
//send logic table at the beginning of the game
for(int i1 = 0; i1 < player.getMyBoard().length; i1++){
for (int j = 0; j < player.getMyBoard()[i1].length; j++){
if(player.getMyBoard()[j][i1] == 1) /////////////////////
sendMessage += "1";
else
sendMessage += "0";
}
}
dataOutputStream.writeUTF(sendMessage);
sendMessage = "";
/*System.out.println("Sever get from Client: " + dataInputStream.readUTF());
System.out.println("Server send: " + start);*/
//receive String and convert it to enemy logic table
receivedMessage = dataInputStream.readUTF();
player.setEnemyBoard(receivedMessage);
receivedMessage = "";
player.setMyTurn(true);
while(!message1.equals("WIN") || !message1.equals("LOOSE")){
dataOutputStream.writeUTF(BattleShipGame.coordinatesOutput);
BattleShipGame.coordinatesOutput = "";
System.out.println("__");
if(!player.isMyTurn()) {
receivedMessage = dataInputStream.readUTF();
System.out.println("server NOT my turn");
if(!receivedMessage.isEmpty()) {
BattleShipGame.coordinatesInput = receivedMessage;
receivedMessage = "";
//player.setMyTurn(true);
}
} else {
sendMessage = BattleShipGame.coordinatesOutput;
System.out.print(asd++);
if(!sendMessage.isEmpty()) {
dataOutputStream.writeUTF(sendMessage);
sendMessage = "";
//player.setMyTurn(false);
}
}
dataOutputStream.flush();
}
dataInputStream.close();
socket.close();
serverSocket.close();
}
}
Client
public class Client {
Socket socket;
DataInputStream dataInputStream;
DataOutputStream dataOutputStream;
BufferedReader bufferedReader;
String sendMessage = "", message1 = "", receivedMessage = "";
public Client(String host, Captain player) throws IOException {
System.out.println("CLIENT");
socket = new Socket(host, 6666);
player.setReady(2);
BattleShipGame.connected = socket.isConnected();
dataInputStream = new DataInputStream(socket.getInputStream());
dataOutputStream = new DataOutputStream(socket.getOutputStream());
bufferedReader = new BufferedReader(new InputStreamReader(System.in));
//send logic table at the beginning of the game
for(int i1 = 0; i1 < player.getMyBoard().length; i1++){
for (int j = 0; j < player.getMyBoard()[i1].length; j++){
if(player.getMyBoard()[j][i1] == 1)
sendMessage += "1";
else
sendMessage += "0";
}
}
dataOutputStream.writeUTF(sendMessage);
sendMessage = "";
/*System.out.println("Client get from Server: " + dataInputStream.readUTF());
System.out.println("Client sends: " + start);*/
//receive String and convert it to enemy logic table
receivedMessage = dataInputStream.readUTF();
player.setEnemyBoard(receivedMessage);
receivedMessage = "";
player.setMyTurn(false);
while(!message1.equals("WIN") || !message1.equals("LOOSE")){
System.out.print("c");
if(!player.isMyTurn()) {
receivedMessage = dataInputStream.readUTF();
System.out.println("client NOT my turn"); /////////////////////////////
if(!receivedMessage.isEmpty()) {
BattleShipGame.coordinatesInput = receivedMessage;
receivedMessage = "";
}
} else {
sendMessage = BattleShipGame.coordinatesOutput;
System.out.println("client MY turn"); ////////////////////////////
if(!sendMessage.isEmpty()) {
dataOutputStream.writeUTF(sendMessage);
sendMessage = "";
}
}
dataOutputStream.flush();
}
dataInputStream.close();
socket.close();
}
}

Audio merging using OpenSL ES Android

I am trying to record my vocals and then merge them with an audio file together using OPENSL ES Library. I found this GitHub sample called Native-Audio. It merges the two audios. But the background audio file is playing much faster than the actual rate in the final output.
Please use headphones to notice the difference.
Samples Links: Before and After
Also, it uses the files from the assets folder only. How can I manually select MP3 files from file manager?
private void mixAudio(){
try {
if (!(ContextCompat.checkSelfPermission(this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) ||
!(ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED))
{
// Show rationale and request permission.
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE, android.Manifest.permission.WRITE_EXTERNAL_STORAGE},
1000);
}
else {
buttonMix.setEnabled(false);
buttonMix.setText("MIXING....");
textViewMixPath.setText("");
buttonPlay.setEnabled(false);
buttonRecord.setEnabled(false);
buttonStart.setEnabled(false);
listView.setEnabled(false);
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try{
//final File file = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + "/" + "mix.wav");
//String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
//File file = new File(baseDir + "/mix.wav");
String path = Environment.getExternalStorageDirectory().getPath() + "/VocalRecorder";
File fileParent = new File(path);
if (!fileParent.exists()){
fileParent.mkdir();
}
final File file = new File(fileParent.getPath() + "/mix.wav");
//String author = getApplicationContext().getPackageName() + ".provider";
//Uri videoUri = FileProvider.get(this, author, mediaFile);
//final File file = new File(getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + "/" + "mix.wav");
//MediaMuxer muxer = new MediaMuxer(file.getAbsolutePath(), MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
String beat = beats[selectedBeat];
//beat = beat.replace(".wav", ".mp3");
AssetFileDescriptor afd = getAssets().openFd(beat);
MediaCodec codec = null;
//ByteBuffer outputBuffer;
//short[] data; // data for the AudioTrack playback
//int outputBufferIndex = -1;
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
String durationStr = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
final long duration = Long.parseLong(durationStr);
MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
// right now I am pointing to a URI but I have tested that both will
// play the media file using MediaPlayer
int sampleRate = 0;
int numChannels = 0;
int dstIndex = -1;
int numTracks = extractor.getTrackCount(); //This says 1
for (int i = 0; i < numTracks; ++i) { // so this will just run once
MediaFormat format = extractor.getTrackFormat(i); // getting info so it looks good so far
String mime = format.getString(MediaFormat.KEY_MIME); // "audio/mpeg"
if (mime.startsWith("audio/")) {
extractor.selectTrack(i);
codec = MediaCodec.createDecoderByType(mime);
codec.configure(format, null, null, 0);
//format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_AMR_NB);
//dstIndex = muxer.addTrack(format);
//writer.setFrameRate(format.getInteger(MediaFormat.KEY_SAMPLE_RATE));
//writer.setSamplesPerFrame(format.getInteger(MediaFormat.KEY_CHANNEL_COUNT));
//writer.setBitsPerSample(16);
sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE);
numChannels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
break;
}
}
// Calculate the number of frames required for specified duration
long numFrames = (long)(duration * sampleRate/1000);
// Create a wav file with the name specified as the first argument
WavFile wavFile = WavFile.newWavFile(file, numChannels, numFrames, 16, sampleRate);
if (codec == null) {
throw new IllegalArgumentException("No decoder for file format");
}
//ByteBuffer[] inputBuffers = decoder.getInputBuffers();
//ByteBuffer[] outputBuffers = decoder.getOutputBuffers();
/*
Boolean eosReceived = false;
while (!eosReceived) {
int inIndex = decoder.dequeueInputBuffer(1000);
if (inIndex >= 0) {
ByteBuffer buffer = decoder.getInputBuffer(inIndex);
int sampleSize = extractor.readSampleData(buffer, 0);
if (sampleSize < 0) {
// We shouldn't stop the playback at this point, just pass the EOS
// flag to mDecoder, we will get it again from the
// dequeueOutputBuffer
Log.d("DecodeActivity", "InputBuffer BUFFER_FLAG_END_OF_STREAM");
decoder.queueInputBuffer(inIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
} else {
decoder.queueInputBuffer(inIndex, 0, sampleSize, extractor.getSampleTime(), 0);
extractor.advance();
}
int outIndex = decoder.dequeueOutputBuffer(info, 1000);
switch (outIndex) {
case MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED:
Log.d("DecodeActivity", "INFO_OUTPUT_BUFFERS_CHANGED");
//outputBuffers = decoder.getOutputBuffers();
break;
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
MediaFormat format = decoder.getOutputFormat();
Log.d("DecodeActivity", "New format " + format);
//audioTrack.setPlaybackRate(format.getInteger(MediaFormat.KEY_SAMPLE_RATE));
break;
case MediaCodec.INFO_TRY_AGAIN_LATER:
Log.d("DecodeActivity", "dequeueOutputBuffer timed out!");
break;
default:
ByteBuffer outBuffer = decoder.getOutputBuffer(outIndex);
Log.v("DecodeActivity", "We can't use this buffer but render it due to the API limit, " + outBuffer);
final byte[] chunk = new byte[info.size];
outBuffer.get(chunk); // Read the buffer all at once
outBuffer.clear(); // ** MUST DO!!! OTHERWISE THE NEXT TIME YOU GET THIS SAME BUFFER BAD THINGS WILL HAPPEN
//audioTrack.write(chunk, info.offset, info.offset + info.size); // AudioTrack write data
decoder.releaseOutputBuffer(outIndex, false);
break;
}
// All decoded frames have been rendered, we can stop playing now
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
Log.d("DecodeActivity", "OutputBuffer BUFFER_FLAG_END_OF_STREAM");
break;
}
}
}
*/
short recordedData[] = recordedData();
int recordMixStartIndex = -1;
//muxer.start();
codec.start();
Boolean sawInputEOS = false;
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
MediaCodec.BufferInfo infoMux = new MediaCodec.BufferInfo();
int count = 0;
while (!sawInputEOS) {
int inputBufIndex = codec.dequeueInputBuffer(TIMEOUT_US);
Log.i(LOG_TAG, "inputBufIndex : " + inputBufIndex);
if (inputBufIndex >= 0) {
ByteBuffer dstBuf = codec.getInputBuffer(inputBufIndex);
int sampleSize = extractor.readSampleData(dstBuf, 0);
Log.i(LOG_TAG, "sampleSize : " + sampleSize);
long presentationTimeUs = 0;
if (sampleSize < 0) {
Log.i(LOG_TAG, "Saw input end of stream!");
sawInputEOS = true;
sampleSize = 0;
} else {
presentationTimeUs = extractor.getSampleTime();
Log.i(LOG_TAG, "presentationTimeUs " + presentationTimeUs);
}
codec.queueInputBuffer(inputBufIndex,
0, //offset
sampleSize,
presentationTimeUs,
sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
if (!sawInputEOS) {
Log.i(LOG_TAG, "extractor.advance()");
extractor.advance();
}
}
final int res = codec.dequeueOutputBuffer(info, TIMEOUT_US);
if (res >= 0) {
int outputBufIndex = res;
ByteBuffer buf = codec.getOutputBuffer(outputBufIndex);
//final byte[] chunk = new byte[info.size];
//buf.get(chunk); // Read the buffer all at once
short[] shortArray = new short[info.size/2];
buf.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(shortArray);
buf.clear(); // ** MUST DO!!! OTHERWISE THE NEXT TIME YOU GET THIS SAME BUFFER BAD THINGS WILL HAPPEN
if (shortArray.length > 0) {
//mAudioTrack.write(chunk, 0, chunk.length);
//infoMux.presentationTimeUs = info.presentationTimeUs;
//infoMux.flags = info.flags;
//muxer.writeSampleData(dstIndex, ByteBuffer.wrap(chunk),
// infoMux);
long []longData = new long[shortArray.length];
// Merge data with vocal
// Calculate the time
final long bufferTimer = info.presentationTimeUs/1000;
int vocalCount = 0;
for (int i = 0; i < shortArray.length; i ++) {
//writer.writeShortLittle(shortArray[i]);
long offsetTime = i*1000/(sampleRate*2); // 2 channels
Boolean mixed = false;
if ((offsetTime + bufferTimer > recordStartTime) && (offsetTime + bufferTimer <= recordStopTime + 500)){
if (recordMixStartIndex == -1){
recordMixStartIndex = 0;
}
if (recordMixStartIndex < recordedData.length){
//Log.i("TAG", "############ mix record data: " + recordMixStartIndex);
longData[i] = TPMixSamples((int)(recordedData[recordMixStartIndex]), (int)shortArray[i]/3);
if (vocalCount >= 3) {
recordMixStartIndex++;
vocalCount = 0;
}
else{
vocalCount ++;
}
mixed = true;
}
}
else {
// All done, set sawInputEOS to stop mixing
if (bufferTimer > recordStopTime + 500){
sawInputEOS = true;
}
}
if (!mixed) {
longData[i] = shortArray[i];
}
}
Log.i("TAG", "############ write frames: " + longData.length/2);
wavFile.writeFrames(longData, longData.length/2);
count ++;
if (count % 5 == 0){
runOnUiThread(new Runnable() {
#Override
public void run() {
long percent = bufferTimer*100/duration;
buttonMix.setText("MIXING..." + percent + "%");
}
});
}
}
codec.releaseOutputBuffer(outputBufIndex, false /* render */);
if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
sawInputEOS = true;
}
} else if (res == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
//codecOutputBuffers = codec.getOutputBuffers();
} else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
final MediaFormat oformat = codec.getOutputFormat();
Log.d(LOG_TAG, "Output format has changed to " + oformat);
//mAudioTrack.setPlaybackRate(oformat.getInteger(MediaFormat.KEY_SAMPLE_RATE));
}
}
// Close the wavFile
wavFile.close();
// muxer.stop();
// muxer.release();
codec.stop();
codec.release();
extractor.release();
runOnUiThread(new Runnable() {
#Override
public void run() {
buttonMix.setText("MIX DONE");
buttonPlay.setEnabled(true);
buttonRecord.setEnabled(true);
textViewMixPath.setText(file.getPath());
buttonStart.setEnabled(true);
listView.setEnabled(true);
}
});
}
catch (Exception e){
}
}
});
thread.start();
}
}
catch (Exception e){
e.printStackTrace();
}
}
private final int INT16_MIN = - 32768;
private final int INT16_MAX = 32767;
private long TPMixSamples(int a, int b) {
if (a > INT16_MAX) {a = INT16_MAX;}
if (a < INT16_MIN) {a = INT16_MIN;}
return
// If both samples are negative, mixed signal must have an amplitude between the lesser of A and B, and the minimum permissible negative amplitude
a < 0 && b < 0 ?
((int)a + (int)b) - (((int)a * (int)b)/INT16_MIN) :
// If both samples are positive, mixed signal must have an amplitude between the greater of A and B, and the maximum permissible positive amplitude
( a > 0 && b > 0 ?
((int)a + (int)b) - (((int)a * (int)b)/INT16_MAX)
// If samples are on opposite sides of the 0-crossing, mixed signal should reflect that samples cancel each other out somewhat
:
a + b);
}
/** Native methods, implemented in jni folder */
public static native void createEngine();
public static native void createBufferQueueAudioPlayer(int sampleRate, int samplesPerBuf);
/////
public static native boolean createAssetAudioPlayer(AssetManager assetManager, String filename);
// true == PLAYING, false == PAUSED
public static native void setPlayingAssetAudioPlayer(boolean isPlaying);
public static native int getDurationAssetAudioPlayer();
public static native int getCurrentPositionAssetAudioPlayer();
//////
public static native boolean createUriAudioPlayer(String uri);
public static native void setPlayingUriAudioPlayer(boolean isPlaying);
public static native void setLoopingUriAudioPlayer(boolean isLooping);
public static native void setChannelMuteUriAudioPlayer(int chan, boolean mute);
public static native void setChannelSoloUriAudioPlayer(int chan, boolean solo);
public static native int getNumChannelsUriAudioPlayer();
public static native void setVolumeUriAudioPlayer(int millibel);
public static native void setMuteUriAudioPlayer(boolean mute);
public static native void enableStereoPositionUriAudioPlayer(boolean enable);
public static native void setStereoPositionUriAudioPlayer(int permille);
public static native boolean selectClip(int which, int count);
public static native void stopClip();
public static native boolean enableReverb(boolean enabled);
public static native boolean createAudioRecorder();
public static native void startRecording();
public static native void stopRecording();
public static native void pauseRecording();
public static native void resumeRecording();
public static native short[] recordedData();
public static native double recordedDuration();
public static native void shutdown();
/** Load jni .so on initialization */
static {
System.loadLibrary("native-audio-jni");
}

KeyListener Supposedly Calling upon other Key's code (JDBC)

I have a system so that you can press space to pause the simulation, and then arrows move the camera etc. and then if you press e, a JFrame pops up with a JTable inside it with the results from a SQL search of a connected database.
This works fine, I can close the JFrame and carry on running the simulation as usual, all the buttons and functions work.
The problem is after 20 seconds, the system takes the collected data and writes this data to the end of the database, which is fine, that works it writes to the end if the data is not already their. However if I press e to open the table, and then close the table, when returning to the simulation screen whatever button I press that has a listener attached to it, will just keep opening new tables, and I am stumped as to the reason why.
Any solution that would allow for when I close this JFrame for my key's to begin to function the way they did before writing to the file, would be greatly appreciated.
Here are the relevant pieces of code (let me know if there is any more you may need)
public void databaseConnector(boolean read){
try{
Connection con = DriverManager.getConnection("jdbc:derby://localhost:1527/Outputs", "Sam", "sam");
Statement st = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
String sql = "SELECT INDEX FROM SHM";
ResultSet rs = st.executeQuery(sql);
int len = 0;
while(rs.next()) {
len++;
}
if (read){
databaseReader(st, len);
} else {
double data[] = {modulus[0] , natural[0], modulus[1], natural[1], length, startPosition, endPosition, amplitude, equilibrium};
for (int i = 4; i < data.length; i++){
data[i] /= 100;
}
PreparedStatement sqls = con.prepareStatement( "SELECT * FROM SHM WHERE " + columnNames[1] + " = " + data[0] + " AND " + columnNames[2] + " = " + data[1] + " AND "
+ columnNames[3] + " = " + data[2] + " AND " + columnNames[4] + " = " + data[3] + " AND "
+ columnNames[5] + " = " + data[4] + " AND " + columnNames[6] + " = " + data[5]);
databaseWriter(st, len, sqls, data);
}
st.close();
con.close();
} catch (Exception e){
e.printStackTrace();
}
}
public void databaseReader(Statement st, int len){
try{
Object[][] data;
//Get data from table and convert to 2D array
data = new Object[len][columnNames.length];
String sql = "SELECT * FROM SHM";
ResultSet rs = st.executeQuery(sql);
int x = 0;
while (rs.next()){
for(int i = 0; i < columnNames.length; i++){
data[x][i] = new Double(rs.getDouble(columnNames[i]));
}
x++;
}
rs.close();
//Output data
JFrame frame = new JFrame("Table");
TableModel model = new DefaultTableModel(data, columnNames);
JTable table = new JTable(model);
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
frame.add(new JScrollPane(table));
frame.setAlwaysOnTop(true);
frame.pack();
frame.setVisible(true);
} catch (Exception e){
System.err.println(e.getMessage());
}
}
public void databaseWriter(Statement st, int len, PreparedStatement sql, double[] data){
try{
//checker
ResultSet rs = sql.executeQuery();
if (!rs.next()){ //if not empty then
rs = st.executeQuery("SELECT * FROM SHM");
rs.moveToInsertRow();
rs.updateInt(columnNames[0],len + 1);
for (int i = 0; i < data.length; i++) {
rs.updateDouble(columnNames[i+1],data[i]);
}
rs.insertRow();
}
rs.close();
} catch (Exception e){
e.printStackTrace();
System.out.println(e.getMessage());
}
}
public void gravity(){
if (moving){
double force = tension();
Player.ha = force / Player.mass;
Player.hSpeed += Player.ha * delta / 60;
//}
Player.vSpeed += Player.va;
Player.move(1, (int) (Player.hSpeed * delta));
if (milliSecondTimer < 20){
calculationChecker();
}
if (milliSecondTimer > 20 && !hasWritten){
endPosition = (int) (maxX - rect.get(0).getMaxX());
databaseConnector(false);
hasWritten = true;
}
} else {
milliSecondTimer = 0;
hasWritten = false;
amplitude = 0;
equilibrium = 0;
MaxX = new ArrayList<Integer>();
MinX = new ArrayList<Integer>();
Equilibrium = new ArrayList<Integer>();
Player.hSpeed = 0;
Player.ha = 0;
}
}
public class MyKeyListener implements KeyListener{
public void action(){
int s = 4;
if (keysDown.contains(KeyEvent.VK_SHIFT)){
s = 10;
} else {
s = 4;
}
if (keysDown.contains(KeyEvent.VK_UP) /*|| keysDown.contains(KeyEvent.VK_W)*/){
scaleChange = true;
moverY += 10;
}
if (keysDown.contains(KeyEvent.VK_RIGHT) /*|| keysDown.contains(KeyEvent.VK_D)*/){
if (!moving) {
Player.move(1,s);
right = true;
} else {
moverX -= 10;
}
}
if (keysDown.contains(KeyEvent.VK_DOWN) /*|| keysDown.contains(KeyEvent.VK_S)*/){
scaleChange = true;
moverY -= 10;
}
if (keysDown.contains(KeyEvent.VK_LEFT) /*|| keysDown.contains(KeyEvent.VK_A)*/){
if (!moving) {
Player.move(3,s);
right = false;
} else {
moverX += 10;
}
}
if (keysDown.contains(KeyEvent.VK_E)){
databaseConnector(true);
}
if (keysDown.contains(KeyEvent.VK_SPACE)){
Player.ha = 0;
Player.va = 0;
Player.vSpeed = 0;
Player.hSpeed = 0;
if (!moving){
modulus[0] = mod1.getValue();
modulus[1] = mod2.getValue();
natural[0] = len1.getValue();
natural[0] /= 10;
natural[1] = len2.getValue();
natural[1] /= 10;
setRectangles();
startPosition = (int) (Player.getCenterX() - rect.get(0).getMaxX());
}
moving = !moving;
}
if (keysDown.contains(KeyEvent.VK_EQUALS)){
scaleScreen += 1;
scaleChange = true;
}
if (keysDown.contains(KeyEvent.VK_SLASH)){
scaleScreen -= 1;
if(scaleScreen == 0){
scaleScreen = 1;
}
}
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
if (!keysDown.contains(e.getKeyCode())){
keysDown.add(e.getKeyCode());
}
action();
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public void keyReleased(KeyEvent e) {
keysDown.remove(new Integer(e.getKeyCode()));
}
}

Tiny GP output in text file

I've recently stumbled upon Tiny GP (A Genetic Programming program), and I found it pretty useful, so I decided to change all System.out.println() in the program to a write to text file method.
Problem: In the text file, for some reason, only says "PROBLEM SOLVED", instead of printing out generations and other things that it is supposed to (see code).
Tiny GP modified class file:
package main;
/*
* Program: tiny_gp.java
*
* Author: Riccardo Poli (email: rpoli#essex.ac.uk)
*
* Modified by Preston Tang
*/
import java.util.*;
import java.io.*;
import java.text.DecimalFormat;
public class tiny_gp {
String Name;
double[] fitness;
char[][] pop;
static Random rd = new Random();
static final int ADD = 110,
SUB = 111,
MUL = 112,
DIV = 113,
FSET_START = ADD,
FSET_END = DIV;
static double[] x = new double[FSET_START];
static double minrandom, maxrandom;
static char[] program;
static int PC;
static int varnumber, fitnesscases, randomnumber;
static double fbestpop = 0.0, favgpop = 0.0;
static long seed;
static double avg_len;
static final int MAX_LEN = 10000,
POPSIZE = 100000,
DEPTH = 5,
GENERATIONS = 100,
TSIZE = 2;
public static final double PMUT_PER_NODE = 0.05,
CROSSOVER_PROB = 0.9;
public static double[][] targets;
public double run() {
/* Interpreter */
char primitive = program[PC++];
if (primitive < FSET_START) {
return (x[primitive]);
}
switch (primitive) {
case ADD:
return (run() + run());
case SUB:
return (run() - run());
case MUL:
return (run() * run());
case DIV: {
double num = run(), den = run();
if (Math.abs(den) <= 0.001) {
return (num);
} else {
return (num / den);
}
}
}
return (0.0); // should never get here
}
public int traverse(char[] buffer, int buffercount) {
if (buffer[buffercount] < FSET_START) {
return (++buffercount);
}
switch (buffer[buffercount]) {
case ADD:
case SUB:
case MUL:
case DIV:
return (traverse(buffer, traverse(buffer, ++buffercount)));
}
return (0); // should never get here
}
public void setup_fitness(String fname) {
try {
int i, j;
String line;
BufferedReader in
= new BufferedReader(
new FileReader(fname));
line = in.readLine();
StringTokenizer tokens = new StringTokenizer(line);
varnumber = Integer.parseInt(tokens.nextToken().trim());
randomnumber = Integer.parseInt(tokens.nextToken().trim());
minrandom = Double.parseDouble(tokens.nextToken().trim());
maxrandom = Double.parseDouble(tokens.nextToken().trim());
fitnesscases = Integer.parseInt(tokens.nextToken().trim());
targets = new double[fitnesscases][varnumber + 1];
if (varnumber + randomnumber >= FSET_START) {
Write("too many variables and constants");
//System.out.println("too many variables and constants");
}
for (i = 0; i < fitnesscases; i++) {
line = in.readLine();
tokens = new StringTokenizer(line);
for (j = 0; j <= varnumber; j++) {
targets[i][j] = Double.parseDouble(tokens.nextToken().trim());
}
}
in.close();
} catch (FileNotFoundException e) {
Write("ERROR: Please provide a data file");
//System.out.println("ERROR: Please provide a data file");
System.exit(0);
} catch (Exception e) {
Write("ERROR: Incorrect data format");
//System.out.println("ERROR: Incorrect data format");
System.exit(0);
}
}
public double fitness_function(char[] Prog) {
int i = 0, len;
double result, fit = 0.0;
len = traverse(Prog, 0);
for (i = 0; i < fitnesscases; i++) {
for (int j = 0; j < varnumber; j++) {
x[j] = targets[i][j];
}
program = Prog;
PC = 0;
result = run();
fit += Math.abs(result - targets[i][varnumber]);
}
return (-fit);
}
public int grow(char[] buffer, int pos, int max, int depth) {
char prim = (char) rd.nextInt(2);
int one_child;
if (pos >= max) {
return (-1);
}
if (pos == 0) {
prim = 1;
}
if (prim == 0 || depth == 0) {
prim = (char) rd.nextInt(varnumber + randomnumber);
buffer[pos] = prim;
return (pos + 1);
} else {
prim = (char) (rd.nextInt(FSET_END - FSET_START + 1) + FSET_START);
switch (prim) {
case ADD:
case SUB:
case MUL:
case DIV:
buffer[pos] = prim;
one_child = grow(buffer, pos + 1, max, depth - 1);
if (one_child < 0) {
return (-1);
}
return (grow(buffer, one_child, max, depth - 1));
}
}
return (0); // should never get here
}
public int print_indiv(char[] buffer, int buffercounter) {
int a1 = 0, a2;
if (buffer[buffercounter] < FSET_START) {
if (buffer[buffercounter] < varnumber) {
Write("X" + (buffer[buffercounter] + 1) + " ");
//System.out.print("X" + (buffer[buffercounter] + 1) + " ");
} else {
WriteDouble(x[buffer[buffercounter]]);
//System.out.print(x[buffer[buffercounter]]);
}
return (++buffercounter);
}
switch (buffer[buffercounter]) {
case ADD:
Write("(");
//System.out.print("(");
a1 = print_indiv(buffer, ++buffercounter);
Write(" + ");
//System.out.print(" + ");
break;
case SUB:
Write("(");
//System.out.print("(");
a1 = print_indiv(buffer, ++buffercounter);
Write(" - ");
//System.out.print(" - ");
break;
case MUL:
Write("(");
//System.out.print("(");
a1 = print_indiv(buffer, ++buffercounter);
Write(" * ");
//System.out.print(" * ");
break;
case DIV:
Write("(");
//System.out.print("(");
a1 = print_indiv(buffer, ++buffercounter);
Write(" / ");
//System.out.print(" / ");
break;
}
a2 = print_indiv(buffer, a1);
Write(")");
//System.out.print(")");
return (a2);
}
public static char[] buffer = new char[MAX_LEN];
public char[] create_random_indiv(int depth) {
char[] ind;
int len;
len = grow(buffer, 0, MAX_LEN, depth);
while (len < 0) {
len = grow(buffer, 0, MAX_LEN, depth);
}
ind = new char[len];
System.arraycopy(buffer, 0, ind, 0, len);
return (ind);
}
public char[][] create_random_pop(int n, int depth, double[] fitness) {
char[][] pop = new char[n][];
int i;
for (i = 0; i < n; i++) {
pop[i] = create_random_indiv(depth);
fitness[i] = fitness_function(pop[i]);
}
return (pop);
}
public void stats(double[] fitness, char[][] pop, int gen) {
int i, best = rd.nextInt(POPSIZE);
int node_count = 0;
fbestpop = fitness[best];
favgpop = 0.0;
for (i = 0; i < POPSIZE; i++) {
node_count += traverse(pop[i], 0);
favgpop += fitness[i];
if (fitness[i] > fbestpop) {
best = i;
fbestpop = fitness[i];
}
}
avg_len = (double) node_count / POPSIZE;
favgpop /= POPSIZE;
Write("Generation=" + gen + " Avg Fitness=" + (-favgpop)
+ " Best Fitness=" + (-fbestpop) + " Avg Size=" + avg_len
+ "\nBest Individual: ");
//System.out.print("Generation=" + gen + " Avg Fitness=" + (-favgpop)
// + " Best Fitness=" + (-fbestpop) + " Avg Size=" + avg_len
// + "\nBest Individual: ");
print_indiv(pop[best], 0);
Write("\n");
//System.out.print("\n");
//System.out.flush();
}
public int tournament(double[] fitness, int tsize) {
int best = rd.nextInt(POPSIZE), i, competitor;
double fbest = -1.0e34;
for (i = 0; i < tsize; i++) {
competitor = rd.nextInt(POPSIZE);
if (fitness[competitor] > fbest) {
fbest = fitness[competitor];
best = competitor;
}
}
return (best);
}
public int negative_tournament(double[] fitness, int tsize) {
int worst = rd.nextInt(POPSIZE), i, competitor;
double fworst = 1e34;
for (i = 0; i < tsize; i++) {
competitor = rd.nextInt(POPSIZE);
if (fitness[competitor] < fworst) {
fworst = fitness[competitor];
worst = competitor;
}
}
return (worst);
}
public char[] crossover(char[] parent1, char[] parent2) {
int xo1start, xo1end, xo2start, xo2end;
char[] offspring;
int len1 = traverse(parent1, 0);
int len2 = traverse(parent2, 0);
int lenoff;
xo1start = rd.nextInt(len1);
xo1end = traverse(parent1, xo1start);
xo2start = rd.nextInt(len2);
xo2end = traverse(parent2, xo2start);
lenoff = xo1start + (xo2end - xo2start) + (len1 - xo1end);
offspring = new char[lenoff];
System.arraycopy(parent1, 0, offspring, 0, xo1start);
System.arraycopy(parent2, xo2start, offspring, xo1start,
(xo2end - xo2start));
System.arraycopy(parent1, xo1end, offspring,
xo1start + (xo2end - xo2start),
(len1 - xo1end));
return (offspring);
}
public char[] mutation(char[] parent, double pmut) {
int len = traverse(parent, 0), i;
int mutsite;
char[] parentcopy = new char[len];
System.arraycopy(parent, 0, parentcopy, 0, len);
for (i = 0; i < len; i++) {
if (rd.nextDouble() < pmut) {
mutsite = i;
if (parentcopy[mutsite] < FSET_START) {
parentcopy[mutsite] = (char) rd.nextInt(varnumber + randomnumber);
} else {
switch (parentcopy[mutsite]) {
case ADD:
case SUB:
case MUL:
case DIV:
parentcopy[mutsite]
= (char) (rd.nextInt(FSET_END - FSET_START + 1)
+ FSET_START);
}
}
}
}
return (parentcopy);
}
public void print_parms() {
Write("-- TINY GP (Java version) --\n");
//System.out.print("-- TINY GP (Java version) --\n");
Write("SEED=" + seed + "\nMAX_LEN=" + MAX_LEN
+ "\nPOPSIZE=" + POPSIZE + "\nDEPTH=" + DEPTH
+ "\nCROSSOVER_PROB=" + CROSSOVER_PROB
+ "\nPMUT_PER_NODE=" + PMUT_PER_NODE
+ "\nMIN_RANDOM=" + minrandom
+ "\nMAX_RANDOM=" + maxrandom
+ "\nGENERATIONS=" + GENERATIONS
+ "\nTSIZE=" + TSIZE
+ "\n----------------------------------\n");
// System.out.print("SEED=" + seed + "\nMAX_LEN=" + MAX_LEN
// + "\nPOPSIZE=" + POPSIZE + "\nDEPTH=" + DEPTH
// + "\nCROSSOVER_PROB=" + CROSSOVER_PROB
// + "\nPMUT_PER_NODE=" + PMUT_PER_NODE
// + "\nMIN_RANDOM=" + minrandom
// + "\nMAX_RANDOM=" + maxrandom
// + "\nGENERATIONS=" + GENERATIONS
// + "\nTSIZE=" + TSIZE
// + "\n----------------------------------\n");
}
public tiny_gp(String fname, long s) {
fitness = new double[POPSIZE];
seed = s;
if (seed >= 0) {
rd.setSeed(seed);
}
setup_fitness(fname);
for (int i = 0; i < FSET_START; i++) {
x[i] = (maxrandom - minrandom) * rd.nextDouble() + minrandom;
}
pop = create_random_pop(POPSIZE, DEPTH, fitness);
}
public void evolve() {
int gen = 0, indivs, offspring, parent1, parent2, parent;
double newfit;
char[] newind;
print_parms();
stats(fitness, pop, 0);
for (gen = 1; gen < GENERATIONS; gen++) {
if (fbestpop > -1e-5) {
Write("PROBLEM SOLVED\n");
//System.out.print("PROBLEM SOLVED\n");
System.exit(0);
}
for (indivs = 0; indivs < POPSIZE; indivs++) {
if (rd.nextDouble() < CROSSOVER_PROB) {
parent1 = tournament(fitness, TSIZE);
parent2 = tournament(fitness, TSIZE);
newind = crossover(pop[parent1], pop[parent2]);
} else {
parent = tournament(fitness, TSIZE);
newind = mutation(pop[parent], PMUT_PER_NODE);
}
newfit = fitness_function(newind);
offspring = negative_tournament(fitness, TSIZE);
pop[offspring] = newind;
fitness[offspring] = newfit;
}
stats(fitness, pop, gen);
}
Write("PROBLEM *NOT* SOLVED\n");
//System.out.print("PROBLEM *NOT* SOLVED\n");
System.exit(1);
}
public void Write(String context) {
FileWriter fileWriter;
try {
fileWriter = new FileWriter("GP.txt");
try (BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) {
bufferedWriter.write(context);
}
} catch (IOException ex) {
}
}
public void WriteDouble(double context) {
FileWriter fileWriter;
try {
fileWriter = new FileWriter("GP.txt");
try (BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) {
String ncontext = Double.toString(context);
bufferedWriter.write(ncontext);
}
} catch (IOException ex) {
}
}
};
The Functions Mapper file that uses the Tiny GP class file:
package function_mapper;
import javax.swing.JOptionPane;
import main.*;
public class Function_Mapper {
public static void main(String[] args) {
String fname = JOptionPane.showInputDialog(null, "File Name", "Input Dialog", JOptionPane.INFORMATION_MESSAGE);
long s = -1;
if (args.length == 2) {
s = Integer.valueOf(args[0]).intValue();
fname = args[1];
}
if (args.length == 1) {
fname = args[0];
}
tiny_gp gp = new tiny_gp(fname, s);
gp.evolve();
}
}
Much help appreciated, thanks!
The Write method overwrites the contents of the file on each invocation. There are two ways to fix this.
An easier one, is to append file, instead of overwriting it. It could be achieved by passing append argument to the FileWriter (I simplified code a little bit along the way).
// true on the next line means "append"
try (Writer writer = new FileWriter("GP.txt", true)) {
writer.write(Double.toString(context));
} catch (IOException ex) {
}
A harder, but much fore efficient one is to openwriter in the constructor, use it in Write method, and close in the specially introduced close method of the tiny_gp.

Categories

Resources