実行可能アクティビティ図アプリ
そういえば、JRubyがでたときに、試用のために、でJUDE APIをたたいて、アクティビティ図を実行するアプリってのを作ったんだった。アクティビティ図の分岐をそのままボタンに換えて、対話的に実行します。
SWTでつくったらぜんぜんRubyらしくないでやんの。GUIをJava側にもってくるのははじめいいかもと思ったが、これをみるかぎりかなり苦しかった。SWT触ったのさえ初めてだったから、ノウハウがないせいかもしれないけど。
前のコードなので動くかどうか不明・・・とりあえずはっときます。
# main.rb # 2007/06/11 # require 'java' require 'main_form' require 'start_form' module Jude include_package "com.change_vision.jude.api.inf.project" include_package "com.change_vision.jude.api.inf.model" end class JudeActivityDiagram attr_reader :ac_node_list def initialize(file_name = 'JudeSampleProject.jude') include_class 'java.lang.System' prjAccessor = Jude::ProjectAccessorFactory.getProjectAccessor prjAccessor.open(file_name) dgms = prjAccessor.getProject.getDiagrams @ac_node_list = {} dgms.each{|dgm| if dgm.java_kind_of?(Jude::IActivityDiagram) activity = dgm.getActivity activityNodes = activity.getActivityNodes activityNodes.each{|node| @ac_node_list[node.getId] = node } end } end end st_form = StartForm.new st_form.show
# main_form.rb # 2007/06/21 # require 'java' module SWTJava include_package 'org.eclipse.swt' include_package 'org.eclipse.swt.layout' include_package 'org.eclipse.swt.widgets' include_package 'org.eclipse.swt.events' end module JudeObject def set_jude_obj(jude_obj) @jude_obj = jude_obj end def get_jude_obj(jude_obj) @jude_obj end end class ButtonClickEvent < SWTJava::SelectionAdapter attr_writer :main_form, :flow def widgetSelected(e) next_action = @flow.getTarget @main_form.set_node(next_action) end end class FinishButtonClickEvent < SWTJava::SelectionAdapter attr_writer :main_form def widgetSelected(e) shell = e.getSource.getShell shell.dispose end end class MainForm def initialize(main_shell = nil) @main_shell = main_shell if @main_shell @shell = SWTJava::Shell.new(@main_shell) else SWTJava::Display.setAppName "Executable Activity Diagram" @display = SWTJava::Display.new @shell = SWTJava::Shell.new(@display) end @shell.setSize(1000, 1000) layout = SWTJava::GridLayout.new() layout.numColumns = 1 layout.marginHeight = 20 layout.marginWidth = 20 layout.verticalSpacing = 20 @shell.setLayout layout @shell.setText "Executable Activity Diagram" @textbox = SWTJava::Text.new(@shell, SWTJava::SWT::MULTI || SWTJava::SWT::READONLY) @textbox.extend JudeObject @textbox.setText("てすとてすと") end def show() @shell.pack @shell.open unless @main_shell until @shell.isDisposed do @display.sleep unless @display.readAndDispatch end @display.dispose end end def set_node(node) set_message(node) flows = node.getOutgoings if node.getOutgoings.size == 1 next_node = node.getOutgoings[0].getTarget if defined? next_node.getName && ( next_node.getName == "" || next_node.getName =~ /(デシジョンノード|マージノード|合流)/ ) flows = next_node.getOutgoings end end set_next_button(flows) @shell.pack end def set_message(node) @textbox.set_jude_obj(node) if node.java_kind_of?(Jude::IControlNode) && node.isInitialNode @textbox.setText("開始します") elsif node.java_kind_of?(Jude::IControlNode) && node.isFinalNode @textbox.setText("ここで終了です") else if defined? node.getName && node.getName != "" @textbox.setText("#{node.getName}") end end end def set_next_button(flows) if @buttons @buttons.each_value{|button| button.dispose } end @buttons = {} if flows.size == 0 button = SWTJava::Button.new(@shell, SWTJava::SWT::PUSH) button.setText("終了") btn_click = FinishButtonClickEvent.new() btn_click.main_form = self button.addSelectionListener(btn_click) @buttons[0] = button else flows.each{ |flow| button = SWTJava::Button.new(@shell, SWTJava::SWT::PUSH) button.extend JudeObject if flow.getAction != "" && flow.getGuard != "" button.setText("アクション:#{flow.getAction}[条件:#{flow.getGuard}]") elsif flow.getAction != "" button.setText("アクション:#{flow.getAction}") elsif flow.getGuard != "" button.setText("条件:#{flow.getGuard}") else button.setText("次へ進む") end button.set_jude_obj(flow) btn_click = ButtonClickEvent.new() btn_click.main_form = self btn_click.flow = flow button.addSelectionListener(btn_click) @buttons[flow.getId] = button } end end end
# start_form.rb # 2007/06/21 # require 'java' require 'main_form' class FileOpenButtonClickEvent < SWTJava::SelectionAdapter attr_writer :form def widgetSelected(e) shell = e.getSource.getShell openDialog = SWTJava::FileDialog.new(shell,SWTJava::SWT::OPEN); openFile = openDialog.open(); @form.textbox.setText(openFile) end end class OkButtonClickEvent < SWTJava::SelectionAdapter attr_writer :form def widgetSelected(e) shell = e.getSource.getShell filepath = @form.textbox.getText main_form = MainForm.new(shell) acDgm = JudeActivityDiagram.new(filepath) #スタートポイントを探して、セット acDgm.ac_node_list.each_value{|node| if node.java_kind_of?(Jude::IControlNode) if node.isInitialNode main_form.set_node(node) break end end } main_form.show end end class StartForm attr_reader :textbox, :ref_button, :ok_button def initialize() SWTJava::Display.setAppName "Executable Activity Diagram" @display = SWTJava::Display.new @shell = SWTJava::Shell.new(@display) @shell.setSize(2000, 1000) layout = SWTJava::GridLayout.new() layout.numColumns = 2 layout.makeColumnsEqualWidth = false @shell.setLayout layout @shell.setText "Executable Activity Diagram" #ファイルパス grid_data1 = SWTJava::GridData.new(SWTJava::GridData::FILL_HORIZONTAL) grid_data1.widthHint = 400 @textbox = SWTJava::Text.new(@shell, SWTJava::SWT::SINGLE) @textbox.setText("") @textbox.setLayoutData(grid_data1) #参照ボタン grid_data2 = SWTJava::GridData.new(SWTJava::GridData::HORIZONTAL_ALIGN_END) grid_data2.heightHint = 20 @ref_button = SWTJava::Button.new(@shell, SWTJava::SWT::PUSH) @ref_button.setText("参照") ref_btn_click = FileOpenButtonClickEvent.new ref_btn_click.form = self @ref_button.addSelectionListener(ref_btn_click) @ref_button.setLayoutData(grid_data2) #okボタン grid_data3 = SWTJava::GridData.new(SWTJava::GridData::HORIZONTAL_ALIGN_END) grid_data3.horizontalSpan = 2 grid_data3.heightHint = 20 grid_data3.widthHint = 60 @ok_button = SWTJava::Button.new(@shell, SWTJava::SWT::PUSH) @ok_button.setText("OK") ok_btn_click = OkButtonClickEvent.new ok_btn_click.form = self @ok_button.addSelectionListener(ok_btn_click) @ok_button.setLayoutData(grid_data3) end def show() @shell.pack @shell.open until @shell.isDisposed do @display.sleep unless @display.readAndDispatch end @display.dispose end end