RapidMiner studio之MainFrame源码分析

    先贴下MainFrame类的UML图:

  一 MainFrame中涉及的接口或类说明

     1.1  ApplicationFrame类

     ApplicationFrame继承自JFrame,是一个单例类,该类中含有一个类型为StatusBar的成员变量,其作用是显示process的状态,而MainFrame继承自ApplicationFrame。

     1.2 EventListener、WindowListener接口

     EventListener是所有事件侦听器接口必须扩展的标记接口,WindowListener用于接收窗口事件的侦听器接口,当通过打开、关闭、激活或停用、图标化或取消图标化而改变了窗口状态时,将调用该侦听器对象中的相关方法,并将 WindowEvent传递给该方法。

     MainFrame类中,除了对WindowListener中的windowClosed方法提供了实现外,其它方法都是提供了空实现。

     1.3 ProcessEditor接口

     ProcessEditor扩展自EventListener接口,用于处理process变更事件,该接口中定义了三个方法:

public interface ProcessEditor extends EventListener {

    /** 通知相关组件当前process已经发生改变(Notifies the component that the entire process has changed.) */
    public void processChanged(Process process);

    /** 设置当前选择的operator(Sets the currently selected operator.) */
    public void setSelection(List<Operator> selection);
    
    /** 通知相关组件当前process以某种方式进行了更新(Notifies the component that process was updated in some way.) */
    public void processUpdated(Process process);
}

     因为GUI中各组件需要根据process的变化而变化,所有添加到MainFrame的组件(JPanle等),多数都实现了该接口,下面在分析MainFrame成员变量时再具体分析。

     1.4  ActionListener、Action接口

     ActionListener用于接收操作事件的侦听器接口,对处理操作事件感兴趣的类可以实现此接口,而使用该类创建的对象可使用组件的 addActionListener 方法向该组件注册,ActionListener中的actionPerformed方法用来处理操作事件。

     Action 接口提供 ActionListener 接口的一个有用扩展,以便若干控件访问相同的功能,具体请参考API。

     RapidMiner中,ConditionalAction在Action接口的抽象实现类AbstractAction的基础上提供了根据不同条件来启用/禁用action的功能,ResourceAction是对ConditionalAction的扩展,增加了根据语言设置资源的功能。

     MainFrame中的Action对象,都是继承自ResourceAction,只要实现actionPerformed方法即可。

     对于Action的详细内容,请参考RapidMiner Studio之Action源码分析

     1.5 Dockable接口

     Dockable是GUI框架VLDocking中的一个接口,定义了二个方法

public interface Dockable {
 
    /** returns the unique key identifying the docked element */
    public DockKey getDockKey();
 
    /** returns the component wrapped. */
    public Component getComponent();
 
}

     对于GUI框架不是本文的重点(本人对GUI编程也是知之甚少),这里就不作分析了。这里提供下VLdocking的源码:vldocking.zip

     1.6 MouseListener、FocusListener、TreeSelectionListener接口

      这三个接口分别提供了鼠标事件、焦点事件、树选择事件的定义。

 

