2016年5月19日 星期四

範例 - 輸入元件(介面)

輸入元件是腳本互動性很重要的一環,就像指標如果無法改變參數造成的困擾一樣,不過如果有繼承CustomCore(指標圖形介面),就不太需要自己做輸入元件的介面了。但對於需要自行開發指標或參數選單的人,這一章可以得到很多東西。


AC可以儲存的變數類型有int、long、double、boolean、String與以上類型的陣列,儲存的方式是透過"變數的名稱"(字串),所以元件的初始化都要給變數的名稱。可以顯示輸入介面的地方有圖格右鍵選單、圖格左側選單、列表則是固定在上方。詳細的用法就透過範例來了解吧。

圖格右鍵選單(或列表選單)




 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
lib "personal";

public class MyScript extends CustomCorePersonal implements InpEventListener
{
 public void init()
 {
  CustomCore_UI_INIT();
 }

 int a = 5;
 public void eventShowInput()
 {
  HtmlInputHelper html = new HtmlInputHelper(LIGHTGRAY);
  html.add("輸入a : ", new InpNum("a", 1, 2, this));

  updateInput(html.get());
 }

 public boolean eventOccurred(InpComponent comp, Args arg)
 {
  dbg.open();
  dbg.print("a為 : " + a);
  return false;
 }
}

Line 3 : 最後面接了implements InpEventListener,表示這個類別會實做InpEventListener的介面函數,就是第19行的函數。

Line 11 : eventShowInput函數是當有顯示選單需求時會被呼叫的函數,這個函數裡要的事情就是把輸入元件的介面HTML字串做出來,再透過updateInput函數傳給系統。

Line 13 : HtmlInputHelper是一個簡化HTML語法的小工具,基本上的佈局配置(Layout)就是每次add為一行,每行可以很多欄。

Line 14 : 實體化了一個InpNum元件用來輸入變數"a",後面接的參數不多說明了,自己亂改看看就知道牽動的關聯了。

Line 19 : eventOccurred函數,當輸入元件被更動時就會透過這個函數告知腳本。如果函數回傳true就表示腳本需要重新執行,若不需要可以回傳false。

---

看起來會很複雜嗎?其實很多都是固定的格式了,重點沒有幾行,如果真的還看不懂,你可能需要加強一下Java語言的能力,或動手亂改看看,反正改壞了重新下載解壓縮就還原了,給他亂整一通,很快就進入狀況了。


圖格左側選單




 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
lib "personal";

public class MyScript extends CustomCorePersonal implements InpEventListener
{
 HtmlPanel my_panel = new HtmlPanel(BLACK, BLACK, false, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
 
 public void init()
 {
  CustomCore_UI_INIT();

  show_menu();
  addTabPanel("選單", my_panel);
 }

 int a = 5;
 public void show_menu()
 {
  HtmlInputHelper html = new HtmlInputHelper(LIGHTGRAY);
  html.add("輸入a : ", new InpNum("a", 1, 2, this));

  my_panel.setText(html.get());
 }

 public boolean eventOccurred(InpComponent comp, Args arg)
 {
  dbg.open();
  dbg.print("a為 : " + a);
  return false;
 }
}

Line 5 : 實體化一個HTML面板。

Line 12 : 把上述的HTML面板加到左側選單。

Line 21 : 把輸入元件的HTML字串設定給HTML面板。



左側頁籤選單
如果選項很多需要分類,可以用類似這樣的方式顯示。


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
lib "personal";

public class MyScript extends CustomCorePersonal
{
 AcTabbedPane tabpane1 = new AcTabbedPane("T1");

