flex air show pdf preview - apache-flex

I am using urlloader to load a tiff file from the server.
Then i get it as ByteArray and show the image in a popup window.
var bytes:ByteArray = urlloader.data as ByteArray;
i use the TIFFbaselineDecoder to decode the bytes and open a popup to show the bitmap.
Works nicely.
Now, i want to do the same thing for a pdf file.
How can i show the pdf file in a window from the bytearray.
Please let me know.
Thanks
Vish

First, you can check if the user's machine is suitable for PDF display
if(HTMLLoader.pdfCapability == HTMLPDFCapability.STATUS_OK){
trace("PDF content can be displayed");
}
else {
trace("PDF cannot be displayed. Error code:", HTMLLoader.pdfCapability);
}
If so, then
var request:URLRequest = new URLRequest("http://www.example.com/test.pdf");
pdf = new HTMLLoader();
pdf.height = 800;
pdf.width = 600;
pdf.load(request);
container.addChild(pdf);
Mind you, this works too :
<mx:HTML width="100%" height="100%" location="understanding_the_flex_3_lifecycle_v1.0.pdf"/>

Related

Copy BitmapData From mx:Image

How can I copy or duplicate the bitmapdata from a mx:image component?
I need to display the same image in multiple screens of my application and don't want to have to download the image multiple times.
I could just use a urlrequest to download the image as a bitmap and copy that but I like the way you can can just set the source of the image component.
Image extends SWFLoader which has a content property that will contain the Bitmap object that was loaded. Wait for the image to load, cast the content to Bitmap and read its bitmapData
public function imageLoadCompleteHandler(e:Event):void
{
var bitmap:Bitmap = img.content as Bitmap;
if(bitmap == null) {
trace("loaded content is not an image");
return;
}
bmpData = bitmap.bitmapData;
//hurray..!
}
Actually after reading the message above (and trying stuff out) I think this is wrong. The Complete listener fires on my second image so I guess it is loading it twice. Oh well.
I couldn't place the whole Flex doc, but this seemed to work. I added this to the Application tag: applicationComplete="Run();"
The following is wrapped in a mx:Script tag:
import mx.controls.Image;
private function Run():void
{
var i:Image = new Image();
i.source = first.source;
addChild(i);
}
And this is just a Image outside of the script tag:
<mx:Image x="12" y="125" source="e53c04a51d5992fb77ab1e20c45ddc9f.jpeg" id="first" />
I also tried this after setting the i source:
first.source = null;
Just to see what happens, the i image keeps it's source

Images won't dynamically refresh

I am writing a Flex application to receive xml from an httpservice. That works because I can populate a datagrid with the information. The xml sends image pathnames. A combobox sends a new HttpService call onChange. This repopulates the datagrid and puts new images in the folder that flex is accessing.
I want to dynamically change the image without changing the pathname of the image.
<mx:Canvas id="borderCanvas"><mx:Canvas id="dropCanvas">
<mx:Tile id="adTile"><mx:Image></mx:Image>
</mx:Tile></mx:Canvas></mx:Canvas>
This is my component.
I assign my Image sources using this code:
var i:Number = 0;
while ( i <= dg_conads.rowCount){
var img:Image = new Image();
img.source = null;
img.source = imageSource+i+".jpg";
adTile.addChild(img);
i++; }
My biggest problem is that the images are not refreshing. I get the same image even though I've prevented caching from the HTML wrapper and the ASP.Net website. The image automatically loads in the folder and refreshes in the folder but I can't get the image to refresh in the application.
I've tried removeAllChildren(); delete(adTile.getChildAt(0)); and neither worked.
I would try using:
img.load(imageSource + i + ".jpg");
If that doesn't work, try appending a random number on the end ie:
img.source = imageSource + i + ".jpg?" + Math.random();
Have you tried to add id="img" into the mx:Image tag directly and remove adTile.addChild(img);
in the script?

Can I print an HTMLLoader (pdf) in Adobe Air?