二 MainFrame类中的成员变量

    2.1 Action类型的成员变量  

    MainFrame类中,Action类型的变量都是继承自ResourceAction或者是ResourceAction类型的匿名内部类,用于响应GUI中响应组件的事件。

    // 自动连线
    public final transient Action AUTO_WIRE = new AutoWireAction(this, "wire",
            CompatibilityLevel.PRE_VERSION_5, false, true);
    // 自动连线(递归)
    public final transient Action AUTO_WIRE_RECURSIVELY = new AutoWireAction(
            this, "wire_recursive", CompatibilityLevel.PRE_VERSION_5, true,
            true);
    // 重新连线
    public final transient Action REWIRE = new AutoWireAction(this, "rewire",
            CompatibilityLevel.PRE_VERSION_5, false, false);
    // 重新连线(递归)
    public final transient Action REWIRE_RECURSIVELY = new AutoWireAction(this,
            "rewire_recursive", CompatibilityLevel.PRE_VERSION_5, true, false);
    // 新建
    public final transient Action NEW_ACTION = new NewAction(this);
    // 打开
    public final transient Action OPEN_ACTION = new OpenAction();
    // 保存
    public final transient SaveAction SAVE_ACTION = new SaveAction();
    // 另存为
    public final transient Action SAVE_AS_ACTION = new SaveAsAction();
    // 另存为模板
    public final transient Action SAVE_AS_TEMPLATE_ACTION = new SaveAsTemplateAction(
            this);
    // 管理模板
    public final transient Action MANAGE_TEMPLATES_ACTION = new ManageTemplatesAction();
    // 不知道BUILDING BLOCKS是啥功能,鸟代码也没有相应的注释,等改天使用到这功能了再加上
    public final transient Action MANAGE_BUILDING_BLOCKS_ACTION = new ManageBuildingBlocksAction(
            this);
    // 打印
    public final transient Action PRINT_ACTION = new PrintAction(this, "all");
    // 打印预览
    public final transient Action PRINT_PREVIEW_ACTION = new PrintPreviewAction(
            this, "all");
    // ???
    public final transient Action PAGE_SETUP_ACTION = new PageSetupAction();
    // 传递元数据(ProcessPanel组件中用到该事件)
    public final transient Action PROPAGATE_REAL_METADATA_ACTION = new PropagateRealMetaDataAction(
            this);
    // 导入CSV
    public final transient Action IMPORT_CSV_FILE_ACTION = new ResourceAction(
            "import_csv_file") {

        private static final long serialVersionUID = 4632580631996166900L;

        @Override
        public void actionPerformed(ActionEvent e) {
            // CSVImportWizard wizard = new CSVImportWizard("import_csv_file");
            CSVImportWizard wizard;
            try {
                wizard = new CSVImportWizard();
                wizard.setVisible(true);
            } catch (OperatorException e1) {
                // should not happen if operator == null
                throw new RuntimeException("Failed to create wizard.", e1);
            }
        }
    };
    // 导入EXCEL
    public final transient Action IMPORT_EXCEL_FILE_ACTION = new ResourceAction(
            "import_excel_sheet") {

        private static final long serialVersionUID = 975782163819088729L;

        @Override
        public void actionPerformed(ActionEvent e) {
            try {
                ExcelImportWizard wizard = new ExcelImportWizard();
                wizard.setVisible(true);
            } catch (OperatorException e1) {
                // should not happen if operator == null
                throw new RuntimeException("Failed to create wizard.", e1);
            }
        }
    };
    // 导入XML
    public final transient Action IMPORT_XML_FILE_ACTION = new ResourceAction(
            "import_xml_file") {

        private static final long serialVersionUID = 1L;

        @Override
        public void actionPerformed(ActionEvent e) {
            try {
                XMLImportWizard wizard = new XMLImportWizard();
                wizard.setVisible(true);
            } catch (OperatorException e1) {
                // should not happen if operator == null
                throw new RuntimeException("Failed to create wizard.", e1);
            }
        }
    };

    // Access file???
    public final transient Action IMPORT_ACCESS_FILE_ACTION = new ResourceAction(
            "import_access_table") {

        private static final long serialVersionUID = 3725652002686421768L;

        @Override
        public void actionPerformed(ActionEvent e) {
            AccessImportWizard wizard;
            try {
                wizard = new AccessImportWizard("import_access_table");
                wizard.setVisible(true);
            } catch (SQLException e1) {
                SwingTools.showSimpleErrorMessage(
                        "db_connection_failed_simple", e1, e1.getMessage());
            }
        }
    };
    // 导入数据库表
    public final transient Action IMPORT_DATABASE_TABLE_ACTION = new ResourceAction(
            "import_database_table") {

        private static final long serialVersionUID = 3725652002686421768L;

        @Override
        public void actionPerformed(ActionEvent e) {
            DatabaseImportWizard wizard;
            try {
                wizard = new DatabaseImportWizard("import_database_table");
                wizard.setVisible(true);
            } catch (SQLException e1) {
                SwingTools.showSimpleErrorMessage(
                        "db_connection_failed_simple", e1, e1.getMessage());
            }
        }
    };
    // 导入process
    public final transient Action IMPORT_PROCESS_ACTION = new ImportProcessAction();
    // 导出process
    public final transient Action EXPORT_PROCESS_ACTION = new ExportProcessAction();
    // 导出
    public final transient Action EXPORT_ACTION = new ExportViewAction(this,
            "all");
    // 退出
    public final transient Action EXIT_ACTION = new ExitAction(this);
    // 运行server端process ???
    public final transient RunRemoteNowAction RUN_REMOTE_NOW_ACTION = new RunRemoteNowAction(
            this);
    // 运行process
    public final transient RunAction RUN_ACTION = new RunAction(this);
    // 暂停
    public final transient Action PAUSE_ACTION = new PauseAction(this);
    // 停止
    public final transient Action STOP_ACTION = new StopAction(this);
    // ???
    public final transient Action RUN_REMOTE_ACTION = new RunRemoteAction();
    // process校验
    public final transient Action VALIDATE_ACTION = new ValidateProcessAction(
            this);
    // process自动校验
    public final transient ToggleAction VALIDATE_AUTOMATICALLY_ACTION = new ValidateAutomaticallyAction();
    // 打开模板
    public final transient Action OPEN_TEMPLATE_ACTION = new WizardAction(this);
    // 类似于自定义桌面这样的功能
    public final transient Action NEW_PERSPECTIVE_ACTION = new NewPerspectiveAction(
            this);
    // 设置(设置的啥???)
    public final transient Action SETTINGS_ACTION = new SettingsAction();
    // 模式切换
    public final transient ToggleAction TOGGLE_EXPERT_MODE_ACTION = new ToggleExpertModeAction(
            this);
    // 下面二个不知道啥区别,待研究
    public final transient Action TUTORIAL_ACTION = new TutorialAction(this);
    public final transient Action TOUR_ACTION = new TourAction();
    // 撤销
    public final transient Action UNDO_ACTION = new UndoAction(this);
    // 重做
    public final transient Action REDO_ACTION = new RedoAction(this);
    // 方差计算
    public final transient Action ANOVA_CALCULATOR_ACTION = new AnovaCalculatorAction();
    // 检查JDBC驱动
    public final transient Action CHECK_FOR_JDBC_DRIVERS_ACTION = new CheckForJDBCDriversAction();
    // 管理数据库连接
    public final transient Action MANAGE_DB_CONNECTIONS_ACTION = new ResourceAction(
            true, "manage_db_connections") {

        private static final long serialVersionUID = 2457587046500212869L;

        @Override
        public void actionPerformed(ActionEvent e) {
            ManageDatabaseConnectionsDialog dialog = new ManageDatabaseConnectionsDialog();
            dialog.setVisible(true);
        }
    };
    // 管理hadoop集群连接(新增的功能)
    public final transient Action MANAGE_HADOOP_CONNECTIONS_ACTION = new ResourceAction(
            true, "manage_hadoop_connections") {

        private static final long serialVersionUID = 8510147303889637712L;

        @Override
        public void actionPerformed(ActionEvent e) {
            ManageHadoopConnectionsDialog dialog = new ManageHadoopConnectionsDialog();
            dialog.setVisible(true);
        }
    };

     

     2.2 JPanel类的变量

     JPanel是面板容器,用于存放其它swing组件,如JButton,JTextArea,JTextField等,而为了在process发生状态变更时,能通知到相应组件,某些JPanel组件在扩展了JPanel类的基础上又实现了ProcessEditor接口,使用观察者模式,能将process的状态变更通知到实现了ProcessEditor接口的Jpanel组件。

