From a018f2021b353bdd4a2e1739eedbac8d807ccd99 Mon Sep 17 00:00:00 2001 From: Mark Langen Date: Wed, 28 Sep 2016 23:27:46 -0600 Subject: [PATCH] Fixed a bug with JFileChooser in the DeckEditorPanel * On specific platforms (it seems Windows 7-10, JRT 7+), under our specific configuration, in the case where the user selects the exact same file as they chose during a previous selection, JFileChooser reports that the user selected a file, but returns chosen file = null. This commit works around that by assuming they chose the same file as last time in that case. --- .../java/mage/client/cards/DragCardGrid.java | 61 ++++++++++++++++--- .../client/deckeditor/DeckEditorPanel.java | 40 ++++++++++-- 2 files changed, 90 insertions(+), 11 deletions(-) diff --git a/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java b/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java index cd8c96e7b2..fa206cb0f6 100644 --- a/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java +++ b/Mage.Client/src/main/java/mage/client/cards/DragCardGrid.java @@ -21,6 +21,7 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuListener; +import javax.swing.filechooser.FileFilter; import java.awt.*; import java.awt.event.*; import java.io.File; @@ -1008,6 +1009,11 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg } } + // Trim the grid + if (didModify) { + trimGrid(); + } + // Add any new card views for (CardView newCard: cardsView.values()) { if (!cardViews.containsKey(newCard.getId())) { @@ -1027,9 +1033,6 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg // Modifications? if (didModify) { - // Trim extra rows / columns from the grid - trimGrid(); - // Update layout layoutGrid(); @@ -1213,7 +1216,7 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg // No card in this column? if (cardInColumn == null) { // Error, should not have an empty column - LOGGER.error("Empty column!"); + LOGGER.error("Empty column! " + currentColumn); } else { int res = cardSort.getComparator().compare(newCard, cardInColumn); if (res <= 0) { @@ -1384,18 +1387,62 @@ public class DragCardGrid extends JPanel implements DragCardSource, DragCardTarg }); } + static class DeckFilter extends FileFilter { + @Override + public boolean accept(File f) { + if (f.isDirectory()) { + return true; + } + + String ext = null; + String s = f.getName(); + int i = s.lastIndexOf('.'); + + if (i > 0 && i < s.length() - 1) { + ext = s.substring(i + 1).toLowerCase(); + } + return (ext == null) ? false : ext.equals("dck"); + } + + @Override + public String getDescription() { + return "Deck Files"; + } + } + public static void main(String[] args) { + JFrame frame = new JFrame(); + /* GUISizeHelper.calculateGUISizes(); Plugins.getInstance().loadPlugins(); - JFrame frame = new JFrame(); frame.setTitle("Test"); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setBackground(Color.BLUE); DragCardGrid grid = new DragCardGrid(); grid.setPreferredSize(new Dimension(800, 600)); - frame.add(grid, BorderLayout.CENTER); - frame.pack(); + */ + try { + UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"); + } catch (UnsupportedLookAndFeelException | ClassNotFoundException | IllegalAccessException | InstantiationException e) {} frame.setVisible(true); + JFileChooser choose = new JFileChooser(); + choose.setAcceptAllFileFilterUsed(false); + choose.addChoosableFileFilter(new DeckFilter()); + choose.showOpenDialog(frame); + LOGGER.info("File: " + choose.getSelectedFile()); + String st = ""; + try { + st = choose.getSelectedFile().getCanonicalPath(); + } catch (Exception e) { + e.printStackTrace(); + } + LOGGER.info("Selected file: " + st); + choose.setSelectedFile(new File(st)); + choose.showOpenDialog(frame); + LOGGER.info("File: " + choose.getSelectedFile()); + //frame.add(grid, BorderLayout.CENTER); + //frame.pack(); + frame.setVisible(false); } } diff --git a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java index 3e4a9f77f2..a6ab56a1c6 100644 --- a/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java +++ b/Mage.Client/src/main/java/mage/client/deckeditor/DeckEditorPanel.java @@ -33,6 +33,7 @@ import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.util.*; import java.util.List; @@ -222,6 +223,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { Card card = temporaryCards.get(cardView.getId()); if (card == null) { // Need to make a new card + Logger.getLogger(DeckEditorPanel.class).info("Retrieve " + cardView.getCardNumber() + " Failed"); card = CardRepository.instance.findCard(cardView.getExpansionSetCode(), cardView.getCardNumber()).getCard(); } else { // Only need a temporary card once @@ -845,6 +847,7 @@ public class DeckEditorPanel extends javax.swing.JPanel { } private void btnLoadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnLoadActionPerformed + //fcSelectDeck.setCurrentDirectory(new File()); String lastFolder = MageFrame.getPreferences().get("lastDeckFolder", ""); if (!lastFolder.isEmpty()) { fcSelectDeck.setCurrentDirectory(new File(lastFolder)); @@ -852,13 +855,26 @@ public class DeckEditorPanel extends javax.swing.JPanel { int ret = fcSelectDeck.showOpenDialog(this); if (ret == JFileChooser.APPROVE_OPTION) { File file = fcSelectDeck.getSelectedFile(); + { + /** + * Work around a JFileChooser bug on Windows 7-10 with JRT 7+ + * In the case where the user selects the exact same file as was previously + * selected without touching anything else in the dialog, getSelectedFile() + * will erroneously return null due to some combination of our settings. + * + * We manually sub in the last selected file in this case. + */ + if (file == null) { + if (!lastFolder.isEmpty()) { + file = new File(lastFolder); + } + } + } try { setCursor(new Cursor(Cursor.WAIT_CURSOR)); deck = Deck.load(DeckImporterUtil.importDeck(file.getPath()), true, true); } catch (GameException ex) { JOptionPane.showMessageDialog(MageFrame.getDesktop(), ex.getMessage(), "Error loading deck", JOptionPane.ERROR_MESSAGE); - } catch (Exception ex) { - logger.fatal(ex); } finally { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } @@ -882,6 +898,21 @@ public class DeckEditorPanel extends javax.swing.JPanel { int ret = fcSelectDeck.showSaveDialog(this); if (ret == JFileChooser.APPROVE_OPTION) { File file = fcSelectDeck.getSelectedFile(); + { + /** + * Work around a JFileChooser bug on Windows 7-10 with JRT 7+ + * In the case where the user selects the exact same file as was previously + * selected without touching anything else in the dialog, getSelectedFile() + * will erroneously return null due to some combination of our settings. + * + * We manually sub in the last selected file in this case. + */ + if (file == null) { + if (!lastFolder.isEmpty()) { + file = new File(lastFolder); + } + } + } try { String fileName = file.getPath(); if (!fileName.endsWith(".dck")) { @@ -889,14 +920,15 @@ public class DeckEditorPanel extends javax.swing.JPanel { } setCursor(new Cursor(Cursor.WAIT_CURSOR)); Sets.saveDeck(fileName, deck.getDeckCardLists()); - } catch (Exception ex) { - logger.fatal(ex); + } catch (FileNotFoundException ex) { + JOptionPane.showMessageDialog(MageFrame.getDesktop(), ex.getMessage() + "\nTry ensuring that the selected directory is writable.", "Error saving deck", JOptionPane.ERROR_MESSAGE); } finally { setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); } try { MageFrame.getPreferences().put("lastDeckFolder", file.getCanonicalPath()); } catch (IOException ex) { + ex.printStackTrace(); } } }//GEN-LAST:event_btnSaveActionPerformed