OSDN Git Service

dmg作成バージョンの取得方法の修正
[charactermanaj/CharacterManaJ.git] / src / main / java / charactermanaj / ui / ManageFavoriteDialog.java
1 package charactermanaj.ui;\r
2 \r
3 import java.awt.BorderLayout;\r
4 import java.awt.Container;\r
5 import java.awt.Dimension;\r
6 import java.awt.GridBagConstraints;\r
7 import java.awt.GridBagLayout;\r
8 import java.awt.Point;\r
9 import java.awt.Toolkit;\r
10 import java.awt.event.ActionEvent;\r
11 import java.awt.event.KeyEvent;\r
12 import java.awt.event.MouseAdapter;\r
13 import java.awt.event.MouseEvent;\r
14 import java.awt.event.WindowAdapter;\r
15 import java.awt.event.WindowEvent;\r
16 import java.util.ArrayList;\r
17 import java.util.Arrays;\r
18 import java.util.Collections;\r
19 import java.util.Iterator;\r
20 import java.util.List;\r
21 import java.util.Map;\r
22 import java.util.Properties;\r
23 \r
24 import javax.swing.AbstractAction;\r
25 import javax.swing.Action;\r
26 import javax.swing.ActionMap;\r
27 import javax.swing.BorderFactory;\r
28 import javax.swing.Box;\r
29 import javax.swing.InputMap;\r
30 import javax.swing.JButton;\r
31 import javax.swing.JComponent;\r
32 import javax.swing.JDialog;\r
33 import javax.swing.JFrame;\r
34 import javax.swing.JMenuItem;\r
35 import javax.swing.JOptionPane;\r
36 import javax.swing.JPanel;\r
37 import javax.swing.JPopupMenu;\r
38 import javax.swing.JRootPane;\r
39 import javax.swing.JScrollPane;\r
40 import javax.swing.JTable;\r
41 import javax.swing.KeyStroke;\r
42 import javax.swing.ListSelectionModel;\r
43 import javax.swing.SwingUtilities;\r
44 import javax.swing.UIManager;\r
45 import javax.swing.event.ListSelectionEvent;\r
46 import javax.swing.event.ListSelectionListener;\r
47 import javax.swing.table.AbstractTableModel;\r
48 \r
49 import charactermanaj.model.CharacterData;\r
50 import charactermanaj.model.PartsSet;\r
51 import charactermanaj.util.LocalizedResourcePropertyLoader;\r
52 import charactermanaj.util.UIHelper;\r
53 \r
54 /**\r
55  * お気に入りの編集ダイアログ\r
56  * \r
57  * @author seraphy\r
58  */\r
59 public class ManageFavoriteDialog extends JDialog {\r
60 \r
61         private static final long serialVersionUID = 1L;\r
62 \r
63         protected static final String STRINGS_RESOURCE = "languages/managefavoritesdialog";\r
64 \r
65         private CharacterData characterData;\r
66         \r
67         private PartsSetListTableModel partsSetListModel;\r
68         \r
69         private JTable partsSetList;\r
70 \r
71         private FavoriteManageCallback callback;\r
72 \r
73         private Action actSelect;\r
74 \r
75         private Action actDelete;\r
76 \r
77         private Action actRename;\r
78 \r
79         public static class PartsSetListTableModel extends AbstractTableModel {\r
80 \r
81                 /**\r
82                  * シリアライズバージョンID\r
83                  */\r
84                 private static final long serialVersionUID = 3012538368342673506L;\r
85 \r
86                 /**\r
87                  * パーツセットのリスト\r
88                  */\r
89                 private List<PartsSet> partsSetList = Collections.emptyList();\r
90 \r
91                 private enum Columns {\r
92                         DISPLAY_NAME("Name") {\r
93                                 @Override\r
94                                 public Object getValue(PartsSet partsSet) {\r
95                                         if (partsSet != null) {\r
96                                                 return partsSet.getLocalizedName();\r
97                                         }\r
98                                         return null;\r
99                                 }\r
100                         },\r
101                         IS_PRESET("Type") {\r
102                                 @Override\r
103                                 public Object getValue(PartsSet partsSet) {\r
104                                         if (partsSet != null) {\r
105                                                 return partsSet.isPresetParts()\r
106                                                                 ? "Preset"\r
107                                                                 : "Favorites";\r
108                                         }\r
109                                         return null;\r
110                                 }\r
111                         };\r
112 \r
113                         private String columnName;\r
114 \r
115                         private Columns(String columnName) {\r
116                                 this.columnName = columnName;\r
117                         }\r
118 \r
119                         public Class<?> getColumnClass() {\r
120                                 return String.class;\r
121                         }\r
122 \r
123                         public String getColumnName() {\r
124                                 return columnName;\r
125                         }\r
126 \r
127                         public abstract Object getValue(PartsSet partsSet);\r
128                 }\r
129 \r
130                 private static Columns[] columns = Columns.values();\r
131 \r
132                 public int getColumnCount() {\r
133                         return columns.length;\r
134                 }\r
135 \r
136                 public int getRowCount() {\r
137                         return partsSetList.size();\r
138                 }\r
139 \r
140                 public Object getValueAt(int rowIndex, int columnIndex) {\r
141                         PartsSet partsSet = getRow(rowIndex);\r
142                         return columns[columnIndex].getValue(partsSet);\r
143                 }\r
144 \r
145                 @Override\r
146                 public Class<?> getColumnClass(int columnIndex) {\r
147                         return columns[columnIndex].getColumnClass();\r
148                 }\r
149 \r
150                 @Override\r
151                 public String getColumnName(int column) {\r
152                         return columns[column].getColumnName();\r
153                 }\r
154 \r
155                 public PartsSet getRow(int rowIndex) {\r
156                         return partsSetList.get(rowIndex);\r
157                 }\r
158 \r
159                 public void updateRow(int rowIndex, PartsSet partsSet) {\r
160                         partsSetList.set(rowIndex, partsSet);\r
161                         fireTableRowsUpdated(rowIndex, rowIndex);\r
162                 }\r
163 \r
164                 public List<PartsSet> getPartsSetList() {\r
165                         return new ArrayList<PartsSet>(partsSetList);\r
166                 }\r
167 \r
168                 public void setPartsSetList(List<PartsSet> partsSetList) {\r
169                         if (partsSetList == null) {\r
170                                 partsSetList = Collections.emptyList();\r
171                         }\r
172                         this.partsSetList = new ArrayList<PartsSet>(partsSetList);\r
173                         fireTableDataChanged();\r
174                 }\r
175         }\r
176 \r
177         /**\r
178          * パーツセットの選択および保存を行うためのコールバック.\r
179          */\r
180         public interface FavoriteManageCallback {\r
181 \r
182                 /**\r
183                  * 引数で指定されたパーツセットを表示する.\r
184                  * \r
185                  * @param partsSet\r
186                  */\r
187                 void selectFavorites(PartsSet partsSet);\r
188 \r
189                 /**\r
190                  * 指定したキャラクターデータのお気に入りを保存する.<br>\r
191                  * presetを変更した場合はcharacter.xmlを更新するためにsavePreset引数をtrueとする.<br>\r
192                  * \r
193                  * @param characterData\r
194                  *            お気に入りを保存するキャラクターデータ\r
195                  * @param savePreset\r
196                  *            character.xmlを更新する場合(presetの更新)\r
197                  */\r
198                 void updateFavorites(CharacterData characterData, boolean savePreset);\r
199         }\r
200 \r
201         public ManageFavoriteDialog(JFrame parent, CharacterData characterData) {\r
202                 super(parent, false);\r
203                 if (characterData == null) {\r
204                         throw new IllegalArgumentException();\r
205                 }\r
206                 \r
207                 setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);\r
208                 addWindowListener(new WindowAdapter() {\r
209                         @Override\r
210                         public void windowClosing(WindowEvent e) {\r
211                                 onClose();\r
212                         }\r
213                 });\r
214                 \r
215                 Properties strings = LocalizedResourcePropertyLoader\r
216                                 .getCachedInstance()\r
217                                 .getLocalizedProperties(STRINGS_RESOURCE);\r
218 \r
219                 setTitle(strings.getProperty("manageFavorites"));\r
220                 \r
221                 this.characterData = characterData;\r
222                 \r
223                 characterData.getPartsSets();\r
224                 \r
225                 Container contentPane = getContentPane();\r
226                 contentPane.setLayout(new BorderLayout());\r
227                 \r
228                 partsSetListModel = new PartsSetListTableModel();\r
229                 partsSetList = new JTable(partsSetListModel);\r
230                 partsSetList.setRowSelectionAllowed(true);\r
231                 partsSetList\r
232                                 .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);\r
233 \r
234                 partsSetList.setTableHeader(null);\r
235                 partsSetList.getColumnModel().getColumn(1).setMaxWidth(150);\r
236                 \r
237                 partsSetList.getSelectionModel().addListSelectionListener(\r
238                                 new ListSelectionListener() {\r
239                                         public void valueChanged(ListSelectionEvent e) {\r
240                                                 updateButtonUI();\r
241                                         }\r
242                                 });\r
243 \r
244                 actSelect = new AbstractAction(strings.getProperty("select")) {\r
245                         private static final long serialVersionUID = 1L;\r
246                         public void actionPerformed(ActionEvent e) {\r
247                                 onSelect();\r
248                         }\r
249                 };\r
250                 actDelete = new AbstractAction(strings.getProperty("remove")) {\r
251                         private static final long serialVersionUID = 1L;\r
252                         public void actionPerformed(ActionEvent e) {\r
253                                 onDelete();\r
254                         }\r
255                 };\r
256                 actRename = new AbstractAction(strings.getProperty("rename")) {\r
257                         private static final long serialVersionUID = 1L;\r
258                         public void actionPerformed(ActionEvent e) {\r
259                                 onRename();\r
260                         }\r
261                 };\r
262 \r
263                 JPanel buttonsPanel = new JPanel();\r
264                 GridBagLayout gb = new GridBagLayout();\r
265                 GridBagConstraints gbc = new GridBagConstraints();\r
266                 buttonsPanel.setLayout(gb);\r
267                 \r
268                 gbc.gridx = 0;\r
269                 gbc.gridy = 0;\r
270                 gbc.anchor = GridBagConstraints.EAST;\r
271                 gbc.fill = GridBagConstraints.BOTH;\r
272                 buttonsPanel.add(new JButton(actSelect), gbc);\r
273 \r
274                 gbc.gridx = 0;\r
275                 gbc.gridy = 1;\r
276                 buttonsPanel.add(new JButton(actDelete), gbc);\r
277 \r
278                 gbc.gridx = 0;\r
279                 gbc.gridy = 2;\r
280                 buttonsPanel.add(new JButton(actRename), gbc);\r
281                 \r
282                 gbc.gridx = 0;\r
283                 gbc.gridy = 3;\r
284                 gbc.weighty = 1.;\r
285                 buttonsPanel.add(Box.createGlue(), gbc);\r
286 \r
287                 \r
288                 JPanel panel2 = new JPanel();\r
289                 panel2.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 42));\r
290                 panel2.setLayout(new BorderLayout());\r
291                 Action actCancel = new AbstractAction(strings.getProperty("close")) {\r
292                         private static final long serialVersionUID = 1L;\r
293                         public void actionPerformed(ActionEvent e) {\r
294                                 onClose();\r
295                         }\r
296                 };\r
297                 JButton btnClose = new JButton(actCancel);\r
298                 panel2.add(btnClose, BorderLayout.EAST);\r
299 \r
300                 JScrollPane scr = new JScrollPane(partsSetList);\r
301                 scr.setBorder(BorderFactory.createEtchedBorder());\r
302                 scr.setPreferredSize(new Dimension(300, 150));\r
303                 \r
304                 contentPane.add(scr, BorderLayout.CENTER);\r
305                 contentPane.add(buttonsPanel, BorderLayout.EAST);\r
306                 contentPane.add(panel2, BorderLayout.SOUTH);\r
307 \r
308                 Toolkit tk = Toolkit.getDefaultToolkit();\r
309                 JRootPane rootPane = getRootPane();\r
310                 rootPane.setDefaultButton(btnClose);\r
311                 InputMap im = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);\r
312                 ActionMap am = rootPane.getActionMap();\r
313                 im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), "deleteFav");\r
314                 im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "closeManageFavoriteDialog");\r
315                 im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, tk.getMenuShortcutKeyMask()), "closeManageFavoriteDialog");\r
316                 am.put("deleteFav", actDelete);\r
317                 am.put("closeManageFavoriteDialog", actCancel);\r
318 \r
319                 setSize(400, 500);\r
320                 setLocationRelativeTo(parent);\r
321                 \r
322                 final JPopupMenu popupMenu = new JPopupMenu();\r
323                 popupMenu.add(new JMenuItem(actSelect));\r
324                 popupMenu.add(new JMenuItem(actRename));\r
325                 popupMenu.add(new JMenuItem(actDelete));\r
326 \r
327                 partsSetList.addMouseListener(new MouseAdapter() {\r
328                         @Override\r
329                         public void mouseClicked(MouseEvent e) {\r
330                                 if (e.getClickCount() == 2) {\r
331                                         onSelect();\r
332                                 }\r
333                         }\r
334                         @Override\r
335                         public void mousePressed(MouseEvent e) {\r
336                                 if (SwingUtilities.isRightMouseButton(e)) {\r
337                                         // 右クリックによる選択\r
338                                         Point pt = e.getPoint();\r
339                                         int rowIndex = partsSetList.rowAtPoint(pt);\r
340                                         if (rowIndex >= 0) {\r
341                                                 int[] selrows = partsSetList.getSelectedRows();\r
342                                                 if (!Arrays.asList(selrows).contains(rowIndex)) {\r
343                                                         // 現在の選択行以外を右クリックした場合、その行を選択行とする.\r
344                                                         ListSelectionModel selModel = partsSetList\r
345                                                                         .getSelectionModel();\r
346                                                         selModel.setSelectionInterval(rowIndex, rowIndex);\r
347                                                 }\r
348                                         }\r
349                                 }\r
350                                 evaluatePopup(e);\r
351                         }\r
352                         @Override\r
353                         public void mouseReleased(MouseEvent e) {\r
354                                 evaluatePopup(e);\r
355                         }\r
356                         private void evaluatePopup(MouseEvent e) {\r
357                                 if (e.isPopupTrigger()) {\r
358                                         popupMenu.show(partsSetList, e.getX(), e.getY());\r
359                                 }\r
360                         }\r
361                 });\r
362 \r
363                 initListModel();\r
364 \r
365                 updateButtonUI();\r
366         }\r
367         \r
368         /**\r
369          * 現在のキャラクターデータの最新の状態でお気に入り一覧を更新する.\r
370          */\r
371         public void initListModel() {\r
372                 ArrayList<PartsSet> partssets = new ArrayList<PartsSet>();\r
373                 for (PartsSet partsset : characterData.getPartsSets().values()) {\r
374                         partssets.add(partsset);\r
375                 }\r
376                 Collections.sort(partssets, PartsSet.DEFAULT_COMPARATOR);\r
377                 partsSetListModel.setPartsSetList(partssets);\r
378         }\r
379 \r
380         protected void updateButtonUI() {\r
381                 int[] rows = partsSetList.getSelectedRows();\r
382                 actSelect.setEnabled(rows.length == 1);\r
383                 actRename.setEnabled(rows.length == 1);\r
384                 actDelete.setEnabled(rows.length >= 1);\r
385         }\r
386 \r
387         /**\r
388          * 選択されている「お気に入り」のパーツセットの一覧を取得する.<br>\r
389          * プリセットが選択されている場合、それは除外される.<br>\r
390          * \r
391          * @param beep\r
392          *            プリセットが選択されている場合にビープを鳴らすか?\r
393          * @return お気に入りのパーツセットのリスト、選択がなければ空のリスト.\r
394          */\r
395         protected List<PartsSet> getSelectedPartsSet() {\r
396                 ArrayList<PartsSet> selectedPartsSet = new ArrayList<PartsSet>();\r
397                 int[] rows = partsSetList.getSelectedRows();\r
398                 for (int row : rows) {\r
399                         PartsSet partsSet = partsSetListModel.getRow(row);\r
400                         selectedPartsSet.add(partsSet);\r
401                 }\r
402                 return selectedPartsSet;\r
403         }\r
404 \r
405         /**\r
406          * お気に入りの削除\r
407          */\r
408         protected void onDelete() {\r
409                 List<PartsSet> removePartsSet = getSelectedPartsSet();\r
410                 if (removePartsSet.isEmpty() || callback == null) {\r
411                         return;\r
412                 }\r
413 \r
414                 // 削除の確認ダイアログ\r
415                 Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()\r
416                                 .getLocalizedProperties(STRINGS_RESOURCE);\r
417 \r
418                 String msg = strings.getProperty("favorite.remove.confirm");\r
419                 JOptionPane optionPane = new JOptionPane(msg,\r
420                                 JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION) {\r
421                         private static final long serialVersionUID = 1L;\r
422                         @Override\r
423                         public void selectInitialValue() {\r
424                                 String noBtnCaption = UIManager\r
425                                                 .getString("OptionPane.noButtonText");\r
426                                 for (JButton btn : UIHelper.getInstance().getDescendantOfClass(\r
427                                                 JButton.class, this)) {\r
428                                         if (btn.getText().equals(noBtnCaption)) {\r
429                                                 // 「いいえ」ボタンにフォーカスを設定\r
430                                                 btn.requestFocus();\r
431                                         }\r
432                                 }\r
433                         }\r
434                 };\r
435                 JDialog dlg = optionPane.createDialog(ManageFavoriteDialog.this,\r
436                                 strings.getProperty("confirm.remove"));\r
437                 dlg.setVisible(true);\r
438                 Object ret = optionPane.getValue();\r
439                 if (ret == null || ((Number) ret).intValue() != JOptionPane.YES_OPTION) {\r
440                         return;\r
441                 }\r
442 \r
443                 // お気に入りリストから削除する.\r
444                 boolean dirty = false;\r
445                 boolean deletePreset = false;\r
446                 Map<String, PartsSet> partsSetMap = characterData.getPartsSets();\r
447                 for (PartsSet partsSet : removePartsSet) {\r
448                         Iterator<Map.Entry<String, PartsSet>> ite = partsSetMap.entrySet().iterator();\r
449                         while (ite.hasNext()) {\r
450                                 Map.Entry<String, PartsSet> entry = ite.next();\r
451                                 PartsSet target = entry.getValue();\r
452                                 if (target == partsSet) {\r
453                                         dirty = true;\r
454                                         if (target.isPresetParts()) {\r
455                                                 // presetを削除した場合はcharacter.xmlの更新が必要\r
456                                                 deletePreset = true;\r
457                                         }\r
458                                         ite.remove();\r
459                                 }\r
460                         }\r
461                 }\r
462                 if (dirty) {\r
463                         callback.updateFavorites(characterData, deletePreset);\r
464                         initListModel();\r
465                 }\r
466         }\r
467         \r
468         /**\r
469          * お気に入りのリネーム\r
470          */\r
471         protected void onRename() {\r
472                 int row = partsSetList.getSelectedRow();\r
473                 if (row < 0 || callback == null) {\r
474                         return;\r
475                 }\r
476                 PartsSet partsSet = partsSetListModel.getRow(row);\r
477 \r
478                 Properties strings = LocalizedResourcePropertyLoader\r
479                                 .getCachedInstance().getLocalizedProperties(STRINGS_RESOURCE);\r
480 \r
481                 String localizedName = JOptionPane.showInputDialog(this,\r
482                                 strings.getProperty("inputName"), partsSet.getLocalizedName());\r
483                 if (localizedName != null) {\r
484                         partsSet.setLocalizedName(localizedName);\r
485                         callback.updateFavorites(characterData, partsSet.isPresetParts());\r
486                         initListModel();\r
487                 }\r
488         }\r
489         \r
490         /**\r
491          * 選択したお気に入りを表示する.\r
492          */\r
493         protected void onSelect() {\r
494                 int row = partsSetList.getSelectedRow();\r
495                 if (row < 0) {\r
496                         return;\r
497                 }\r
498                 PartsSet partsSet = partsSetListModel.getRow(row);\r
499                 if (callback != null) {\r
500                         callback.selectFavorites(partsSet);\r
501                 }\r
502         }\r
503 \r
504         protected void onClose() {\r
505                 dispose();\r
506         }\r
507         \r
508         public void setFavoriteManageCallback(FavoriteManageCallback callback) {\r
509                 this.callback = callback;\r
510         }\r
511 \r
512         public FavoriteManageCallback getFavoriteManageCallback() {\r
513                 return callback;\r
514         }\r
515 }\r