以下是MainFrame中JPanle类型的成员变量:

      可以看到,所有的JPanle类型的成员变量都实现了Dockable接口;

      NewOperatorEditor实现了TreeSelectionListener,支持Operator Tree的拖拽等操作功能;

      LoggingViewer只实现了MouseListener中的mousepressed方法,对其它方法都是空实现;

      ResultDisplay接口添加了显示数据和添加数据表(DataTable??)等方法;

      实现了ProcessEditor接口的JPanel组件,将能接收到process对象发生改变时传播的消息(观察者模式)

      

      2.3 DOCKING

      对这个不了解,看API介绍是GUI编程的一个框架,应该是放置GUI组件用的,有兴趣的同学可以自己下载vldocking.zip研究研究。

    public static final DockGroup DOCK_GROUP_ROOT = new DockGroup("root");
    public static final DockGroup DOCK_GROUP_RESULTS = new DockGroup("results");
    private final DockingContext dockingContext = new DockingContext();
    private final DockingDesktop dockingDesktop = new DockingDesktop("mainDesktop", dockingContext);

     

      2.4 EventListenerList 

      EventListenerList是保存EventListener列表的类,这个类中有一个add方法,用来添加EventListener类型的对象

public synchronized <T extends EventListener> void add(Class<T> t, T l)

      MainFrame类中定义了一个EventListenerList类型的对象,并调用add方法向该对象中添加EventListener对象

