« 2016年12月 | トップページ | 2017年2月 »

2017年1月

2017年1月31日 (火)

Dock のアイコンに待ち人数表示

カルテ画面に待ち人数のバッジ表示をするようにしていたが,これをドックのアイコンにも表示するようにした。
// Dock のアイコンにバッジを出す
com.apple.eawt.Application app = com.apple.eawt.Application.getApplication();
app.setDockIconBadge(waitingCount == 0? null: String.valueOf(waitingCount));

Screenshot

2017年1月23日 (月)

デザインの結構大幅な変更

  • メインウインドウに常に検索フィールドが出るようにした。検索フィールド(CompletableSearcField)は,バックグランドに薄く「患者検索」という文字が出るようになっていて,この文字は検索語を入力すると消える。
    ほとんど出番がなくなった更新ボタンは,ステータスバーの左端に持っていった。

    Mainwindow

  • 患者検索フィールドに入力すると,自動的に患者検索パネルに切り替わる。
    検索語を入力するとフィールドの右端に X がでて,ここをクリックすると検索語がクリアされるようになっている。

    Mainwindow2

  • インスペクタ画面。アイコンをシックな白黒アイコン(DefaultIcon ver 2.0)に変えた。
    ツールパネルに病名検索フィールドを付けた。

    Inspector

  • 病名スタンプをここから検索して入力することができる。コードヘルパーのスタンプ検索入力を知ってから,入力スタイルが一変してしまった。入力するものが決まっているときは,検索入力の方がずっと速い。一方,迷いながら入力するような時はスタンプ箱の方が便利である。

    Inspector1   Inspector2_2

  • メニューとスタンプ箱のアイコンも白黒のシックなものにした。

    Menu   Stampbox

2017年1月20日 (金)

OS X Sierra

本日から Sierra (10.12.2)で診療開始。今のところ何も問題なし。

2017年1月18日 (水)

Code Helper の改造

Code Helper というのは,カルテ入力中,文頭から登録したキーワード(tx, rp 等)を打って ctrl + return でスタンプ箱の内容がポップアップメニューとして表示されるという機能である。この使い方しかしていなかったのだが,リファクタリング中にコードを読んでいて,実は Code Helper の機能はこれだけではないことが分かって驚いた。なんと,入力文字列がキーワードに一致しない場合,そのテキストを検索文字として解釈し,スタンプ箱からスタンプを検索して,ポップアップメニューにまとめて表示してくれるという機能が組み込まれていたのだ。OpenDolphin を使い始めて 9年になるが,まだ知らない機能があったとは。
 オリジナルでは,"^text.*" の検索をするようになっていたが,これを ".*text.*" に変えて,さらに大文字・小文字を無視するようにした。また,SOA pane で病名にも対応するように改造した。

Codehelper_2

右上:P pane で「創処置」と入れると創処置を含むポップアップメニューが出る(これは今まで知らなかったオリジナルの機能)。右下:「hs」と入力すると,大文字小文字は無視して「hs]を含んでいるスタンプを全て表示する。左上:SOA pane で dx を入れると病名ポップアップが表示される。左下:SOA pane での検索は,テキストスタンプだけでなく病名も検索し,ポップアップに表示する。

2017年1月15日 (日)

BasicInfoInspecter の表示

BasicInfoInspecter でカナ名も出すことにした。名前が長いと欠けてしまうので,deriveFont で無理矢理詰め込む処理を組み込んだ。

Jugem

// 名前が長い場合は,カナ名を圧縮する
if (kanjiName.length() + kanaName.length() > 15) {
  float sy = (float) (15.5 - kanjiName.length()) / kanaName.length();
  Font font = nameLabel.getFont().deriveFont(AffineTransform.getScaleInstance(sy, 1));
  kanaLabel.setFont(font);
}

2017年1月14日 (土)

フォーカス処理の見直し

文書入力の際に,フォーカス処理はとても重要で,ウインドウが開いたらすぐに必要な場所に入力できないとかなりストレスがたまる。今まで,気がついたときに色々フォーカス処理()を加えてきたのだが,行き当たりばったりで組み込んできたので,どこでどのようなフォーカス処理をしているのか把握できなくなってしまっていた。フォーカスの取り合い?かもしれない動作が見られるようにもなっていたので,フォーカス処理を全部見直しすることにした。フォーカスは Focuser というクラスを使って,必ずここにフォーカス請求するようにリファクタリングした。案の定,不要なフォーカス請求をかなり入れてしまっていることが判明して,すっきりさせることができた。
package open.dolphin.ui;

