Flex settling in at The Apache Software Foundation
This is the beginning of a new era for Flex. On December 31st 2011, our project was accepted as an incubator podling at the Apache Software Foundation. read more..
That snippet would build and test your project. Important here is to specify coverage and coverageReportFormat . The coverageReportFormat is xml, so it can be used later on.src test org.sonatype.flexmojos flexmojos-maven-plugin 4.0-beta-5 true com.adobe.flex compiler 4.1.0.16248 pom TestSonar.mxml C:\FlashPlayer\FlashPlayer.exe true xml true
flex reuseReports target\surefire-reports target\coverage\coverage.xml
mvn clean install sonar:sonar -Pflex
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Script>
<![CDATA[
[Bindable]
public var buttonX:Number;
[Bindable]
public var buttonY:Number;
]]>
</fx:Script>
<s:Button label="Target" x="{buttonX}" y="{buttonY}" depth="1"/>
<s:HGroup horizontalCenter="0" verticalCenter="0" >
<s:Button label="buttonX = 100" click="buttonX = 100"/>
<s:Button label="buttonY = 100" click="buttonY = 100"/>
</s:HGroup>
</s:Application>
[Bindable] public var buttonX:Number = 0; [Bindable] public var buttonY:Number = 0;
public function interpolate(fraction:Number, startValue:Object, endValue:Object):Object
{
var startPP:PerspectiveProjection = startValue as PerspectiveProjection;
var endPP:PerspectiveProjection = endValue as PerspectiveProjection;
var currentPP:PerspectiveProjection = new PerspectiveProjection();
currentPP.fieldOfView = startPP.fieldOfView + fraction * (endPP.fieldOfView - startPP.fieldOfView);
currentPP.focalLength = startPP.focalLength + fraction * (endPP.focalLength - startPP.focalLength);
var projectionCenterX:Number = startPP.projectionCenter.x + fraction * (endPP.projectionCenter.x - startPP.projectionCenter.x);
var projectionCenterY:Number = startPP.projectionCenter.y + fraction * (endPP.projectionCenter.y - startPP.projectionCenter.y);
currentPP.projectionCenter = new Point(projectionCenterX, projectionCenterY);
return currentPP;
}
<fx:Declarations>
<effects:PPInterpolator id="ppInterpolator"/>
<s:Animate id="ppAnimate" target="{group.transform}" duration="3000" >
<s:motionPaths>
<fx:Script>
<![CDATA[
import com.tgeorgiev.effects.PPInterpolator;
]]>
</fx:Script>
<s:SimpleMotionPath property="perspectiveProjection" valueFrom="{startPP}" valueTo="{endPP}" interpolator="{ppInterpolator}" />
</s:motionPaths>
</s:Animate>
</fx:Declarations>
public static File convertToPDF(File file){
String oldFilePath = file.getAbsolutePath();
//change the extension to .pdf
String newFilePath = oldFilePath.substring(0, oldFilePath.lastIndexOf(".")) + ".pdf";
OfficeManager officeManager = new DefaultOfficeManagerConfiguration().buildOfficeManager();
officeManager.start();
OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
File newFile = new File(newFilePath);
converter.convert(file, newFile);
officeManager.stop();
return newFile;
}
private static File convertToSWF(File file) throws IOException{
String oldFilePath = file.getAbsolutePath();
//change the extension to .swf
String newFilePath = oldFilePath.substring(0, oldFilePath.lastIndexOf(".")) + ".swf";
//calling pdf2swf to convert our file.pdf to file.swf
String[] command = { "pdf2swf", file.getAbsolutePath(), "-o", newFilePath, "-f",
"-T 10", "-t", "-G"};
Process p = Runtime.getRuntime().exec(command);
BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null) {
log.info(line);
}
return new File(newFilePath);
}
So what is this? It's a custom flex 4 layout that displays elements as in cylinder. The idea for it I got a long time ago when I saw Safari's Top Sites. Back then I managed to achieve this look and feel with flex using Papervision3D. But I didn't like the way I made it at all. So year later I have decided to try again. This time with the native 3D support of Flash Player 10 and the new layouting in Flex 4 it was quite intuitive and the most proper solution.var matrix:Matrix3D = new Matrix3D(); matrix.appendTranslation(-_columnWidth/2, 0, radius); matrix.appendRotation(startDegree + degreesMove*j, Vector3D.Y_AXIS); matrix.appendTranslation(width/2, (_rowHeight + _horizontalGap) * i ,-cameraPosition); element.setLayoutMatrix3D(matrix, false);
var pp:PerspectiveProjection = new PerspectiveProjection(); pp.projectionCenter = new Point(width/2, height/2); element["transform"].perspectiveProjection = pp;
var filter:WetFloorFilter = new WetFloorFilter(); filter.height = 100; filter.alpha = 0.5; BindingUtils.bindProperty(filter, "y", thumbnail, "height"); thumbnail.filters = [filter];
private File currentDirectory = new File(System.getProperty("user.home"));
This will keep track of our current directory, as we will browse the content from the client application. I've taken a note from Helen Neely on my previous post and now the path is OS independent and it points to the user's home directory.@RemotingInclude
public List<FileInfo> listFiles() {
File files[] = currentDirectory.listFiles();
ArrayList<FileInfo> allFiles = new ArrayList<FileInfo>();
for(int i = 0; i < files.length; i++){
if(!files[i].isHidden())
{
allFiles.add(new FileInfo(files[i].getName(),
files[i].length(), files[i].isDirectory()));
}
}
return allFiles;
}
@RemotingInclude
public void changeDir(String dir) {
if(StringUtils.hasText(dir)){
File tempDirectory = new File(currentDirectory.getPath() + File.separator + dir);
if(tempDirectory.exists() && tempDirectory.isDirectory())
currentDirectory = tempDirectory;
}
}
When called this method with a name of folder we look if there is a folder with this name in our current directory and we change the current directory to it.@RemotingInclude
public FileInfo downloadFile(String fileName) throws Exception {
File file = new File(currentDirectory.getPath() + File.separator + fileName);
FileInputStream input = new FileInputStream(file);
byte data[] = new byte[(int)file.length()];
input.read(data);
return new FileInfo(file.getName(), file.length(), file.isDirectory(),
data);
}
Basically this creates a new FileInputStream for the file specified by the current directory and filename and reads it's data in a array of bytes and then we return a new FileInfo instance that holds these bytes.remoteBrowseDownload.listFiles();place a DataGrid and for it's dataProvider bind to the last result of this operation
<mx:DataGrid id="dataGrid" width="100%" height="100%"
doubleClickEnabled="true" doubleClick="dataGridDoubleClick(event)"
dragEnabled="true"
dataProvider="{remoteBrowseDownload.listFiles.lastResult}">
public function changeDir(dir:String):void
{
remoteBrowseDownload.changeDir(dir);
remoteBrowseDownload.listFiles();
}
Where "dir" is the name of the selected folder.public function downloadFile(file:FileInfo):void
{
for (var i:int = 0; i < downloadedFiles.length; i++)
{
if(file.name == downloadedFiles[i].name &&
file.size == downloadedFiles[i].size)
return;
}
remoteBrowseDownload.downloadFile(file.name);
file.isDownloaded = false;
downloadedFiles.addItem(file);
}
We are doing a simple check whether this file is already downloaded and if it's not we call the downloadFile method from our service with only the name of the file and add it in this downloadedFiles array that holds all of our downloaded files. You can see how fast the data is transfered, this is thanks to BlazeDS and AMF.private function onFileDownloaded(event:ResultEvent):void
{
var file:FileInfo = (FileInfo)(event.result);
file.isDownloaded = true;
for (var i:int = 0; i < downloadedFiles.length; i++)
{
if(file.name == downloadedFiles[i].name &&
file.size == downloadedFiles[i].size)
{
downloadedFiles.setItemAt(file, i);
}
}
}
public function saveFile(file:FileInfo):void
{
var fileRef:FileReference = new FileReference();
fileRef.save(file.data, file.name);
}
Have in mind that use this feature you have to target your application to use Flash player 10.<s:Button label="Browse Files" click="browseFiles(event)" />
<mx:DataGrid id="dataGrid" width="200">
<mx:columns>
<mx:DataGridColumn headerText="Selected files"/>
</mx:columns>
</mx:DataGrid>
<s:Button label="Upload Files" click="uploadFiles(event)"/>
private function browseFiles(event:MouseEvent):void
{
fileRefList = new FileReferenceList();
fileRefList.addEventListener(Event.SELECT, selectFiles);
fileRefList.browse();
}
private function selectFiles(e:Event):void
{
for each(var fileRef : FileReference in fileRefList.fileList)
{
fileRef.load();
selectedFiles.push(fileRef.name);
selectedFileReferences.push(fileRef);
}
dataGrid.dataProvider = selectedFiles;
}
private function uploadFiles(e:MouseEvent):void
{
for each(var fileRef : FileReference in selectedFileReferences)
{
remoteObjectUpload.doUpload(fileRef.name, fileRef.data);
}
}
@Service("fileUploadService")
@RemotingDestination(channels = {"my-amf"})
public class FileUploadService {
//change this to the desired path you wish the files to be uploaded
private static String File_Path = "C:\\workspace\\Temp\\";
@RemotingInclude
public static Boolean doUpload(String fileName, byte[] data) {
try{
//create the dir that we will store files
File dir = new File(File_Path);
dir.mkdirs();
File file = new File(File_Path + fileName);
FileOutputStream output = new FileOutputStream(file);
output.write(data);
output.close();
}
catch(FileNotFoundException e){
return false;
}
catch(IOException e){
return false;
}
return true;
}
}
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768"
applicationComplete="remoteObject.addMessage(null, null, null)">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
]]>
</fx:Script>
<fx:Declarations>
<s:RemoteObject id="remoteObject" destination="myService" fault="Alert.show(event.fault.message);">
<s:channelSet>
<s:ChannelSet>
<s:AMFChannel uri="http://maverix77.s215.eatj.com/spring-flex-server/messagebroker/amf"/>
</s:ChannelSet>
</s:channelSet>
</s:RemoteObject>
</fx:Declarations>
<mx:DataGrid x="0" dataProvider="{remoteObject.addMessage.lastResult}" width="402" y="0">
<mx:columns>
<mx:DataGridColumn dataField="sender"/>
<mx:DataGridColumn dataField="text"/>
<mx:DataGridColumn dataField="date"/>
</mx:columns>
</mx:DataGrid>
<mx:Form x="10" y="160" width="252" height="142">
<mx:FormHeading label="Leave new message" width="206"/>
<mx:FormItem label="Your name">
<s:TextInput id="nameInput"/>
</mx:FormItem>
<mx:FormItem label="Message text">
<s:TextInput id="messageInput"/>
</mx:FormItem>
<s:Button click="{remoteObject.addMessage(nameInput.text, messageInput.text, new Date())}" label="Send"/>
</mx:Form>
</s:Application>
<?xml version="1.0"?> <!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd"> <cross-domain-policy> <allow-access-from domain="*.googlegroups.com" /> </cross-domain-policy>