private final EventListenerList processEditors = new EventListenerList();
    public void addProcessEditor(ProcessEditor p) {
        assert (p != null);
        processEditors.add(ProcessEditor.class, p);
    }

 

      2.5 Actions

      com.rapidminer.gui.actions.Actions响应是process editor功能中的事件(2.1中的Action是整个GUI的不同功能界面或者按钮的事件处理器)

      Actions中的Action:Actions类中定义的action,都是调用Actions类中的getFirstSelectedOperator或者getSelectedOperators方法来获取当前选择的Operator或者该process中所有的Operator(List<Operator>),然后调用Operator中的相关方法来完成相应的功能,对Operator的分析,请参考:RapidMiner之Operator源码分析。 

    public final Action INFO_OPERATOR_ACTION = new InfoOperatorAction() {
        private static final long serialVersionUID = 6758272768665592429L;
        @Override
        protected Operator getOperator() {
            return getFirstSelectedOperator();
        }        
    }; 
    public final ToggleActivationItem TOGGLE_ACTIVATION_ITEM = new ToggleActivationItem(this);
    public final Action RENAME_OPERATOR_ACTION = new ResourceAction(true, "rename_in_processrenderer") {
        {
            setCondition(OPERATOR_SELECTED, MANDATORY);
        }
        private static final long serialVersionUID = -3104160320178045540L;
        @Override
        public void actionPerformed(ActionEvent e) {
            Operator operator = getFirstSelectedOperator();
            String name = SwingTools.showInputDialog("rename_operator", operator.getName());
            if (name != null && name.length() > 0) {
                operator.rename(name);
            }
        }
    };
    public final Action NEW_OPERATOR_ACTION = new NewOperatorAction(this);
    public final Action NEW_BUILDING_BLOCK_ACTION = new NewBuildingBlockAction(this);
    public final Action SAVE_BUILDING_BLOCK_ACTION = new SaveBuildingBlockAction(this);
    public final Action DELETE_OPERATOR_ACTION = new DeleteOperatorAction();
    public final ToggleBreakpointItem TOGGLE_BREAKPOINT[] = { 
            new ToggleBreakpointItem(this, BreakpointListener.BREAKPOINT_BEFORE), 
            new ToggleBreakpointItem(this, BreakpointListener.BREAKPOINT_AFTER) 
    };
    public transient final ToggleAllBreakpointsItem TOGGLE_ALL_BREAKPOINTS = new ToggleAllBreakpointsItem(this);
    public transient final Action MAKE_DIRTY_ACTION = new ResourceAction(true, "make_dirty") {                
        private static final long serialVersionUID = -1260942717363137733L;
        {
            setCondition(OPERATOR_SELECTED, MANDATORY);
        }
        @Override
        public void actionPerformed(ActionEvent e) {
            for (Operator selectedOperator : new LinkedList<Operator>(getSelectedOperators())) {                
                selectedOperator.makeDirty();
            }
        }                
    };

       

      Actions中的私有成员变量

      selection是当前选中的operaror,在setSelection方法中初始化;

      process在方法processChanged中初始化;

      mainFrame在构造器中初始化;

      BreakpointListener接口是用来设置断点,运行process时达到断点时会调用接口中的breakpointReached方法;

      ProcessListener是监听process运行情况的,该接口中有四个方法,分别是在process运行前后、process中每个operator运行前后调用。

    private List<Operator> selection; 