import java.awt.Component;
import java.awt.KeyboardFocusManager;
import javax.swing.SwingUtilities;
import org.apache.log4j.Logger;

public class Focuser {
    private static final Logger logger = Logger.getLogger(Focuser.class);
    private static Component component;

    public static void requestFocus(Component c) {
        component = c;
        KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
        SwingUtilities.invokeLater(Focuser::request);
    }

    private static void request() {
        boolean result = component.requestFocusInWindow();
        logger.info(component.getClass().toString() + ": request focus " + ((result)? "succeeded" : "failed"));
    }
}

2017年1月13日 (金)

JTextComponent の undo

オリジナルでは KartePane のみ ChartMediator 内で undo 機能が付けられていたが,JTextComponentUndoManager を作って undo 機能を独立させ,MemoInspector,TextStampEditor にも undo 機能を付けた。
package open.dolphin.helper;

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
import javax.swing.event.UndoableEditEvent;
import javax.swing.text.JTextComponent;
import javax.swing.undo.UndoManager;

/**
 * JTextComponent に Undo 機能を付ける.<br>
 * 使用例:
 * <pre>{@code
 * TextComponentUndoManager manager = new TextComponentUndoManager();
 * JTextPane textComponent = new JTextPane();
 * manager.addUndoActionTo(textComponent);
 * textComponent.getDocument().addUndoableEditListener(manager::listener);
 * }</pre>
 * @author pns
 */
public class TextComponentUndoManager extends UndoManager {
    private static final long serialVersionUID = 1L;

    private Action undoAction;
    private Action redoAction;

    public TextComponentUndoManager() {
        // default undo action
        undoAction = new AbstractAction("undo") {
            private static final long serialVersionUID = 1L;
            @Override
            public void actionPerformed(ActionEvent e) {
                undo();
            }
        };
        // default redo action
        redoAction = new AbstractAction("redo") {
            private static final long serialVersionUID = 1L;
            @Override
            public void actionPerformed(ActionEvent e) {
                redo();
            }
        };
    }

    /**
     * JTextComponent に Undo 機能を付ける utility static method.
     * @param c
     * @return
     */
    public static TextComponentUndoManager getManager(JTextComponent c) {
        TextComponentUndoManager manager = new TextComponentUndoManager();
        manager.addUndoActionTo(c);
        c.getDocument().addUndoableEditListener(manager::listener);
        return manager;
    }

    public void addUndoActionTo(JTextComponent c) {
        ActionMap am = c.getActionMap();
        InputMap im = c.getInputMap();
        am.put("undo", undoAction);
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, KeyEvent.META_DOWN_MASK), "undo");
        am.put("redo", redoAction);
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, KeyEvent.META_DOWN_MASK | KeyEvent.SHIFT_DOWN_MASK), "redo");
    }

    public void setUndoAction(Action action) {
        undoAction = action;
    }

    public void setRedoAction(Action action) {
        redoAction = action;
    }

    public void listener (UndoableEditEvent e) {
        addEdit(e.getEdit());
        updateActionStatus(); // 文字入力毎に action が enable/disable される
    }

    @Override
    public void undo() {
        if (canUndo()) { super.undo(); }
        updateActionStatus();
    }

    @Override
    public void redo() {
        if (canRedo()) { super.redo(); }
        updateActionStatus();
    }

    private void updateActionStatus() {
        undoAction.setEnabled(canUndo());
        redoAction.setEnabled(canRedo());
    }
}

追記
PatientSearchPanel の JTextField や,CellEditorTreeCellEditor にも組み込んで,ほぼ全てのテキスト入力で undo できるようになった。

2017年1月 6日 (金)

インスペクタのデザイン

インスペクタ部分のデザインを微調整して,全体に連続感が出るようにした。
さらに,関連文書がある場合 Badge で関連文書数を表示するようにした。(右が新しい画面)

Inspector

2017年1月 5日 (木)

待ち人数のバッジ表示

待ち人数をバッジ表示するようにしてみた。患者検索で作業中の時に患者さんが来ても,受付リストボタンにバッジが表示されるので受付されたことが分かる。

Badge_3

PNSBadgeTabbedPane.java

« 2016年12月 | トップページ | 2017年2月 »