package open.dolphin.order; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.concurrent.ExecutionException; import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.ListSelectionEvent; import javax.swing.table.TableColumn; import javax.swing.text.JTextComponent; import open.dolphin.client.AutoKanjiListener; import open.dolphin.client.ClientContext; import open.dolphin.delegater.OrcaDelegater; import open.dolphin.delegater.OrcaDelegaterFactory; import open.dolphin.infomodel.DiseaseEntry; import open.dolphin.infomodel.RegisteredDiagnosisModel; import open.dolphin.infomodel.TensuMaster; import open.dolphin.project.Project; import open.dolphin.table.ListTableModel; import open.dolphin.table.StripeTableCellRenderer; import open.dolphin.util.StringTool; /** * 傷病名編集テーブルクラス。 * * @author Kazushi Minagawa */ public final class DiseaseEditor extends AbstractStampEditor { // 傷病名の修飾語コード private static final String MODIFIER_CODE = "ZZZ"; // 傷病名手入力時につけるコード private static final String HAND_CODE = "0000999"; // Diagnosis table のパラメータ private static final int NAME_COL = 1; private static final int ALIAS_COL = 2; private static final int DISEASE_NUM_ROWS = 5; // Table model private IDiseaseView view; private ListTableModel<RegisteredDiagnosisModel> tableModel; private ListTableModel<DiseaseEntry> searchResultModel; ////s.oh^ 2014/07/11 スタンプエディタのフォーカス制御 // private boolean editCellStart; // private boolean editCellEnter; ////s.oh$ @Override public JPanel getView() { return (JPanel)view; } @Override public void dispose() { if (tableModel != null) { tableModel.clear(); } if (searchResultModel != null) { searchResultModel.clear(); } super.dispose(); } @Override public Object getValue() { if (hasModifier()) { return getValue1(); } else { return getValue2(); } } /** * 傷病名テーブルをスキャンし修飾語つきの傷病にして返す。 */ private Object getValue1() { RegisteredDiagnosisModel diagnosis = null; StringBuilder name = new StringBuilder(); StringBuilder code = new StringBuilder(); // テーブルをスキャンする int count = tableModel.getObjectCount(); for (int i = 0; i < count; i++) { RegisteredDiagnosisModel diag = tableModel.getObject(i); String diagCode = diag.getDiagnosisCode(); if (!diagCode.startsWith(MODIFIER_CODE)) { // // 修飾語でない場合は基本病名と見なし、パラメータを設定する // diagnosis = new RegisteredDiagnosisModel(); diagnosis.setDiagnosisCodeSystem(diag.getDiagnosisCodeSystem()); } else { // ZZZ をトリムする ORCA 実装 diagCode = diagCode.substring(MODIFIER_CODE.length()); } // コードを . で連結する if (code.length() > 0) { code.append("."); } code.append(diagCode); // 名前を連結する name.append(diag.getDiagnosis()); } if (diagnosis != null && name.length() > 0 && code.length() > 0) { // 名前とコードを設定する diagnosis.setDiagnosis(name.toString()); diagnosis.setDiagnosisCode(code.toString()); ArrayList<RegisteredDiagnosisModel> ret = new ArrayList<>(1); ret.add(diagnosis); return ret; } else { return null; } } /** * 傷病名テーブルをスキャンし修飾語つきの傷病にして返す。 */ private Object getValue2() { return tableModel.getDataProvider(); } @Override public void setValue(Object o) { clear(); } @Override protected void checkValidation() { setIsEmpty = tableModel.getObjectCount() == 0; setIsValid = true; int diseaseCnt = 0; List<RegisteredDiagnosisModel> itemList = tableModel.getDataProvider(); for (RegisteredDiagnosisModel diag : itemList) { if (diag.getDiagnosisCode().startsWith(MODIFIER_CODE)) { } else { diseaseCnt++; } } setIsValid = setIsValid && (diseaseCnt > 0); // ButtonControl view.getClearBtn().setEnabled(!setIsEmpty); view.getOkCntBtn().setEnabled(setIsValid && getFromStampEditor()); view.getOkBtn().setEnabled(setIsValid && getFromStampEditor()); // 傷病名チェックボックス view.getDiseaseCheck().setSelected((diseaseCnt > 0)); // 通知する super.checkValidation(); } @Override protected void addSelectedTensu(TensuMaster tm) { // No use } @Override protected void search(final String text, boolean hitReturn) { boolean pass = true; pass = pass && ipOk(); final int searchType = getSearchType(text, hitReturn); pass = pass && (searchType==TT_LETTER_SEARCH); if (!pass) { return; } // 件数をゼロにしておく view.getCountField().setText("0"); // 検索を実行する SwingWorker worker = new SwingWorker<List<DiseaseEntry>, Void>() { @Override protected List<DiseaseEntry> doInBackground() throws Exception { OrcaDelegater dao = OrcaDelegaterFactory.create(); String d = new SimpleDateFormat("yyyyMMdd").format(new Date()); List<DiseaseEntry> result = dao.getDiseaseByName(StringTool.hiraganaToKatakana(text), d, view.getPartialChk().isSelected()); //s.oh^ 2013/11/08 傷病名検索不具合 if(result == null || result.size() <= 0) { result = dao.getDiseaseByName(text, d, view.getPartialChk().isSelected()); } //s.oh$ return result; } @Override protected void done() { try { List<DiseaseEntry> result = get(); searchResultModel.setDataProvider(result); int cnt = searchResultModel.getObjectCount(); view.getCountField().setText(String.valueOf(cnt)); Rectangle r = view.getSearchResultTable().getCellRect(0, 0, true); view.getSearchResultTable().scrollRectToVisible(r); } catch (InterruptedException ex) { } catch (ExecutionException ex) { alertSearchError(ex.getMessage()); } } }; worker.execute(); } @Override protected void clear() { tableModel.clear(); view.getStampNameField().setText(""); checkValidation(); } private final void initComponents() { //view = new DiseaseView(); view = editorButtonTypeIsIcon() ? new DiseaseView() : new DiseaseViewText(); // Info Label view.getInfoLabel().setIcon(ClientContext.getImageIconArias("icon_info_small")); // Resource Injection java.util.ResourceBundle bundle = ClientContext.getMyBundle(DiseaseEditor.class); // テーブルのカラム名を取得する String line = bundle.getString("columnNames.diceaseTable"); String[] diganosisColumns = line.split(","); // テーブルのMethod名を取得する line = bundle.getString("methods.diceaseTable"); String[] methodNames = line.split(","); // 病名テーブルを生成する tableModel = new ListTableModel<RegisteredDiagnosisModel>(diganosisColumns, DISEASE_NUM_ROWS, methodNames, null) { // 病名カラムも修飾語の編集が可能 @Override public boolean isCellEditable(int row, int col) { boolean ret = false; RegisteredDiagnosisModel model = getObject(row); if (col == NAME_COL) { if (model == null) { ret = true; } else if (!model.getDiagnosisCode().startsWith(MODIFIER_CODE)) { ret = true; } } else if (col == ALIAS_COL) { if (model != null && (!model.getDiagnosisCode().startsWith(MODIFIER_CODE))) { ret = true; } } return ret; } @Override public void setValueAt(Object o, int row, int col) { if (o == null) { return; } int index = ((String)o).indexOf(','); if (index > 0) { return; } RegisteredDiagnosisModel model = getObject(row); String value = (String) o; switch (col) { case NAME_COL: // // 病名が手入力された場合は、コードに 0000999 を設定する // if (!value.equals("")) { if (model != null) { model.setDiagnosis(value); model.setDiagnosisCode(HAND_CODE); fireTableCellUpdated(row, col); } else { model = new RegisteredDiagnosisModel(); model.setDiagnosis(value); model.setDiagnosisCode(HAND_CODE); addObject(model); checkValidation(); } } break; case ALIAS_COL: // // エイリアスの入力があった場合 // if (model != null) { String test = model.getDiagnosis(); int idx = test.indexOf(','); if (idx >0 ) { test = test.substring(0, idx); test = test.trim(); } if (value.equals("")) { model.setDiagnosis(test); } else { StringBuilder sb = new StringBuilder(); sb.append(test); sb.append(","); sb.append(value); model.setDiagnosis(sb.toString()); } } break; } } }; // SetTable を生成し transferHandler を生成する JTable table = view.getSetTable(); table.setModel(tableModel); table.setDragEnabled(true); table.setDropMode(DropMode.INSERT); table.setTransferHandler(new RegisteredDiagnosisTransferHandler()); // TransferHandler table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); table.setRowSelectionAllowed(true); ListSelectionModel m = table.getSelectionModel(); m.addListSelectionListener((ListSelectionEvent e) -> { if (e.getValueIsAdjusting() == false) { int row = view.getSetTable().getSelectedRow(); if (tableModel.getObject(row)!= null) { view.getDeleteBtn().setEnabled(true); } else { view.getDeleteBtn().setEnabled(false); } } }); //table.setDefaultRenderer(Object.class, new OddEvenRowRenderer()); StripeTableCellRenderer rederer = new StripeTableCellRenderer(); rederer.setTable(table); rederer.setDefaultRenderer(); // Set Table の行の高さ table.setRowHeight(ClientContext.getMoreHigherRowHeight()); // CellEditor を設定する // 疾患名 TableColumn column = table.getColumnModel().getColumn(NAME_COL); JTextField nametf = new JTextField(); //s.oh^ 2014/02/24 スタンプ内項目削除不具合 //nametf.addFocusListener(AutoKanjiListener.getInstance()); FocusListener flRoman = new FocusListener() { @Override public void focusGained(FocusEvent e) { Object source = e.getSource(); if (source != null && source instanceof JTextComponent) { JTextComponent tc = (JTextComponent) source; if (tc.getInputContext() != null) { tc.getInputContext().setCharacterSubsets(null); } } view.getDeleteBtn().setEnabled(false); view.getClearBtn().setEnabled(false); ////s.oh^ 2014/07/11 スタンプエディタのフォーカス制御 // editCellStart = true; ////s.oh$ } @Override public void focusLost(FocusEvent e) { if(view.getSetTable().isEditing()) { view.getSetTable().getCellEditor().stopCellEditing(); } int row = view.getSetTable().getSelectedRow(); if (tableModel.getObject(row)!= null) { view.getDeleteBtn().setEnabled(true); } else { view.getDeleteBtn().setEnabled(false); } view.getClearBtn().setEnabled(!setIsEmpty); ////s.oh^ 2014/07/11 スタンプエディタのフォーカス制御 // if(editCellStart && editCellEnter) { // view.getSearchTextField().requestFocus(); // } // editCellStart = false; // editCellEnter = false; ////s.oh$ } }; FocusListener flKanji = new FocusListener() { @Override public void focusGained(FocusEvent e) { if (ClientContext.isWin()) { Object source = e.getSource(); if (source != null && source instanceof JTextComponent) { JTextComponent tc = (JTextComponent) source; if (tc.getInputContext() != null) { tc.getInputContext().setCompositionEnabled(true); } } } view.getDeleteBtn().setEnabled(false); view.getClearBtn().setEnabled(false); ////s.oh^ 2014/07/11 スタンプエディタのフォーカス制御 // editCellStart = true; ////s.oh$ } @Override public void focusLost(FocusEvent e) { if (ClientContext.isWin()) { Object source = e.getSource(); if (source != null && source instanceof JTextComponent) { JTextComponent tc = (JTextComponent) source; if (tc.getInputContext() != null) { tc.getInputContext().setCompositionEnabled(false); } } }else{ if(view.getSetTable().isEditing()) { view.getSetTable().getCellEditor().stopCellEditing(); } } int row = view.getSetTable().getSelectedRow(); if (tableModel.getObject(row)!= null) { view.getDeleteBtn().setEnabled(true); } else { view.getDeleteBtn().setEnabled(false); } view.getClearBtn().setEnabled(!setIsEmpty); ////s.oh^ 2014/07/11 スタンプエディタのフォーカス制御 // if(editCellStart && editCellEnter) { // view.getSearchTextField().requestFocus(); // } // editCellStart = false; // editCellEnter = false; ////s.oh$ } }; nametf.addFocusListener(flKanji); //s.oh$ DefaultCellEditor nameEditor = new DefaultCellEditor(nametf); int clickCountToStart = Project.getInt("diagnosis.table.clickCountToStart", 1); nameEditor.setClickCountToStart(clickCountToStart); column.setCellEditor(nameEditor); // 病名エイリアス column = table.getColumnModel().getColumn(ALIAS_COL); JTextField aliastf = new JTextField(); //s.oh^ 2014/02/24 スタンプ内項目削除不具合 //aliastf.addFocusListener(AutoRomanListener.getInstance()); // alias aliastf.addFocusListener(flRoman); // alias //s.oh$ DefaultCellEditor aliasEditor = new DefaultCellEditor(aliastf); aliasEditor.setClickCountToStart(clickCountToStart); column.setCellEditor(aliasEditor); ////s.oh^ 2014/07/11 スタンプエディタのフォーカス制御 // nametf.addKeyListener(new KeyListener() { // @Override // public void keyTyped(KeyEvent e) {} // @Override // public void keyPressed(KeyEvent e) { // if(e.getKeyCode() == KeyEvent.VK_ENTER && editCellStart) { // editCellEnter = true; // }else{ // editCellEnter = false; // } // } // @Override // public void keyReleased(KeyEvent e) {} // }); // aliastf.addKeyListener(new KeyListener() { // @Override // public void keyTyped(KeyEvent e) {} // @Override // public void keyPressed(KeyEvent e) { // if(e.getKeyCode() == KeyEvent.VK_ENTER && editCellStart) { // editCellEnter = true; // }else{ // editCellEnter = false; // } // } // @Override // public void keyReleased(KeyEvent e) {} // }); ////s.oh$ // 列幅設定 int[] columnWidth = new int[]{20, 135, 135}; int len = columnWidth.length; for (int i = 0; i < len; i++) { column = table.getColumnModel().getColumn(i); column.setPreferredWidth(columnWidth[i]); } // // 病名マスタ検索結果テーブル // line = bundle.getString("columnNames.masterTable"); String[] srColumnNames = line.split(","); line = bundle.getString("methods.masterTable"); String[] srMthodNames = line.split(","); int[] srColumnWidth = new int[]{10, 135, 135, 10}; searchResultModel = new ListTableModel<>(srColumnNames, 0, srMthodNames, null); JTable searchResultTable = view.getSearchResultTable(); searchResultTable.setModel(searchResultModel); searchResultTable.setRowHeight(ClientContext.getHigherRowHeight()); searchResultTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); searchResultTable.setRowSelectionAllowed(true); ListSelectionModel lm = searchResultTable.getSelectionModel(); lm.addListSelectionListener((ListSelectionEvent e) -> { if (e.getValueIsAdjusting() == false) { int row = view.getSearchResultTable().getSelectedRow(); DiseaseEntry o = searchResultModel.getObject(row); if (o != null) { String codeSystem = ClientContext.getString("mml.codeSystem.diseaseMaster"); RegisteredDiagnosisModel model = new RegisteredDiagnosisModel(); model.setDiagnosis(o.getName()); model.setDiagnosisCode(o.getCode()); model.setDiagnosisCodeSystem(codeSystem); tableModel.addObject(model); reconstractDiagnosis(); checkValidation(); } searchTextField.requestFocus(); } }); len = srColumnWidth.length; for (int i = 0; i < len; i++) { column = searchResultTable.getColumnModel().getColumn(i); column.setPreferredWidth(srColumnWidth[i]); } StripeTableCellRenderer str = new StripeTableCellRenderer(); str.setTable(searchResultTable); str.setDefaultRenderer(); // 複合病名フィールド JTextField combinedDiagnosis = view.getStampNameField(); combinedDiagnosis.setEditable(false); String toolTipText = bundle.getString("toolTipText.combinedDicease"); combinedDiagnosis.setToolTipText(toolTipText); // 検索フィールド DocumentListener dl = new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { //s.oh^ 2014/04/14 RT検索改善 //if (view.getRtBtn().isSelected()) { // search(view.getSearchTextField().getText().trim(), false); //} SwingUtilities.invokeLater(() -> { if (view.getRtBtn().isSelected()) { search(view.getSearchTextField().getText().trim(), false); } }); //s.oh$ } @Override public void removeUpdate(DocumentEvent e) { //s.oh^ 2014/04/14 RT検索改善 //if (view.getRtBtn().isSelected()) { // search(view.getSearchTextField().getText().trim(), false); //} SwingUtilities.invokeLater(() -> { if (view.getRtBtn().isSelected()) { search(view.getSearchTextField().getText().trim(), false); } }); //s.oh$ } @Override public void changedUpdate(DocumentEvent e) { //s.oh^ 2014/04/14 RT検索改善 //if (view.getRtBtn().isSelected()) { // search(view.getSearchTextField().getText().trim(), false); //} SwingUtilities.invokeLater(() -> { if (view.getRtBtn().isSelected()) { search(view.getSearchTextField().getText().trim(), false); } }); //s.oh$ } }; searchTextField = view.getSearchTextField(); searchTextField.getDocument().addDocumentListener(dl); searchTextField.addActionListener((ActionEvent e) -> { search(view.getSearchTextField().getText().trim(),true); }); searchTextField.addFocusListener(AutoKanjiListener.getInstance()); // マスター検索ができない場合を追加 searchTextField.setEnabled(Project.canSearchMaster()); // Real Time Search boolean rt = Project.getBoolean("masterSearch.realTime", true); view.getRtBtn().setSelected(rt); view.getRtBtn().addActionListener((ActionEvent arg0) -> { Project.setBoolean("masterSearch.realTime", view.getRtBtn().isSelected()); }); // 部分一致 boolean pmatch = Project.getBoolean("masterSearch.partialMatch", false); view.getPartialChk().setSelected(pmatch); view.getPartialChk().addActionListener((ActionEvent arg0) -> { Project.setBoolean("masterSearch.partialMatch", view.getPartialChk().isSelected()); }); // 件数フィールド countField = view.getCountField(); // OK & 連続ボタン view.getOkCntBtn().setEnabled(false); if(editorButtonTypeIsIcon()) { view.getOkCntBtn().setIcon(ClientContext.getImageIconArias("icon_gear_small")); } ////s.oh^ 2014/10/22 Icon表示 // view.getSearchLabel().setIcon(ClientContext.getImageIconArias("icon_search_small")); ////s.oh$ view.getOkCntBtn().addActionListener((ActionEvent e) -> { boundSupport.firePropertyChange(VALUE_PROP, null, getValue()); clear(); }); // OK ボタン view.getOkBtn().setEnabled(false); if(editorButtonTypeIsIcon()) { view.getOkBtn().setIcon(ClientContext.getImageIconArias("icon_accept_small")); } view.getOkBtn().addActionListener((ActionEvent e) -> { boundSupport.firePropertyChange(VALUE_PROP, null, getValue()); dispose(); boundSupport.firePropertyChange(EDIT_END_PROP, false, true); }); // 削除ボタン view.getDeleteBtn().setEnabled(false); if(editorButtonTypeIsIcon()) { view.getDeleteBtn().setIcon(ClientContext.getImageIconArias("icon_delete_small")); } view.getDeleteBtn().addActionListener((ActionEvent e) -> { int row = view.getSetTable().getSelectedRow(); if ((!view.getSetTable().isEditing()) && tableModel.getObject(row) != null) { tableModel.deleteAt(row); checkValidation(); } else { Toolkit.getDefaultToolkit().beep(); } }); // クリアボタン view.getClearBtn().setEnabled(false); if(editorButtonTypeIsIcon()) { view.getClearBtn().setIcon(ClientContext.getImageIconArias("icon_clear_small")); } view.getClearBtn().addActionListener((ActionEvent e) -> { clear(); }); } /** * テーブルをスキャンし、傷病名コンポジットする。 */ public void reconstractDiagnosis() { if (hasModifier()) { StringBuilder sb = new StringBuilder(); int count = tableModel.getObjectCount(); for (int i = 0; i < count; i++) { RegisteredDiagnosisModel diag = (RegisteredDiagnosisModel) tableModel.getObject(i); sb.append(diag.getDiagnosis()); } view.getStampNameField().setText(sb.toString()); } else { view.getStampNameField().setText(""); } } /** * 修飾語をふくんでいるかどうかを返す。 */ private boolean hasModifier() { boolean hasModifier = false; int count = tableModel.getObjectCount(); for (int i = 0; i < count; i++) { RegisteredDiagnosisModel diag = (RegisteredDiagnosisModel) tableModel.getObject(i); if (diag.getDiagnosisCode().startsWith(MODIFIER_CODE)) { hasModifier = true; break; } } return hasModifier; } public DiseaseEditor() { this(true); } public DiseaseEditor(boolean mode) { super(); initComponents(); this.setFromStampEditor(mode); String on = ClientContext.getMyBundle(DiseaseEditor.class).getString("title.document"); this.setOrderName(on); } }