• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

テキストの各行をキーと値に分離し、複数テキストファイルを読み込み、キーを突き合わせ照合し、その結果を表示するGUIユーテリティです。


Commit MetaInfo

修訂f430af4474148ef1f60c1cd29d54671edf26b3be (tree)
時間2011-11-06 03:26:26
作者seraphy <seraphy@dime...>
Commiterseraphy

Log Message

・ データのマージ

Change Summary

差異

--- a/src/textkeymatcher/entity/KeyMatchedRowMap.java
+++ b/src/textkeymatcher/entity/KeyMatchedRowMap.java
@@ -94,6 +94,19 @@ public class KeyMatchedRowMap extends AbstractMap<RowKey, RowValues> {
9494 public LineDataList getLineDataList(int idx) {
9595 return lineDataLists.get(idx);
9696 }
97+
98+ /**
99+ * 指定されたインデックスのデータソースを設定する.<br>
100+ * インデックスは既存のデータの範囲内でなければなりません.<br>
101+ * @param idx インデックス
102+ * @param lineDataList データソース
103+ */
104+ public void setLineDataList(int idx, LineDataList lineDataList) {
105+ if (lineDataList == null) {
106+ throw new IllegalArgumentException();
107+ }
108+ lineDataLists.set(idx, lineDataList);
109+ }
97110
98111 /**
99112 * データソースのタイトルを取得する.<br>
--- /dev/null
+++ b/src/textkeymatcher/service/LineDataListMergeService.java
@@ -0,0 +1,54 @@
1+/*
2+ * To change this template, choose Tools | Templates
3+ * and open the template in the editor.
4+ */
5+package textkeymatcher.service;
6+
7+import java.util.ArrayList;
8+import textkeymatcher.entity.AbstractLineDataList;
9+import textkeymatcher.entity.LineData;
10+import textkeymatcher.entity.LineDataList;
11+
12+/**
13+ * データソースをマージします.<br>
14+ * @author seraphy
15+ */
16+public class LineDataListMergeService {
17+
18+ /**
19+ * ベースとなるデータソースに、指定したデータソースの内容をマージした結果を返します.<br>
20+ * 元となるデータは変更されません.<br>
21+ * @param base マージされるデータ
22+ * @param source マージするデータ、nullの場合は空とみなす.
23+ */
24+ public LineDataList merge(final LineDataList base, final LineDataList source) {
25+ if (base == null) {
26+ throw new IllegalArgumentException();
27+ }
28+
29+ final ArrayList<LineData> results = new ArrayList<LineData>();
30+
31+ results.addAll(base);
32+ if (source != null) {
33+ results.addAll(source);
34+ }
35+
36+ return new AbstractLineDataList() {
37+ @Override
38+ public String getTitle() {
39+ return base.getTitle();
40+ }
41+
42+ @Override
43+ public LineData get(int index) {
44+ return results.get(index);
45+ }
46+
47+ @Override
48+ public int size() {
49+ return results.size();
50+ }
51+ };
52+ }
53+
54+}
--- a/src/textkeymatcher/ui/TextKeyMatcherView.form
+++ b/src/textkeymatcher/ui/TextKeyMatcherView.form
@@ -142,7 +142,9 @@
142142 </MenuItem>
143143 <MenuItem class="javax.swing.JMenuItem" name="mergeMenuItem">
144144 <Properties>
145- <Property name="mnemonic" type="int" value="77"/>
145+ <Property name="action" type="javax.swing.Action" editor="org.netbeans.modules.swingapp.ActionEditor">
146+ <action class="textkeymatcher.ui.TextKeyMatcherView" id="onMergeColumn" methodName="onMergeColumn"/>
147+ </Property>
146148 <Property name="text" type="java.lang.String" resourceKey="mergeMenuItem.text"/>
147149 <Property name="name" type="java.lang.String" value="mergeMenuItem" noResource="true"/>
148150 </Properties>
@@ -470,6 +472,115 @@
470472 </Component>
471473 </SubComponents>
472474 </Container>
475+ <Container class="javax.swing.JPanel" name="confirmMergeColumnPanel">
476+ <Properties>
477+ <Property name="name" type="java.lang.String" value="confirmMergeColumnPanel" noResource="true"/>
478+ </Properties>
479+
480+ <Layout>
481+ <DimensionLayout dim="0">
482+ <Group type="103" groupAlignment="0" attributes="0">
483+ <Group type="102" attributes="0">
484+ <EmptySpace max="-2" attributes="0"/>
485+ <Group type="103" groupAlignment="0" attributes="0">
486+ <Group type="102" attributes="0">
487+ <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
488+ <EmptySpace type="separate" max="-2" attributes="0"/>
489+ <Component id="baseColumnCombo" pref="189" max="32767" attributes="0"/>
490+ </Group>
491+ <Group type="102" alignment="0" attributes="0">
492+ <Component id="jLabel2" min="-2" max="-2" attributes="0"/>
493+ <EmptySpace type="unrelated" max="-2" attributes="0"/>
494+ <Group type="103" groupAlignment="0" attributes="0">
495+ <Component id="removeAfterMergedCheckbox" alignment="0" min="-2" max="-2" attributes="0"/>
496+ <Component id="replaceBaseCheckBox" alignment="0" min="-2" max="-2" attributes="0"/>
497+ <Component id="mergeColumnCombo" alignment="1" pref="195" max="32767" attributes="0"/>
498+ </Group>
499+ </Group>
500+ </Group>
501+ <EmptySpace min="-2" pref="14" max="-2" attributes="0"/>
502+ </Group>
503+ </Group>
504+ </DimensionLayout>
505+ <DimensionLayout dim="1">
506+ <Group type="103" groupAlignment="0" attributes="0">
507+ <Group type="102" alignment="0" attributes="0">
508+ <EmptySpace max="-2" attributes="0"/>
509+ <Group type="103" groupAlignment="3" attributes="0">
510+ <Component id="jLabel1" alignment="3" min="-2" max="-2" attributes="0"/>
511+ <Component id="baseColumnCombo" alignment="3" min="-2" max="-2" attributes="0"/>
512+ </Group>
513+ <EmptySpace max="-2" attributes="0"/>
514+ <Component id="replaceBaseCheckBox" min="-2" max="-2" attributes="0"/>
515+ <EmptySpace pref="6" max="32767" attributes="0"/>
516+ <Group type="103" groupAlignment="3" attributes="0">
517+ <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
518+ <Component id="mergeColumnCombo" alignment="3" min="-2" max="-2" attributes="0"/>
519+ </Group>
520+ <EmptySpace max="-2" attributes="0"/>
521+ <Component id="removeAfterMergedCheckbox" min="-2" max="-2" attributes="0"/>
522+ <EmptySpace min="-2" pref="10" max="-2" attributes="0"/>
523+ </Group>
524+ </Group>
525+ </DimensionLayout>
526+ </Layout>
527+ <SubComponents>
528+ <Component class="javax.swing.JLabel" name="jLabel1">
529+ <Properties>
530+ <Property name="text" type="java.lang.String" resourceKey="jLabel1.text"/>
531+ <Property name="name" type="java.lang.String" value="jLabel1" noResource="true"/>
532+ </Properties>
533+ </Component>
534+ <Component class="javax.swing.JLabel" name="jLabel2">
535+ <Properties>
536+ <Property name="text" type="java.lang.String" resourceKey="jLabel2.text"/>
537+ <Property name="name" type="java.lang.String" value="jLabel2" noResource="true"/>
538+ </Properties>
539+ </Component>
540+ <Component class="javax.swing.JComboBox" name="baseColumnCombo">
541+ <Properties>
542+ <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
543+ <StringArray count="4">
544+ <StringItem index="0" value="Item 1"/>
545+ <StringItem index="1" value="Item 2"/>
546+ <StringItem index="2" value="Item 3"/>
547+ <StringItem index="3" value="Item 4"/>
548+ </StringArray>
549+ </Property>
550+ <Property name="name" type="java.lang.String" value="baseColumnCombo" noResource="true"/>
551+ </Properties>
552+ </Component>
553+ <Component class="javax.swing.JComboBox" name="mergeColumnCombo">
554+ <Properties>
555+ <Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
556+ <StringArray count="4">
557+ <StringItem index="0" value="Item 1"/>
558+ <StringItem index="1" value="Item 2"/>
559+ <StringItem index="2" value="Item 3"/>
560+ <StringItem index="3" value="Item 4"/>
561+ </StringArray>
562+ </Property>
563+ <Property name="name" type="java.lang.String" value="mergeColumnCombo" noResource="true"/>
564+ </Properties>
565+ </Component>
566+ <Component class="javax.swing.JCheckBox" name="removeAfterMergedCheckbox">
567+ <Properties>
568+ <Property name="selected" type="boolean" value="true"/>
569+ <Property name="text" type="java.lang.String" resourceKey="removeAfterMergedCheckbox.text"/>
570+ <Property name="name" type="java.lang.String" value="removeAfterMergedCheckbox" noResource="true"/>
571+ </Properties>
572+ </Component>
573+ <Component class="javax.swing.JCheckBox" name="replaceBaseCheckBox">
574+ <Properties>
575+ <Property name="selected" type="boolean" value="true"/>
576+ <Property name="text" type="java.lang.String" resourceKey="replaceBaseCheckBox.text"/>
577+ <Property name="name" type="java.lang.String" value="replaceBaseCheckBox" noResource="true"/>
578+ </Properties>
579+ </Component>
580+ </SubComponents>
581+ </Container>
582+ <Component class="textkeymatcher.service.LineDataListMergeService" name="lineDataListMergeService">
583+ </Component>
473584 </NonVisualComponents>
474585 <Properties>
475586 <Property name="component" type="javax.swing.JComponent" editor="org.netbeans.modules.form.ComponentChooserEditor">
--- a/src/textkeymatcher/ui/TextKeyMatcherView.java
+++ b/src/textkeymatcher/ui/TextKeyMatcherView.java
@@ -23,6 +23,7 @@ import java.awt.event.InputEvent;
2323 import java.awt.event.KeyEvent;
2424 import java.io.File;
2525 import java.util.ArrayList;
26+import java.util.List;
2627 import java.util.logging.Level;
2728 import java.util.logging.Logger;
2829 import javax.swing.DefaultComboBoxModel;
@@ -347,6 +348,14 @@ public class TextKeyMatcherView extends FrameView implements ExitListener {
347348 confirmRemoveColumnPanel = new javax.swing.JPanel();
348349 removeColumnLabel = new javax.swing.JLabel();
349350 removeColumnComboBox = new javax.swing.JComboBox();
351+ confirmMergeColumnPanel = new javax.swing.JPanel();
352+ jLabel1 = new javax.swing.JLabel();
353+ jLabel2 = new javax.swing.JLabel();
354+ baseColumnCombo = new javax.swing.JComboBox();
355+ mergeColumnCombo = new javax.swing.JComboBox();
356+ removeAfterMergedCheckbox = new javax.swing.JCheckBox();
357+ replaceBaseCheckBox = new javax.swing.JCheckBox();
358+ lineDataListMergeService = new textkeymatcher.service.LineDataListMergeService();
350359
351360 mainPanel.setName("mainPanel"); // NOI18N
352361
@@ -418,7 +427,7 @@ public class TextKeyMatcherView extends FrameView implements ExitListener {
418427 removeMenuItem.setName("removeMenuItem"); // NOI18N
419428 dataMenu.add(removeMenuItem);
420429
421- mergeMenuItem.setMnemonic('M');
430+ mergeMenuItem.setAction(actionMap.get("onMergeColumn")); // NOI18N
422431 mergeMenuItem.setText(resourceMap.getString("mergeMenuItem.text")); // NOI18N
423432 mergeMenuItem.setName("mergeMenuItem"); // NOI18N
424433 dataMenu.add(mergeMenuItem);
@@ -582,7 +591,7 @@ public class TextKeyMatcherView extends FrameView implements ExitListener {
582591 statusPanelLayout.setHorizontalGroup(
583592 statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
584593 .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, statusPanelLayout.createSequentialGroup()
585- .addComponent(statusMessageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 225, Short.MAX_VALUE)
594+ .addComponent(statusMessageLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE)
586595 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
587596 .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
588597 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
@@ -615,6 +624,66 @@ public class TextKeyMatcherView extends FrameView implements ExitListener {
615624 removeColumnComboBox.setName("removeColumnComboBox"); // NOI18N
616625 confirmRemoveColumnPanel.add(removeColumnComboBox, java.awt.BorderLayout.CENTER);
617626
627+ confirmMergeColumnPanel.setName("confirmMergeColumnPanel"); // NOI18N
628+
629+ jLabel1.setText(resourceMap.getString("jLabel1.text")); // NOI18N
630+ jLabel1.setName("jLabel1"); // NOI18N
631+
632+ jLabel2.setText(resourceMap.getString("jLabel2.text")); // NOI18N
633+ jLabel2.setName("jLabel2"); // NOI18N
634+
635+ baseColumnCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
636+ baseColumnCombo.setName("baseColumnCombo"); // NOI18N
637+
638+ mergeColumnCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
639+ mergeColumnCombo.setName("mergeColumnCombo"); // NOI18N
640+
641+ removeAfterMergedCheckbox.setSelected(true);
642+ removeAfterMergedCheckbox.setText(resourceMap.getString("removeAfterMergedCheckbox.text")); // NOI18N
643+ removeAfterMergedCheckbox.setName("removeAfterMergedCheckbox"); // NOI18N
644+
645+ replaceBaseCheckBox.setSelected(true);
646+ replaceBaseCheckBox.setText(resourceMap.getString("replaceBaseCheckBox.text")); // NOI18N
647+ replaceBaseCheckBox.setName("replaceBaseCheckBox"); // NOI18N
648+
649+ javax.swing.GroupLayout confirmMergeColumnPanelLayout = new javax.swing.GroupLayout(confirmMergeColumnPanel);
650+ confirmMergeColumnPanel.setLayout(confirmMergeColumnPanelLayout);
651+ confirmMergeColumnPanelLayout.setHorizontalGroup(
652+ confirmMergeColumnPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
653+ .addGroup(confirmMergeColumnPanelLayout.createSequentialGroup()
654+ .addContainerGap()
655+ .addGroup(confirmMergeColumnPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
656+ .addGroup(confirmMergeColumnPanelLayout.createSequentialGroup()
657+ .addComponent(jLabel1)
658+ .addGap(18, 18, 18)
659+ .addComponent(baseColumnCombo, 0, 189, Short.MAX_VALUE))
660+ .addGroup(confirmMergeColumnPanelLayout.createSequentialGroup()
661+ .addComponent(jLabel2)
662+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
663+ .addGroup(confirmMergeColumnPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
664+ .addComponent(removeAfterMergedCheckbox)
665+ .addComponent(replaceBaseCheckBox)
666+ .addComponent(mergeColumnCombo, javax.swing.GroupLayout.Alignment.TRAILING, 0, 195, Short.MAX_VALUE))))
667+ .addGap(14, 14, 14))
668+ );
669+ confirmMergeColumnPanelLayout.setVerticalGroup(
670+ confirmMergeColumnPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
671+ .addGroup(confirmMergeColumnPanelLayout.createSequentialGroup()
672+ .addContainerGap()
673+ .addGroup(confirmMergeColumnPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
674+ .addComponent(jLabel1)
675+ .addComponent(baseColumnCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
676+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
677+ .addComponent(replaceBaseCheckBox)
678+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 6, Short.MAX_VALUE)
679+ .addGroup(confirmMergeColumnPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
680+ .addComponent(jLabel2)
681+ .addComponent(mergeColumnCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
682+ .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
683+ .addComponent(removeAfterMergedCheckbox)
684+ .addGap(10, 10, 10))
685+ );
686+
618687 setComponent(mainPanel);
619688 setMenuBar(menuBar);
620689 setStatusBar(statusPanel);
@@ -735,6 +804,7 @@ public class TextKeyMatcherView extends FrameView implements ExitListener {
735804 checkEnableSave();
736805 checkEnableNew();
737806 checkEnableRemoveColumn();
807+ checkEnableMergeColumn();
738808 statusMessageLabel.setText("done.");
739809 }
740810 }
@@ -801,6 +871,7 @@ public class TextKeyMatcherView extends FrameView implements ExitListener {
801871 checkEnableSave();
802872 checkEnableNew();
803873 checkEnableRemoveColumn();
874+ checkEnableMergeColumn();
804875
805876 statusMessageLabel.setText("initialized.");
806877 }
@@ -845,6 +916,7 @@ public class TextKeyMatcherView extends FrameView implements ExitListener {
845916 checkEnableSave();
846917 checkEnableNew();
847918 checkEnableRemoveColumn();
919+ checkEnableMergeColumn();
848920 }
849921
850922
@@ -898,20 +970,11 @@ public class TextKeyMatcherView extends FrameView implements ExitListener {
898970 @Override
899971 String toString();
900972 }
901-
902- /**
903- * カラムの削除アクション
904- */
905- @Action(enabledProperty = "enableRemoveColumn")
906- public void onRemoveColumn() {
907- int mx = dataViewTableModel.getNumOfLineDataLists();
908- if (mx <= 1) {
909- // 最低2列以上なければ削除できない.
910- return;
911- }
912-
973+
974+ private List<LineDataListItemDisplay> getAllColumns() {
913975 // カラム一覧を作成する.
914- ArrayList<Object> items = new ArrayList<Object>();
976+ ArrayList<LineDataListItemDisplay> items = new ArrayList<LineDataListItemDisplay>();
977+ int mx = dataViewTableModel.getNumOfLineDataLists();
915978 for (int idx = 0; idx < mx; idx++) {
916979 final LineDataList lineDataList = dataViewTableModel.getLineDataList(idx);
917980 final int selIdx = idx;
@@ -934,8 +997,22 @@ public class TextKeyMatcherView extends FrameView implements ExitListener {
934997 };
935998 items.add(item);
936999 }
1000+ return items;
1001+ }
1002+
1003+ /**
1004+ * カラムの削除アクション
1005+ */
1006+ @Action(enabledProperty = "enableRemoveColumn")
1007+ public void onRemoveColumn() {
1008+ int mx = dataViewTableModel.getNumOfLineDataLists();
1009+ if (mx <= 1) {
1010+ // 最低2列以上なければ削除できない.
1011+ return;
1012+ }
9371013
9381014 // ドロップダウンコンボの表示
1015+ List<LineDataListItemDisplay> items = getAllColumns();
9391016 DefaultComboBoxModel comboboxModel = new DefaultComboBoxModel(
9401017 items.toArray(new Object[items.size()]));
9411018
@@ -946,7 +1023,7 @@ public class TextKeyMatcherView extends FrameView implements ExitListener {
9461023 JOptionPane.PLAIN_MESSAGE,
9471024 JOptionPane.YES_NO_OPTION
9481025 );
949- JDialog dlg = optionPane.createDialog(getFrame(), "CONFIRM");
1026+ JDialog dlg = optionPane.createDialog(getFrame(), "REMOVE");
9501027 dlg.setResizable(true);
9511028 dlg.setModal(true);
9521029 dlg.setVisible(true);
@@ -975,6 +1052,93 @@ public class TextKeyMatcherView extends FrameView implements ExitListener {
9751052 checkEnableSave();
9761053 checkEnableNew();
9771054 checkEnableRemoveColumn();
1055+ checkEnableMergeColumn();
1056+ }
1057+
1058+ /**
1059+ * カラムのマージアクション
1060+ */
1061+ @Action(enabledProperty = "enableMergeColumn")
1062+ public void onMergeColumn() {
1063+ int mx = dataViewTableModel.getNumOfLineDataLists();
1064+ if (mx < 1) {
1065+ // 最低1列以上なければ削除できない.
1066+ return;
1067+ }
1068+
1069+ // ドロップダウンコンボの表示
1070+ List<LineDataListItemDisplay> items = getAllColumns();
1071+
1072+ DefaultComboBoxModel baseColumnComboModel = new DefaultComboBoxModel(
1073+ items.toArray(new Object[items.size()]));
1074+ baseColumnCombo.setModel(baseColumnComboModel);
1075+
1076+ DefaultComboBoxModel mergeColumnComboModel = new DefaultComboBoxModel(
1077+ items.toArray(new Object[items.size()]));
1078+ mergeColumnCombo.setModel(mergeColumnComboModel);
1079+
1080+ JOptionPane optionPane = new JOptionPane(
1081+ confirmMergeColumnPanel,
1082+ JOptionPane.PLAIN_MESSAGE,
1083+ JOptionPane.YES_NO_OPTION
1084+ );
1085+ JDialog dlg = optionPane.createDialog(getFrame(), "MERGE");
1086+ dlg.setResizable(true);
1087+ dlg.setModal(true);
1088+ dlg.setVisible(true);
1089+
1090+ Number ret = (Number) optionPane.getValue();
1091+ if (ret == null || ret.intValue() != JOptionPane.YES_OPTION) {
1092+ // キャンセルされた場合
1093+ return;
1094+ }
1095+
1096+ // ドロップダウンで選択されたデータソースの取得
1097+ LineDataListItemDisplay selBaseItem =
1098+ (LineDataListItemDisplay) baseColumnCombo.getSelectedItem();
1099+ LineDataListItemDisplay selMergeItem =
1100+ (LineDataListItemDisplay) mergeColumnCombo.getSelectedItem();
1101+ if (selBaseItem == null || selMergeItem == null) {
1102+ return;
1103+ }
1104+
1105+ boolean replace = replaceBaseCheckBox.isSelected();
1106+ boolean remove = removeAfterMergedCheckbox.isSelected();
1107+
1108+ int baseColumnIdx = selBaseItem.getIndex();
1109+ int mergeColumnIdx = selMergeItem.getIndex();
1110+
1111+ // マージする.
1112+ LineDataList baseColumn = selBaseItem.get();
1113+ LineDataList mergeColumn = selBaseItem.get();
1114+
1115+ LineDataList merged = lineDataListMergeService.merge(baseColumn, mergeColumn);
1116+
1117+ // マージ結果の更新(置換する場合)
1118+ if (replace) {
1119+ dataViewTableModel.setLineDataList(baseColumnIdx, merged);
1120+ }
1121+
1122+ // モデルからカラムの削除
1123+ if (remove) {
1124+ if (!replace || (baseColumnIdx != mergeColumnIdx)) {
1125+ // 同じカラム同士の場合はカラムの削除をしない.
1126+ // (ただし元カラムがコピーされる場合は除く)
1127+ dataViewTableModel.removeLineDataList(mergeColumnIdx);
1128+ }
1129+ }
1130+
1131+ // マージ結果の追加(追加の場合)
1132+ // (削除時のインデックスがずれないように最後に追加する.)
1133+ if (!replace) {
1134+ dataViewTableModel.addLineDataList(merged);
1135+ }
1136+
1137+ // メニューの更新
1138+ checkEnableSave();
1139+ checkEnableNew();
1140+ checkEnableRemoveColumn();
1141+ checkEnableMergeColumn();
9781142 }
9791143
9801144 private void checkEnableSave() {
@@ -988,6 +1152,11 @@ public class TextKeyMatcherView extends FrameView implements ExitListener {
9881152 }
9891153
9901154 private void checkEnableRemoveColumn() {
1155+ boolean hasDataSource = dataViewTableModel.getNumOfLineDataLists() > 0;
1156+ setEnableMergeColumn(hasDataSource);
1157+ }
1158+
1159+ private void checkEnableMergeColumn() {
9911160 // key/valueはペアであるため、最低1列は残す必要があるため、2以上の場合のみ削除可能.
9921161 boolean hasDataSource = dataViewTableModel.getNumOfLineDataLists() > 1;
9931162 setEnableRemoveColumn(hasDataSource);
@@ -1026,8 +1195,21 @@ public class TextKeyMatcherView extends FrameView implements ExitListener {
10261195 firePropertyChange("enableRemoveColumn", old, isEnableRemoveColumn());
10271196 }
10281197
1198+ private boolean enableMergeColumn = false;
1199+ public boolean isEnableMergeColumn() {
1200+ return enableMergeColumn;
1201+ }
1202+
1203+ public void setEnableMergeColumn(boolean b) {
1204+ boolean old = isEnableMergeColumn();
1205+ this.enableMergeColumn = b;
1206+ firePropertyChange("enableMergeColumn", old, isEnableMergeColumn());
1207+ }
1208+
10291209 // Variables declaration - do not modify//GEN-BEGIN:variables
10301210 private javax.swing.JRadioButtonMenuItem allRadioButtonMenuItem;
1211+ private javax.swing.JComboBox baseColumnCombo;
1212+ private javax.swing.JPanel confirmMergeColumnPanel;
10311213 private javax.swing.JPanel confirmRemoveColumnPanel;
10321214 private javax.swing.JMenu dataMenu;
10331215 private javax.swing.JTable dataViewTable;
@@ -1036,6 +1218,8 @@ public class TextKeyMatcherView extends FrameView implements ExitListener {
10361218 private textkeymatcher.ui.model.DisplayModeBinder displayModeBinder;
10371219 private javax.swing.JRadioButtonMenuItem existsLeftRadioButtonMenuItem;
10381220 private javax.swing.JMenu helpMenu;
1221+ private javax.swing.JLabel jLabel1;
1222+ private javax.swing.JLabel jLabel2;
10391223 private javax.swing.JRadioButtonMenuItem jRadioButtonMenuItem1;
10401224 private javax.swing.JRadioButtonMenuItem jRadioButtonMenuItem2;
10411225 private javax.swing.JPopupMenu.Separator jSeparator1;
@@ -1043,19 +1227,23 @@ public class TextKeyMatcherView extends FrameView implements ExitListener {
10431227 private javax.swing.ButtonGroup keyButtonGroup;
10441228 private textkeymatcher.ui.model.KeyMatcherBinder keyMatcherBinder;
10451229 private javax.swing.JMenu keyMenu;
1230+ private textkeymatcher.service.LineDataListMergeService lineDataListMergeService;
10461231 private javax.swing.JMenuItem loadDataMenuItem;
10471232 private javax.swing.JPanel mainPanel;
10481233 private javax.swing.JRadioButtonMenuItem matchedRadioButtonMenuItem;
10491234 private javax.swing.JMenuBar menuBar;
1235+ private javax.swing.JComboBox mergeColumnCombo;
10501236 private javax.swing.JMenuItem mergeMenuItem;
10511237 private javax.swing.JRadioButtonMenuItem missingLeftRadioButtonMenuItem;
10521238 private javax.swing.JMenuItem newMenuItem;
10531239 private javax.swing.JRadioButtonMenuItem numberRadioButtonMenuItem;
10541240 private javax.swing.JMenuItem openMenuItem;
10551241 private javax.swing.JProgressBar progressBar;
1242+ private javax.swing.JCheckBox removeAfterMergedCheckbox;
10561243 private javax.swing.JComboBox removeColumnComboBox;
10571244 private javax.swing.JLabel removeColumnLabel;
10581245 private javax.swing.JMenuItem removeMenuItem;
1246+ private javax.swing.JCheckBox replaceBaseCheckBox;
10591247 private javax.swing.JMenuItem saveMenuItem;
10601248 private javax.swing.JLabel statusAnimationLabel;
10611249 private javax.swing.JLabel statusMessageLabel;
--- a/src/textkeymatcher/ui/model/DataViewTableModel.java
+++ b/src/textkeymatcher/ui/model/DataViewTableModel.java
@@ -149,6 +149,23 @@ public class DataViewTableModel extends KeyMatchedRowView implements TextKeyMatc
149149 }
150150
151151 /**
152+ * 指定したインデックスのデータソースを設定する.<br>
153+ * インデックスは既存のデータの範囲内でなければなりません.<br>
154+ * @param index インデックス
155+ * @param lineDataList データソース
156+ */
157+ public void setLineDataList(int index, LineDataList lineDataList) {
158+ if (lineDataList == null) {
159+ throw new IllegalArgumentException();
160+ }
161+ rowMap.setLineDataList(index, lineDataList);
162+ rowMap.remap();
163+
164+ renumbering(rowMap);
165+ setDirty(true);
166+ }
167+
168+ /**
152169 * 指定したインデックスのデータソースを削除する.
153170 * @param index インデックス
154171 */
--- a/src/textkeymatcher/ui/resources/TextKeyMatcherView.properties
+++ b/src/textkeymatcher/ui/resources/TextKeyMatcherView.properties
@@ -72,3 +72,9 @@ jRadioButtonMenuItem2.text=Ununique (Strict)
7272 onRemoveColumn.Action.text=
7373 onRemoveColumn.Action.shortDescription=
7474 removeColumnLabel.text=Choose the Remove Column
75+onMergeColumn.Action.text=
76+onMergeColumn.Action.shortDescription=
77+jLabel1.text=Base Column
78+jLabel2.text=Merge Column
79+removeAfterMergedCheckbox.text=Remove after merged.
80+replaceBaseCheckBox.text=Replace
--- a/src/textkeymatcher/ui/resources/TextKeyMatcherView_ja_JP.properties
+++ b/src/textkeymatcher/ui/resources/TextKeyMatcherView_ja_JP.properties
@@ -61,3 +61,7 @@ ununiqueRadioButtonMenuItem.text=\u975e\u30e6\u30cb\u30fc\u30af(D)
6161 jRadioButtonMenuItem1.text=\u30e6\u30cb\u30fc\u30af(\u81ea\u5217\u3082\u5bfe\u8c61)
6262 jRadioButtonMenuItem2.text=\u975e\u30e6\u30cb\u30fc\u30af(\u81ea\u5217\u3082\u5bfe\u8c61)
6363 removeColumnLabel.text=\u524a\u9664\u3059\u308b\u5217\u3092\u9078\u629e\u3057\u3066\u304f\u3060\u3055\u3044\u3002
64+jLabel1.text=\u30de\u30fc\u30b8\u5148\u30ab\u30e9\u30e0
65+jLabel2.text=\u30de\u30fc\u30b8\u5143\u30ab\u30e9\u30e0
66+replaceBaseCheckBox.text=\u30de\u30fc\u30b8\u7d50\u679c\u3067\u7f6e\u63db\u3059\u308b
67+removeAfterMergedCheckbox.text=\u30de\u30fc\u30b8\u5f8c\u306b\u524a\u9664\u3059\u308b