private Process process;
private final MainFrame mainFrame; private final BreakpointListener breakpointListener = new BreakpointListener() { @Override public void breakpointReached(Process process, Operator op, IOContainer iocontainer, int location) { enableActions(); } @Override public void resume() { enableActions(); } }; private final ProcessListener processListener = new ProcessListener() { @Override public void processEnded(Process process) { enableActions(); mainFrame.RUN_ACTION.setState(process.getProcessState()); } @Override public void processFinishedOperator(Process process, Operator op) { } @Override public void processStartedOperator(Process process, Operator op) { } @Override public void processStarts(Process process) { enableActions(); } }; public Actions(MainFrame mainFrame) { this.mainFrame = mainFrame; } @Override public void setSelection(List<Operator> selection) { this.selection = selection; enableActions(); } @Override public void processChanged(Process process) { if (this.process != process) { if (this.process != null) { this.process.removeBreakpointListener(breakpointListener); this.process.getRootOperator().removeProcessListener(processListener); } this.process = process; enableActions(); if (this.process != null) { this.process.addBreakpointListener(breakpointListener); this.process.getRootOperator().addProcessListener(processListener); } } } public void enableActions() { if (SwingUtilities.isEventDispatchThread()) { enableActionsNow(); } else { SwingUtilities.invokeLater(new Runnable() { public void run() { enableActionsNow(); } }); } updateCheckboxStates(); }

         

      Actions类中的public方法:

      addToOperatorPopupMenu:这个方法是在OperatorTree和ProcessRenderer方法中被调用

      delete:删除选中的Operator

      insert:在operator链的最后位置插入选中的operator

      这三个方法都是调用Operator类中的方法完成相关功能的,在RapidMiner之Operator源码分析 中,会对这三个方法作具体分析。

      getRootOperator:获取当前process的RootOperator

         

      Actions类中的private方法:

      enableActions方法是根据设置的状态来决定是否启用对应的action,最终调用的是enableActionsNow和updateCheckboxStates方法

    private void enableActionsNow() {        
        synchronized (process) {
// NUMBER_OF_CONDITIONS 定义了有多少种状态
boolean[] currentStates = new boolean[ConditionalAction.NUMBER_OF_CONDITIONS];
// 获取当前选中的operator Operator op
= getFirstSelectedOperator(); if (op != null) {
// 非空,设置对应位置状态
// 是否有operator选中 currentStates[ConditionalAction.OPERATOR_SELECTED]
= true; if (op instanceof OperatorChain)
// operator链(operator可以嵌套operator) currentStates[ConditionalAction.OPERATOR_CHAIN_SELECTED]
= true; if (op.getParent() == null) {
// 选中的是RootOperator currentStates[ConditionalAction.ROOT_SELECTED]
= true; } else {
// 有上级 currentStates[ConditionalAction.PARENT_ENABLED]
= op.getParent().isEnabled(); if (op.getExecutionUnit().getNumberOfOperators() > 1) {
// 有兄弟姐妹 currentStates[ConditionalAction.SIBLINGS_EXIST]
= true; } } }
//当前process状态
int processState = process.getProcessState(); currentStates[ConditionalAction.PROCESS_STOPPED] = processState == Process.PROCESS_STATE_STOPPED; currentStates[ConditionalAction.PROCESS_PAUSED] = processState == Process.PROCESS_STATE_PAUSED; currentStates[ConditionalAction.PROCESS_RUNNING] = processState == Process.PROCESS_STATE_RUNNING; currentStates[ConditionalAction.EDIT_IN_PROGRESS] = EditBlockingProgressThread.isEditing(); currentStates[ConditionalAction.PROCESS_SAVED] = process.hasSaveDestination(); currentStates[ConditionalAction.PROCESS_RENDERER_IS_VISIBLE] = mainFrame.getProcessPanel().getProcessRenderer().isShowing(); currentStates[ConditionalAction.PROCESS_RENDERER_HAS_UNDO_STEPS] = mainFrame.hasUndoSteps(); currentStates[ConditionalAction.PROCESS_RENDERER_HAS_REDO_STEPS] = mainFrame.hasRedoSteps(); ConditionalAction.updateAll(currentStates); updateCheckboxStates(); } }
    private void updateCheckboxStates() {
        Operator op = getSelectedOperator();
        if (op != null) {
            for (int pos = 0; pos < TOGGLE_BREAKPOINT.length; pos++) {            
                TOGGLE_BREAKPOINT[pos].setSelected(op.hasBreakpoint(pos));
            }
            TOGGLE_ACTIVATION_ITEM.setSelected(op.isEnabled());
        }
    }

 

      2.6 JMenuBar与JMenu

      这是添加到GUI界面的菜单

    private final JMenuBar menuBar;

    private final JMenu fileMenu;
    private final JMenu editMenu;
    private final JMenu processMenu;
    private final JMenu toolsMenu;
    private final JMenu viewMenu;
    private final JMenu helpMenu;

    private DockableMenu dockableMenu;

    private final JMenu recentFilesMenu = new ResourceMenu("recent_files");

 

      2.7 其它类型成员变量

      ProcessStorageListener:是监听process保存和打开事件

      BreakpointListener的功能在上面已有说明

      Observer<Process>:process观察者,该变量由Process类中的removeObserver和addObserver来调用

      ProcessUndoManager:处理procee编辑的undo和redo事件

      String lastProcessXML:process GUI界面的xml形式

      OperatorChain:Operator链,是一个operator的child,而这个child也是由一个或多个operator组成,这个child可以运行一次或多次,关于OperatorChain的更多信息,请参考RapidMiner Studio之Process源码分析

      Process:当前打开的Process

  ProcessThread:负责运行Process的线程

  MetaDataUpdateQueue:当process有变更时,变更元素数据的队列

      Perspectives:自定义界面

      

      三 MainFrame类中的方法

      3.1 构造方法

      MainFrame的构造方法的功能是添加Swing组件,组织菜单栏与菜单、菜单与按钮的关系,添加监听到EventListenerList对象。

      3.2 新建、打开process相关的方法

      newProcess、setProcess、setOpenedProcess、fireProcessChanged、fireProcessLoaded

      MainFrame可以打开或者新建一个process进行编辑,其对应的Action分别是OpenAction和NewAction:

      NewAction中的actionPerformed方法调用的是MainFrame类中的newProcess方法来响应创建一个新的process的请求:

    /** Creates a new process. */
    public void newProcess() {
        // ask for confirmation before stopping the currently running process and opening a new one!
        if (getProcessState() == Process.PROCESS_STATE_RUNNING
                || getProcessState() == Process.PROCESS_STATE_PAUSED) {
            if (SwingTools.showConfirmDialog("close_running_process",
                    ConfirmDialog.YES_NO_OPTION) == ConfirmDialog.NO_OPTION) {
                return;
            }
        }
// 打开一个新的process之前,先关闭当前的process(如果有process打开的话)
// 关闭process时,如果该process正在运行,则要停止该process
if (close(false)) { // process changed -> clear undo history 初始化undoIndex和undoManager,且禁用UNDO_ACTION和REDO_ACTION resetUndo(); stopProcess(); changed = false;
// 为MainFrame设置process并为该process注册监听 setProcess(
new Process(), true);
// 设置并启用undo,这个方法会在后面详细说明 addToUndoList();
if (!"false" .equals(ParameterService .getParameterValue(PROPERTY_RAPIDMINER_GUI_SAVE_ON_PROCESS_CREATION))) { SaveAction.save(getProcess()); }
//启用SAVE_ACTION SAVE_ACTION.setEnabled(
false); } }
    public void setProcess(Process process, boolean newProcess,
            boolean addToUndoList) {
// 是否是第一个process,这是perspectives判断用来显示哪个模板的
boolean firstProcess = this.process == null;
// 删除在process上的监听并停止正在运行的process
if (this.process != null) { this.process.removeObserver(processObserver); } if (getProcessState() != Process.PROCESS_STATE_STOPPED) { if (processThread != null) { processThread.stopProcess(); } } if (process != null) { // 为新建的process注册监听,该监听会将发生在process的变更通知到实现ProcessEditor的组件 process.addObserver(processObserver, true); synchronized (process) {
// 设置process、processThread、breakpointListener
this.process = process; this.processThread = new ProcessThread(this.process); this.process.addBreakpointListener(breakpointListener); if (addToUndoList) { addToUndoList( process.getRootOperator().getXML(true, false), false); }

// 通知实现了ProcessEditor接口的组件,当前已换成新的process fireProcessChanged(); selectOperator(
this.process.getRootOperator()); if (VALIDATE_AUTOMATICALLY_ACTION.isSelected()) { validateProcess(false); } }

