1 package charactermanaj.ui;
3 import java.awt.BorderLayout;
4 import java.awt.CardLayout;
6 import java.awt.Component;
7 import java.awt.Container;
8 import java.awt.Cursor;
9 import java.awt.Dimension;
11 import java.awt.GridBagConstraints;
12 import java.awt.GridBagLayout;
13 import java.awt.Insets;
14 import java.awt.Rectangle;
15 import java.awt.Toolkit;
16 import java.awt.event.ActionEvent;
17 import java.awt.event.ActionListener;
18 import java.awt.event.ComponentAdapter;
19 import java.awt.event.ComponentEvent;
20 import java.awt.event.ComponentListener;
21 import java.awt.event.KeyEvent;
22 import java.awt.event.WindowAdapter;
23 import java.awt.event.WindowEvent;
24 import java.awt.image.BufferedImage;
26 import java.io.IOException;
27 import java.io.PrintWriter;
28 import java.io.StringWriter;
29 import java.sql.Timestamp;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Collection;
33 import java.util.Collections;
34 import java.util.Comparator;
35 import java.util.HashMap;
36 import java.util.HashSet;
37 import java.util.LinkedList;
38 import java.util.List;
40 import java.util.Properties;
42 import javax.swing.AbstractAction;
43 import javax.swing.Action;
44 import javax.swing.ActionMap;
45 import javax.swing.BorderFactory;
46 import javax.swing.Box;
47 import javax.swing.BoxLayout;
48 import javax.swing.InputMap;
49 import javax.swing.JButton;
50 import javax.swing.JCheckBox;
51 import javax.swing.JComponent;
52 import javax.swing.JDialog;
53 import javax.swing.JFrame;
54 import javax.swing.JLabel;
55 import javax.swing.JOptionPane;
56 import javax.swing.JPanel;
57 import javax.swing.JPopupMenu;
58 import javax.swing.JRootPane;
59 import javax.swing.JScrollPane;
60 import javax.swing.JTable;
61 import javax.swing.JTextArea;
62 import javax.swing.JTextField;
63 import javax.swing.KeyStroke;
64 import javax.swing.ListSelectionModel;
65 import javax.swing.event.ChangeEvent;
66 import javax.swing.event.ChangeListener;
67 import javax.swing.event.TableModelEvent;
68 import javax.swing.event.TableModelListener;
69 import javax.swing.table.TableCellRenderer;
70 import javax.swing.table.TableColumnModel;
72 import charactermanaj.Main;
73 import charactermanaj.model.AppConfig;
74 import charactermanaj.model.CharacterData;
75 import charactermanaj.model.CustomLayerOrder;
76 import charactermanaj.model.CustomLayerOrderKey;
77 import charactermanaj.model.PartsCategory;
78 import charactermanaj.model.PartsIdentifier;
79 import charactermanaj.model.PartsSet;
80 import charactermanaj.model.PartsSpec;
81 import charactermanaj.model.PartsSpecResolver;
82 import charactermanaj.model.io.CharacterDataFileReaderWriterFactory;
83 import charactermanaj.model.io.CharacterDataWriter;
84 import charactermanaj.model.io.CustomLayerOrderPersist;
85 import charactermanaj.model.io.ExportInfoKeys;
86 import charactermanaj.ui.model.AbstractTableModelWithComboBoxModel;
87 import charactermanaj.ui.progress.ProgressHandle;
88 import charactermanaj.ui.progress.Worker;
89 import charactermanaj.ui.progress.WorkerException;
90 import charactermanaj.ui.progress.WorkerWithProgessDialog;
91 import charactermanaj.ui.util.ScaleSupport;
92 import charactermanaj.util.ErrorMessageHelper;
93 import charactermanaj.util.LocalizedResourcePropertyLoader;
95 public class ExportWizardDialog extends JDialog {
97 private static final long serialVersionUID = 1L;
99 protected static final String STRINGS_RESOURCE = "languages/exportwizdialog";
101 protected static ArchiveFileDialog archiveFileDialog = new ArchiveFileDialog();
103 private JPanel activePanel;
105 private AbstractAction actNext;
107 private AbstractAction actPrev;
109 private AbstractAction actFinish;
111 private ExportInformationPanel basicPanel;
113 private ExportPartsSelectPanel partsSelectPanel;
115 private ExportPresetSelectPanel presetSelectPanel;
117 private CharacterData source;
119 public static File getLastUsedDir() {
120 return archiveFileDialog.getLastUSedDir();
123 public static void setLastUsedDir(File lastUsedDir) {
124 archiveFileDialog.setLastUSedDir(lastUsedDir);
127 public ExportWizardDialog(JFrame parent, CharacterData characterData, BufferedImage samplePicture) {
129 initComponent(parent, characterData, samplePicture);
132 public ExportWizardDialog(JDialog parent, CharacterData characterData, BufferedImage samplePicture) {
134 initComponent(parent, characterData, samplePicture);
137 private void initComponent(Component parent, CharacterData characterData, BufferedImage samplePicture) {
138 if (characterData == null) {
139 throw new IllegalArgumentException();
141 this.source = characterData;
143 setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
144 addWindowListener(new WindowAdapter() {
146 public void windowClosing(WindowEvent e) {
151 Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
152 .getLocalizedProperties(STRINGS_RESOURCE);
155 setTitle(strings.getProperty("title"));
159 ScaleSupport scaleSupport = ScaleSupport.getInstance(this);
161 Container contentPane = getContentPane();
162 contentPane.setLayout(new BorderLayout());
164 final JPanel mainPanel = new JPanel();
165 mainPanel.setBorder(BorderFactory.createEtchedBorder());
166 int mergin = (int)(5 * scaleSupport.getManualScaleX());
167 final CardLayout mainPanelLayout = new CardLayout(mergin, mergin);
168 mainPanel.setLayout(mainPanelLayout);
169 contentPane.add(mainPanel, BorderLayout.CENTER);
171 ComponentListener componentListener = new ComponentAdapter() {
172 public void componentShown(ComponentEvent e) {
173 onComponentShown((JPanel) e.getComponent());
180 this.actNext = new AbstractAction(strings.getProperty("btn.next")) {
181 private static final long serialVersionUID = 1L;
182 public void actionPerformed(ActionEvent e) {
183 mainPanelLayout.next(mainPanel);
186 this.actPrev = new AbstractAction(strings.getProperty("btn.prev")) {
187 private static final long serialVersionUID = 1L;
188 public void actionPerformed(ActionEvent e) {
189 mainPanelLayout.previous(mainPanel);
192 this.actFinish = new AbstractAction(strings.getProperty("btn.finish")) {
193 private static final long serialVersionUID = 1L;
194 public void actionPerformed(ActionEvent e) {
198 AbstractAction actCancel = new AbstractAction(strings.getProperty("btn.cancel")) {
199 private static final long serialVersionUID = 1L;
200 public void actionPerformed(ActionEvent e) {
205 ChangeListener actChangeValue = new ChangeListener() {
206 public void stateChanged(ChangeEvent e) {
207 updateBtnPanelState();
211 ChangeListener actPanelEnabler = new ChangeListener() {
212 public void stateChanged(ChangeEvent e) {
218 this.basicPanel = new ExportInformationPanel(characterData, samplePicture, scaleSupport);
219 this.basicPanel.addComponentListener(componentListener);
220 this.basicPanel.addChangeListener(actChangeValue);
221 this.basicPanel.addChangeListener(actPanelEnabler);
222 mainPanel.add(this.basicPanel, "basicPanel");
224 // panel2 : panelSelectPanel
225 this.partsSelectPanel = new ExportPartsSelectPanel(characterData, scaleSupport);
226 this.partsSelectPanel.addComponentListener(componentListener);
227 this.partsSelectPanel.addChangeListener(actChangeValue);
228 mainPanel.add(this.partsSelectPanel, "partsSelectPanel");
230 // panel3 : presetSelectPanel
231 this.presetSelectPanel = new ExportPresetSelectPanel(
232 this.partsSelectPanel,
234 characterData.getPartsSets().values(),
235 characterData.getDefaultPartsSetId(),
237 this.presetSelectPanel.addComponentListener(componentListener);
238 this.presetSelectPanel.addChangeListener(actChangeValue);
239 mainPanel.add(this.presetSelectPanel, "presetSelectPanel");
244 JPanel btnPanel = new JPanel();
245 int gap = (int)(3 * scaleSupport.getManualScaleX());
246 btnPanel.setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap * 15)); // 3, 3, 3, 45
247 GridBagLayout btnPanelLayout = new GridBagLayout();
248 btnPanel.setLayout(btnPanelLayout);
250 actPrev.setEnabled(false);
251 actNext.setEnabled(false);
252 actFinish.setEnabled(false);
254 GridBagConstraints gbc = new GridBagConstraints();
260 gbc.anchor = GridBagConstraints.EAST;
261 gbc.fill = GridBagConstraints.BOTH;
264 gbc.insets = new Insets(gap, gap, gap, gap);
267 btnPanel.add(Box.createHorizontalGlue(), gbc);
269 gbc.gridx = Main.isLinuxOrMacOSX() ? 2 : 1;
272 btnPanel.add(new JButton(this.actPrev), gbc);
274 gbc.gridx = Main.isLinuxOrMacOSX() ? 3 : 2;
276 JButton btnNext = new JButton(this.actNext);
277 btnPanel.add(btnNext, gbc);
279 gbc.gridx = Main.isLinuxOrMacOSX() ? 4 : 3;
281 btnPanel.add(new JButton(this.actFinish), gbc);
283 gbc.gridx = Main.isLinuxOrMacOSX() ? 1 : 4;
285 JButton btnCancel = new JButton(actCancel);
286 btnPanel.add(btnCancel, gbc);
288 contentPane.add(btnPanel, BorderLayout.SOUTH);
292 Toolkit tk = Toolkit.getDefaultToolkit();
293 JRootPane rootPane = getRootPane();
295 rootPane.setDefaultButton(btnNext);
297 InputMap im = rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
298 ActionMap am = rootPane.getActionMap();
299 im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "closeExportWizDialog");
300 im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, tk.getMenuShortcutKeyMask()), "closeExportWizDialog");
301 am.put("closeExportWizDialog", actCancel);
305 // HiDpi環境でのスケールを考慮したウィンドウサイズに補正する
306 setSize(scaleSupport.manualScaled(new Dimension(500, 500)));
307 setLocationRelativeTo(parent);
309 mainPanelLayout.first(mainPanel);
310 updateBtnPanelState();
314 protected void onComponentShown(JPanel panel) {
316 updateBtnPanelState();
319 protected void updatePanelStatus() {
320 partsSelectPanel.setEnabled(basicPanel.isExportPartsImages());
321 presetSelectPanel.setEnabled(basicPanel.isExportPresets());
324 protected void updateBtnPanelState() {
325 actPrev.setEnabled(activePanel != null && activePanel != basicPanel);
326 actNext.setEnabled(activePanel != null && activePanel != presetSelectPanel);
327 actFinish.setEnabled(isComplete());
330 protected void checkMissingParts(Collection<PartsSet> partaSets) {
331 if (partaSets == null) {
332 partaSets = presetSelectPanel.getSelectedPresets();
334 partsSelectPanel.checkMissingPartsList(partaSets);
337 protected boolean isComplete() {
339 if (basicPanel.isExportPartsImages()) {
340 if (partsSelectPanel.getSelectedCount() == 0) {
341 // パーツイメージのエクスポートを指定した場合、エクスポートするパーツの選択は必須
345 if (basicPanel.isExportPresets()) {
346 if (presetSelectPanel.getSelectedCount() == 0) {
347 // プリセットのエクスポートを指定した場合、エクスポートするプリセットの選択は必須
355 protected void onClose() {
356 Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
357 .getLocalizedProperties(ExportWizardDialog.STRINGS_RESOURCE);
359 if (JOptionPane.showConfirmDialog(this,
360 strings.getProperty("confirm.close"),
361 strings.getProperty("confirm"),
362 JOptionPane.YES_NO_OPTION,
363 JOptionPane.QUESTION_MESSAGE) != JOptionPane.YES_OPTION) {
370 protected void onFinish() {
372 Toolkit tk = Toolkit.getDefaultToolkit();
378 final File outFile = archiveFileDialog.showSaveDialog(this);
379 if (outFile == null) {
384 setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
386 Worker<Object> worker = new Worker<Object>() {
387 public Object doWork(ProgressHandle progressHandle) throws IOException {
393 WorkerWithProgessDialog<Object> dlg
394 = new WorkerWithProgessDialog<Object>(this, worker);
398 setCursor(Cursor.getDefaultCursor());
402 Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
403 .getLocalizedProperties(ExportWizardDialog.STRINGS_RESOURCE);
404 JOptionPane.showMessageDialog(this, strings.getProperty("complete"));
409 } catch (WorkerException ex) {
410 ErrorMessageHelper.showErrorDialog(this, ex.getCause());
412 } catch (Exception ex) {
413 ErrorMessageHelper.showErrorDialog(this, ex);
417 protected void doExport(File outFile) throws IOException {
418 CharacterDataFileReaderWriterFactory writerFactory = CharacterDataFileReaderWriterFactory.getInstance();
419 CharacterDataWriter exportWriter = writerFactory.createWriter(outFile);
421 // 基本情報のみをコピーし、これをエクスポートするキャラクター定義のベースとする。
422 // (プリセットとパーツイメージはリセットされている状態。)
423 CharacterData cd = source.duplicateBasicInfo();
424 cd.clearPartsSets(false);
426 boolean exportPresets = basicPanel.isExportPresets();
427 boolean exportSamplePicture = basicPanel.isExportSamplePicture();
428 boolean exportCharacterData = true;
429 boolean exportPartsImages = basicPanel.isExportPartsImages();
432 cd.setAuthor(basicPanel.getAuthor());
433 cd.setDescription(basicPanel.getDescription());
436 Properties exportProp = new Properties();
437 exportProp.setProperty(ExportInfoKeys.EXPORT_PRESETS, Boolean.toString(exportPresets));
438 exportProp.setProperty(ExportInfoKeys.EXPORT_SAMPLE_PICTURE, Boolean.toString(exportSamplePicture));
439 exportProp.setProperty(ExportInfoKeys.EXPORT_CHARACTER_DATA, Boolean.toString(exportCharacterData));
440 exportProp.setProperty(ExportInfoKeys.EXPORT_PARTS_IMAGES, Boolean.toString(exportPartsImages));
441 exportProp.setProperty(ExportInfoKeys.EXPORT_TIMESTAMP, Long.toString(System.currentTimeMillis()));
443 exportWriter.writeExportProp(exportProp);
445 // プリセットをエクスポートする場合、プリセット情報を登録する.
447 HashSet<String> registered = new HashSet<String>();
448 for (PartsSet partsSet : presetSelectPanel.getSelectedPresets()) {
449 registered.add(partsSet.getPartsSetId());
450 cd.addPartsSet(partsSet);
452 // プリセットとして登録済みのもののみ既定に設定可能
453 String defaultPresetId = presetSelectPanel.getDefaultPresetId();
454 if (registered.contains(defaultPresetId)) {
455 cd.setDefaultPartsSetId(defaultPresetId);
460 exportWriter.writeCharacterData(cd);
462 // カスタムレイヤーパターンを出力する(有効であれば)
463 if (cd.isEnableCustonLayerPattern()) {
464 Map<CustomLayerOrderKey, List<CustomLayerOrder>> customLayerPatternMap = CustomLayerOrderPersist
465 .newInstance(cd).load();
466 if (customLayerPatternMap != null) {
467 exportWriter.writeCustomLayerPatterns(customLayerPatternMap);
472 String readmeContents = cd.getDescription();
473 if (readmeContents != null && readmeContents.trim().length() > 0) {
474 AppConfig appConfig = AppConfig.getInstance();
475 StringWriter sw = new StringWriter();
476 PrintWriter pw = new PrintWriter(sw);
477 pw.println("exported by CharacterManaJ (version "
478 + appConfig.getSpecificationVersion() + " "
479 + appConfig.getImplementationVersion() + ")");
481 pw.println(readmeContents);
483 exportWriter.writeTextUTF16LE("readme.txt", sw.toString());
487 if (exportSamplePicture) {
488 BufferedImage pic = null;
489 pic = basicPanel.getSamplePicture();
491 exportWriter.writeSamplePicture(pic);
495 if (exportPartsImages) {
496 Map<PartsIdentifier, PartsSpec> partsSpecMap = partsSelectPanel.getSelectedParts();
499 exportWriter.writePartsManageData(partsSpecMap);
502 exportWriter.writePartsImages(partsSpecMap);
506 exportWriter.close();
511 interface ExportResolverBase {
513 void addChangeListener(ChangeListener l);
515 void removeChangeListener(ChangeListener l);
525 interface ExportInformationResolver extends ExportResolverBase {
527 BufferedImage getSamplePicture();
529 boolean isExportSamplePicture();
531 boolean isExportPartsImages();
533 boolean isExportPresets();
537 String getDescription();
540 abstract class AbstractImportPanel extends JPanel implements ExportResolverBase {
542 private static final long serialVersionUID = 1L;
544 protected LinkedList<ChangeListener> listeners = new LinkedList<ChangeListener>();
546 public void addChangeListener(ChangeListener l) {
552 public void removeChangeListener(ChangeListener l) {
558 protected void fireChangeEvent() {
559 ChangeEvent e = new ChangeEvent(this);
560 for (ChangeListener listener : listeners) {
561 listener.stateChanged(e);
570 class ExportInformationPanel extends AbstractImportPanel implements ExportInformationResolver {
572 private static final long serialVersionUID = 1L;
574 private BufferedImage samplePicture;
576 private SamplePicturePanel sampleImagePanel;
578 private JTextField txtAuthor;
580 private JTextArea txtDescription;
582 private JCheckBox chkPartsImages;
584 private JCheckBox chkPresets;
586 private JCheckBox chkSampleImage;
590 protected ExportInformationPanel(final CharacterData characterData, final BufferedImage samplePicture,
591 ScaleSupport scaleSupport) {
592 if (characterData == null) {
593 throw new IllegalArgumentException();
596 setName("basicPanel");
597 this.samplePicture = samplePicture;
599 Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
600 .getLocalizedProperties(ExportWizardDialog.STRINGS_RESOURCE);
602 GridBagLayout basicPanelLayout = new GridBagLayout();
603 GridBagConstraints gbc = new GridBagConstraints();
604 setLayout(basicPanelLayout);
606 JPanel contentsSpecPanel = new JPanel();
607 int mergin = (int)(5 * scaleSupport.getManualScaleX());
608 contentsSpecPanel.setBorder(BorderFactory.createCompoundBorder(
609 BorderFactory.createEmptyBorder(mergin, mergin, mergin, mergin),
610 BorderFactory.createTitledBorder(strings.getProperty("basic.contentsSpec"))));
611 BoxLayout contentsSpecPanelLayout = new BoxLayout(contentsSpecPanel, BoxLayout.PAGE_AXIS);
612 contentsSpecPanel.setLayout(contentsSpecPanelLayout);
614 JCheckBox chkCharacterDef = new JCheckBox(strings.getProperty("characterdef"));
615 chkPartsImages = new JCheckBox(strings.getProperty("basic.chk.partsImages"));
616 chkPresets = new JCheckBox(strings.getProperty("basic.chk.presets"));
617 chkSampleImage = new JCheckBox(strings.getProperty("basic.chk.samplePicture"));
619 chkCharacterDef.setEnabled(false); // キャラクター定義は固定
620 chkCharacterDef.setSelected(true);
622 contentsSpecPanel.add(chkCharacterDef);
623 contentsSpecPanel.add(chkPartsImages);
624 contentsSpecPanel.add(chkPresets);
625 contentsSpecPanel.add(chkSampleImage);
629 JPanel commentPanel = new JPanel();
630 Dimension archiveInfoPanelMinSize = scaleSupport.manualScaled(new Dimension(300, 200));
631 commentPanel.setMinimumSize(archiveInfoPanelMinSize);
632 commentPanel.setPreferredSize(archiveInfoPanelMinSize);
633 commentPanel.setBorder(BorderFactory.createCompoundBorder(
634 BorderFactory.createEmptyBorder(mergin, mergin, mergin, mergin),
635 BorderFactory.createTitledBorder(strings.getProperty("basic.comment"))));
636 GridBagLayout commentPanelLayout = new GridBagLayout();
637 commentPanel.setLayout(commentPanelLayout);
645 int gap = (int)(3 * scaleSupport.getManualScaleX());
646 gbc.insets = new Insets(gap, gap, gap, gap);
647 gbc.anchor = GridBagConstraints.WEST;
648 gbc.fill = GridBagConstraints.BOTH;
649 commentPanel.add(new JLabel(strings.getProperty("author"), JLabel.RIGHT), gbc);
656 txtAuthor = new JTextField();
657 commentPanel.add(txtAuthor, gbc);
665 commentPanel.add(new JLabel(strings.getProperty("description"), JLabel.RIGHT), gbc);
673 txtDescription = new JTextArea();
674 commentPanel.add(new JScrollPane(txtDescription), gbc);
678 sampleImagePanel = new SamplePicturePanel(samplePicture);
679 sampleImagePanel.setBorder(BorderFactory.createCompoundBorder(
680 BorderFactory.createEmptyBorder(mergin, mergin, mergin, mergin),
681 BorderFactory.createTitledBorder(strings.getProperty("basic.sampleImage"))));
692 gbc.anchor = GridBagConstraints.WEST;
693 gbc.fill = GridBagConstraints.BOTH;
694 add(contentsSpecPanel, gbc);
702 gbc.anchor = GridBagConstraints.WEST;
703 gbc.fill = GridBagConstraints.BOTH;
704 add(commentPanel, gbc);
712 gbc.anchor = GridBagConstraints.WEST;
713 gbc.fill = GridBagConstraints.BOTH;
714 add(sampleImagePanel, gbc);
716 loadBasicInfo(characterData);
720 ActionListener modListener = new ActionListener() {
721 public void actionPerformed(ActionEvent e) {
722 updateSamplePicture();
726 chkPartsImages.addActionListener(modListener);
727 chkPresets.addActionListener(modListener);
728 chkSampleImage.addActionListener(modListener);
731 protected void updateSamplePicture() {
732 sampleImagePanel.setVisiblePicture(chkSampleImage.isSelected());
735 protected void loadBasicInfo(CharacterData characterData) {
736 if (samplePicture == null) {
737 // サンプルイメージがなければディセーブル
738 chkSampleImage.setEnabled(false);
739 chkSampleImage.setSelected(false);
740 sampleImagePanel.setVisiblePicture(false);
742 chkSampleImage.setSelected(true);
743 sampleImagePanel.setVisiblePicture(true);
745 chkPartsImages.setSelected(true);
746 chkPresets.setSelected(true);
748 String author = characterData.getAuthor();
749 String description = characterData.getDescription();
750 txtAuthor.setText(author == null ? "" : author);
751 txtDescription.setText(description == null ? "" : description);
754 public BufferedImage getSamplePicture() {
755 return samplePicture;
758 public boolean isExportSamplePicture() {
759 return chkSampleImage.isSelected();
762 public boolean isExportPartsImages() {
763 return chkPartsImages.isSelected();
766 public boolean isExportPresets() {
767 return chkPresets.isSelected();
770 public String getAuthor() {
771 return txtAuthor.getText();
774 public String getDescription() {
775 return txtDescription.getText();
783 interface ExportPartsResolver extends ExportResolverBase {
785 int getSelectedCount();
787 void selectByPartsSet(Collection<PartsSet> partsSet);
789 Map<PartsIdentifier, PartsSpec> getSelectedParts();
791 Map<PartsSet, List<PartsIdentifier>> checkMissingPartsList(Collection<PartsSet> partsSets);
799 class ExportPartsSelectPanel extends AbstractImportPanel implements ExportPartsResolver {
801 private static final long serialVersionUID = 1L;
803 private ExportPartsTableModel partsTableModel;
805 private JTable partsTable;
807 private Action actSelectAll;
809 private Action actDeselectAll;
811 private Action actSort;
813 private Action actSortByTimestamp;
815 protected ExportPartsSelectPanel(PartsSpecResolver partsSpecResolver, ScaleSupport scaleSupport) {
816 if (partsSpecResolver == null) {
817 throw new IllegalArgumentException();
820 Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
821 .getLocalizedProperties(ExportWizardDialog.STRINGS_RESOURCE);
823 setName("choosePartsPanel");
824 setBorder(BorderFactory.createTitledBorder(strings.getProperty("parts.title")));
826 setLayout(new BorderLayout());
828 partsTableModel = new ExportPartsTableModel();
830 partsTableModel.addTableModelListener(new TableModelListener() {
831 public void tableChanged(TableModelEvent e) {
836 loadPartsInfo(partsSpecResolver);
838 AppConfig appConfig = AppConfig.getInstance();
840 final Color disabledForeground = appConfig.getDisabledCellForgroundColor();
842 partsTable = new JTable(partsTableModel) {
843 private static final long serialVersionUID = 1L;
845 public Component prepareRenderer(TableCellRenderer renderer,
846 int row, int column) {
847 Component comp = super.prepareRenderer(renderer, row, column);
848 if (comp instanceof JCheckBox) {
849 // BooleanのデフォルトのレンダラーはKCheckBoxを継承したJTable$BooleanRenderer
850 comp.setEnabled(isCellEditable(row, column) && isEnabled());
852 comp.setForeground(isEnabled() ?
853 (isCellSelected(row,column) ? getSelectionForeground() : getForeground())
854 : disabledForeground);
858 partsTable.setShowGrid(true);
859 partsTable.setGridColor(appConfig.getGridColor());
860 partsTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
861 partsTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
862 partsTable.setRowSelectionAllowed(true);
865 partsTable.setRowHeight((int)(partsTable.getFont().getSize() * 1.2));
868 partsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
869 partsTableModel.adjustColumnModel(partsTable.getColumnModel(), scaleSupport.getManualScaleX());
871 Action actPartsSetCheck = new AbstractAction(strings.getProperty("parts.popup.check")) {
872 private static final long serialVersionUID = 1L;
873 public void actionPerformed(ActionEvent e) {
874 int[] selRows = partsTable.getSelectedRows();
875 partsTableModel.setCheck(selRows, true);
878 Action actPartsUnsetCheck = new AbstractAction(strings.getProperty("parts.popup.uncheck")) {
879 private static final long serialVersionUID = 1L;
880 public void actionPerformed(ActionEvent e) {
881 int[] selRows = partsTable.getSelectedRows();
882 partsTableModel.setCheck(selRows, false);
886 final JPopupMenu partsTablePopupMenu = new JPopupMenu();
887 partsTablePopupMenu.add(actPartsSetCheck);
888 partsTablePopupMenu.add(actPartsUnsetCheck);
890 partsTable.setComponentPopupMenu(partsTablePopupMenu);
892 add(new JScrollPane(partsTable), BorderLayout.CENTER);
894 actSelectAll = new AbstractAction(strings.getProperty("parts.btn.selectAll")) {
895 private static final long serialVersionUID = 1L;
896 public void actionPerformed(ActionEvent e) {
900 actDeselectAll = new AbstractAction(strings.getProperty("parts.btn.deselectAll")) {
901 private static final long serialVersionUID = 1L;
902 public void actionPerformed(ActionEvent e) {
906 actSort = new AbstractAction(strings.getProperty("parts.btn.sort")) {
907 private static final long serialVersionUID = 1L;
908 public void actionPerformed(ActionEvent e) {
912 actSortByTimestamp = new AbstractAction(strings.getProperty("parts.btn.sortByTimestamp")) {
913 private static final long serialVersionUID = 1L;
914 public void actionPerformed(ActionEvent e) {
920 JPanel btnPanel = new JPanel();
921 GridBagLayout btnPanelLayout = new GridBagLayout();
922 btnPanel.setLayout(btnPanelLayout);
924 GridBagConstraints gbc = new GridBagConstraints();
930 gbc.anchor = GridBagConstraints.EAST;
931 gbc.fill = GridBagConstraints.BOTH;
932 int gap = (int)(3 * scaleSupport.getManualScaleX());
933 gbc.insets = new Insets(gap, gap, gap, gap);
936 JButton btnSelectAll = new JButton(actSelectAll);
937 btnPanel.add(btnSelectAll, gbc);
941 JButton btnDeselectAll = new JButton(actDeselectAll);
942 btnPanel.add(btnDeselectAll, gbc);
946 JButton btnSort = new JButton(actSort);
947 btnPanel.add(btnSort, gbc);
951 JButton btnSortByTimestamp = new JButton(actSortByTimestamp);
952 btnPanel.add(btnSortByTimestamp, gbc);
957 btnPanel.add(Box.createHorizontalGlue(), gbc);
959 add(btnPanel, BorderLayout.SOUTH);
962 protected void loadPartsInfo(PartsSpecResolver partsSpecResolver) {
963 partsTableModel.clear();
964 for (PartsCategory partsCategory : partsSpecResolver.getPartsCategories()) {
965 Map<PartsIdentifier, PartsSpec> partsSpecMap = partsSpecResolver.getPartsSpecMap(partsCategory);
966 for (Map.Entry<PartsIdentifier, PartsSpec> entry : partsSpecMap.entrySet()) {
967 PartsIdentifier partsIdentifier = entry.getKey();
968 PartsSpec partsSpec = entry.getValue();
969 ExportPartsSelectModel model = new ExportPartsSelectModel(partsIdentifier, partsSpec, false);
970 partsTableModel.addRow(model);
973 partsTableModel.sort();
976 protected void onSelectAll() {
977 partsTableModel.selectAll();
980 protected void onDeselectAll() {
981 partsTableModel.deselectAll();
984 protected void onSort() {
985 partsTableModel.sort();
986 if (partsTableModel.getRowCount() > 0) {
987 Rectangle rct = partsTable.getCellRect(0, 0, true);
988 partsTable.scrollRectToVisible(rct);
992 protected void onSortByTimestamp() {
993 partsTableModel.sortByTimestamp();
994 if (partsTableModel.getRowCount() > 0) {
995 Rectangle rct = partsTable.getCellRect(0, 0, true);
996 partsTable.scrollRectToVisible(rct);
1000 public Map<PartsIdentifier, PartsSpec> getSelectedParts() {
1001 return partsTableModel.getSelectedParts();
1004 public Map<PartsSet, List<PartsIdentifier>> checkMissingPartsList(Collection<PartsSet> partsSets) {
1005 return partsTableModel.checkMissingPartsList(partsSets);
1008 public void selectByPartsSet(Collection<PartsSet> partsSets) {
1009 partsTableModel.selectByPartsSet(partsSets);
1012 public int getSelectedCount() {
1013 return partsTableModel.getSelectedCount();
1017 public void setEnabled(boolean enabled) {
1018 partsTable.setEnabled(enabled);
1019 partsTableModel.setEnabled(enabled);
1020 actSelectAll.setEnabled(enabled);
1021 actDeselectAll.setEnabled(enabled);
1022 super.setEnabled(enabled);
1027 interface ExportPresetResolve extends ExportResolverBase {
1029 int getSelectedCount();
1031 List<PartsSet> getSelectedPresets();
1034 class ExportPresetSelectPanel extends AbstractImportPanel implements ExportPresetResolve {
1036 private static final long serialVersionUID = 1L;
1038 private ExportPartsResolver exportPartsResolver;
1040 private ExportPresetTableModel presetTableModel;
1042 private JTable presetTable;
1044 private Action actSelectAll;
1046 private Action actDeselectAll;
1049 protected ExportPresetSelectPanel(
1050 final ExportPartsResolver exportPartsResolver,
1051 final ExportInformationResolver exportInfoResolver,
1052 Collection<PartsSet> partsSets, String defaultPresetId,
1053 ScaleSupport scaleSupport) {
1055 this.exportPartsResolver = exportPartsResolver;
1057 setName("presetSelectPanel");
1059 Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
1060 .getLocalizedProperties(ExportWizardDialog.STRINGS_RESOURCE);
1062 setName("choosePartsPanel");
1063 setBorder(BorderFactory.createTitledBorder(strings.getProperty("preset.title")));
1065 setLayout(new BorderLayout());
1067 presetTableModel = new ExportPresetTableModel();
1069 presetTableModel.addTableModelListener(new TableModelListener() {
1070 public void tableChanged(TableModelEvent e) {
1071 if (e.getType() == TableModelEvent.UPDATE) {
1076 exportPartsResolver.addChangeListener(new ChangeListener() {
1077 public void stateChanged(ChangeEvent e) {
1078 checkMissingParts();
1082 loadPresetInfo(partsSets, defaultPresetId);
1084 AppConfig appConfig = AppConfig.getInstance();
1085 final Color warningForegroundColor = appConfig.getExportPresetWarningsForegroundColor();
1086 final Color disabledForeground = appConfig.getDisabledCellForgroundColor();
1088 presetTable = new JTable(presetTableModel) {
1089 private static final long serialVersionUID = 1L;
1091 public Component prepareRenderer(TableCellRenderer renderer,
1092 int row, int column) {
1093 Component comp = super.prepareRenderer(renderer, row, column);
1095 if (comp instanceof JCheckBox) {
1096 // BooleanのデフォルトのレンダラーはKCheckBoxを継承したJTable$BooleanRenderer
1097 comp.setEnabled(isCellEditable(row, column) && isEnabled());
1100 ExportPresetModel presetModel = presetTableModel.getRow(row);
1101 if (presetModel.isPresetParts()) {
1102 comp.setFont(getFont().deriveFont(Font.BOLD));
1104 comp.setFont(getFont());
1108 comp.setForeground(disabledForeground);
1111 if (presetModel.isSelected() && presetModel.getMissingPartsIdentifiers().size() > 0) {
1112 comp.setForeground(warningForegroundColor);
1114 comp.setForeground(getForeground());
1120 presetTable.setShowGrid(true);
1121 presetTable.setGridColor(appConfig.getGridColor());
1122 presetTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
1125 presetTable.setRowHeight((int)(presetTable.getFont().getSize() * 1.2));
1128 presetTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
1129 presetTableModel.adjustColumnModel(presetTable.getColumnModel(), scaleSupport.getManualScaleX());
1131 final Action actSelectUsedParts = new AbstractAction(
1132 strings.getProperty("preset.popup.selectUsedParts")) {
1133 private static final long serialVersionUID = 1L;
1134 public void actionPerformed(ActionEvent e) {
1139 final JPopupMenu popupMenu = new JPopupMenu();
1140 popupMenu.add(actSelectUsedParts);
1142 presetTable.setComponentPopupMenu(popupMenu);
1145 add(new JScrollPane(presetTable), BorderLayout.CENTER);
1147 actSelectAll = new AbstractAction(strings.getProperty("parts.btn.selectAll")) {
1148 private static final long serialVersionUID = 1L;
1149 public void actionPerformed(ActionEvent e) {
1153 actDeselectAll = new AbstractAction(strings.getProperty("parts.btn.deselectAll")) {
1154 private static final long serialVersionUID = 1L;
1155 public void actionPerformed(ActionEvent e) {
1159 Action actSort = new AbstractAction(strings.getProperty("parts.btn.sort")) {
1160 private static final long serialVersionUID = 1L;
1161 public void actionPerformed(ActionEvent e) {
1167 JPanel btnPanel = new JPanel();
1168 GridBagLayout btnPanelLayout = new GridBagLayout();
1169 btnPanel.setLayout(btnPanelLayout);
1171 GridBagConstraints gbc = new GridBagConstraints();
1177 gbc.anchor = GridBagConstraints.EAST;
1178 gbc.fill = GridBagConstraints.BOTH;
1179 int gap = (int)(3 * scaleSupport.getManualScaleX());
1180 gbc.insets = new Insets(gap, gap, gap, gap);
1183 JButton btnSelectAll = new JButton(actSelectAll);
1184 btnPanel.add(btnSelectAll, gbc);
1188 JButton btnDeselectAll = new JButton(actDeselectAll);
1189 btnPanel.add(btnDeselectAll, gbc);
1193 JButton btnSort = new JButton(actSort);
1194 btnPanel.add(btnSort, gbc);
1199 btnPanel.add(Box.createHorizontalGlue(), gbc);
1201 add(btnPanel, BorderLayout.SOUTH);
1204 protected void loadPresetInfo(Collection<PartsSet> partsSets, String defaultPresetId) {
1205 presetTableModel.clear();
1206 for (PartsSet orgPartsSet : partsSets) {
1207 PartsSet partsSet = orgPartsSet.clone();
1208 ExportPresetModel model = new ExportPresetModel(partsSet, partsSet.isPresetParts());
1209 presetTableModel.addRow(model);
1211 presetTableModel.setDefaultPresetId(defaultPresetId);
1212 presetTableModel.sort();
1213 checkMissingParts();
1216 public void checkMissingParts() {
1217 ArrayList<PartsSet> changedPartsSets = new ArrayList<PartsSet>();
1218 HashMap<PartsSet, ExportPresetModel> partsSetModelMap = new HashMap<PartsSet, ExportPresetModel>();
1219 int mx = presetTableModel.getRowCount();
1220 for (int idx = 0; idx < mx; idx++) {
1221 ExportPresetModel presetModel = presetTableModel.getRow(idx);
1222 PartsSet partsSet = presetModel.getPartsSet();
1223 partsSetModelMap.put(partsSet, presetModel);
1224 changedPartsSets.add(partsSet);
1226 Map<PartsSet, List<PartsIdentifier>> missingPartsIdentifiersMap = exportPartsResolver
1227 .checkMissingPartsList(changedPartsSets);
1228 for (Map.Entry<PartsSet, List<PartsIdentifier>> entry : missingPartsIdentifiersMap.entrySet()) {
1229 PartsSet partsSet = entry.getKey();
1230 List<PartsIdentifier> missingPartsIdentifiers = entry.getValue();
1231 ExportPresetModel presetModel = partsSetModelMap.get(partsSet);
1232 presetModel.setMissingPartsIdentifiers(missingPartsIdentifiers);
1234 if (!missingPartsIdentifiersMap.isEmpty()) {
1235 presetTableModel.fireTableDataChanged();
1239 protected void onSelectAll() {
1240 presetTableModel.selectAll();
1243 protected void onDeselectAll() {
1244 presetTableModel.deselectAll();
1247 protected void onSort() {
1248 presetTableModel.sort();
1249 if (presetTableModel.getRowCount() > 0) {
1250 Rectangle rct = presetTable.getCellRect(0, 0, true);
1251 presetTable.scrollRectToVisible(rct);
1255 public List<PartsSet> getSelectedPresets() {
1256 return presetTableModel.getSelectedPresets();
1259 protected void exportUsedParts() {
1260 ArrayList<PartsSet> partsSets = new ArrayList<PartsSet>();
1261 int[] selRows = presetTable.getSelectedRows();
1262 for (int selRow : selRows) {
1263 ExportPresetModel presetModel = presetTableModel.getRow(selRow);
1264 partsSets.add(presetModel.getPartsSet());
1267 exportPartsResolver.selectByPartsSet(partsSets);
1270 public int getSelectedCount() {
1271 return presetTableModel.getSelectedCount();
1274 public String getDefaultPresetId() {
1275 return presetTableModel.getDefaultPresetId();
1279 public void setEnabled(boolean enabled) {
1280 this.presetTable.setEnabled(enabled);
1281 this.presetTableModel.setEnabled(enabled);
1282 this.actSelectAll.setEnabled(enabled);
1283 this.actDeselectAll.setEnabled(enabled);
1284 super.setEnabled(enabled);
1290 class ExportPartsTableModel extends AbstractTableModelWithComboBoxModel<ExportPartsSelectModel> {
1292 private static final long serialVersionUID = 1L;
1294 private static final String[] columnNames;
1296 private static final int[] columnWidths;
1298 private boolean enabled = true;
1301 Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
1302 .getLocalizedProperties(ExportWizardDialog.STRINGS_RESOURCE);
1304 columnNames = new String[] {
1305 strings.getProperty("parts.column.selected"),
1306 strings.getProperty("parts.column.category"),
1307 strings.getProperty("parts.column.name"),
1308 strings.getProperty("parts.column.timestamp"),
1309 strings.getProperty("parts.column.author"),
1310 strings.getProperty("parts.column.version"),
1313 columnWidths = new int[] {
1314 Integer.parseInt(strings.getProperty("parts.column.selected.width")),
1315 Integer.parseInt(strings.getProperty("parts.column.category.width")),
1316 Integer.parseInt(strings.getProperty("parts.column.name.width")),
1317 Integer.parseInt(strings.getProperty("parts.column.timestamp.width")),
1318 Integer.parseInt(strings.getProperty("parts.column.author.width")),
1319 Integer.parseInt(strings.getProperty("parts.column.version.width")),
1323 public void adjustColumnModel(TableColumnModel columnModel, double scale) {
1324 for (int idx = 0; idx < columnWidths.length; idx++) {
1325 columnModel.getColumn(idx).setPreferredWidth((int)(columnWidths[idx] * scale));
1329 public int getColumnCount() {
1330 return columnNames.length;
1334 public String getColumnName(int column) {
1335 return columnNames[column];
1338 public Object getValueAt(int rowIndex, int columnIndex) {
1339 ExportPartsSelectModel partsSelectModel = getRow(rowIndex);
1340 switch (columnIndex) {
1342 return Boolean.valueOf(partsSelectModel.isChecked() && enabled);
1344 return partsSelectModel.getPartsCategory().getLocalizedCategoryName();
1346 return partsSelectModel.getPartsName();
1348 Timestamp tm = partsSelectModel.getTimestamp();
1350 return tm.toString();
1354 return partsSelectModel.getAuthor();
1356 return partsSelectModel.getVersion();
1363 public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
1364 ExportPartsSelectModel partsSelectModel = getRow(rowIndex);
1365 switch (columnIndex) {
1367 partsSelectModel.setChecked(((Boolean) aValue).booleanValue());
1372 fireTableRowsUpdated(rowIndex, rowIndex);
1376 public boolean isCellEditable(int rowIndex, int columnIndex) {
1377 if (columnIndex == 0) {
1384 public Class<?> getColumnClass(int columnIndex) {
1385 switch (columnIndex) {
1387 return Boolean.class;
1389 return String.class;
1391 return String.class;
1393 return String.class;
1396 return String.class;
1399 public void sort() {
1400 Collections.sort(elements);
1401 fireTableDataChanged();
1404 public void sortByTimestamp() {
1405 Collections.sort(elements, new Comparator<ExportPartsSelectModel>() {
1406 public int compare(ExportPartsSelectModel o1, ExportPartsSelectModel o2) {
1408 Timestamp t1 = o1.getTimestamp();
1409 Timestamp t2 = o2.getTimestamp();
1410 if (t1 == null || t2 == null) {
1411 if (t1 == null && t2 == null) {
1413 } else if (t1 == null) {
1419 ret = t2.compareTo(t1); // 逆順(日付の新しいもの順)
1422 ret = o1.compareTo(o2);
1427 fireTableDataChanged();
1430 public void selectAll() {
1431 for (ExportPartsSelectModel model : elements) {
1432 model.setChecked(true);
1434 fireTableDataChanged();
1437 public void deselectAll() {
1438 for (ExportPartsSelectModel model : elements) {
1439 model.setChecked(false);
1441 fireTableDataChanged();
1445 * 選択されているパーツイメージのマップを返す.<br>
1446 * @return 選択されているパーツイメージのマップ
1448 public Map<PartsIdentifier, PartsSpec> getSelectedParts() {
1449 HashMap<PartsIdentifier, PartsSpec> selectedPartsMap = new HashMap<PartsIdentifier, PartsSpec>();
1450 for (ExportPartsSelectModel partsSelectModel : elements) {
1451 if (partsSelectModel.isChecked() && isEnabled()) {
1452 selectedPartsMap.put(partsSelectModel.getPartsIdentifier(), partsSelectModel.getPartsSpec());
1455 return selectedPartsMap;
1459 * パーツセットのコレクションを指定し、パーツセットの各パーツがすべてエクスポート対象になっているものだけを返す.<br>
1460 * @param partsSets パーツセットのリスト
1461 * @return 不足しているパーツセットと、その不足しているパーツリストを返す.
1463 public Map<PartsSet, List<PartsIdentifier>> checkMissingPartsList(Collection<PartsSet> partsSets) {
1464 if (partsSets == null) {
1465 throw new IllegalArgumentException();
1467 Map<PartsIdentifier, PartsSpec> selectedPartsMap = getSelectedParts();
1468 HashMap<PartsSet, List<PartsIdentifier>> missingPartsMap = new HashMap<PartsSet, List<PartsIdentifier>>();
1470 for (PartsSet partsSet : partsSets) {
1471 ArrayList<PartsIdentifier> missingPartss = new ArrayList<PartsIdentifier>();
1472 for (List<PartsIdentifier> partsIdentifiers : partsSet.values()) {
1473 for (PartsIdentifier requirePartsIdentifier : partsIdentifiers) {
1474 if (!selectedPartsMap.containsKey(requirePartsIdentifier)) {
1475 missingPartss.add(requirePartsIdentifier);
1479 Collections.sort(missingPartss);
1480 missingPartsMap.put(partsSet, missingPartss);
1483 return missingPartsMap;
1487 * パーツセットで使用されているパーツを選択状態にする.
1488 * @param partsSet パーツセットのコレクション
1490 public void selectByPartsSet(Collection<PartsSet> partsSets) {
1491 if (partsSets == null) {
1492 throw new IllegalArgumentException();
1494 HashSet<PartsIdentifier> requirePartsIdentifiers = new HashSet<PartsIdentifier>();
1495 for (PartsSet partsSet : partsSets) {
1496 for (List<PartsIdentifier> partsIdentifiers : partsSet.values()) {
1497 for (PartsIdentifier partsIdentifier : partsIdentifiers) {
1498 requirePartsIdentifiers.add(partsIdentifier);
1502 for (ExportPartsSelectModel partsSelectModel : elements) {
1503 if (requirePartsIdentifiers.contains(partsSelectModel.getPartsIdentifier())) {
1504 partsSelectModel.setChecked(true);
1507 fireTableDataChanged();
1514 public int getSelectedCount() {
1516 for (ExportPartsSelectModel partsSelectModel : elements) {
1517 if (partsSelectModel.isChecked() && isEnabled()) {
1524 public void setEnabled(boolean enabled) {
1525 if (this.enabled != enabled) {
1526 this.enabled = enabled;
1527 fireTableDataChanged();
1531 public boolean isEnabled() {
1535 public void setCheck(int[] selRows, boolean checked) {
1536 if (selRows == null || selRows.length == 0) {
1539 Arrays.sort(selRows);
1540 for (int selRow : selRows) {
1541 ExportPartsSelectModel rowModel = getRow(selRow);
1542 rowModel.setChecked(checked);
1544 fireTableRowsUpdated(selRows[0], selRows[selRows.length - 1]);
1549 class ExportPartsSelectModel implements Comparable<ExportPartsSelectModel> {
1551 private boolean checked;
1553 private PartsIdentifier partsIdentifier;
1555 private PartsSpec partsSpec;
1557 private Timestamp timestamp;
1559 public ExportPartsSelectModel(PartsIdentifier partsIdentifier, PartsSpec partsSpec, boolean selected) {
1560 if (partsIdentifier == null || partsSpec == null) {
1561 throw new IllegalArgumentException();
1563 this.partsIdentifier = partsIdentifier;
1564 this.partsSpec = partsSpec;
1565 this.checked = selected;
1567 long maxLastModified = partsSpec.getPartsFiles().lastModified();
1568 if (maxLastModified > 0) {
1569 timestamp = new Timestamp(maxLastModified);
1576 public int hashCode() {
1577 return partsIdentifier.hashCode();
1581 public boolean equals(Object obj) {
1585 if (obj != null && obj instanceof ExportPartsSelectModel) {
1586 ExportPartsSelectModel o = (ExportPartsSelectModel) obj;
1587 return partsIdentifier.equals(o.partsIdentifier);
1592 public int compareTo(ExportPartsSelectModel o) {
1593 int ret = (checked ? 0 : 1) - (o.checked ? 0 : 1); // 逆順
1595 ret = partsIdentifier.compareTo(o.partsIdentifier);
1600 public PartsIdentifier getPartsIdentifier() {
1601 return this.partsIdentifier;
1604 public PartsSpec getPartsSpec() {
1605 return this.partsSpec;
1608 public boolean isChecked() {
1612 public void setChecked(boolean checked) {
1613 this.checked = checked;
1616 public PartsCategory getPartsCategory() {
1617 return this.partsIdentifier.getPartsCategory();
1620 public String getPartsName() {
1621 return this.partsIdentifier.getLocalizedPartsName();
1624 public Timestamp getTimestamp() {
1625 return timestamp == null ? null : (Timestamp) timestamp.clone();
1628 public String getAuthor() {
1629 return partsSpec.getAuthor();
1632 public String getVersion() {
1633 double version = partsSpec.getVersion();
1637 return Double.toString(version);
1642 class ExportPresetTableModel extends AbstractTableModelWithComboBoxModel<ExportPresetModel> {
1644 private static final long serialVersionUID = 1L;
1646 private static final String[] columnNames;
1648 private static final int[] columnWidths;
1650 private boolean enabled = true;
1653 Properties strings = LocalizedResourcePropertyLoader.getCachedInstance()
1654 .getLocalizedProperties(ExportWizardDialog.STRINGS_RESOURCE);
1656 columnNames = new String[] {
1657 strings.getProperty("preset.column.selected"),
1658 strings.getProperty("preset.column.default"),
1659 strings.getProperty("preset.column.name"),
1660 strings.getProperty("preset.column.missingparts"),
1663 columnWidths = new int[] {
1664 Integer.parseInt(strings.getProperty("preset.column.selected.width")),
1665 Integer.parseInt(strings.getProperty("preset.column.default.width")),
1666 Integer.parseInt(strings.getProperty("preset.column.name.width")),
1667 Integer.parseInt(strings.getProperty("preset.column.missingparts.width")),
1671 private String defaultPresetId;
1673 public void adjustColumnModel(TableColumnModel columnModel, double scale) {
1674 for (int idx = 0; idx < columnWidths.length; idx++) {
1675 columnModel.getColumn(idx).setPreferredWidth((int)(columnWidths[idx] * scale));
1679 public int getColumnCount() {
1680 return columnNames.length;
1684 public String getColumnName(int column) {
1685 return columnNames[column];
1688 public Object getValueAt(int rowIndex, int columnIndex) {
1689 ExportPresetModel presetModel = getRow(rowIndex);
1690 switch (columnIndex) {
1692 return Boolean.valueOf(presetModel.isSelected() && isEnabled());
1694 return Boolean.valueOf(presetModel.getPartsSet().getPartsSetId().equals(defaultPresetId) && isEnabled());
1696 return presetModel.getPartsSetName();
1698 StringBuilder buf = new StringBuilder();
1699 for (PartsIdentifier partsIdentifier : presetModel.getMissingPartsIdentifiers()) {
1700 if (buf.length() > 0) {
1703 buf.append(partsIdentifier.getLocalizedPartsName());
1705 return buf.toString();
1712 public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
1713 ExportPresetModel presetModel = getRow(rowIndex);
1714 switch (columnIndex) {
1716 if (((Boolean) aValue).booleanValue()) {
1717 presetModel.setSelected(true);
1719 presetModel.setSelected(false);
1720 if (presetModel.getPartsSet().getPartsSetId().equals(defaultPresetId)) {
1721 // 選択解除したものが既定のパーツセットであった場合、既定も解除する.
1722 defaultPresetId = null;
1723 fireTableRowsUpdated(rowIndex, rowIndex);
1729 if (((Boolean) aValue).booleanValue()) {
1730 defaultPresetId = presetModel.getPartsSet().getPartsSetId();
1731 presetModel.setSelected(true); // 既定のパーツセットにした場合は自動的にエクスポート対象にもする。
1732 fireTableDataChanged();
1738 fireTableRowsUpdated(rowIndex, rowIndex);
1742 public Class<?> getColumnClass(int columnIndex) {
1743 switch (columnIndex) {
1745 return Boolean.class;
1747 return Boolean.class;
1749 return String.class;
1751 return String.class;
1754 return String.class;
1758 public boolean isCellEditable(int rowIndex, int columnIndex) {
1759 if (columnIndex == 0 || columnIndex == 1) {
1765 public void sort() {
1766 Collections.sort(elements);
1767 fireTableDataChanged();
1770 public void selectAll() {
1771 for (ExportPresetModel model : elements) {
1772 model.setSelected(true);
1774 fireTableDataChanged();
1777 public void deselectAll() {
1778 for (ExportPresetModel model : elements) {
1779 model.setSelected(false);
1781 fireTableDataChanged();
1785 * 選択されているパーツセットのリストを返す.<br>
1787 * @return 選択されているパーツセットのリスト
1789 public List<PartsSet> getSelectedPresets() {
1790 ArrayList<PartsSet> partsSets = new ArrayList<PartsSet>();
1791 for (ExportPresetModel presetModel : elements) {
1792 if (presetModel.isSelected() && isEnabled()) {
1793 PartsSet partsSet = presetModel.getPartsSet().clone();
1794 partsSet.setPresetParts(true);
1795 partsSets.add(partsSet);
1801 public int getSelectedCount() {
1803 for (ExportPresetModel presetModel : elements) {
1804 if (presetModel.isSelected() && isEnabled()) {
1811 public String getDefaultPresetId() {
1812 return defaultPresetId;
1816 * デフォルトのプリセットを設定する.<br>
1817 * @param defaultPresetId
1819 public void setDefaultPresetId(String defaultPresetId) {
1820 this.defaultPresetId = defaultPresetId;
1823 public void setEnabled(boolean enabled) {
1824 if (this.enabled != enabled) {
1825 this.enabled = enabled;
1826 fireTableDataChanged();
1830 public boolean isEnabled() {
1835 class ExportPresetModel implements Comparable<ExportPresetModel> {
1837 private boolean selected;
1839 private PartsSet partsSet;
1841 private List<PartsIdentifier> missingPartsIdentifiers;
1843 public ExportPresetModel(PartsSet partsSet, boolean selected) {
1844 if (partsSet == null) {
1845 throw new IllegalArgumentException();
1847 this.partsSet = partsSet;
1848 this.selected = selected;
1852 public int hashCode() {
1853 return partsSet.hashCode();
1857 public boolean equals(Object obj) {
1861 if (obj != null && obj instanceof ExportPresetModel) {
1862 ExportPresetModel o = (ExportPresetModel) obj;
1863 return partsSet.equals(o.partsSet);
1868 public int compareTo(ExportPresetModel o) {
1869 int ret = (selected ? 0 : 1) - (o.selected ? 0 : 1);
1871 ret = getPartsSetName().compareTo(o.getPartsSetName());
1876 public String getPartsSetName() {
1877 String name = partsSet.getLocalizedName();
1878 return name == null ? "" : name;
1881 public boolean isPresetParts() {
1882 return partsSet.isPresetParts();
1885 public boolean isSelected() {
1889 public void setSelected(boolean selected) {
1890 this.selected = selected;
1893 public PartsSet getPartsSet() {
1897 public void setMissingPartsIdentifiers(
1898 List<PartsIdentifier> missingPartsIdentifiers) {
1899 this.missingPartsIdentifiers = Collections.unmodifiableList(missingPartsIdentifiers);
1902 public List<PartsIdentifier> getMissingPartsIdentifiers() {
1903 if (missingPartsIdentifiers == null) {
1904 return Collections.emptyList();
1906 return missingPartsIdentifiers;