Take a screenshot and send it synchronized trouble

Hi,

I’m trying too send a screen shot on http request but when i do it the first time it don’t find the file.

I know i should use synchronized somewhere if you can brighten me i will be thankful.

Your code looks fine to me. In other words, hard to help without some information… any information, really.

2 Likes

42

Sorry i should have think about it before posting.

Here is the initialisation of the ScreenshotAppState
[java]screenShot = new SreenshotAppState(System.getProperty(“user.home”)+ File.separator);
this.stateManager.attach(screenShot);[/java]

All this process is tigger by nifty interaction

Here I take a screen shot
[java]public void screenShot()
{
if(soc == null || tel == null || mail == null || server == null){
soc = “Test”;
tel = “0123456789”;
nom = “test”;
mail = “vjoisseaux@globanet.fr”;
ville= “Gentilly”;
server = “http://www.regiedesign.com/test/devis_applet.php”;
}
if(!soc.equals(“Test”)){
nifty.showPopup(nifty.getCurrentScreen(), popupElement2.getId(), null);
}else{
resetCamera();

        screenShot.takeScreenshot();

        envoieFichier();
    }
}[/java]

And here i send it :
[java]public void envoieFichier(){
/upload du fichier pris en screen/

    //initialisation de connexion http au server
    HttpClient httpclient = new DefaultHttpClient();

    HttpPost httppost = new HttpPost(server);

    // filtre les fichiers pour ne récupérer que les png
    FilenameFilter pngFilter = new FilenameFilter(){
        @Override
        public boolean accept(File arg0, String arg1){
            return (arg1.endsWith(".png") && arg1.contains("CreezStand3d"));
        }
    };

    //liste les fichiers du répertoire de sauvegarde du screen
    String[] fichiers = null;
    while(fichiers == null){
        fichiers = new File(System.getProperty("user.home")).list(pngFilter);
        System.out.println("test : " + fichiers);
    }

    //test
    if(fichiers == null){
        System.out.println("Je trouve pas le dossier");
    }

    //trouve le fichier correspondant au screen       
    file = null;
    for(int i = 0;i<fichiers.length;i++){
        File tmp = new File(System.getProperty("user.home") + File.separator + fichiers[i]);
        System.out.println(tmp.getAbsolutePath()); //test
        if(file == null || tmp.lastModified()>=file.lastModified()){
            file = tmp;
        }
    }
    
    if(file == null){
        System.out.println("J'ai pas de fichier");
    }else{
        System.out.println(file.getAbsolutePath());
    }

    //envoie le screen et les infos clients au server
    try {
        MultipartEntity mpEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
        ContentBody cbFile = new FileBody(file, "image/png");
        mpEntity.addPart("userfile", cbFile);

        mpEntity.addPart("soc", new StringBody(soc));
        mpEntity.addPart("nom", new StringBody(nom));
        mpEntity.addPart("tel", new StringBody(tel));
        mpEntity.addPart("mail", new StringBody(mail));
        mpEntity.addPart("ville", new StringBody(ville));
        String prods = hashMap2String();
        mpEntity.addPart("prods", new StringBody(prods));

        httppost.setEntity(mpEntity);
        System.out.println("executing request " + httppost.getRequestLine());
        System.out.println(soc);
        System.out.println(nom);
        System.out.println(tel);
        System.out.println(mail);
        System.out.println(ville);
        System.out.println(prods);
        HttpResponse response = httpclient.execute(httppost);
        HttpEntity resEntity = response.getEntity();

        System.out.println(response.getStatusLine());
        if (resEntity != null) {
            //System.out.println(EntityUtils.toString(resEntity));
            String entree = EntityUtils.toString(resEntity);
            if(entree.contains("marche")){
                //reset valeur et aller à la page de fin "tout est ok"
                rootNode.detachAllChildren();
                //suppression du screen
                file.delete();
                nifty.gotoScreen("endok");
            } else {
                //aller à la page de fin "ya eu un pepin"
                rootNode.detachAllChildren();
                nifty.gotoScreen("enderreur");
            }
        } else {
            System.out.println("argh j'ai pas de réponse");
        }
    } catch(Exception e){
        System.out.println(e.getMessage());
    }
    httpclient.getConnectionManager().shutdown();
}[/java]

when i launch this code and don’t have any file that could be send in the source directory i got the message “i can’t find any file” (line 40) but when i do it a second time it work (except this always sent the first screen i take) so i think the application don’t have the time to fully take a screen shot before sending it.

PS : if commentary in french disturbe you i can translate them.

As far as I remmber the takeScreenshot can take a few ms?

Anyway possible solutions.

Primitive but easy:
Loop
while(!file.exist){
//wait retry for 1 second.
}

Complex but clean, (in regard that no filesystem is involved)
Create a Lock block the webrequest, make a own processor similar to the current one, take the screenshot into a buffer, unlock the web stuff, send out the buffer.

As far as i rember there is a overwrite flag in the state, that you need to set to true.

The second solution seems beautiful (because i have also trouble with file access on applet).
So basically I rewrite something similar to ScreenshotAppState with a buffer but i don’t understand what do you mean by a create lock block

Well (assuming) you have a thread that processes stuff, and does the webrequest handeling, you need to make sure to wait untill the result from the rendering thread is available, and then return the result created there.

1: request forwareded to renderThread
1: waitForRenderer
2: doing screenshot
2: releaseWaitforRenderer
1: returning result

A possible solution for this simple scenario is to use a Semaphore for the lock and the Application.enqueue for the actual request of taking a screenshot.