OSDN Git Service

mainエントリのパッケージを変更。
[jindolf/Jindolf.git] / src / main / java / jp / sfjp / jindolf / glyph / FontListModel.java
1 /*
2  * font list model
3  *
4  * License : The MIT License
5  * Copyright(c) 2012 olyutorskii
6  */
7
8 package jp.sfjp.jindolf.glyph;
9
10 import java.awt.EventQueue;
11 import java.util.LinkedList;
12 import java.util.List;
13 import javax.swing.AbstractListModel;
14
15 /**
16  * フォントファミリ名一覧表示用リストのデータモデル。
17  * <p>環境によってはフォントリストを完成させるのに
18  * 数千msかかる場合があるので、その対策として非同期に一覧を読み込む。
19  * <p>実際のリスト作成は裏で走るタスクにより行われ、
20  * リスト完成の暁にはEDTによりリスナに通知される。
21  * 一般的なリストモデルと同様、
22  * 基本的にスレッド間競合の問題はEDTで解決すること。
23  */
24 @SuppressWarnings("serial")
25 public class FontListModel extends AbstractListModel {
26
27     private final List<String> familyList = new LinkedList<String>();
28
29     private volatile boolean hasDone = false;
30
31     /**
32      * コンストラクタ。
33      * <p>コンストラクタ完了と同時にリスト生成タスクが裏で走り始める。
34      */
35     public FontListModel(){
36         super();
37
38         Runnable task = createFillTask();
39         startTask(task);
40
41         return;
42     }
43
44     /**
45      * フォントリスト埋めタスクを生成する。
46      * @return タスク
47      */
48     private Runnable createFillTask(){
49         Runnable task = new Runnable(){
50             /** {@inheritDoc} */
51             @Override
52             @SuppressWarnings("CallToThreadYield")
53             public void run(){
54                 Thread.yield();
55                 fillModel();
56             }
57         };
58
59         return task;
60     }
61
62     /**
63      * フォントファミリ名リストを設定する。
64      * @param familyNames フォントファミリ名のリスト
65      * @return リストの要素数
66      */
67     private int fillList(List<String> familyNames){
68         this.familyList.addAll(familyNames);
69         this.hasDone = true;
70         int size = this.familyList.size();
71         return size;
72     }
73
74     /**
75      * フォントリストを収集しモデルに反映させる。
76      */
77     private void fillModel(){
78         final List<String> fontList = FontUtils.createFontList();
79
80         // スレッド間競合を避けるため、ここより先の処理はEDT任せ。
81         EventQueue.invokeLater(new Runnable(){
82             /** {@inheritDoc} */
83             @Override
84             public void run(){
85                 int size = fillList(fontList);
86                 if(size <= 0) return;
87
88                 int begin = 0;
89                 int end   = size - 1;
90                 fireContentsChanged(this, begin, end);
91
92                 return;
93             }
94         });
95
96         return;
97     }
98
99     /**
100      * フォントリスト埋めタスクを起動する。
101      * @param task タスク
102      */
103     private void startTask(Runnable task){
104         Thread thread = new Thread(task);
105         thread.start();
106         return;
107     }
108
109     /**
110      * モデルが完成済みか否か判定する。
111      * @return モデルが完成していればtrue
112      */
113     public boolean hasCompleted(){
114         return this.hasDone;
115     }
116
117     /**
118      * {@inheritDoc}
119      * @param index {@inheritDoc}
120      * @return {@inheritDoc}
121      */
122     @Override
123     public Object getElementAt(int index){
124         Object result = this.familyList.get(index);
125         return result;
126     }
127
128     /**
129      * {@inheritDoc}
130      * @return {@inheritDoc}
131      */
132     @Override
133     public int getSize(){
134         int result = this.familyList.size();
135         return result;
136     }
137
138 }