CyauShell封装了JUkaShell的createBallon()方法

CyauShell
 封装了JUkaShell的createBallon()方法使之可以被无参数调用.
JUkaShell
 createBallon()方法被更改为protected的以避免被错误调用
这次提交主要是提高bin_32中的class
Signed-off-by: sky-weihao <110458260@qq.com>
Merge branch 'galin' of https://github.com/cuter44/JUkagaka.git into sky-weihao
提供给Ghost使用的动画机函数头预览

! 这个版本不能正常运行
JUkaShell
  加入了支援动画的函数(实作中)
  削除了unlockUkagaka()方法
  修改lockUkagaka()->setUkagakaLock(), 以解决并发时的同步问题.(未测试)
    因此, 解锁的方法目前已经改变, 使用相同参数调用setLockUkagaka()可以解锁
AnimationCtrl
  增加了此组件用于实际控制动画执行(实作中)
Merge branch 'galin' of https://github.com/cuter44/JUkagaka.git into sky-weihao
Signed-off-by: sky-weihao <110458260@qq.com>
@@ -1,33 +1,51 @@
 package jukagaka.ghost.cyaughost;

+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Scanner;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.Timer;
 import jukagaka.ghost.*;
-
+import jukagaka.JUkaUtility;
+import jukagaka.shell.BalloonWin;
+import jukagaka.JUkaGhostCtrl;
 import jukagaka.shell.JUkaShell;
 import jukagaka.shell.UkagakaWin;
 import jukagaka.shell.cyaushell.CyauShell;