// 判断是否是server端的process
try { RepositoryLocation location = this.process .getRepositoryLocation(); if (location != null && location.getRepository() instanceof RemoteRepository) { RUN_REMOTE_NOW_ACTION.setEnabled(true); } else { RUN_REMOTE_NOW_ACTION.setEnabled(false); } } catch (RepositoryException e) { RUN_REMOTE_NOW_ACTION.setEnabled(false); } } if (newProcess && !firstProcess) { perspectives.showPerspective("design"); } setTitle(); getStatusBar().setTrafficLight(StatusBar.TRAFFIC_LIGHT_INACTIVE); getStatusBar().clearSpecialText(); }

      OpenAction打开一个已存在的process时,情况比NewAction稍微复杂一些,但最终调用的是MainFrame中的setOpenedProcess方法。

      setOpenedProcess和上面的setProcess方法,分别调用到了fireProcessChanged和fireProcessLoaded方法:

    // 通知实现了ProcessEditor的组件,新打开(新建)了一个process,各组件调用processChanged作相关处理 
private void fireProcessChanged() {
// MainFrame构造方法中对processEditors进行了初始化
for (ProcessEditor editor : processEditors .getListeners(ProcessEditor.class)) { editor.processChanged(process); } }
    // 暂时没发现storageListeners变量的作用,等以后再补充
