« ownCloud 導入 | トップページ | java 1.7 に移行 - opendolphin 編 »

2013年11月 2日 (土)

java 1.7 に移行 - monsiaj 編

NetBeans 7.4 から,java 1.7 がインストールされていないと NetBeans がインストールできなくなってしまった。java 1.6 環境での開発ができなくなったという意味ではないのだが,どうせなのでこれを機会に java 1.7 に移行することにした。

 

mac での ATOK 対応

ATOK を ATOK8 の時代から使っているが,いつもトラブルの元になって苦しめられている気がする。今回も java 1.7 で monsiaj の最新版(monsiaj-20130418)を使ってみたところ,ATOK on でテキストフィールドにカーソルがある状態からファンクションキーを押すと,exception を出してフリーズするという問題が発生した。(java 6 では問題ない)

ATOK26[233]: Exception in proxy  -[IPMDServerClientWrapper selectedRange]
		name = NSPortTimeoutException
		reason = connection timeout: did not receive reply
		userInfo = (null)
	(
	0   CoreFoundation                      0x00007fff8a737b06 __exceptionPreprocess + 198
	1   libobjc.A.dylib                     0x00007fff863c43f0 objc_exception_throw + 43
	2   CoreFoundation                      0x00007fff8a7378dc +[NSException raise:format:] + 204
	3   Foundation                          0x00007fff85d68539 -[NSConnection sendInvocation:internal:] + 3209
	4   CoreFoundation                      0x00007fff8a726197 ___forwarding___ + 775
	5   CoreFoundation                      0x00007fff8a725e18 _CF_forwarding_prep_0 + 232
	6   InputMethodKit                      0x0000000100e26a99 -[IPMDServerClientWrapper selectedRange] + 207
	7   ATOK26                              0x00000001000b963d -[ATOKInputSessionWrapper selectedRangeWithClient:] + 77
	8   ATOK26                              0x00000001000aa994 -[ATOKIMController handleEvent:client:isInterruptedEvent:] + 476
	9   ATOK26                              0x00000001000aaac2 -[ATOKIMController handleEvent:client:] + 19
	10  InputMethodKit                      0x0000000100e31902 -[IMKServer handleEvent:characterIndex:edge:client:] + 2209
	11  CoreFoundation                      0x00007fff8a72b09c __invoking___ + 140
	12  CoreFoundation                      0x00007fff8a72af37 -[NSInvocation invoke] + 263
	13  CoreFoundation                      0x00007fff8a72b109 -[NSInvocation invokeWithTarget:] + 57
	14  CoreFoundation                      0x00007fff8a726197 ___forwarding___ + 775
	15  CoreFoundation                      0x00007fff8a725e18 _CF_forwarding_prep_0 + 232
	16  CoreFoundation                      0x00007fff8a72b09c __invoking___ + 140
	17  CoreFoundation                      0x00007fff8a72af37 -[NSInvocation invoke] + 263
	18  Foundation                          0x00007fff85d735f3 -[NSConnection dispatchInvocation:] + 331
	19  Foundation                          0x00007fff85d72651 -[NSConnection handleRequest:sequence:] + 1378
	20  Foundation                          0x00007fff85d6c7dd -[NSConnection handlePortCoder:] + 895
	21  Foundation                          0x00007fff85d6c00f -[NSConnection dispatchWithComponents:] + 53
	22  Foundation                          0x00007fff85d6bb15 __NSFireMachPort + 257
	23  CoreFoundation                      0x00007fff8a6a6e40 __CFMachPortPerform + 288
	24  CoreFoundation                      0x00007fff8a6a6d09 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
	25  CoreFoundation                      0x00007fff8a6a6a49 __CFRunLoopDoSource1 + 153
	26  CoreFoundation                      0x00007fff8a6d9c02 __CFRunLoopRun + 1826
	27  CoreFoundation                      0x00007fff8a6d90e2 CFRunLoopRunSpecific + 290
	28  HIToolbox                           0x00007fff89c3deb4 RunCurrentEventLoopInMode + 209
	29  HIToolbox                           0x00007fff89c3dc52 ReceiveNextEventCommon + 356
	30  HIToolbox                           0x00007fff89c3dae3 BlockUntilNextEventMatchingListInMode + 62
	31  AppKit                              0x00007fff88dac533 _DPSNextEvent + 685
	32  AppKit                              0x00007fff88dabdf2 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 128
	33  AppKit                              0x00007fff88da31a3 -[NSApplication run] + 517
	34  AppKit                              0x00007fff88d47bd6 NSApplicationMain + 869
	35  ATOK26                              0x00000001001002bc main + 913
	36  ATOK26                              0x00000001000017f4 start + 52
	)

ATOK on の状態だと,他の操作でもしばしば exception を出さずにフリーズしてしまい,実用にならない状態であった。いずれも ATOK を切って操作すればフリーズしない。しかたがないので,全ての Component で enableInputMethod(false) として,ATOK を切った。

WidgetBuilder.java

