iiley's profileAll about iiley and AsWi...PhotosBlogLists Tools Help

Blog


    February 26

    Write Real Desktop Application with Flash And Third-party tools

    You know, the flash security makes you can't write a real desktop application with it, you can't write data to the specified location of the disk, you can't load data from the file not located at the same forlder of swf(flash6+?). Anyway, you can't do many thing as C/C++, java... can do.
     
    I wrote a demo with JFlashPlayer , you can open and save text files with this Flash/Java application, UI based on AsWing:)
     
    Download runable and source include package. (Don't run it at an path include blankspace or un-ASCII chars, it will make dll loaded faild, it's java problem)
     
    //java file
    package iiley.desktop;
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.Font;
    import java.awt.Graphics2D;
    import java.awt.Image;
    import java.awt.event.AdjustmentEvent;
    import java.awt.event.AdjustmentListener;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.OutputStreamWriter;
    import java.io.PrintWriter;
    
    import javax.swing.JFileChooser;
    import javax.swing.JFrame;
    import javax.swing.JOptionPane;
    import javax.swing.JScrollBar;
    
    import jflashplayer.FlashPanel;
    import jflashplayer.FlashPanelListener;
    
    public class JFPSample extends JFrame implements FlashPanelListener {
     
     private FlashPanel flashPanel;
     
     public JFPSample(){
      super("HomeEnvGenerator");
      FlashPanel.setRequiredFlashVersion("7");
      
      //create the flash panel with scrollbar.swf and an error image
      flashPanel = new FlashPanel(new File ("./flash.swf"), createErrorImage(), true);
       getContentPane().add(flashPanel, BorderLayout.CENTER);
      //init handler
      flashPanel.addFlashPanelListener(this);
     }
      
     private Image createErrorImage(){
      BufferedImage img = new BufferedImage(500, 200, BufferedImage.TYPE_INT_ARGB);
      Graphics2D g = img.createGraphics();
      g.setFont(new Font("Aral", Font.PLAIN, 36));
      g.setColor(Color.RED);
      g.drawString("Can't Load the SWF!", 200, 300);
      g.dispose();
      return img;
     }
     
     //receive the flash command, if it is a scrollBarValue, then adjust
     public void FSCommand(String cmd, String param) {
      if(cmd.endsWith("OpenText")){
       chooseFileAndPassPathToFlash();
      }else if(cmd.endsWith("SaveText")){
       saveText(param);
      }
     }
     
     private void chooseFileAndPassPathToFlash(){
      JFileChooser chooser = new JFileChooser();
      chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
      chooser.setDialogTitle("Select a xml file to open");
      chooser.showOpenDialog(this);
      File file = chooser.getSelectedFile();
      if(file == null){
       return;
      }
      //changed flash movieclip's variable to notify opening a file
      flashPanel.setVariable("textFilePath", file.getAbsolutePath());
     }
     
     private void saveText(String text){
      JFileChooser chooser = new JFileChooser();
      chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
      chooser.setDialogTitle("Select a path to save the file");
      chooser.showSaveDialog(this);
      File file = chooser.getSelectedFile();
      if(file == null){
       return;
      }
      if(file.exists()){
       String msg = file.getParentFile().getName() + "/" + file.getName() + " already esists, cover it?";
       int cover = JOptionPane.showConfirmDialog(this, msg);
       if(cover != JOptionPane.YES_OPTION){
        return;
       }
      }
      try {
       PrintWriter writer = new PrintWriter(
         new OutputStreamWriter(
           new FileOutputStream(file),
           "UTF-8"));
       writer.print(text);
       writer.close();
      } catch (Exception e) {
       JOptionPane.showMessageDialog(this, e.getMessage());
      }
     }
     
     public static void main(String[] args){
      JFPSample sample = new JFPSample();
      sample.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      sample.setBounds(10, 100, 520, 220);
      sample.setVisible(true);
     }
    }
    
     
     
     

    //------AS file----
    import org.aswing.BorderLayout;
    import org.aswing.FlowLayout;
    import org.aswing.JButton;
    import org.aswing.JLabel;
    import org.aswing.JPanel;
    import org.aswing.JScrollPane;
    import org.aswing.JTextArea;
    import org.aswing.JWindow;
    import org.aswing.utils.Delegate;
    
    /**
     * @author iiley
     */
    class iiley.desktop.JFPSample extends JWindow {
     
     private var root:MovieClip;
     private var loader:XML;
     
     private var xmlText:JTextArea;
     private var openButton:JButton;
     private var saveButton:JButton;
     
     public function JFPSample(root:MovieClip) {
      super(root);
      
      //init handler to java(Note that Java App will change the property)
      root["textFilePath"] = "";
      root.watch("textFilePath", Delegate.create(this, __pathGot));
      
      //This is important, make window keep same size to the Stage, Because JFlashPlayer may change the stage size
      Stage.scaleMode = "noScale";
      Stage.align = "TL";
      Stage.addListener({onResize:Delegate.create(this, __onStageResized)});
      
      //create and layout components
      xmlText = new JTextArea();
      openButton = new JButton("Open Text");
      saveButton = new JButton("Save Text");
      getContentPane().append(new JLabel("The text:"), BorderLayout.NORTH);
      getContentPane().append(new JScrollPane(xmlText), BorderLayout.CENTER);
      var buttonPane:JPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20));
      buttonPane.append(openButton);
      buttonPane.append(saveButton);
      getContentPane().append(buttonPane, BorderLayout.SOUTH);
      //init handlers for components
      openButton.addActionListener(__openTextFile, this);
      saveButton.addActionListener(__saveTextFile, this);
      //init loader handler
      loader = new XML();
      loader.onData = Delegate.create(this, __onTextData);
     }
     
     /**
      * Java changed xmlFilePath variable, means file path got
      */
     private function __pathGot(prop, oldVal, newVal):Void{
      var path:String = newVal;
      loader.load(path);
     }
     private function __onTextData(src:String):Void{
      xmlText.setText(src);
     }
     /**
      * Fire command to java app let it save the xml text
      */
     private function __saveTextFile():Void{
      fscommand("SaveText", xmlText.getText());
     }
     /**
      * Fire command to java app let it open dialog to choose a xml file path
      */ 
     private function __openTextFile():Void{
      fscommand("OpenText");
     }
    
     private function __onStageResized():Void{
      setSize(Stage.width, Stage.height);
     }
     
     public static function main(entry:MovieClip):Void{
      var sample:JFPSample = new JFPSample(entry);
      sample.setSize(Stage.width, Stage.height);
      sample.setVisible(true);
     }
    }
    
    So third-party tools borns to make you can do these, they are:
    JFlashPlayer (Windows Java Swing)
    SWTFlash (Windows Java SWT)
    mdm ZINC (Commercial, powerful)
    ....
     
     
    *referrence:
    February 16

    AsWing source repository moved to OSFlash SVN

    The old cvs repository is at sourceforge, it'll not be maintained any more. The new subversion repository is here:

    see www.aswing.org for details.

     

    With this moving, i also did some big refactors, many package names refactore, org.aswing.events renamed to org.aswing.event, org.aswing.utils renamed to org.aswing.util, etc.

    And also after alpha2, there's FocusManager finished now, you can press keybord Tab/Ctrl+Tab/Shift+Tab to navigating and focus components now.

    February 05

    Really MovieClip.hitTest(globalX,globalY) ?

    Well from flash8 livedocs, we can see this:
     
    hitTest (MovieClip.hitTest method)

    Parameters x: Number The x coordinate of the hit area on the Stage. y: Number The y coordinate of the hit area on the Stage. The x and y coordinates are defined in the global coordinate space.

     

    It said that x, y are defined in the global coordinate space. If i am not understanding wrong, the global coordinate space should be the MovieClip.localToGlobal() returned point's coordinate space. Well, if it is, i should say, the livedocs has mistakes. lets make a test:

    First create a read rectangle movieclip at root stage. named aMC.

    Then add these code at frame1:

    //--------------------------------------------------------------------------

    var mouseLis:Object = new Object();
    mouseLis.onMouseDown = function(){
     var mc:MovieClip = _root.aMC;
     var p:Object = {x:mc._xmouse, y:mc._ymouse};
     mc.localToGlobal(p);
     if(mc.hitTest(p.x, p.y, false)){
      trace("Hit!");
     }else{
      trace("Not hit!");
     }
    }
    Mouse.addListener(mouseLis);
    _root._x = 200;

    //--------------------------------------------------------------------------

    Test this movie, well, you think if mc hit the mouse point(in global coordinate space), it will trace "Hit"? No, it will trace "Not hit!".

    If i replace

     var p:Object = {x:mc._xmouse, y:mc._ymouse};
     mc.localToGlobal(p);

    to:

     var p:Object = {x:_root._xmouse, y:_root._ymouse};

     //mc.localToGlobal(p);//don't call here.

    Then, it will be runs well.

    So you can see, the livedocs's explanation has problems. But, in fact what coordinate space it use indeed? I just know normally it is _root coordinate, but when there's other _level for example you loaded a swf to _level2, the mcs in _level2 should use what coordinate space to do hitTest??? _level0 ? or _level2?