private void fireProcessLoaded() { LinkedList<ProcessStorageListener> list = new LinkedList<ProcessStorageListener>( storageListeners); for (ProcessStorageListener l : list) { l.opened(process); } }

       

     3.3 处理process状态变更的方法:fireProcessUpdated

     在打开或新建一个process时,process调用addObserver方法添加一个观察者processObserver,当编辑process,会通过这个观察者来发布状态的变更信息并通知订阅者做相关处理。processObserver中的update方法最终调用的是MainFrame中的fireProcessUpdated方法:

   // 通知实现了ProcessEditor的组件当然process配置发生改变,各组件调用processUpdate作相关处理 
    public void fireProcessUpdated() {
        for (ProcessEditor editor : processEditors
                .getListeners(ProcessEditor.class)) {
            editor.processUpdated(process);
        }
    }

      

      3.4 process运行的相关方法

      ----------------------待续

 

       

      3.5 其它方法

      MainFrame中剩余的其它方法,exit和close是处理窗口关闭事件的,其它的方法都是成员变量的get方法,用于获取GUI的某个组件。

      

     遗留问题:MainFrame中,创建或者打开一个新的process时,需要关闭当前打开的process,这个功能需要进行改进,能同时打开多个process编辑界面。

     

     从上面的分析可以看出,process是这个工具的核心,而process的核心是operator,下面一步就是要研究与这二个组件相关的Java代码:

      RapidMiner Studio之Process源码分析

      RapidMiner之Operator源码分析    

posted @ 2015-07-15 13:32  haizhun  阅读(909)  评论(0编辑  收藏  举报