テキストの各行をキーと値に分離し、複数テキストファイルを読み込み、キーを突き合わせ照合し、その結果を表示するGUIユーテリティです。
リビジョン | 52632cfd0bc6e346dd62cab5b7277c30ef1598ae (tree) |
---|---|
日時 | 2011-10-13 00:45:25 |
作者 | seraphy <seraphy@192....> |
コミッター | seraphy |
キーマッチング方法のメニューからの選択と、それによるテーブルの再構成
@@ -150,10 +150,12 @@ | ||
150 | 150 | <Property name="buttonGroup" type="javax.swing.ButtonGroup" editor="org.netbeans.modules.form.RADComponent$ButtonGroupPropertyEditor"> |
151 | 151 | <ComponentRef name="keyButtonGroup"/> |
152 | 152 | </Property> |
153 | - <Property name="selected" type="boolean" value="true"/> | |
154 | 153 | <Property name="text" type="java.lang.String" resourceKey="textNormalRadioButtonMenuItem.text"/> |
155 | 154 | <Property name="name" type="java.lang.String" value="textNormalRadioButtonMenuItem" noResource="true"/> |
156 | 155 | </Properties> |
156 | + <BindingProperties> | |
157 | + <BindingProperty name="selected" source="keyMatcherBinder" sourcePath="${text}" target="textNormalRadioButtonMenuItem" targetPath="selected" updateStrategy="0" immediately="false"/> | |
158 | + </BindingProperties> | |
157 | 159 | </MenuItem> |
158 | 160 | <MenuItem class="javax.swing.JRadioButtonMenuItem" name="textIgnoreCaseRadioButtonMenuItem"> |
159 | 161 | <Properties> |
@@ -163,6 +165,9 @@ | ||
163 | 165 | <Property name="text" type="java.lang.String" resourceKey="textIgnoreCaseRadioButtonMenuItem.text"/> |
164 | 166 | <Property name="name" type="java.lang.String" value="textIgnoreCaseRadioButtonMenuItem" noResource="true"/> |
165 | 167 | </Properties> |
168 | + <BindingProperties> | |
169 | + <BindingProperty name="selected" source="keyMatcherBinder" sourcePath="${textIgnoreCase}" target="textIgnoreCaseRadioButtonMenuItem" targetPath="selected" updateStrategy="0" immediately="false"/> | |
170 | + </BindingProperties> | |
166 | 171 | </MenuItem> |
167 | 172 | <MenuItem class="javax.swing.JRadioButtonMenuItem" name="numberRadioButtonMenuItem"> |
168 | 173 | <Properties> |
@@ -172,14 +177,17 @@ | ||
172 | 177 | <Property name="text" type="java.lang.String" resourceKey="numberRadioButtonMenuItem.text"/> |
173 | 178 | <Property name="name" type="java.lang.String" value="numberRadioButtonMenuItem" noResource="true"/> |
174 | 179 | </Properties> |
180 | + <BindingProperties> | |
181 | + <BindingProperty name="selected" source="keyMatcherBinder" sourcePath="${numeric}" target="numberRadioButtonMenuItem" targetPath="selected" updateStrategy="0" immediately="false"/> | |
182 | + </BindingProperties> | |
175 | 183 | </MenuItem> |
176 | 184 | </SubComponents> |
177 | 185 | </Menu> |
178 | 186 | <Menu class="javax.swing.JMenu" name="viewMenu"> |
179 | 187 | <Properties> |
180 | 188 | <Property name="mnemonic" type="int" value="86"/> |
181 | - <Property name="name" type="java.lang.String" value="viewMenu" noResource="true"/> | |
182 | 189 | <Property name="text" type="java.lang.String" resourceKey="viewMenu.text"/> |
190 | + <Property name="name" type="java.lang.String" value="viewMenu" noResource="true"/> | |
183 | 191 | </Properties> |
184 | 192 | <SubComponents> |
185 | 193 | <MenuItem class="javax.swing.JRadioButtonMenuItem" name="allRadioButtonMenuItem"> |
@@ -233,8 +241,8 @@ | ||
233 | 241 | <Menu class="javax.swing.JMenu" name="helpMenu"> |
234 | 242 | <Properties> |
235 | 243 | <Property name="mnemonic" type="int" value="72"/> |
236 | - <Property name="name" type="java.lang.String" value="helpMenu" noResource="true"/> | |
237 | 244 | <Property name="text" type="java.lang.String" resourceKey="helpMenu.text"/> |
245 | + <Property name="name" type="java.lang.String" value="helpMenu" noResource="true"/> | |
238 | 246 | </Properties> |
239 | 247 | <AuxValues> |
240 | 248 | <AuxValue name="JavaCodeGenerator_VariableLocal" type="java.lang.Boolean" value="true"/> |
@@ -343,6 +351,11 @@ | ||
343 | 351 | </Component> |
344 | 352 | <Component class="textkeymatcher.ui.model.DataViewTableModel" name="dataViewTableModel"> |
345 | 353 | </Component> |
354 | + <Component class="textkeymatcher.ui.model.KeyMatcherBinder" name="keyMatcherBinder"> | |
355 | + <AuxValues> | |
356 | + <AuxValue name="JavaCodeGenerator_InitCodePre" type="java.lang.String" value="keyMatcherBinder.bindDataViewTableModel(dataViewTableModel);"/> | |
357 | + </AuxValues> | |
358 | + </Component> | |
346 | 359 | </NonVisualComponents> |
347 | 360 | <Properties> |
348 | 361 | <Property name="component" type="javax.swing.JComponent" editor="org.netbeans.modules.form.ComponentChooserEditor"> |
@@ -137,6 +137,7 @@ public class TextKeyMatcherView extends FrameView { | ||
137 | 137 | @SuppressWarnings("unchecked") |
138 | 138 | // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents |
139 | 139 | private void initComponents() { |
140 | + bindingGroup = new org.jdesktop.beansbinding.BindingGroup(); | |
140 | 141 | |
141 | 142 | mainPanel = new javax.swing.JPanel(); |
142 | 143 | dataViewTableSP = new javax.swing.JScrollPane(); |
@@ -173,6 +174,7 @@ public class TextKeyMatcherView extends FrameView { | ||
173 | 174 | viewButtonGroup = new javax.swing.ButtonGroup(); |
174 | 175 | keyButtonGroup = new javax.swing.ButtonGroup(); |
175 | 176 | dataViewTableModel = new textkeymatcher.ui.model.DataViewTableModel(); |
177 | + keyMatcherBinder = new textkeymatcher.ui.model.KeyMatcherBinder(); | |
176 | 178 | |
177 | 179 | mainPanel.setName("mainPanel"); // NOI18N |
178 | 180 |
@@ -253,26 +255,37 @@ public class TextKeyMatcherView extends FrameView { | ||
253 | 255 | keyMenu.setName("keyMenu"); // NOI18N |
254 | 256 | |
255 | 257 | keyButtonGroup.add(textNormalRadioButtonMenuItem); |
256 | - textNormalRadioButtonMenuItem.setSelected(true); | |
257 | 258 | textNormalRadioButtonMenuItem.setText(resourceMap.getString("textNormalRadioButtonMenuItem.text")); // NOI18N |
258 | 259 | textNormalRadioButtonMenuItem.setName("textNormalRadioButtonMenuItem"); // NOI18N |
260 | + | |
261 | + org.jdesktop.beansbinding.Binding binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, keyMatcherBinder, org.jdesktop.beansbinding.ELProperty.create("${text}"), textNormalRadioButtonMenuItem, org.jdesktop.beansbinding.BeanProperty.create("selected")); | |
262 | + bindingGroup.addBinding(binding); | |
263 | + | |
259 | 264 | keyMenu.add(textNormalRadioButtonMenuItem); |
260 | 265 | |
261 | 266 | keyButtonGroup.add(textIgnoreCaseRadioButtonMenuItem); |
262 | 267 | textIgnoreCaseRadioButtonMenuItem.setText(resourceMap.getString("textIgnoreCaseRadioButtonMenuItem.text")); // NOI18N |
263 | 268 | textIgnoreCaseRadioButtonMenuItem.setName("textIgnoreCaseRadioButtonMenuItem"); // NOI18N |
269 | + | |
270 | + binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, keyMatcherBinder, org.jdesktop.beansbinding.ELProperty.create("${textIgnoreCase}"), textIgnoreCaseRadioButtonMenuItem, org.jdesktop.beansbinding.BeanProperty.create("selected")); | |
271 | + bindingGroup.addBinding(binding); | |
272 | + | |
264 | 273 | keyMenu.add(textIgnoreCaseRadioButtonMenuItem); |
265 | 274 | |
266 | 275 | keyButtonGroup.add(numberRadioButtonMenuItem); |
267 | 276 | numberRadioButtonMenuItem.setText(resourceMap.getString("numberRadioButtonMenuItem.text")); // NOI18N |
268 | 277 | numberRadioButtonMenuItem.setName("numberRadioButtonMenuItem"); // NOI18N |
278 | + | |
279 | + binding = org.jdesktop.beansbinding.Bindings.createAutoBinding(org.jdesktop.beansbinding.AutoBinding.UpdateStrategy.READ_WRITE, keyMatcherBinder, org.jdesktop.beansbinding.ELProperty.create("${numeric}"), numberRadioButtonMenuItem, org.jdesktop.beansbinding.BeanProperty.create("selected")); | |
280 | + bindingGroup.addBinding(binding); | |
281 | + | |
269 | 282 | keyMenu.add(numberRadioButtonMenuItem); |
270 | 283 | |
271 | 284 | menuBar.add(keyMenu); |
272 | 285 | |
273 | 286 | viewMenu.setMnemonic('V'); |
274 | - viewMenu.setName("viewMenu"); // NOI18N | |
275 | 287 | viewMenu.setText(resourceMap.getString("viewMenu.text")); // NOI18N |
288 | + viewMenu.setName("viewMenu"); // NOI18N | |
276 | 289 | |
277 | 290 | viewButtonGroup.add(allRadioButtonMenuItem); |
278 | 291 | allRadioButtonMenuItem.setSelected(true); |
@@ -303,8 +316,8 @@ public class TextKeyMatcherView extends FrameView { | ||
303 | 316 | menuBar.add(viewMenu); |
304 | 317 | |
305 | 318 | helpMenu.setMnemonic('H'); |
306 | - helpMenu.setName("helpMenu"); // NOI18N | |
307 | 319 | helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N |
320 | + helpMenu.setName("helpMenu"); // NOI18N | |
308 | 321 | |
309 | 322 | aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N |
310 | 323 | aboutMenuItem.setName("aboutMenuItem"); // NOI18N |
@@ -350,9 +363,13 @@ public class TextKeyMatcherView extends FrameView { | ||
350 | 363 | .addGap(3, 3, 3)) |
351 | 364 | ); |
352 | 365 | |
366 | + keyMatcherBinder.bindDataViewTableModel(dataViewTableModel); | |
367 | + | |
353 | 368 | setComponent(mainPanel); |
354 | 369 | setMenuBar(menuBar); |
355 | 370 | setStatusBar(statusPanel); |
371 | + | |
372 | + bindingGroup.bind(); | |
356 | 373 | }// </editor-fold>//GEN-END:initComponents |
357 | 374 | |
358 | 375 | private ImportDataDialogModel importDataDialogModel; |
@@ -448,6 +465,7 @@ public class TextKeyMatcherView extends FrameView { | ||
448 | 465 | private javax.swing.JPopupMenu.Separator jSeparator1; |
449 | 466 | private javax.swing.JPopupMenu.Separator jSeparator2; |
450 | 467 | private javax.swing.ButtonGroup keyButtonGroup; |
468 | + private textkeymatcher.ui.model.KeyMatcherBinder keyMatcherBinder; | |
451 | 469 | private javax.swing.JMenu keyMenu; |
452 | 470 | private javax.swing.JMenuItem loadDataMenuItem; |
453 | 471 | private javax.swing.JPanel mainPanel; |
@@ -469,6 +487,7 @@ public class TextKeyMatcherView extends FrameView { | ||
469 | 487 | private javax.swing.JRadioButtonMenuItem unmatchedRadioButtonMenuItem; |
470 | 488 | private javax.swing.ButtonGroup viewButtonGroup; |
471 | 489 | private javax.swing.JMenu viewMenu; |
490 | + private org.jdesktop.beansbinding.BindingGroup bindingGroup; | |
472 | 491 | // End of variables declaration//GEN-END:variables |
473 | 492 | |
474 | 493 | private final Timer messageTimer; |
@@ -4,18 +4,66 @@ | ||
4 | 4 | */ |
5 | 5 | package textkeymatcher.ui.model; |
6 | 6 | |
7 | +import java.beans.PropertyChangeListener; | |
8 | +import java.beans.PropertyChangeSupport; | |
9 | +import org.apache.commons.lang3.StringUtils; | |
7 | 10 | import textkeymatcher.entity.KeyMatchedRowMap; |
8 | 11 | import textkeymatcher.entity.KeyMatchedRowView; |
9 | 12 | import textkeymatcher.entity.LineDataList; |
13 | +import textkeymatcher.service.KeyMatcher; | |
10 | 14 | |
11 | 15 | /** |
12 | - * | |
16 | + * ビューに表示されるテーブルのモデル.<br> | |
13 | 17 | * @author seraphy |
14 | 18 | */ |
15 | 19 | public class DataViewTableModel extends KeyMatchedRowView { |
16 | - | |
20 | + | |
21 | + /** | |
22 | + * プロパティ変更サポート | |
23 | + */ | |
24 | + private PropertyChangeSupport propCng = new PropertyChangeSupport(this); | |
25 | + | |
26 | + /** | |
27 | + * キーマッチング方法のプロパティ名 | |
28 | + */ | |
29 | + public static final String PROPERTY_KEY_MATCHER = "keyMatcher"; | |
30 | + | |
31 | + /** | |
32 | + * 取り込んだデータソースや、キーマッチングなどを決定している | |
33 | + * データマップ | |
34 | + */ | |
17 | 35 | private KeyMatchedRowMap rowMap = new KeyMatchedRowMap(); |
18 | 36 | |
37 | + | |
38 | + public void addPropertyChangeListener(PropertyChangeListener pl) { | |
39 | + propCng.addPropertyChangeListener(pl); | |
40 | + } | |
41 | + | |
42 | + public void removePropertyChangeListener(PropertyChangeListener pl) { | |
43 | + propCng.removePropertyChangeListener(pl); | |
44 | + } | |
45 | + | |
46 | + public PropertyChangeListener[] getPropertyChangeListeners() { | |
47 | + return propCng.getPropertyChangeListeners(); | |
48 | + } | |
49 | + | |
50 | + public void addPropertyChangeListener(String string, PropertyChangeListener pl) { | |
51 | + propCng.addPropertyChangeListener(pl); | |
52 | + } | |
53 | + | |
54 | + public void removePropertyChangeListener(String string, PropertyChangeListener pl) { | |
55 | + propCng.removePropertyChangeListener(pl); | |
56 | + } | |
57 | + | |
58 | + public PropertyChangeListener[] getPropertyChangeListeners(String string) { | |
59 | + return propCng.getPropertyChangeListeners(string); | |
60 | + } | |
61 | + | |
62 | + | |
63 | + /** | |
64 | + * データソースを追加する. | |
65 | + * @param lineDataList | |
66 | + */ | |
19 | 67 | public void addLineDataList(LineDataList lineDataList) { |
20 | 68 | if (lineDataList == null) { |
21 | 69 | throw new IllegalArgumentException(); |
@@ -26,12 +74,56 @@ public class DataViewTableModel extends KeyMatchedRowView { | ||
26 | 74 | renumbering(rowMap); |
27 | 75 | } |
28 | 76 | |
77 | + /** | |
78 | + * 現在適用されているキーマッチング方法を取得する. | |
79 | + * @return キーマッヂング方法 | |
80 | + */ | |
81 | + public KeyMatcher getKeyMatcher() { | |
82 | + return rowMap.getKeyMatcher(); | |
83 | + } | |
84 | + | |
85 | + /** | |
86 | + * キーマッチング方法を設定する.<br> | |
87 | + * 必要に応じて表は再構成される.<br> | |
88 | + * @param keyMatcher キーマッチング方法 | |
89 | + */ | |
90 | + public void setKeyMatcher(KeyMatcher keyMatcher) { | |
91 | + if (keyMatcher == null) { | |
92 | + throw new IllegalArgumentException(); | |
93 | + } | |
94 | + | |
95 | + KeyMatcher oldValue = getKeyMatcher(); | |
96 | + if (oldValue != keyMatcher) { | |
97 | + // キータイプが変更される場合のみ | |
98 | + // キーを変更してマッチチングを再適用し、表を構成し直す. | |
99 | + rowMap.setKeyMatcher(keyMatcher); | |
100 | + rowMap.remap(); | |
101 | + | |
102 | + renumbering(rowMap); | |
103 | + | |
104 | + propCng.firePropertyChange(PROPERTY_KEY_MATCHER, oldValue, keyMatcher); | |
105 | + } | |
106 | + } | |
107 | + | |
108 | + /** | |
109 | + * キーまたはデータソースのタイトルを返す.<br> | |
110 | + * 0列がキーで、それ以降はデータソースごとのタイトルが返される.<br> | |
111 | + * @param i | |
112 | + * @return | |
113 | + */ | |
29 | 114 | @Override |
30 | 115 | public String getColumnName(int i) { |
31 | 116 | if (i == 0) { |
32 | 117 | return "Key"; |
33 | 118 | } |
34 | 119 | int column = i - 1; // 左端はキーカラム固定 |
35 | - return rowMap.getTitle(column); | |
120 | + String title = rowMap.getTitle(column); | |
121 | + | |
122 | + if (StringUtils.isBlank(title)) { | |
123 | + // 空の場合は列番号をつけて返す. | |
124 | + title = "(" + column + ")"; | |
125 | + } | |
126 | + | |
127 | + return title; | |
36 | 128 | } |
37 | 129 | } |
@@ -0,0 +1,127 @@ | ||
1 | +/* | |
2 | + * To change this template, choose Tools | Templates | |
3 | + * and open the template in the editor. | |
4 | + */ | |
5 | +package textkeymatcher.ui.model; | |
6 | + | |
7 | +import java.beans.PropertyChangeEvent; | |
8 | +import java.beans.PropertyChangeListener; | |
9 | +import java.util.logging.Level; | |
10 | +import java.util.logging.Logger; | |
11 | +import org.jdesktop.application.AbstractBean; | |
12 | +import textkeymatcher.service.KeyMatcher; | |
13 | + | |
14 | +/** | |
15 | + * メニューのチェックボックス付きメニューアイテムでキーマッチングを切り替える場合に便利なようにバイントサポートするクラス.<br> | |
16 | + * setText/setTextIgnoreCase/setNumericでは、引数enableがtrueである場合のみ設定されます。 | |
17 | + * 引数がfalseの場合は単に無視して解除しません.別のタイプがsetでenableされたときに変更されます.<br> | |
18 | + * @author seraphy | |
19 | + */ | |
20 | +public class KeyMatcherBinder extends AbstractBean { | |
21 | + | |
22 | + /** | |
23 | + * ロガー` | |
24 | + */ | |
25 | + private static final Logger logger = Logger.getLogger(KeyMatcherBinder.class.getName()); | |
26 | + | |
27 | + /** | |
28 | + * キーマッチャをもつ実体オブジェクト | |
29 | + */ | |
30 | + private DataViewTableModel tableModel; | |
31 | + | |
32 | + | |
33 | + /** | |
34 | + * 実体オブジェクトを設定します.<br> | |
35 | + * プロパティ変更リスナーがセットアップされます.<br> | |
36 | + * @param tableModel | |
37 | + */ | |
38 | + public void bindDataViewTableModel(DataViewTableModel tableModel) { | |
39 | + if (tableModel == null) { | |
40 | + throw new IllegalArgumentException(); | |
41 | + } | |
42 | + this.tableModel = tableModel; | |
43 | + this.tableModel.addPropertyChangeListener(new PropertyChangeListener() { | |
44 | + @Override | |
45 | + public void propertyChange(PropertyChangeEvent pce) { | |
46 | + tableModelPropertyChanged(pce); | |
47 | + } | |
48 | + }); | |
49 | + } | |
50 | + | |
51 | + /** | |
52 | + * キーマッチャが変更されたことを通知される.<br> | |
53 | + * @param pce プロパティ変更イベント | |
54 | + */ | |
55 | + protected void tableModelPropertyChanged(PropertyChangeEvent pce) { | |
56 | + String propertyName = pce.getPropertyName(); | |
57 | + if (DataViewTableModel.PROPERTY_KEY_MATCHER.equals(propertyName)) { | |
58 | + changeKeyMatcher( | |
59 | + (KeyMatcher) pce.getOldValue(), | |
60 | + (KeyMatcher) pce.getNewValue() | |
61 | + ); | |
62 | + } | |
63 | + } | |
64 | + | |
65 | + protected KeyMatcher getKeyMatcher() { | |
66 | + if (tableModel == null) { | |
67 | + throw new IllegalStateException("先にsetDataViewTableModelで設定しておく必要があります."); | |
68 | + } | |
69 | + return tableModel.getKeyMatcher(); | |
70 | + } | |
71 | + | |
72 | + protected void setKeyMatcher(KeyMatcher keyMatcher) { | |
73 | + if (tableModel == null) { | |
74 | + throw new IllegalStateException("先にsetDataViewTableModelで設定しておく必要があります."); | |
75 | + } | |
76 | + tableModel.setKeyMatcher(keyMatcher); // thisにも変更通知がくることを想定 | |
77 | + } | |
78 | + | |
79 | + protected void changeKeyMatcher(KeyMatcher oldValue, KeyMatcher newValue) { | |
80 | + logger.log(Level.INFO, ">change: {0}->{1}", new Object[] {oldValue, newValue}); | |
81 | + | |
82 | + boolean oldText = oldValue == KeyMatcher.TEXT; | |
83 | + boolean oldTextIC = oldValue == KeyMatcher.TEXT_IGNORECASE; | |
84 | + boolean oldNumeric = oldValue == KeyMatcher.NUMERIC; | |
85 | + | |
86 | + boolean newText = newValue == KeyMatcher.TEXT; | |
87 | + boolean newTextIC = newValue == KeyMatcher.TEXT_IGNORECASE; | |
88 | + boolean newNumeric = newValue == KeyMatcher.NUMERIC; | |
89 | + | |
90 | + firePropertyChange("text", oldText, newText); | |
91 | + firePropertyChange("textIgnoreCase", oldTextIC, newTextIC); | |
92 | + firePropertyChange("numeric", oldNumeric, newNumeric); | |
93 | + } | |
94 | + | |
95 | + public boolean isText() { | |
96 | + return getKeyMatcher() == KeyMatcher.TEXT; | |
97 | + } | |
98 | + | |
99 | + public boolean isTextIgnoreCase() { | |
100 | + return getKeyMatcher() == KeyMatcher.TEXT_IGNORECASE; | |
101 | + } | |
102 | + | |
103 | + public boolean isNumeric() { | |
104 | + return getKeyMatcher() == KeyMatcher.NUMERIC; | |
105 | + } | |
106 | + | |
107 | + public void setText(boolean enable) { | |
108 | + logger.log(Level.INFO, "setText: {0}", enable); | |
109 | + if (enable) { | |
110 | + setKeyMatcher(KeyMatcher.TEXT); | |
111 | + } | |
112 | + } | |
113 | + | |
114 | + public void setTextIgnoreCase(boolean enable) { | |
115 | + logger.log(Level.INFO, "setTextIgnoreCase: {0}", enable); | |
116 | + if (enable) { | |
117 | + setKeyMatcher(KeyMatcher.TEXT_IGNORECASE); | |
118 | + } | |
119 | + } | |
120 | + | |
121 | + public void setNumeric(boolean enable) { | |
122 | + logger.log(Level.INFO, "setNumeric: {0}", enable); | |
123 | + if (enable) { | |
124 | + setKeyMatcher(KeyMatcher.NUMERIC); | |
125 | + } | |
126 | + } | |
127 | +} |