public static Component buildWidget(Interface xml, WidgetInfo info, Container parent) {
 :
  // ATOK causes freeze everywhere, so kill it unless necessary
  widget.enableInputMethods(false);
 :

しかし,これでは日本語入力ができない。そこで,「かな」キーを押すと,押した Component だけ enableInputMethod(true) になるようにした。

PandaFocusManager.java

public void processKeyEvent(Component focusedComponent, KeyEvent e) {
 :
  if (e.getKeyCode() == KeyEvent.VK_KATAKANA) {
    focusedComponent.enableInputMethods(true);
  }
  :

その他,AccelHandler.java,PandaTable.java にも ATOK を切るコードを入れた。この改造で,java 7 でも何とか1日フリーズなしで過ごせるようになった。こういう個人的な環境に合わせた改造ができるのは,オープンソースのよいところだと思う。

 

その他の改造

ついでに気になっていた部分をいくつか改造した。

  1. (K02)診療行為入力画面の PandaTable の行数が常に 400行になっていて,データの後に大量の空白行がくっついた状態で表示されてしまう。そこで,空白行は無視して,データがある行だけを表示するように改造した。

    PandaTable.java

    public void keyPressed(KeyEvent e) {
     :
      // 現在の selectedRow が実データの最終行なら,それ以上下へは移動しないようにする
      if (e.getKeyCode() != KeyEvent.VK_DOWN || getRealRowCount() != getSelectedRow()) {
          Component parent = ((Component) e.getSource()).getParent();
          KeyEvent pass = new KeyEvent(parent, e.getID(), e.getWhen(), e.getModifiers(), e.getKeyCode(), e.getKeyChar());
          parent.dispatchEvent(pass);
      }
     :
      public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) {
        // 空行への changeSelection は拒否る
        if (getRealRowCount() < rowIndex) { return; }
     :
     /**
      * pns サーバから帰ってくるデータの行数が,実データの有無にかかわらず常に400行なので,
      * 実データのある必要行数だけ表示するようにする
      * @return 
      */
     @Override
     public Dimension getPreferredSize() {
         Dimension size = super.getPreferredSize();
         
         int realRowCount = getRealRowCount();
    
         // 実データを表示するのに必要な高さ
         size.height = (realRowCount + 1) * getRowHeight();
         
         // 親が Viewport であれば,その高さよりも小さくならないようにする
         Object parent = getParent();
         if (parent != null && (parent instanceof JViewport)) {
             JViewport view = (JViewport) parent;
             if (size.height < view.getHeight()) {
                 size.height = view.getHeight(); 
             }
         }
         
         return size;
     }
     /**
      * pns 実データの行数を返す
      * @return 
      */
     private int getRealRowCount() {
         int realRowCount = 0;
         // 最終行からスキャンして,実データを見つけた時点で行数とする
         for (int r=getRowCount()-1; r>=0; r--) {
             // columm 1 に何か入っていれば実データである
             Object value = model.getValueAt(r, 1);
             if (value != null && !"".equals(((String)value).trim())) {
                 realRowCount = r + 1;
                 break;
             }
         }        
         return realRowCount;       
     }
    
  2. (K02)診療行為入力画面で,表示されたデータ行で編集を行ってリターンキーを押すと,セルの選択が最後の行に飛んでしまう。自分的には飛ばない方が良いと思うので,飛ばないように改造した。

    PandaTableMarshaller.java

    public synchronized void receive(WidgetValueManager manager, Component widget) throws IOException {
     :
      //pns 現在編集中の行を保存
      editingRow = table.getSelectedRow();
     :
      if (trow >= 0 && tcolumn >= 0) {      
          //pns 編集中の行があれば選択を変えない begins
          if (editingRow != -1) {
              // ただし最後の行の編集であれば,selectedRow を1つ下に送る
              if (trow == editingRow + 1) { trow = editingRow + 1; }
              else if (trow > editingRow) { trow = editingRow; }
          }
          //pns ends
    
  3. PandaPreview で表示倍率を選択できるようになっているが,初期値をシステムプロパティーから設定できるようにした。

    PandaPreview.java

    //pns zoom 初期値を system property から取得 begins
    //pns zoom = SCALE_FIT_PAGE_WIDTH;
    int index = 1;
    if (System.getProperty("monsia.pandapreview.initialzoom") != null) {
        try {
            int n = Integer.parseInt(System.getProperty("monsia.pandapreview.initialzoom"));
            if (n >= 0 && n <=9) {
                index = n;
            } else {
                if (n == 50) { index = 2; }
                else if (n ==  75) { index = 3; }
                else if (n == 100) { index = 4; }
                else if (n == 125) { index = 5; }
                else if (n == 150) { index = 6; }
                else if (n == 175) { index = 7; }
                else if (n == 200) { index = 8; }
                else if (n == 300) { index = 9; }
            }
        } catch (NumberFormatException e) {}
    }
    zoom = SCALE_VALUE[index];
    combo.setSelectedIndex(index);
    
  4. これまで CListMarsheller.java にグリッド表示コードを入れていたが,コードを見ていたところ,PandaCList.java に,グリッド表示をシステムプロパティーで制御しようとした痕跡を見つけた。そこで,グリッド表示コードをこちらに移した。monsia.panadaclist.showgrid=true などと値を設定するとグリッドが表示される。

    PandaCList.java

     :
    // if (System.getProperty("monsia.widget.pandaclist.showgrid") == null) {
    if (System.getProperty("monsia.pandaclist.showgrid") == null) {
        this.setShowGrid(false);
    } 
    //pns show grid
    else {
        this.setShowGrid(true);
        this.setGridColor(new java.awt.Color(235,235,235));            
    }
     :
    

改造したコードは bitbucket さんに上げた。

« ownCloud 導入 | トップページ | java 1.7 に移行 - opendolphin 編 »

ORCA」カテゴリの記事