-class  CyauGhost extends JUkaGhost
+public class  CyauGhost extends JUkaGhost
 {
+    public CyauGhost(){
+        try {
+            Speak tmpSpeak = new Speak();
+        } catch (FileNotFoundException ex) {
+            Logger.getLogger(CyauGhost.class.getName()).log(Level.SEVERE, null, ex);
+        }
+    }
 	    /**
      * <p>主要 Shell</p>
      * <p>主要 Shell 是指在主调模块未指定具体 Shell 情况下供给的缺省 Shell,
      * 它通常指向 assignedShell[0].<br>
      * 虽然在此平台上没有定义, 但 masterShell 一般对应于传统的"主人格"</p>
      */
-    protected JUkaShell masterShell;
+    protected CyauShell masterShell;

     /**
      * <p>从属 Shell</p>
      * <p>它通常指向 assignedShell[1].<br>
      * 虽然在此平台上没有定义, 但 slaveShell 一般对应于传统的"使魔"</p>
      */
-    protected JUkaShell slaveShell;
+    //protected JUkaShell slaveShell;


     protected GhostOperatingSystem mainGhost;
     /**
      * <p>链接的 Shell 的记录表</p>
@@ -38,11 +56,11 @@ class  CyauGhost extends JUkaGhost

     /**
 	 *作为记录单个Ghost的文件名
 	 *文件名用创建和打开指定Ghost
 	 */
-	String ghostargFile = JUkaUtility.getProgramDir()+"ghost/JUkaGhost1.txt";
+	static String ghostargFile = JUkaUtility.getProgramDir()+"/ghost/JUkaGhost1.txt";

     /**
      * <p>根据指定的序号获取该 Ghost 控制的 Shell </p>
      */
     public JUkaShell getAssignedShell(int argShellID)
@@ -114,13 +132,14 @@ class  CyauGhost extends JUkaGhost
     /**
      * <p>此方法不包含任何代码, 仅仅作为 token 存在.</p>
      * <p>(*) 任何扩展此类的子类都必须以此方法签名重写该方法<br>
      * 子类的该方法会在 JUkagaka 启动时被调用, 以提供机会让 Ghost 完成初始化工作</p>
      */
-    public static void onLoad()
+    public static void onLoad()
     {
-		JUkaGhost.onload();
+		CyauShell.onLoad();
+		JUkaGhost.onLoad(ghostargFile);

         return;
     }

     /**
@@ -129,14 +148,17 @@ class  CyauGhost extends JUkaGhost
      * 子类的该方法会在所有 JUkaComponentCtrl 初始化完成后被调用, 以引导 Ghost 开始工作</p>
      *现在CyauGhost中onStart代码用于测试，根据传说，手法非常暴力
 	 */
     public static void onStart()
     {
-		JUkaGhost.onstart();
+
+		JUkaGhost.onStart();
 		CyauGhost temGhost = CyauGhost.createGhost();
         CyauShell tmpshell = CyauShell.createShell();
 		temGhost.masterShell=tmpshell;
+
+
         UkagakaWin tmpukawin = tmpshell.getUkagaka();
         tmpukawin.setVisible(true);
         tmpukawin.repaint();
         tmpukawin.clip();
         return;
@@ -155,31 +177,270 @@ class  CyauGhost extends JUkaGhost
      //*/
     //public String speak(String argSpeech, JUkaShell argShell)
 //null值为文件路径名
     public static CyauGhost createGhost(){
 		CyauGhost cyauGhost=new CyauGhost();
+
         try {
             //initalize方法为当Ghost保存文件存在后使用，
                 //这个方法为在程序实在运行时使用
-           cyauGhost.initalizeGhost(ghostargFile);
+           cyauGhost.initalizeGhost();
         } catch (IOException ex) {
             Logger.getLogger(CyauGhost.class.getName()).log(Level.SEVERE, null, ex);
         } catch (ClassNotFoundException ex) {
             Logger.getLogger(CyauGhost.class.getName()).log(Level.SEVERE, null, ex);
         }
         //这个null值也为文件名，不过这是在创建时候做出的文件名
 		//该方法作为测试时创建初始Ghost使用
-		cyauGhost.createGhost(cyauGhost,ghostargFile);
+		//cyauGhost.createGhost(cyauGhost);

 		return cyauGhost;
      }
   // Other | 杂项

 	//存储Ghost人格以及部分Shell



-	public static void main(String[] args)
-	{
+class Speak extends JPanel {
+    private int lth = GetTucaoLength();
+    private JTextArea area = new JTextArea();
+    private String[] tucaoText = GetTucaoText();
+    private int time;
+
+    int delay = 1500; //milliseconds
+    final int seconddelay = 4000;//第二延时器
+    Timer timer;
+
+    public Speak() throws FileNotFoundException{
+        initalizeSpeak();

-	}
+    }
+
+    protected void initalizeSpeak() {
+
+        int delay = 6000; //milliseconds
+        final int seconddelay = 4000;//第二延时器
+
+        timer = new Timer(delay, new Speak.timelistener());
+
+   timer.start();
+
+    }
+
+        class timelistener implements ActionListener {
+
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                BalloonWin testBall = masterShell.createBalloon();
+
+                time = (int) (Math.random() * lth);            //产生随机内容
+                SpeakCtrl(testBall);
+
+                area.setLineWrap(true);
+                area.setEditable(false);
+                area.setWrapStyleWord(true);
+                testBall.add(area, BorderLayout.CENTER);
+                testBall.setVisible(true);
+                testBall.setDragable(true);
+               area.repaint();
+                ActionListener taskPerformer1 = new ActionListener() {
+
+                    @Override////第二计时器
+                    public void actionPerformed(ActionEvent e) {
+                        setVisible(false);
+                        //   shell.destroyBalloon(newballoon);
+                    }
+                };
+
+                new Timer(seconddelay, taskPerformer1).start();
+            }
+        }
+
+        //
+    public void CheckTucaoFile(File file) {//检查Tucao.txt是否存在
+
+        if (!file.exists()) {//检查Tucao.txt是否存在
+            System.out.println("读取吐槽文件失败");
+
+            System.exit(0);
+        }
+    }
+
+    public int GetTucaoLength() throws FileNotFoundException {//获取Tucao.txt的行数
+
+        int length = 0;
+
+        File speakfile = new File(JUkaUtility.getProgramDir() + "/Tucao.txt");
+
+        CheckTucaoFile(speakfile);
+
+		   CheckTucaoFile(speakfile);
+            try (Scanner input = new Scanner(speakfile)) {
+                while (input.hasNextLine()) {
+                    length++;
+                    input.nextLine();//将input扫描器移到下一行
+                }
+            }
+
+
+            return length;
+        }
+
+        public String[] GetTucaoText() {//将Tucao.txt中的文本读取并存到一个字符串数组中
+
+
+            String username = null;//用户名
+
+            //username = log.getUsername();//获取用户名
+
+            File speakfile = new File(JUkaUtility.getProgramDir() + "/Tucao.txt");//读取文本
+            CheckTucaoFile(speakfile);//检查文本是否存在
+            System.out.print(lth);
+            String[] tucaotext = new String[lth];//创建文本行数长度的字符串数组
+            Scanner input = null;//初始化扫描器
+            try {
+                input = new Scanner(speakfile);
+            } catch (FileNotFoundException ex) {
+            }
+            int i = 0;//计算tucaotext字符串数组下标
+            while (input.hasNextLine()) {//是否存在下一行
+                String tempstring = input.nextLine();//获取Tucao.txt中的一行字符串
+                tucaotext[i] = tempstring;//将处理后的字符串存到tucaotext字符串数组中
+                i++;
+            }
+            tucaoText = tucaotext;
+            return tucaotext;
+        }
+
+
+        public void setTucao(boolean word) {
+            if (word == true) {
+                timer.start();
+            } else {
+                timer.stop();
+            }
+        }
+
+        public int SpeakCtrl(BalloonWin testBall) {
+            String test = tucaoText[time].trim();
+            StringBuilder demo1 = new StringBuilder();
+            StringBuilder demo2 = new StringBuilder();
+
+            int i = 0;
+            while (i < test.length()) {
+                char a = test.charAt(i);
+
+
+                if (a == '$') {
+                    demo1.append(a);
+                    while (test.charAt(i) != ';' || i < test.length()) {
+                        demo1.append(test.charAt(i));
+                        i++;
+                    }
+                    if (demo1.indexOf("$var") >= 0) {
+                        //Todo转换为user名臣
+                        continue;
+                    }
+
+
+                    if (demo1.indexOf("$s") >= 0) {
+                        // 设定操作对象的shell
+                        continue;
+                    }
+
+
+                    if (demo1.indexOf("$p") >= 0) {
+                        //单独使用暂停说话，ani中使用暂停
+                        continue;
+                    }
+
+
+
+                    if (demo1.indexOf("$em") >= 0) {
+                        //Todo设定图层，换表情
+                        continue;
+                    }
+
+
+                    if (demo1.indexOf("$ani") >= 0) {
+                        //Todo标记动画开始，不允许嵌套
+                        continue;
+                    }
+
+
+                    if (demo1.indexOf("$_ani") >= 0) {
+                        //Todo标记动画结束
+                        continue;
+                    }
+
+
+                    if (demo1.indexOf("$sp") >= 0) {
+                        //Todo字符上屏速度，不设定则使用默认，仅影响此speak中此标记之后的文字
+                        continue;
+                    }
+
+
+                    if (demo1.indexOf("$brani") >= 0) {
+                        //Todo打断动画
+                        continue;
+                    }
+                    if (demo1.indexOf("$$") >= 0) {
+                        //Todo解析为一个文本的$
+                        continue;
+                    }
+                    if (demo1.indexOf("$n") >= 0) {
+                        //Todo换行
+                        continue;
+                    }
+
+                } else {
+                    while (test.charAt(i) != '$' && i < test.length()-1) {
+
+						a=test.charAt(i);
+                        demo2.append(a);
+                        i++;
+                    }
+
+                    area.setText(demo2.toString());//在气球上输出内容
+                    new Thread(new Runnable() {
+                        public void run() {
+                            try {
+                                Thread.sleep(500);
+                            } catch (InterruptedException ex) {
+                                Logger.getLogger(JUkaGhost.class.getName()).log(Level.SEVERE, null, ex);
+                            }
+                            }
+
+                    }).start();
+                }
+                i++;
+                demo1.delete(0, demo1.length());
+                demo2.delete(0, demo2.length());
+
+            }
+
+            return 0;
+        }
+    }
+
+//       //以下测试
+    public static void main(String[] args) {
+
+         //CyauShell.onLoad();
+//        CyauShell tmpshell = CyauShell.createShell();
+//
+//        UkagakaWin tmpukawin = tmpshell.getUkagaka();
+//        //BalloonWin testballoon = tmpshell.createBalloon();
+         CyauGhost.onLoad();
+		 CyauGhost.onStart();
+
+
+
+
+
+        //tmpukawin.setVisible(true);
+        //tmpukawin.repaint();
+        //tmpukawin.clip();
+        return;
+    }
 }
