77
88import com .dazednconfused .catalauncher .backup .SaveManager ;
99import com .dazednconfused .catalauncher .configuration .ConfigurationManager ;
10+ import com .dazednconfused .catalauncher .helper .FileExplorerManager ;
1011import com .dazednconfused .catalauncher .helper .GitInfoManager ;
1112import com .dazednconfused .catalauncher .helper .LogLevelManager ;
1213import com .dazednconfused .catalauncher .launcher .CDDALauncherManager ;
1920import java .awt .Component ;
2021import java .awt .event .InputEvent ;
2122import java .awt .event .KeyEvent ;
23+ import java .awt .event .MouseAdapter ;
24+ import java .awt .event .MouseEvent ;
2225import java .io .File ;
2326import java .util .ArrayList ;
2427import java .util .Comparator ;
2528import java .util .Date ;
2629import java .util .List ;
30+ import java .util .function .BiConsumer ;
2731
2832import javax .swing .JButton ;
2933import javax .swing .JCheckBox ;
3539import javax .swing .JMenuBar ;
3640import javax .swing .JMenuItem ;
3741import javax .swing .JPanel ;
42+ import javax .swing .JPopupMenu ;
3843import javax .swing .JProgressBar ;
3944import javax .swing .JTable ;
4045import javax .swing .KeyStroke ;
@@ -171,7 +176,7 @@ public MainWindow() {
171176
172177 // BACKUP NOW BUTTON LISTENER ---
173178 this .backupNowButton .addActionListener (e -> {
174- LOGGER .trace ("Backup button clicked" );
179+ LOGGER .trace ("Save backup button clicked" );
175180
176181 // enable backup progressbar
177182 this .globalProgressBar .setEnabled (true );
@@ -184,10 +189,10 @@ public MainWindow() {
184189
185190 // BACKUP RESTORE BUTTON LISTENER ---
186191 backupRestoreButton .addActionListener (e -> {
187- LOGGER .trace ("Backup restore button clicked" );
192+ LOGGER .trace ("Save backup restore button clicked" );
188193
189- File selectedBackup = (File ) this .saveBackupTable .getValueAt (this .saveBackupTable .getSelectedRow (), 0 );
190- LOGGER .trace ("Backup currently on selection: [{}]" , selectedBackup );
194+ File selectedBackup = (File ) this .saveBackupTable .getValueAt (this .saveBackupTable .getSelectedRow (), 1 );
195+ LOGGER .trace ("Save backup currently on selection: [{}]" , selectedBackup );
191196
192197 ConfirmDialog confirmDialog = new ConfirmDialog (
193198 String .format ("Are you sure you want to restore the backup [%s]? Current save will be moved to trash folder [%s]" , selectedBackup .getName (), CUSTOM_TRASHED_SAVE_PATH ),
@@ -219,8 +224,8 @@ public MainWindow() {
219224 this .backupDeleteButton .addActionListener (e -> {
220225 LOGGER .trace ("Delete backup button clicked" );
221226
222- File selectedBackup = (File ) this .saveBackupTable .getValueAt (this .saveBackupTable .getSelectedRow (), 0 );
223- LOGGER .trace ("Backup currently on selection: [{}]" , selectedBackup );
227+ File selectedBackup = (File ) this .saveBackupTable .getValueAt (this .saveBackupTable .getSelectedRow (), 1 );
228+ LOGGER .trace ("Save backup currently on selection: [{}]" , selectedBackup );
224229
225230 ConfirmDialog confirmDialog = new ConfirmDialog (
226231 String .format ("Are you sure you want to delete the backup [%s]? This action is irreversible!" , selectedBackup .getName ()),
@@ -239,16 +244,28 @@ public MainWindow() {
239244 confirmDialog .packCenterAndShow (this .mainPanel );
240245 });
241246
242- // BACKUP TABLE LISTENER ---
247+ // BACKUP TABLE LISTENER(S) ---
248+ this .saveBackupTable .setName ("Save backups table" ); // needed in order to recognize component in generic methods
249+
243250 this .saveBackupTable .getSelectionModel ().addListSelectionListener (event -> {
244- LOGGER .trace ("Backup table row selected" );
251+ LOGGER .trace ("Save backups table row selected" );
245252
246253 if (saveBackupTable .getSelectedRow () > -1 ) {
247254 this .backupDeleteButton .setEnabled (true );
248255 this .backupRestoreButton .setEnabled (true );
249256 }
250257 });
251258
259+ this .saveBackupTable .addMouseListener (new MouseAdapter () {
260+ public void mousePressed (MouseEvent e ) { // mousedPressed event needed for macOS - https://stackoverflow.com/a/3558324
261+ genericTableOnClickEventListener ().accept (e , (JTable ) e .getComponent ());
262+ }
263+
264+ public void mouseReleased (MouseEvent e ) { // mouseReleased event needed for other OSes
265+ genericTableOnClickEventListener ().accept (e , (JTable ) e .getComponent ());
266+ }
267+ });
268+
252269 // SOUNDPACK INSTALL BUTTON LISTENER ---
253270 this .installSoundpackButton .addActionListener (e -> {
254271 LOGGER .trace ("Install soundpack button clicked" );
@@ -302,14 +319,26 @@ public MainWindow() {
302319 confirmDialog .packCenterAndShow (this .mainPanel );
303320 });
304321
305- // SOUNDPACKS TABLE LISTENER ---
322+ // SOUNDPACKS TABLE LISTENER(S) ---
323+ this .soundpacksTable .setName ("Soundpacks table" ); // needed in order to recognize component in generic methods
324+
306325 this .soundpacksTable .getSelectionModel ().addListSelectionListener (event -> {
307326 LOGGER .trace ("Soundpacks table row selected" );
308327
309328 if (soundpacksTable .getSelectedRow () > -1 ) {
310329 this .uninstallSoundpackButton .setEnabled (true );
311330 }
312331 });
332+
333+ this .soundpacksTable .addMouseListener (new MouseAdapter () {
334+ public void mousePressed (MouseEvent e ) { // mousedPressed event needed for macOS - https://stackoverflow.com/a/3558324
335+ genericTableOnClickEventListener ().accept (e , (JTable ) e .getComponent ());
336+ }
337+
338+ public void mouseReleased (MouseEvent e ) { // mouseReleased event needed for other OSes
339+ genericTableOnClickEventListener ().accept (e , (JTable ) e .getComponent ());
340+ }
341+ });
313342 }
314343
315344 /**
@@ -482,11 +511,12 @@ private void openFinder(Component parent) {
482511 private void refreshSaveBackupsTable () {
483512 LOGGER .trace ("Refreshing save backups table..." );
484513
485- String [] columns = new String []{"Backup " , "Size" , "Date" };
514+ String [] columns = new String []{"Name" , "Path " , "Size" , "Date" };
486515
487516 List <Object []> values = new ArrayList <>();
488517 SaveManager .listAllBackups ().stream ().sorted (Comparator .comparing (File ::lastModified ).reversed ()).forEach (backup ->
489518 values .add (new Object []{
519+ backup .getName (),
490520 backup ,
491521 backup .length () / (1024 * 1024 ) + " MB" ,
492522 new Date (backup .lastModified ())
@@ -518,4 +548,40 @@ private void refreshSoundpacksTable() {
518548 TableModel tableModel = new DefaultTableModel (values .toArray (new Object [][]{}), columns );
519549 this .soundpacksTable .setModel (tableModel );
520550 }
551+
552+ /**
553+ * Returns a generic right-click "open in files" context popup for usage in {@link JTable}s.
554+ * */
555+ private BiConsumer <MouseEvent , JTable > genericTableOnClickEventListener () {
556+ return (e , table ) -> {
557+ LOGGER .trace ("[{}] clicked" , table .getName ());
558+
559+ int r = table .rowAtPoint (e .getPoint ());
560+ if (r >= 0 && r < table .getRowCount ()) {
561+ table .setRowSelectionInterval (r , r );
562+ } else {
563+ table .clearSelection ();
564+ }
565+
566+ int rowindex = table .getSelectedRow ();
567+ if (rowindex < 0 ) {
568+ return ;
569+ }
570+
571+ if (e .isPopupTrigger () && e .getComponent () instanceof JTable ) {
572+ LOGGER .trace ("Opening right-click popup for [{}]" , table .getName ());
573+
574+ JPopupMenu popup = new JPopupMenu ();
575+
576+ JMenuItem openInFinder = new JMenuItem ("Open folder in file explorer" );
577+ openInFinder .addActionListener (e1 -> {
578+ File targetPath = (File ) table .getValueAt (table .getSelectedRow (), 1 );
579+ FileExplorerManager .openFileInFileExplorer (targetPath );
580+ });
581+ popup .add (openInFinder );
582+
583+ popup .show (e .getComponent (), e .getX (), e .getY ());
584+ }
585+ };
586+ }
521587}
0 commit comments