1 package charactermanaj.ui;
\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
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
49 import charactermanaj.model.CharacterData;
\r
50 import charactermanaj.model.PartsSet;
\r
51 import charactermanaj.util.LocalizedResourcePropertyLoader;
\r
52 import charactermanaj.util.UIHelper;
\r
59 public class ManageFavoriteDialog extends JDialog {
\r
61 private static final long serialVersionUID = 1L;
\r
63 protected static final String STRINGS_RESOURCE = "languages/managefavoritesdialog";
\r
65 private CharacterData characterData;
\r
67 private PartsSetListTableModel partsSetListModel;
\r
69 private JTable partsSetList;
\r
71 private FavoriteManageCallback callback;
\r
73 private Action actSelect;
\r
75 private Action actDelete;
\r
77 private Action actRename;
\r
79 public static class PartsSetListTableModel extends AbstractTableModel {
\r
84 private static final long serialVersionUID = 3012538368342673506L;
\r
89 private List<PartsSet> partsSetList = Collections.emptyList();
\r
91 private enum Columns {
\r
92 DISPLAY_NAME("Name") {
\r
94 public Object getValue(PartsSet partsSet) {
\r
95 if (partsSet != null) {
\r
96 return partsSet.getLocalizedName();
\r
101 IS_PRESET("Type") {
\r
103 public Object getValue(PartsSet partsSet) {
\r
104 if (partsSet != null) {
\r
105 return partsSet.isPresetParts()
\r
113 private String columnName;
\r
115 private Columns(String columnName) {
\r
116 this.columnName = columnName;
\r
119 public Class<?> getColumnClass() {
\r
120 return String.class;
\r
123 public String getColumnName() {
\r
127 public abstract Object getValue(PartsSet partsSet);
\r
130 private static Columns[] columns = Columns.values();
\r
132 public int getColumnCount() {
\r
133 return columns.length;
\r
136 public int getRowCount() {
\r
137 return partsSetList.size();
\r
140 public Object getValueAt(int rowIndex, int columnIndex) {
\r
141 PartsSet partsSet = getRow(rowIndex);
\r
142 return columns[columnIndex].getValue(partsSet);
\r
146 public Class<?> getColumnClass(int columnIndex) {
\r
147 return columns[columnIndex].getColumnClass();
\r
151 public String getColumnName(int column) {
\r
152 return columns[column].getColumnName();
\r
155 public PartsSet getRow(int rowIndex) {
\r
156 return partsSetList.get(rowIndex);
\r
159 public void updateRow(int rowIndex, PartsSet partsSet) {
\r
160 partsSetList.set(rowIndex, partsSet);
\r
161 fireTableRowsUpdated(rowIndex, rowIndex);
\r
164 public List<PartsSet> getPartsSetList() {
\r
165 return new ArrayList<PartsSet>(partsSetList);
\r
168 public void setPartsSetList(List<PartsSet> partsSetList) {
\r
169 if (partsSetList == null) {
\r
170 partsSetList = Collections.emptyList();
\r
172 this.partsSetList = new ArrayList<PartsSet>(partsSetList);
\r
173 fireTableDataChanged();
\r
178 * パーツセットの選択および保存を行うためのコールバック.
\r
180 public interface FavoriteManageCallback {
\r
183 * 引数で指定されたパーツセットを表示する.
\r
187 void selectFavorites(PartsSet partsSet);
\r
190 * 指定したキャラクターデータのお気に入りを保存する.<br>
\r
191 * presetを変更した場合はcharacter.xmlを更新するためにsavePreset引数をtrueとする.<br>
\r
193 * @param characterData
\r
194 * お気に入りを保存するキャラクターデータ
\r
195 * @param savePreset
\r
196 * character.xmlを更新する場合(presetの更新)
\r
198 void updateFavorites(CharacterData characterData, boolean savePreset);
\r
201 public ManageFavoriteDialog(JFrame parent, CharacterData characterData) {
\r
202 super(parent, false);
\r
203 if (characterData == null) {
\r
204 throw new IllegalArgumentException();
\r
207 setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
\r
208 addWindowListener(new WindowAdapter() {
\r
210 public void windowClosing(WindowEvent e) {
\r
215 Properties strings = LocalizedResourcePropertyLoader
\r
216 .getCachedInstance()
\r
217 .getLocalizedProperties(STRINGS_RESOURCE);
\r
219 setTitle(strings.getProperty("manageFavorites"));
\r
221 this.characterData = characterData;
\r
223 characterData.getPartsSets();
\r
225 Container contentPane = getContentPane();
\r
226 contentPane.setLayout(new BorderLayout());
\r
228 partsSetListModel = new PartsSetListTableModel();
\r
229 partsSetList = new JTable(partsSetListModel);
\r
230 partsSetList.setRowSelectionAllowed(true);
\r
232 .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
\r
234 partsSetList.setTableHeader(null);
\r
235 partsSetList.getColumnModel().getColumn(1).setMaxWidth(150);
\r
237 partsSetList.getSelectionModel().addListSelectionListener(
\r
238 new ListSelectionListener() {
\r
239 public void valueChanged(ListSelectionEvent e) {
\r
244 actSelect = new AbstractAction(strings.getProperty("select")) {
\r
245 private static final long serialVersionUID = 1L;
\r
246 public void actionPerformed(ActionEvent e) {
\r
250 actDelete = new AbstractAction(strings.getProperty("remove")) {
\r
251 private static final long serialVersionUID = 1L;
\r
252 public void actionPerformed(ActionEvent e) {
\r
256 actRename = new AbstractAction(strings.getProperty("rename")) {
\r
257 private static final long serialVersionUID = 1L;
\r
258 public void actionPerformed(ActionEvent e) {
\r
263 JPanel buttonsPanel = new JPanel();
\r
264 GridBagLayout gb = new GridBagLayout();
\r
265 GridBagConstraints gbc = new GridBagConstraints();
\r
266 buttonsPanel.setLayout(gb);
\r
270 gbc.anchor = GridBagConstraints.EAST;
\r
271 gbc.fill = GridBagConstraints.BOTH;
\r
272 buttonsPanel.add(new JButton(actSelect), gbc);
\r
276 buttonsPanel.add(new JButton(actDelete), gbc);
\r
280 buttonsPanel.add(new JButton(actRename), gbc);
\r
285 buttonsPanel.add(Box.createGlue(), gbc);
\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
297 JButton btnClose = new JButton(actCancel);
\r
298 panel2.add(btnClose, BorderLayout.EAST);
\r
300 JScrollPane scr = new JScrollPane(partsSetList);
\r
301 scr.setBorder(BorderFactory.createEtchedBorder());
\r
302 scr.setPreferredSize(new Dimension(300, 150));
\r
304 contentPane.add(scr, BorderLayout.CENTER);
\r
305 contentPane.add(buttonsPanel, BorderLayout.EAST);
\r
306 contentPane.add(panel2, BorderLayout.SOUTH);
\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
320 setLocationRelativeTo(parent);
\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
327 partsSetList.addMouseListener(new MouseAdapter() {
\r
329 public void mouseClicked(MouseEvent e) {
\r
330 if (e.getClickCount() == 2) {
\r
335 public void mousePressed(MouseEvent e) {
\r
336 if (SwingUtilities.isRightMouseButton(e)) {
\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
353 public void mouseReleased(MouseEvent e) {
\r
356 private void evaluatePopup(MouseEvent e) {
\r
357 if (e.isPopupTrigger()) {
\r
358 popupMenu.show(partsSetList, e.getX(), e.getY());
\r
369 * 現在のキャラクターデータの最新の状態でお気に入り一覧を更新する.
\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
376 Collections.sort(partssets, PartsSet.DEFAULT_COMPARATOR);
\r
377 partsSetListModel.setPartsSetList(partssets);
\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
388 * 選択されている「お気に入り」のパーツセットの一覧を取得する.<br>
\r
389 * プリセットが選択されている場合、それは除外される.<br>
\r
392 * プリセットが選択されている場合にビープを鳴らすか?
\r
393 * @return お気に入りのパーツセットのリスト、選択がなければ空のリスト.
\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
402 return selectedPartsSet;
\r
408 protected void onDelete() {
\r
409 List<PartsSet> removePartsSet = getSelectedPartsSet();
\r
410 if (removePartsSet.isEmpty() || callback == null) {
\r
415 Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
\r
416 .getLocalizedProperties(STRINGS_RESOURCE);
\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
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
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
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
454 if (target.isPresetParts()) {
\r
455 // presetを削除した場合はcharacter.xmlの更新が必要
\r
456 deletePreset = true;
\r
463 callback.updateFavorites(characterData, deletePreset);
\r
471 protected void onRename() {
\r
472 int row = partsSetList.getSelectedRow();
\r
473 if (row < 0 || callback == null) {
\r
476 PartsSet partsSet = partsSetListModel.getRow(row);
\r
478 Properties strings = LocalizedResourcePropertyLoader
\r
479 .getCachedInstance().getLocalizedProperties(STRINGS_RESOURCE);
\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
493 protected void onSelect() {
\r
494 int row = partsSetList.getSelectedRow();
\r
498 PartsSet partsSet = partsSetListModel.getRow(row);
\r
499 if (callback != null) {
\r
500 callback.selectFavorites(partsSet);
\r
504 protected void onClose() {
\r
508 public void setFavoriteManageCallback(FavoriteManageCallback callback) {
\r
509 this.callback = callback;
\r
512 public FavoriteManageCallback getFavoriteManageCallback() {
\r