@@ -3,16 +3,25 @@
  * @version v120827
  */

 package jukagaka.ghost;

+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
 import java.io.*;
 import jukagaka.*;
 import jukagaka.shell.*;
 import jukagaka.shell.cyaushell.CyauShell;

 import java.util.ArrayList;
+import java.util.Scanner;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.Timer;

 public class JUkaGhost extends JUkaComponent implements Serializable
 {
   // Shell Manipulate | Shell 操控
     /**
@@ -114,24 +123,28 @@ public class JUkaGhost extends JUkaComponent implements Serializable
     /**
      * <p>此方法不包含任何代码, 仅仅作为 token 存在.</p>
      * <p>(*) 任何扩展此类的子类都必须以此方法签名重写该方法<br>
      * 子类的该方法会在 JUkagaka 启动时被调用, 以提供机会让 Ghost 完成初始化工作</p>
      */
-    public static void onLoad() throws IOException, ClassNotFoundException {
-
-        JUkaGhost.argghost = JUkaGhost.OSReading(null);
-
-
+    protected static void onLoad(String ghostargFile){
+
+            try {
+            JUkaGhost.argghost = JUkaGhost.OSReading(ghostargFile);
+        } catch (IOException ex) {
+            Logger.getLogger(JUkaGhost.class.getName()).log(Level.SEVERE, null, ex);
+        } catch (ClassNotFoundException ex) {
+            Logger.getLogger(JUkaGhost.class.getName()).log(Level.SEVERE, null, ex);
+        }
         return;
     }

     /**
      * <p>此方法不包含任何代码, 仅仅作为 token 存在.</p>
      * <p>(*) 任何扩展此类的子类都必须以此方法签名重写该方法<br>
      * 子类的该方法会在所有 JUkaComponentCtrl 初始化完成后被调用, 以引导 Ghost 开始工作</p>
      */
-    public static void onStart()
+    protected static void onStart()
     {
         return;
     }

   // Speak & Marco System | 宏解析
@@ -146,17 +159,17 @@ public class JUkaGhost extends JUkaComponent implements Serializable
      //* @return 最终解析的说话内容
      //*/
     //public String speak(String argSpeech, JUkaShell argShell)


-    protected void createGhost(JUkaGhost os,String GhostargFile){
-        docreateGhost(this,GhostargFile);
+    protected void createGhost(JUkaGhost os){
+        docreateGhost(this);


 	}

-    private JUkaGhost docreateGhost(JUkaGhost os,String GhostargFile){
+    private JUkaGhost docreateGhost(JUkaGhost os){
         os.mainGhost=new GhostOperatingSystem();
         os.mainGhost.initalizeOS();

 		return os;
     }
@@ -174,38 +187,260 @@ public class JUkaGhost extends JUkaComponent implements Serializable


 	//存储Ghost人格以及部分Shell,进行中


+    public void OSStorage(String ghostargFile){
+        try {
+            JUkaGhost.doOSStorage(this, ghostargFile);
+        } catch (IOException ex) {
+           System.err.println("error in 196");
+        }
+    }

-	public static void OSStorage(GhostOperatingSystem os,String ghostargFile) throws IOException
-	{
-            ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream(ghostargFile));
-			output.close();
-	}
+    public static void doOSStorage(JUkaGhost argGhost, String ghostargFile) throws IOException {
+
+        ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream(ghostargFile));
+        output.writeObject(argGhost);
+        output.close();
+
+    }



     public static Object OSReading(String ghostargFile) throws IOException, ClassNotFoundException{
             ObjectInputStream input = new ObjectInputStream(new FileInputStream(ghostargFile));
           Object initghost=input.readObject();
           input.close();
           return initghost;
         }

-/**
-     * @deprecated 此方法目前仅用于调试
+/*
+ * 这个类为茶兔speak类的第一版，修改自第一个CyauGhost,但是其中加入了宏解释功能
+ * 此类之后较适合加入于GhostOperatingSystem类，当然加入Ghost中也能运行，此类只能
+ * 作为测试功能供你们吐槽的作用。
+*/
+//public class Speak extends JPanel {
+//    private int lth = GetTucaoLength();
+//    private JTextArea area = new JTextArea();
+//    private String[] tucaoText = GetTucaoText();
+//    private int time;
+//
+//    int delay = 1500; //milliseconds
+//    final int seconddelay = 4000;//第二延时器
+//    Timer timer;
+//
+//    public Speak() throws FileNotFoundException{
+//        initalizeSpeak();
+//    }
+//
+//    protected void initalizeSpeak() {
+//
+//        int delay = 6000; //milliseconds
+//        final int seconddelay = 4000;//第二延时器
+//
+//        timer = new Timer(delay, new Speak.timelistener());
+//
+//
+//    }
+//
+//        class timelistener implements ActionListener {
+//
+//            @Override
+//            public void actionPerformed(ActionEvent e) {
+//                BalloonWin testBall = masterShell.createBalloon(TOOL_TIP_TEXT_KEY, null, null);
+//                time = (int) (Math.random() * lth);            //产生随机内容
+//                SpeakCtrl(testBall);
+//                area.setLineWrap(true);
+//                area.setEditable(false);
+//                area.setWrapStyleWord(true);
+//                testBall.add(area, BorderLayout.CENTER);
+//                testBall.setVisible(true);
+//                testBall.setDragable(true);
+//
+//                ActionListener taskPerformer1 = new ActionListener() {
+//
+//                    @Override////第二计时器
+//                    public void actionPerformed(ActionEvent e) {
+//                        setVisible(false);
+//                        //   shell.destroyBalloon(newballoon);
+//                    }
+//                };
+//
+//                new Timer(seconddelay, taskPerformer1).start();
+//            }
+//        }
+//
+//        //
+//        public void CheckTucaoFile(File file) {//检查Tucao.txt是否存在
+//
+//            if (!file.exists()) {//检查Tucao.txt是否存在
+//                System.out.println("读取吐槽文件失败");
+//                System.exit(0);
+//            }
+//        }
+//
+//        public int GetTucaoLength() throws FileNotFoundException {//获取Tucao.txt的行数
+//
+//            int length = 0;
+//            File speakfile = new File(JUkaUtility.getProgramDir() + "Tucao.txt");
+//            CheckTucaoFile(speakfile);
+//            try (Scanner input = new Scanner(speakfile)) {
+//                while (input.hasNextLine()) {
+//                    length++;
+//                    input.nextLine();//将input扫描器移到下一行
+//                }
+//            }
+//
+//
+//            return length;
+//        }
+//
+//        public String[] GetTucaoText() {//将Tucao.txt中的文本读取并存到一个字符串数组中
+//
+//
+//            String username = null;//用户名
+//
+//            //username = log.getUsername();//获取用户名
+//
+//            File speakfile = new File(JUkaUtility.getProgramDir() + "Tucao.txt");//读取文本
+//            CheckTucaoFile(speakfile);//检查文本是否存在
+//            String[] tucaotext = new String[lth];//创建文本行数长度的字符串数组
+//            Scanner input = null;//初始化扫描器
+//            try {
+//                input = new Scanner(speakfile);
+//            } catch (FileNotFoundException ex) {
+//            }
+//            int i = 0;//计算tucaotext字符串数组下标
+//            while (input.hasNextLine()) {//是否存在下一行
+//                String tempstring = input.nextLine();//获取Tucao.txt中的一行字符串
+//                tucaotext[i] = tempstring;//将处理后的字符串存到tucaotext字符串数组中
+//                i++;
+//            }
+//            tucaoText = tucaotext;
+//            return tucaotext;
+//        }
+////吐槽面板开关
+//
+//        public void setTucao(boolean word) {
+//            if (word == true) {
+//                timer.start();
+//            } else {
+//                timer.stop();
+//            }
+//        }
+//
+//        public int SpeakCtrl(BalloonWin testBall) {
+//            String test = tucaoText[time].trim();
+//            StringBuilder demo1 = null;
+//            StringBuilder demo2 = null;
+//            int i = 0;
+//            while (i < test.length()) {
+//                char a = test.charAt(i);
+//
+//                if (a == '$') {
+//                    demo1.append(a);
+//                    while (test.charAt(i) != ';' || i < test.length()) {
+//                        demo1.append(test.charAt(i));
+//                        i++;
+//                    }
+//                    if (demo1.indexOf("$var") >= 0) {
+//                        //Todo转换为user名臣
+//                        continue;
+//                    }
+//
+//
+//                    if (demo1.indexOf("$s") >= 0) {
+//                        // 设定操作对象的shell
+//                        continue;
+//                    }
+//
+//
+//                    if (demo1.indexOf("$p") >= 0) {
+//                        //单独使用暂停说话，ani中使用暂停
+//                        continue;
+//                    }
+//
+//
+//
+//                    if (demo1.indexOf("$em") >= 0) {
+//                        //Todo设定图层，换表情
+//                        continue;
+//                    }
+//
+//
+//                    if (demo1.indexOf("$ani") >= 0) {
+//                        //Todo标记动画开始，不允许嵌套
+//                        continue;
+//                    }
+//
+//
+//                    if (demo1.indexOf("$_ani") >= 0) {
+//                        //Todo标记动画结束
+//                        continue;
+//                    }
+//
+//
+//                    if (demo1.indexOf("$sp") >= 0) {
+//                        //Todo字符上屏速度，不设定则使用默认，仅影响此speak中此标记之后的文字
+//                        continue;
+//                    }
+//
+//
+//                    if (demo1.indexOf("$brani") >= 0) {
+//                        //Todo打断动画
+//                        continue;
+//                    }
+//                    if (demo1.indexOf("$$") >= 0) {
+//                        //Todo解析为一个文本的$
+//                        continue;
+//                    }
+//                    if (demo1.indexOf("$n") >= 0) {
+//                        //Todo换行
+//                        continue;
+//                    }
+//
+//                } else {
+//                    while (test.charAt(i) != '$' || i < test.length()) {
+//                        demo2.append(a);
+//                        i++;
+//                    }
+//
+//                    area.setText(demo2.toString());//在气球上输出内容
+//                    new Thread(new Runnable() {
+//                        public void run() {
+//                            try {
+//                                Thread.sleep(500);
+//                            } catch (InterruptedException ex) {
+//                                Logger.getLogger(JUkaGhost.class.getName()).log(Level.SEVERE, null, ex);
+//                            }
+//                            }
+//
+//                    }).start();
+//                }
+//                i++;
+//                demo1 = null;
+//                demo2 = null;
+//
+//            }
+//
+//            return 0;
+//        }
+//    }
+
+    /**
+     *
      */
-    public static void main(String[] args)
-    {
-        // 此代码段演示创建一个Shell的方法
-        // 注意因为这段代码写于JUkaShell尚未完全构建之时, 所以使用的方法有些许暴力
-        CyauShell.onLoad();
+    public static void main(String[] args) {
+        //以下测试
+         CyauShell.onLoad();
         CyauShell tmpshell = CyauShell.createShell();
+
         UkagakaWin tmpukawin = tmpshell.getUkagaka();
+        //BalloonWin testballoon = tmpshell.createBalloon();
+
         tmpukawin.setVisible(true);
         tmpukawin.repaint();
         tmpukawin.clip();
-
         return;
     }
 }



Signed-off-by: sky-weihao <110458260@qq.com>