 public void init()
 {
  CustomCore_UI_INIT();

  HtmlPanel htmlp1 = new HtmlPanel();
  HtmlPanel htmlp2 = new HtmlPanel();

  htmlp1.print("我是HTML-1");
  htmlp1.setSidePanelSelectedListener(new SidePanelSelectedListener()
  {
   public void selected()
   {
    dbg.open();
    dbg.print("我被選到了!");
   }
  });

  tabpane1.insertTab("HTML-1", null, htmlp1, "", tabpane1.getTabCount());
  tabpane1.insertTab("HTML-2", null, htmlp2, "", tabpane1.getTabCount());
  addTabPanel("頁籤", tabpane1);
 }
}

這幾乎都是複製貼上的用法,不逐行解釋了。

全元件示範


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
lib "personal";

public class MyScript extends CustomCorePersonal implements InpEventListener
{
 HtmlPanel my_panel = new HtmlPanel(BLACK, BLACK, false, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
 
 public void init()
 {
  CustomCore_UI_INIT();

  show_menu();
  addTabPanel("選單", my_panel);
 }

 int value1 = 20;
 Date date_ = new Date();

 String[] slt_arr = new String[]{"選項0", "選項1", "選項2"};
 int slt_1_idx = 0;
 String slt_1_text = slt_arr[1];
 int slt_2_idx = 0;
 int slt_3_idx = 0;

 String text = "";

 boolean check1 = false;
 boolean[] check2 = new boolean[3];
 int check_s_int = 0;
 String check_s_str = "";

 Color color = Color.blue;

 double num = 3;
 int[] num_arr = new int[]{5, 10};

 public void show_menu()
 {
  HtmlInputHelper html = new HtmlInputHelper(LIGHTGRAY);
  html.add("勾選1", new InpChk("check1", ""));
  html.add("數字 : ", new InpNum("num", 0.5, 2));
  html.add("陣列數字 : ", new InpNum("num_arr[0]", 1, 2), new InpNum("num_arr[1]", 1, 2));
  html.add("日期 : ", new InpDate("date_"));
  html.add("字串輸入 : ", new InpText("text", 10));
  html.add("顏色 : ", new InpColor("color"));

  html.add("===========================");

  html.add("選項1 : ", new InpSlt("slt_1_idx", slt_arr), " (數字變數)");
  html.add("選項1 : ", new InpSlt("slt_1_text", slt_arr), " (字串變數)");
  html.add("選項2 : ", new InpSlt2("slt_2_idx", slt_arr), " 選單 : ", new InpMenu("slt_3_idx", slt_arr));

  html.add("===========================");

  html.add("勾選(多選多)", new InpChk("check2[0]", "A"), new InpChk("check2[1]", "B"), new InpChk("check2[2]", "C"));
  html.add("勾選(數字多選一)", new InpChk_S("check_s_int#0", "0"), new InpChk_S("check_s_int#1", "1"), new InpChk_S("check_s_int#2", "2"));
  html.add("勾選(字串多選一)", new InpChk_S("check_s_str#A", "A"), new InpChk_S("check_s_str#B", "B"), new InpChk_S("check_s_str#C", "C"));

  html.add("===========================");

  html.add(new InpBtn("按鈕1", this, new Args("")));
  html.add(new InpBtn("按鈕2", this).setListener(new InpEventListener()
   {
    public boolean eventOccurred(InpComponent comp, Args arg)
    {
     dbg.print("按下了按鈕2 (另一種處理方式)");
     return false;
    }
   })
  );

  my_panel.setText(html.get());
 }

 public boolean eventOccurred(InpComponent comp, Args arg)
 {
  dbg.open();
  dbg.print("變動了 '" + comp.vname + "' 的值");
  return false;
 }
}

這...應該也不用解釋了。



進階-建立有參數物件
用Java的好處就是物件導向,很多類別可透過繼承產生,同樣的類別也能無數次的實體化,當系統越做越"功夫"的時候,就產生了在自訂的物件上儲存參數的需求了。

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
lib "personal";

public class MyScript extends CustomCorePersonal implements InpEventListener
{
 HtmlPanel my_panel = new HtmlPanel(BLACK, BLACK, false, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

 InClass icls1 = null;
 InClass icls2 = null;

 OutClass1 a1cls = null;
 OutClass2 a2cls = null;

 public void init()
 {
  CustomCore_UI_INIT();

  icls1 = new InClass("ins_1");
  icls2 = new InClass("ins_2");

  a1cls = new OutClass1("a1", this);
  a2cls = new OutClass2("a2", this);
  
  show_menu();
  addTabPanel("選單", my_panel);
 }

 public void show_menu()
 {
  HtmlInputHelper html = new HtmlInputHelper(LIGHTGRAY);

  icls1.appendMenu(html);
  icls2.appendMenu(html);
  html.add("===========================");

  a1cls.appendMenu(html);
  a2cls.appendMenu(html);
  html.add("===========================");

  my_panel.setText(html.get());
 }

 public boolean eventOccurred(InpComponent comp, Args arg)
 {
  dbg.open();
  dbg.print("A:變動了 '" + comp.ins.getClass().getSimpleName() + " - " + comp.ins.getInsName() + " - " + comp.vname + "' 的值");
  return false;
 }

 class InClass implements ParamIns
 {
  int value = 20;
  final String insname;
  public InClass(String insname)
  {
   this.insname = insname;
   addParamIns(this);
  }
  final public String getInsName()
  {
   return insname;
  }

  public void appendMenu(HtmlInputHelper html)
  {
   html.add("內部類別("+insname+") : value : ", new InpNum("value", 1, 2, this));
  }
 }
}

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

class OutClass implements ParamIns, InpEventListener
{
 final String insname;
 final ScriptCore core;
 double value = 20;
 public OutClass(String insname, ScriptCore core)
 {
  this.core = core;
  this.insname = insname;
  core.addParamIns(this);
 }
 final public String getInsName()
 {
  return insname;
 }

 public void appendMenu(HtmlInputHelper html)
 {
  html.add("外部類別("+insname+") : value : ", core.new InpNum("value", 1, 2, this));
 }

 public boolean eventOccurred(InpComponent comp, Args arg)
 {
  core.dbg.open();
  core.dbg.print("B:變動了 '" + comp.ins.getClass().getSimpleName() + " - " + comp.ins.getInsName() + " - " + comp.vname + "' 的值");
  return false;
 }
}

class OutClass1 extends OutClass
{
 public OutClass1(String insname, ScriptCore core)
 {
  super(insname, core);
 }
}
class OutClass2 extends OutClass
{
 public OutClass2(String insname, ScriptCore core)
 {
  super(insname, core);
 }
}

這個範例中示範了內部與外部類別的用法,其實是差不多的,只是外部類別因為沒有包含在MyScript裡,也就沒有辦法直接使用MyScript繼承的函數,所以會把MyScript自己(this)丟給外部類別,讓外部類別能間接使用。可以看17~21行,OutClass比InClass多了一個this的參數。

一個類別要能夠儲存變數有幾個要點:
1.必須實做ParamIns介面好讓物件間有InsName可以辨別。
2.實體化後要執行addParamIns函數,把物件丟給AC核心認識,並覆載參數初始值。

沒有留言:

張貼留言

本人僅以個人知識經驗分享,多所無知,難免有錯,還請見諒。