I'm using AlivePDF to create a PDF file, then save it to the desktop. I can then use an HTMLLoader to display my lovely PDF file.
Now, the print button in Adobe Reader works fine. However, there will be young children using the app, so I'd like to have a big "Print" button right above it.
I figured I could just start up a print job and feed it my HTMLLoader. This won't work because the HTML loader rasterizes the content.
Any suggestions?
One answer I have found in order to solve this problem is called Cross-scripting PDF content. The idea is that a PDF can have embedded JavaScript, which can be called from the JavaScript within the HTML page "housing" said PDF (object tag only, no embed).
This site was of particular help. I had to simplify the JavaScript from that page down quite a bit. I kept getting syntax errors.
I also need my program to generate the PDF and the HTML content. I cannot ship a single PDF with embedded JS and an HTML file pointing to it. They need to be dynamically generated by the user. Here is a basic rundown:
private function printText(text:String):void
{
var p:PDF=new PDF(Orientation.PORTRAIT, Unit.MM, Size.LETTER);
p.addPage();
p.addText(text, 100, 100);
p.addJavaScript(this.getJavascript());
var f:FileStream=new FileStream();
var html:File=File.desktopDirectory.resolvePath("exported.html");
f.open(html, FileMode.WRITE);
f.writeUTF(this.getHtml());
f.close();
var file:File=File.desktopDirectory.resolvePath("exported.pdf");
f.open(file, FileMode.WRITE);
var bytes:ByteArray=p.save(Method.LOCAL);
f.writeBytes(bytes);
f.close();
Now that we have our two files, HTML and PDF, we can view the PDF, and create a giant purple print button for our younger / sight-impared users.
if (HTMLLoader.pdfCapability == HTMLPDFCapability.STATUS_OK)
{
var win:PrintTitleWindow; //the window w/giant button
var htmlLoader:HTMLLoader=new HTMLLoader();
var url:URLRequest=new URLRequest(html.url);
htmlLoader.width=880;
htmlLoader.height=(appHeight - 150); //i figure out the height elsewhere
htmlLoader.load(url);
var holder:UIComponent=new UIComponent();
holder.addChild(htmlLoader);
win=PrintTitleWindow(PopUpManager.createPopUp(mainWindow, PrintTitleWindow, true));
win.width=900;
win.height=(appHeight - 50);
win.addChild(holder);
win.addContent(htmlLoader);
PopUpManager.centerPopUp(win);
}
}
Here is the JS and HTML I used. I'm adding these in here for laughs. I'm sure there is a better way to do this, but I'm tired and it is late.
private function getJavascript():String
{
return 'function myOnMessage(aMessage) { print({ bUI: true, bSilent: false, bShrinkToFit: true }); } function myOnDisclose(cURL,cDocumentURL) { return true; } function myOnError(error, aMessage) { app.alert(error); } var msgHandlerObject = new Object(); msgHandlerObject.onMessage = myOnMessage; msgHandlerObject.onError = myOnError; msgHandlerObject.onDisclose = myOnDisclose; this.hostContainer.messageHandler = msgHandlerObject;';
}
private function getHtml():String
{
return '<html><head><script>function callPdfFunctionFromJavascript(arg) { pdfObject = document.getElementById("PDFObj");pdfObject.postMessage([arg]);}</script></head><body><object id="PDFObj" data="exported.pdf" type="application/pdf" width="100%" height="100%"></object></body></html>';
}
The PrintTitleWindow is a simple title window with the print button on it. The code to print is simple.
myHtmlLoader.window.callPdfFunctionFromJavascript('Print');
Eh Voila! I have a gigantor-print-button like so:
(source: cetola.net)
Hitting that big purple print button is the same as hitting the print icon in the PDF toolbar. The difference for me is that my users, who could be elementary or middle-school kids, won't have to look around for the stupid button.
So, it's a long way around the block. Still, if you need to print and can't rely on that adobe toolbar button, here's your answer :) .

Flex Air HTMLLoader blank pop up window when flash content is loaded

