@@ -29,33 +29,51 @@ public class EditUserDefinedCombis {
2929
3030 JTable usercombiTable ;
3131 MyTableModel model ;
32+ TableModelListener modelListener ;
3233 List <String > tablerowdata = new ArrayList <String >();
34+ List <String > defaultValues = new ArrayList <String >();
3335 String strcustomconfigfile = "" ;
3436
3537 /*
36- / This option makes only the 3rd column (0, 1, 2) editable
37- / column 1 (no. 0) & 2 (no. 1) are ready-only
38+ / This option makes only the 3rd (tag value) and 4th (Save checkbox) columns (2, 3) editable
39+ / column 1 (no. 0) & 2 (no. 1) are ready-only.
40+ / Also override getColumnClass to allow for the Save checkbox in 4th column.
3841 */
3942 public class MyTableModel extends DefaultTableModel {
4043 public boolean isCellEditable (int row , int column ){
41- return column == 2 ;
44+ return column == 2 || column == 3 ;
4245 }
4346
47+ public Class getColumnClass (int column ) {
48+ if (column == 3 )
49+ return Boolean .class ;
50+ else
51+ return String .class ;
52+ }
4453 }
54+
4555 /*
4656 / This method updates the table in case we have selected another combi from the JCombobox
4757 */
4858 public void UpdateTable (JPanel rootpanel , JComboBox combicombobox , JScrollPane userCombiPane ) {
59+ if (model != null && modelListener != null )
60+ model .removeTableModelListener (modelListener );
4961
50- List <String > tablerowdata = new ArrayList <String >();
51- usercombiTable = new JTable (new MyTableModel ());
62+ tablerowdata .clear ();
63+ defaultValues .clear ();
64+
65+ if (model == null ) {
66+ model = new MyTableModel ();
67+ model .setColumnIdentifiers (new String []{ResourceBundle .getBundle ("translations/program_strings" ).getString ("mduc.columnlabel" ),
68+ ResourceBundle .getBundle ("translations/program_strings" ).getString ("mduc.columntag" ),
69+ ResourceBundle .getBundle ("translations/program_strings" ).getString ("mduc.columndefault" ),
70+ ResourceBundle .getBundle ("translations/program_strings" ).getString ("label.save" )});
71+ }
72+ else
73+ model .setRowCount (0 );
5274
53- model = ((MyTableModel ) (usercombiTable .getModel ()));
54- model .setColumnIdentifiers (new String []{ResourceBundle .getBundle ("translations/program_strings" ).getString ("mduc.columnlabel" ),
55- ResourceBundle .getBundle ("translations/program_strings" ).getString ("mduc.columntag" ),
56- ResourceBundle .getBundle ("translations/program_strings" ).getString ("mduc.columndefault" )});
57- model .setRowCount (0 );
58- Object [] row = new Object [1 ];
75+ if (usercombiTable == null )
76+ usercombiTable = new JTable (model );
5977
6078 String setName = combicombobox .getSelectedItem ().toString ();
6179 String sql = "select screen_label, tag, default_value from custommetadatasetLines where customset_name='" + setName .trim () + "' order by rowcount" ;
@@ -65,19 +83,40 @@ public void UpdateTable(JPanel rootpanel, JComboBox combicombobox, JScrollPane u
6583
6684 for (String line : lines ) {
6785 String [] cells = line .split ("\\ t" , 4 );
68- model .addRow (new Object []{cells [0 ], cells [1 ], cells [2 ]});
86+ String defVal = cells [2 ].trim ();
87+ model .addRow (new Object []{cells [0 ], cells [1 ], defVal , defVal .length () == 0 ? Boolean .FALSE : Boolean .TRUE });
6988 tablerowdata .add ("" );
89+ defaultValues .add (defVal ); // We'll use the default values again during a copy operation
7090 }
7191 MyVariables .setuserCombiTableValues (tablerowdata );
7292 }
7393 userCombiPane .setViewportView (usercombiTable );
94+ // Make the Save column narrower.
95+ usercombiTable .getColumnModel ().getColumn (3 ).setMinWidth (50 );
96+ usercombiTable .getColumnModel ().getColumn (3 ).setMaxWidth (110 );
97+ usercombiTable .getColumnModel ().getColumn (3 ).setPreferredWidth (70 );
7498
75- usercombiTable .getModel ().addTableModelListener (new TableModelListener () {
76- public void tableChanged (TableModelEvent e ) {
77- logger .debug ("source {}; firstRow {}; lastRow {}, column{}" , e .getSource (), e .getFirstRow (), e .getLastRow (), e .getColumn ());
78- logger .debug ("tag {}; original value {}; modified tablecell value {}" , model .getValueAt (e .getFirstRow (),1 ), tablerowdata .get (e .getFirstRow ()), model .getValueAt (e .getFirstRow (),e .getColumn ()));
79- }
80- });
99+ if (modelListener == null ) {
100+ modelListener = new TableModelListener () {
101+ // React to edits of tag values. If value is different to original value then tick the Save checkbox
102+ public void tableChanged (TableModelEvent e ) {
103+ int col = e .getColumn ();
104+ if (col == 3 ) // No need to react to checkboxes
105+ return ;
106+ int row = e .getFirstRow ();
107+ Object originalValue = tablerowdata .get (row );
108+ Object modifiedValue = model .getValueAt (row , col );
109+ logger .debug ("source {}; firstRow {}; lastRow {}, column{}" , e .getSource (), row , e .getLastRow (), col );
110+ logger .debug ("tag {}; original value {}; modified tablecell value {}" , model .getValueAt (row , 1 ), originalValue , modifiedValue );
111+ if (originalValue .equals (modifiedValue ))
112+ model .setValueAt (Boolean .FALSE , row , 3 );
113+ else
114+ model .setValueAt (Boolean .TRUE , row , 3 );
115+ }
116+ };
117+ }
118+
119+ model .addTableModelListener (modelListener );
81120 }
82121
83122 public void UpdateCustomConfigLabel (JComboBox combicombobox , JLabel customconfiglabel ) {
@@ -100,8 +139,7 @@ public void ResetFields(JScrollPane userCombiPane) {
100139 }
101140
102141 public void SaveTableValues (JCheckBox udcOverwriteOriginalscheckBox , JProgressBar progressBar ) {
103- // if changed => save
104- // else if !empty => save
142+ // if Save checkedbox ticked => save
105143 File [] files = MyVariables .getLoadedFiles ();
106144 int [] selectedIndices = MyVariables .getSelectedFilenamesIndices ();
107145 tablerowdata = MyVariables .getuserCombiTableValues ();
@@ -125,21 +163,25 @@ public void SaveTableValues(JCheckBox udcOverwriteOriginalscheckBox, JProgressBa
125163 cmdparams .add ("-overwrite_original" );
126164 }
127165 cmdparams .addAll (Utils .AlwaysAdd ());
128- cmdparams .add ("-n" ); // Need is this for some tags, eg Orientation
166+ cmdparams .add ("-n" ); // Need this for some tags, eg Orientation
129167 boolean hasChanged = false ;
168+ model .removeTableModelListener (modelListener ); // Temporarily remove listener to avoid triggering unnecessary events
130169 for (String value : tablerowdata ) {
131- if ( ! model .getValueAt (rowcounter , 2 ). equals ( value ) ) {
170+ if (( Boolean ) model .getValueAt (rowcounter , 3 ) ) {
132171 hasChanged = true ;
133- logger .info ("tag {}; original value {}; modified tablecell value {}" , model .getValueAt (rowcounter ,1 ), tablerowdata .get (rowcounter ), model .getValueAt (rowcounter ,2 ));
172+ String cellValue = model .getValueAt (rowcounter ,2 ).toString ().trim ();
173+ logger .info ("tag {}; original value {}; modified tablecell value {}" , model .getValueAt (rowcounter ,1 ), tablerowdata .get (rowcounter ), cellValue );
134174 if (model .getValueAt (rowcounter ,1 ).toString ().startsWith ("-" )) {
135- cmdparams .add (model .getValueAt (rowcounter ,1 ).toString () + "=" + model . getValueAt ( rowcounter , 2 ). toString (). trim () );
175+ cmdparams .add (model .getValueAt (rowcounter ,1 ).toString () + "=" + cellValue );
136176 } else { //tag without - (minus sign/hyphen) as prefix
137- cmdparams .add ("-" + model .getValueAt (rowcounter ,1 ).toString () + "=" + model . getValueAt ( rowcounter , 2 ). toString (). trim () );
177+ cmdparams .add ("-" + model .getValueAt (rowcounter ,1 ).toString () + "=" + cellValue );
138178 }
139- tablerowdata .set (rowcounter , model .getValueAt (rowcounter , 2 ).toString ().trim ());
179+ tablerowdata .set (rowcounter , cellValue );
180+ model .setValueAt (cellValue , rowcounter , 2 );
140181 }
141182 rowcounter ++;
142183 }
184+ model .addTableModelListener (modelListener ); // Add back listener
143185
144186 for (int index : selectedIndices ) {
145187 //logger.info("index: {} image path: {}", index, files[index].getPath());
@@ -200,7 +242,9 @@ public void CopyFromSelectedImage() {
200242 }
201243 if (res .length () > 0 ) {
202244 String [] strTagnames = tagnames .stream ().toArray (String []::new );
245+ model .removeTableModelListener (modelListener ); // Temporarily remove listener to avoid triggering unnecessary events
203246 displayCopiedInfo ( res , strTagnames );
247+ model .addTableModelListener (modelListener ); // Add back listener
204248 }
205249
206250 }
@@ -210,8 +254,14 @@ private void displayCopiedInfo(String exiftoolInfo, String[] tagNames) {
210254 String [] lines = exiftoolInfo .split (SystemPropertyFacade .getPropertyByKey (LINE_SEPARATOR ));
211255 tablerowdata = MyVariables .getuserCombiTableValues ();
212256
257+ // Clear previous values and set defaults
258+ for (int row = 0 ; row < model .getRowCount (); row ++) {
259+ tablerowdata .set (row , "" );
260+ model .setValueAt (defaultValues .get (row ), row , 2 );
261+ }
262+
213263 for (String line : lines ) {
214- String [] returnedValuesRow = line .split ("::" , 2 ); // Only split on first : as some tags also contain (multiple) :
264+ String [] returnedValuesRow = line .split ("::" , 2 ); // Only split on first :: as some tags also contain (multiple) : :
215265 if (returnedValuesRow .length < 2 ) // line does not contain "TAGNAME::VALUE" so skip it, eg warning messages
216266 continue ;
217267 String SpaceStrippedTag = returnedValuesRow [0 ];
@@ -221,12 +271,19 @@ private void displayCopiedInfo(String exiftoolInfo, String[] tagNames) {
221271 for (String tagname : tablerowdata ) {
222272 if (model .getValueAt (rowcounter ,1 ).toString ().equals (SpaceStrippedTag )) {
223273 // The model data and tablerowdata values are the same when first retrieved.
224- // Late, during save, each row is checked if it was changed.
225- model .setValueAt (returnedValuesRow [1 ].trim (),rowcounter ,2 );
274+ // Later, during save, each row is checked if it was changed.
226275 tablerowdata .set (rowcounter , returnedValuesRow [1 ].trim ());
276+ model .setValueAt (returnedValuesRow [1 ].trim (),rowcounter ,2 );
227277 }
228278 rowcounter ++;
229279 }
230280 }
281+ // Tick the Save checkbox for any tags which have defaults still remaining
282+ for (int row = 0 ; row < model .getRowCount (); row ++) {
283+ if (model .getValueAt (row , 2 ).equals (tablerowdata .get (row )))
284+ model .setValueAt (Boolean .FALSE , row , 3 );
285+ else
286+ model .setValueAt (Boolean .TRUE , row , 3 );
287+ }
231288 }
232289}
0 commit comments