package open.dolphin.order; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.HashMap; import java.util.concurrent.ExecutionException; import javax.swing.*; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import open.dolphin.client.ClientContext; import open.dolphin.stampbox.StampTree; import open.dolphin.stampbox.StampTreeNode; import open.dolphin.delegater.StampDelegater; import open.dolphin.infomodel.IInfoModel; import open.dolphin.infomodel.ModuleInfoBean; import open.dolphin.infomodel.ModuleModel; import open.dolphin.infomodel.StampModel; import open.dolphin.util.BeanUtils; /** * EditorSetPanel * * @author Minagawa,Kazushi * */ public class EditorSetPanel extends JPanel implements PropertyChangeListener, TreeSelectionListener { public static final String EDITOR_VALUE_PROP = "editorValue"; private final String TITLE_NEW; private final String TITLE_REPLACE; private final String TITLE_IMPORT; private final String TITLE_TO_LAB; private final String TITLE_TO_PHYSIO; private final String TITLE_TO_BACTERIA; private final String TITLE_FROM_EDITOR; // エディタ の組 private AbstractStampEditor bacteria; private AbstractStampEditor baseCharge; private AbstractStampEditor diagnosis; private AbstractStampEditor general; private AbstractStampEditor injection; private AbstractStampEditor instraction; private AbstractStampEditor med; private AbstractStampEditor other; private AbstractStampEditor physiology; private AbstractStampEditor radiology; private AbstractStampEditor surgery; private AbstractStampEditor test; private AbstractStampEditor treatment; // 上記エディタを格納するカードパネル private final JPanel cardPanel; private final CardLayout cardLayout; // 現在使用中のエディタ private AbstractStampEditor curEditor; // 辞書 private HashMap<String, AbstractStampEditor> table; // StampBox とやりとりするボタン private JButton rightNew; // 新規スタンプとして保存ボタン private JButton rightReplace; // 上書きボタン private JButton leftImport; // 取り込みボタン private JButton right6001; private JButton right6002; //------------------------------------- // StampBox と連携するためのオブジェクト //------------------------------------- // 右側のStampTreeで選択された Node // これが編集領域(エディタ)に取り込まれる private StampTreeNode selectedNode; private ModuleInfoBean importedInfo; // エディタで編集された Stamp private Object editorValue; // 上記編集値(束縛属性)をStampBoxへ通知するサポート private final PropertyChangeSupport boundSupport = new PropertyChangeSupport(this); /** * 編集したスタンプオブジェクトを返す。 * @return 編集したスタンプオブジェクト */ public Object getEditorValue() { return editorValue; } /** * 編集値をセットする。この属性は束縛プロパティであり、リスナ(StampBoxPlugin)へ通知される。 * @param value 編集されたスタンプ */ public void setEditorValue(Object value) { editorValue = value; boundSupport.firePropertyChange(EditorSetPanel.EDITOR_VALUE_PROP, null, editorValue); } public StampTreeNode getSelectedNode() { return selectedNode; } /** * スタンプボックスで選択されているノード(スタンプ)をセットする。 * @param node スタンプボックスで選択されているスタンプノード */ public void setSelectedNode(StampTreeNode node) { selectedNode = node; } /** * EditorSet を終了する。 */ public void close() { if (curEditor!=null) { curEditor.dispose(); curEditor.remopvePropertyChangeListener(AbstractStampEditor.EMPTY_DATA_PROP, this); curEditor.remopvePropertyChangeListener(AbstractStampEditor.VALIDA_DATA_PROP, this); } } /** * プロパティチェンジリスナを登録する。 * @param prop プロパティ名 * @param listener プロパティチェンジリスナ */ @Override public void addPropertyChangeListener(String prop, PropertyChangeListener listener) { boundSupport.addPropertyChangeListener(prop, listener); } /** * プロパティチェンジリスナを削除する。 * @param prop プロパティ名 * @param listener プロパティチェンジリスナ */ public void remopvePropertyChangeListener(String prop, PropertyChangeListener listener) { boundSupport.removePropertyChangeListener(prop, listener); } /** * スタンプボックスのタブが切り替えられた時、対応するエディタを show する。 * @param entity */ public void show(String entity) { rightNew.setEnabled(false); rightReplace.setEnabled(false); right6001.setEnabled(false); right6002.setEnabled(false); leftImport.setEnabled(false); importedInfo = null; // 現在エディタがあれば後始末する if (curEditor != null) { curEditor.dispose(); // setTable, searchResultTable が clear される curEditor.remopvePropertyChangeListener(AbstractStampEditor.EMPTY_DATA_PROP, this); curEditor.remopvePropertyChangeListener(AbstractStampEditor.VALIDA_DATA_PROP, this); } // ORCA及びパスタブの場合 if (table.get(entity)==null) { return; } // 要求されたエディタに切り替える curEditor = table.get(entity); if (curEditor == diagnosis) { curEditor.setValue(null); } else { boolean visible = false; if (curEditor == test) { right6001.setText(TITLE_TO_PHYSIO); right6002.setText(TITLE_TO_BACTERIA); visible = true; } else if (curEditor == physiology) { right6001.setText(TITLE_TO_LAB); right6002.setText(TITLE_TO_BACTERIA); visible = true; } else if (curEditor == bacteria) { right6001.setText(TITLE_TO_LAB); right6002.setText(TITLE_TO_PHYSIO); visible = true; } right6001.setVisible(visible); right6002.setVisible(visible); //---------------------------------------------- // 空のStamp(ModuleModel)をエディタに設定しておく //---------------------------------------------- ModuleModel stamp = new ModuleModel(); ModuleInfoBean stampInfo = stamp.getModuleInfoBean(); stampInfo.setStampName(TITLE_FROM_EDITOR); stampInfo.setStampRole(IInfoModel.ROLE_P); stampInfo.setEntity(entity); curEditor.setValue(stamp); } // 最初にclearされるイベントを受けない curEditor.addPropertyChangeListener(AbstractStampEditor.EMPTY_DATA_PROP, this); curEditor.addPropertyChangeListener(AbstractStampEditor.VALIDA_DATA_PROP, this); cardLayout.show(cardPanel, entity); curEditor.getSearchTextField().requestFocusInWindow(); } /** * 編集中のスタンプの有効/無効の属性通知を受け、右向きボタンを制御する。 * @param e */ @Override public void propertyChange(PropertyChangeEvent e) { String prop = e.getPropertyName(); if (prop.equals(AbstractStampEditor.VALIDA_DATA_PROP)) { // 有効か無効かで右矢印ボタンを制御する Boolean i = (Boolean) e.getNewValue(); boolean valid = i; // 新規スタンプとして保存 rightNew.setEnabled(valid); // 上書き保存 valid かつ imported!=null rightReplace.setEnabled(valid && (importedInfo!=null)); // 600 right6001.setEnabled(valid && (right6001.isVisible())); right6002.setEnabled(valid && (right6002.isVisible())); } else if (prop.equals(AbstractStampEditor.EMPTY_DATA_PROP)) { // 空の場合は importedInfo = null Boolean i = (Boolean) e.getNewValue(); boolean setIsEmpty = i; if (setIsEmpty && rightReplace.isEnabled()) { importedInfo = null; } } } /** * スタンプツリーで選択されたスタンプに応じて取り込みボタンを制御する。 */ @Override public void valueChanged(TreeSelectionEvent e) { StampTree tree = (StampTree) e.getSource(); String treeEntity = tree.getTreeInfo().getEntity(); //System.err.println(treeEntity); if (treeEntity.equals(IInfoModel.ENTITY_DIAGNOSIS) || treeEntity.equals(IInfoModel.ENTITY_PATH) || treeEntity.equals(IInfoModel.ENTITY_ORCA) || treeEntity.equals(IInfoModel.ENTITY_TEXT) ) { leftImport.setEnabled(false); setSelectedNode(null); return; } // ノードが葉で傷病名でない時取り込みボタン(左矢印)をenabled にする // またその時以外は選択ノード属性をnullにする StampTreeNode node =(StampTreeNode) tree.getLastSelectedPathComponent(); //ModuleInfoBean info = (ModuleInfoBean)node.getUserObject(); boolean enabled = (node != null && node.isLeaf() && ((ModuleInfoBean)node.getUserObject()).isSerialized()); StampTreeNode selected = enabled ? node : null; leftImport.setEnabled(enabled); // 選択されている TreeNode を保存する setSelectedNode(selected); } //-------------------------- // ボタンへListnerを登録する //-------------------------- private void connect() { //-------------------------------------------------- // 取り込みボタン 左矢印 //-------------------------------------------------- leftImport.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent ae) { // StampTreeで選択されているNodeを得る StampTreeNode node = getSelectedNode(); if (node == null || !(node.getUserObject() instanceof ModuleInfoBean)) { return; } // Nodeから StampInfo(UserObject)を得る final ModuleInfoBean stampInfo = (ModuleInfoBean) node.getUserObject(); SwingWorker worker = new SwingWorker<StampModel, Void>() { @Override protected StampModel doInBackground() throws Exception { //----------------------------------------------------------- // stampId から StampModel(DBのレコード:EntityBean)をフェッチする //----------------------------------------------------------- StampDelegater sdl = new StampDelegater(); StampModel stampModel = sdl.getStamp(stampInfo.getStampId()); return stampModel; } @Override protected void done() { try { StampModel stampModel = get(); if (stampModel != null && curEditor != null) { //---------------------------------------------------- // 取得したEntityの binary object をdecodeして Modelを得る //---------------------------------------------------- IInfoModel model = (IInfoModel) BeanUtils.xmlDecode(stampModel.getStampBytes()); if (model != null) { ModuleModel stampToEdit = new ModuleModel(); stampToEdit.setModel(model); stampToEdit.setModuleInfoBean(stampInfo); importedInfo = stampInfo; // 実際にインポートされたInfo leftImport.setEnabled(false); curEditor.setValue(stampToEdit); } } } catch (InterruptedException ex) { System.err.println(ex); } catch (ExecutionException ex) { String title = ClientContext.getMyBundle(EditorSetPanel.class).getString("title.optionPane"); JOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(cardPanel), ex.getMessage(), ClientContext.getFrameTitle(title), JOptionPane.WARNING_MESSAGE); } } }; worker.execute(); } }); //-------------------------------------------------- // 新規スタンプとして保存ボタン 右矢印 //-------------------------------------------------- rightNew.addActionListener((ActionEvent ae) -> { // cureditor から値を取得し、自分自身のプロパティに設定する。 // 束縛プロパティによりリスナのStampBoxへこの値が通知される。 Object obj = curEditor.getValue(); setEditorValue(obj); importedInfo = null; curEditor.setValue(null); }); //-------------------------------------------------- // 置き換えスタンプボタン 右矢印 //-------------------------------------------------- rightReplace.addActionListener((ActionEvent ae) -> { // cureditor から値を取得し、自分自身のプロパティに設定する。 // 束縛プロパティによりリスナへこの値が通知される。 Object obj = curEditor.getValue(); ModuleModel stamp = (ModuleModel) obj; if (importedInfo!=null) { stamp.setModuleInfoBean(importedInfo); } setEditorValue((Object)stamp); importedInfo = null; curEditor.setValue(null); }); //-------------------------------------------------- // 600 入れ替えスタンプボタン 右矢印 //-------------------------------------------------- ActionListener al = (ActionEvent ae) -> { // cureditor から値を取得し、自分自身のプロパティに設定する。 // 束縛プロパティによりリスナへこの値が通知される。 Object obj = curEditor.getValue(); ModuleModel stamp = (ModuleModel) obj; ModuleInfoBean info = stamp.getModuleInfoBean(); info.setStampId(null); // 新規スタンプ // entity 入れ替え JButton btn = (JButton)ae.getSource(); String text = btn.getText(); if (text.equals(TITLE_TO_PHYSIO)) { info.setEntity(IInfoModel.ENTITY_PHYSIOLOGY_ORDER); } else if (text.equals(TITLE_TO_BACTERIA)) { info.setEntity(IInfoModel.ENTITY_BACTERIA_ORDER); } else if (text.equals(TITLE_TO_LAB)) { info.setEntity(IInfoModel.ENTITY_LABO_TEST); } setEditorValue((Object)stamp); rightNew.setEnabled(false); rightReplace.setEnabled(false); importedInfo = null; curEditor.setValue(null); }; right6001.addActionListener(al); right6002.addActionListener(al); } /** * GUI コンポーネントを生成する。 */ private void initComponent() { // 編集したスタンプをボックスへ登録する右向きボタンを生成する rightNew = new JButton(TITLE_NEW, ClientContext.getImageIconArias("icon_arrow_right_small")); rightNew.setEnabled(false); // 編集したスタンプを上書きする右向きボタンを生成する rightReplace = new JButton(TITLE_REPLACE, ClientContext.getImageIconArias("icon_arrow_right_small")); rightReplace.setEnabled(false); // 診区 600 (検体、生体、細菌)入れ替えボタン right6001 = new JButton(ClientContext.getImageIconArias("icon_arrow_right_small")); right6002 = new JButton(ClientContext.getImageIconArias("icon_arrow_right_small")); right6001.setVisible(false); right6002.setVisible(false); // スタンプボックスのスタンプをセットテーブルへ取り込む左向きのボタンを生成する leftImport = new JButton(TITLE_IMPORT, ClientContext.getImageIconArias("icon_arrow_left_small")); leftImport.setEnabled(false); //----------------------------------- // 個別のエディタを生成する //----------------------------------- bacteria = new BaseEditor(IInfoModel.ENTITY_BACTERIA_ORDER, false); baseCharge = new BaseEditor(IInfoModel.ENTITY_BASE_CHARGE_ORDER, false); diagnosis = new DiseaseEditor(false); general = new BaseEditor(IInfoModel.ENTITY_GENERAL_ORDER, false); injection = new InjectionEditor(IInfoModel.ENTITY_INJECTION_ORDER, false); instraction = new BaseEditor(IInfoModel.ENTITY_INSTRACTION_CHARGE_ORDER, false); med = new RpEditor(IInfoModel.ENTITY_MED_ORDER, false); other = new BaseEditor(IInfoModel.ENTITY_OTHER_ORDER, false); physiology = new BaseEditor(IInfoModel.ENTITY_PHYSIOLOGY_ORDER, false); radiology = new RadEditor(IInfoModel.ENTITY_RADIOLOGY_ORDER, false); surgery = new BaseEditor(IInfoModel.ENTITY_SURGERY_ORDER, false); test = new BaseEditor(IInfoModel.ENTITY_LABO_TEST, false); treatment = new BaseEditor(IInfoModel.ENTITY_TREATMENT, false); // Hashテーブルに登録し show(entity) で使用する table = new HashMap<>(); table.put(IInfoModel.ENTITY_BACTERIA_ORDER, bacteria); table.put(IInfoModel.ENTITY_BASE_CHARGE_ORDER, baseCharge); table.put(IInfoModel.ENTITY_DIAGNOSIS, diagnosis); table.put(IInfoModel.ENTITY_GENERAL_ORDER, general); table.put(IInfoModel.ENTITY_INJECTION_ORDER, injection); table.put(IInfoModel.ENTITY_INSTRACTION_CHARGE_ORDER, instraction); table.put(IInfoModel.ENTITY_MED_ORDER, med); table.put(IInfoModel.ENTITY_OTHER_ORDER, other); table.put(IInfoModel.ENTITY_PHYSIOLOGY_ORDER, physiology); table.put(IInfoModel.ENTITY_RADIOLOGY_ORDER, radiology); table.put(IInfoModel.ENTITY_SURGERY_ORDER, surgery); table.put(IInfoModel.ENTITY_LABO_TEST, test); table.put(IInfoModel.ENTITY_TREATMENT, treatment); //----------------------------------- // カードパネルにエディタを追加する //----------------------------------- cardPanel.add(bacteria.getView(), IInfoModel.ENTITY_BACTERIA_ORDER); cardPanel.add(baseCharge.getView(), IInfoModel.ENTITY_BASE_CHARGE_ORDER); cardPanel.add(diagnosis.getView(), IInfoModel.ENTITY_DIAGNOSIS); cardPanel.add(general.getView(), IInfoModel.ENTITY_GENERAL_ORDER); cardPanel.add(injection.getView(), IInfoModel.ENTITY_INJECTION_ORDER); cardPanel.add(instraction.getView(), IInfoModel.ENTITY_INSTRACTION_CHARGE_ORDER); cardPanel.add(med.getView(), IInfoModel.ENTITY_MED_ORDER); cardPanel.add(other.getView(), IInfoModel.ENTITY_OTHER_ORDER); cardPanel.add(physiology.getView(), IInfoModel.ENTITY_PHYSIOLOGY_ORDER); cardPanel.add(radiology.getView(), IInfoModel.ENTITY_RADIOLOGY_ORDER); cardPanel.add(surgery.getView(), IInfoModel.ENTITY_SURGERY_ORDER); cardPanel.add(test.getView(), IInfoModel.ENTITY_LABO_TEST); cardPanel.add(treatment.getView(), IInfoModel.ENTITY_TREATMENT); // StampBox との間にある矢印ボタンパネル JPanel btnPanel = new JPanel(); BoxLayout box = new BoxLayout(btnPanel, BoxLayout.Y_AXIS); btnPanel.setLayout(box); btnPanel.add(Box.createVerticalStrut(70)); btnPanel.add(right6001); btnPanel.add(right6002); btnPanel.add(Box.createVerticalStrut(30)); btnPanel.add(rightNew); btnPanel.add(rightReplace); btnPanel.add(leftImport); btnPanel.add(Box.createVerticalGlue()); // 配置する this.setLayout(new BorderLayout(0, 0)); this.add(cardPanel, BorderLayout.CENTER); this.add(btnPanel, BorderLayout.EAST); } public AbstractStampEditor getCurrentEditor() { return curEditor; } /** EditorSetPanel を生成する。 */ public EditorSetPanel() { // Resource Injection java.util.ResourceBundle bundle = ClientContext.getMyBundle(EditorSetPanel.class); TITLE_NEW = bundle.getString("actionText.new"); TITLE_REPLACE = bundle.getString("actionText.replace"); TITLE_IMPORT = bundle.getString("actionText.import"); TITLE_TO_LAB = bundle.getString("actionText.labTest"); TITLE_TO_PHYSIO = bundle.getString("actionText.physiology"); TITLE_TO_BACTERIA = bundle.getString("actionText.bacteria"); TITLE_FROM_EDITOR = bundle.getString("treeName.fromEditor"); cardPanel = new JPanel(); cardLayout = new CardLayout(); cardPanel.setLayout(cardLayout); initComponent(); connect(); } }