I have a flex Air program that loads external content with the HTMLLoader. Now for some reason whenever I load a page that has any flash content a blank system window pops up outside of my program. It's completely blank, all white with min, max and close buttons. If I close it any flash content I loaded stops working. For the life of my I can't figure out what's happening and there's no messages in the console and no title for the window.
Does anyone have any ideas? I appreciate any help you can give. Here's the code I'm using:
private var webPage:HTMLLoader;
private function registerEvents():void
{
this.addEventListener(gameLoadEvent.GAME_LOAD, gameLoad);
//webPage = new HTMLLoader();
}
//function called back from Game Command to load correct game
private function gameLoad(event:Event):void
{
var gameEvent:gameLoadEvent = event as gameLoadEvent;
loadgame(gameEvent.url, gameEvent.variables);
}
private function loadgame(url:String, variableString:String):void
{
DesktopModelLocator.getInstance().scaleX = 1;
DesktopModelLocator.getInstance().scaleY = 1;
//var url:String = "http://pro-us.sbt-corp.com/aspx/member/LaunchGame.aspx";
var request:URLRequest = new URLRequest(url);
//var variables:URLVariables = new URLVariables("gameNum=17&as=as1&t=demo&package=a&btnQuit=0");
if(variableString != null && variableString != ""){
var variables:URLVariables = new URLVariables(variableString);
variables.exampleSessionId = new Date().getTime();
variables.exampleUserLabel = "guest";
request.data = variables;
}
webPage = HTMLLoader.createRootWindow(true, null, true, null);
webPage.height = systemManager.stage.nativeWindow.height - 66;
webPage.width = systemManager.stage.nativeWindow.width;
webPage.load(request);
webPage.navigateInSystemBrowser = false;
flexBrowser.addChild(webPage);
}
]]>
</mx:Script>
<mx:HTML id="flexBrowser" width="1366" height="658" backgroundAlpha="0.45" creationComplete="registerEvents();" x="0" y="0">
</mx:HTML>
you're not using any of the capabilities of your html component. As is, it may as well be a canvas since all you're doing is addChild to flexBrowser, a DisplayObjectContainer. Though I wouldn't do it this way, you can pretty simply set the flexBrowser.htmlLoader.load(request); and get rid of all that webPage stuff.
Is your application using a transparent window? air won't display flash content in the HTMLLoader in that case, see http://bugs.adobe.com/jira/browse/SDK-15033
One workaround is to use http://code.google.com/p/adobe-air-util/source/browse/trunk/src/net/tw/util/air/HTMLOverlay.as.
I had to do some changes to get it to work well with our app. I sent an email to the project owner to contribute the changes, if you are still on it I can send you the patch. The most important change, is that the html overlay window does go behind other apps when switching i.e. alt-tab or opening another app.
Update: I committed the changes to the overlay above, check it out as it should work for you as well. I know it seems like an awful workaround, but there doesn't seem to be anything better until adobe fixes the issue. If you do see something better, make sure to post the update :)
This problem has been fixed in AIR 1.5.2:
Before AIR 1.5.2, SWF content embedded in and HTML container in a transparent window could not be displayed. With AIR 1.5.2, SWF content can be displayed with certain wmode settings.

Flex 3: Is it possible to use a remote image as the icon for a LinkButton?

We are creating a LinkButton programmatically and would like to set it's icon to an image retrieved from the remote server rather than something embedded within the SWF. The .icon property expects a Class but I can't figure out how to create one equivalent to an #Embed but from a dynamically generated URLRequest or URL String.
var myImage:Image = new Image();
myImage.source = "http://www.domain.com/img/1234.png";
myImage.width = 16;
myImage.height = 16;
myImage.scaleContent = true;
var myButton:LinkButton = new LinkButton();
myButton.label = "Some text"
// This is what I'm trying to figure out.
myButton.setStyle("icon", ???)
I'm probably missing something obvious - I've tried passing in the URL and myImage separately but both throw errors. Stepping into the setStyle() method shows that the code is expecting a Class - so what do I pass in place of the ???
I can't embed the image itself because it's dynamic - the URL is different each time the software runs.
Thanks for any assistance!
Why not just set the buttonMode of a mx:Image to true then add a click event?
<mx:Image source="{imageSource}" buttonMode="true" click="action()" />
I'm not sure its possible without using an embedded images with a linkButton
This might be worth a read
Edit... in AS3:
var img:Image = new Image();
img.source = "...";
img.buttonMode = true;
img.addEventListenever(MouseEvent.CLICK, funcName);
I think that instead of trying to set the style, you need to change the child object that holds the icon. You can access it by something like:
Var:Bitmap icon = myButton.getChildByName("upIcon") as Bitmap
It should be easy to replace the bitmapData in there with the one from a Loader.
If memory serves, you'll want to use button.setStyle('icon', img), where img is an image loaded via Loader class.
for laalto,
this may be too late of an answer but somebody might find it useful or as a starting point to a solution to your problem. Have you tried referencing your image icon as a class? I don't know if this will work for an image which is in a dynamic URL but this worked for me:
[Embed("assets/LinkButton.png")]
private const linkButtonIcon:Class;
Then in your code:
myButton.setStyle("icon", linkButtonIcon);
See this example here:
http://blog.flexexamples.com/2008/09/03/setting-the-icon-on-a-linkbutton-control-in-flex/
<mx:Button id="example" label="Example" icon="{IconUtility.getClass(example, 'http://www.exampledomain.com/image.jpg')}" />
http://blog.benstucki.net/?p=42

Resources