1 /* 2 * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * - Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * - Neither the name of Oracle nor the names of its 16 * contributors may be used to endorse or promote products derived 17 * from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * This source code is provided to illustrate the usage of a given feature 34 * or technique and has been deliberately simplified. Additional steps 35 * required for a production-quality application, such as security checks, 36 * input validation and proper error handling, might not be present in 37 * this sample code. 38 */ 39 40 41 42 import java.lang.reflect.InvocationTargetException; 43 import java.util.logging.Level; 44 import java.util.logging.Logger; 45 import javax.swing.UIManager.LookAndFeelInfo; 46 import java.awt.BorderLayout; 47 import java.awt.CardLayout; 48 import java.awt.Component; 49 import java.awt.Dimension; 50 import java.awt.Graphics; 51 import java.awt.Image; 52 import java.awt.Insets; 53 import java.awt.event.ActionEvent; 54 import java.awt.event.ActionListener; 55 import java.beans.PropertyChangeEvent; 56 import java.beans.PropertyChangeListener; 57 import java.util.List; 58 import javax.swing.BorderFactory; 59 import javax.swing.Box; 60 import javax.swing.BoxLayout; 61 import javax.swing.ButtonGroup; 62 import javax.swing.DefaultComboBoxModel; 63 import javax.swing.ImageIcon; 64 import javax.swing.JButton; 65 import javax.swing.JCheckBox; 66 import javax.swing.JComboBox; 67 import javax.swing.JComponent; 68 import javax.swing.JDialog; 69 import javax.swing.JFileChooser; 70 import javax.swing.JFrame; 71 import javax.swing.JLabel; 72 import javax.swing.JOptionPane; 73 import javax.swing.JPanel; 74 import javax.swing.JRadioButton; 75 import javax.swing.JTextField; 76 import javax.swing.JToggleButton; 77 import javax.swing.LookAndFeel; 78 import javax.swing.SwingUtilities; 79 import javax.swing.UIManager; 80 import javax.swing.UnsupportedLookAndFeelException; 81 import javax.swing.WindowConstants; 82 import javax.swing.filechooser.FileFilter; 83 import javax.swing.filechooser.FileNameExtensionFilter; 84 import javax.swing.filechooser.FileSystemView; 85 import java.util.ArrayList; 86 import javax.swing.plaf.FileChooserUI; 87 import javax.swing.plaf.basic.BasicFileChooserUI; 88 import java.io.File; 89 import static javax.swing.JFileChooser.*; 90 91 92 /** 93 * 94 * A demo which makes extensive use of the file chooser. 95 * 96 * @author Jeff Dinkins 97 */ 98 @SuppressWarnings("serial") 99 public class FileChooserDemo extends JPanel implements ActionListener { 100 101 public static final String NIMBUS_LAF_NAME = "Nimbus"; 102 private static JFrame frame; 103 private final List<SupportedLaF> supportedLaFs = 104 new ArrayList<SupportedLaF>(); 105 private static SupportedLaF nimbusLaF; 106 107 108 private static class SupportedLaF { 109 110 private final String name; 111 private final LookAndFeel laf; 112 SupportedLaF(String name, LookAndFeel laf)113 SupportedLaF(String name, LookAndFeel laf) { 114 this.name = name; 115 this.laf = laf; 116 } 117 118 @Override toString()119 public String toString() { 120 return name; 121 } 122 } 123 private JButton showButton; 124 private JCheckBox showAllFilesFilterCheckBox; 125 private JCheckBox showImageFilesFilterCheckBox; 126 private JCheckBox showFullDescriptionCheckBox; 127 private JCheckBox useFileViewCheckBox; 128 private JCheckBox useFileSystemViewCheckBox; 129 private JCheckBox accessoryCheckBox; 130 private JCheckBox setHiddenCheckBox; 131 private JCheckBox useEmbedInWizardCheckBox; 132 private JCheckBox useControlsCheckBox; 133 private JCheckBox enableDragCheckBox; 134 private JRadioButton singleSelectionRadioButton; 135 private JRadioButton multiSelectionRadioButton; 136 private JRadioButton openRadioButton; 137 private JRadioButton saveRadioButton; 138 private JRadioButton customButton; 139 private JComboBox lafComboBox; 140 private JRadioButton justFilesRadioButton; 141 private JRadioButton justDirectoriesRadioButton; 142 private JRadioButton bothFilesAndDirectoriesRadioButton; 143 private JTextField customField; 144 private final ExampleFileView fileView; 145 private final ExampleFileSystemView fileSystemView; 146 private static final Dimension hpad10 = new Dimension(10, 1); 147 private static final Dimension vpad20 = new Dimension(1, 20); 148 private static final Dimension vpad7 = new Dimension(1, 7); 149 private static final Dimension vpad4 = new Dimension(1, 4); 150 private static final Insets insets = new Insets(5, 10, 0, 10); 151 private final FilePreviewer previewer; 152 private final JFileChooser chooser; 153 154 @SuppressWarnings("LeakingThisInConstructor") FileChooserDemo()155 public FileChooserDemo() { 156 UIManager.LookAndFeelInfo[] installedLafs = UIManager. 157 getInstalledLookAndFeels(); 158 for (UIManager.LookAndFeelInfo lafInfo : installedLafs) { 159 try { 160 Class<?> lnfClass = Class.forName(lafInfo.getClassName()); 161 LookAndFeel laf = (LookAndFeel) (lnfClass.newInstance()); 162 if (laf.isSupportedLookAndFeel()) { 163 String name = lafInfo.getName(); 164 SupportedLaF supportedLaF = new SupportedLaF(name, laf); 165 supportedLaFs.add(supportedLaF); 166 if (NIMBUS_LAF_NAME.equals(name)) { 167 nimbusLaF = supportedLaF; 168 } 169 } 170 } catch (Exception ignored) { 171 // If ANYTHING weird happens, don't add this L&F 172 } 173 } 174 175 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 176 177 chooser = new JFileChooser(); 178 previewer = new FilePreviewer(chooser); 179 180 // Create Custom FileView 181 fileView = new ExampleFileView(); 182 fileView.putIcon("jpg", new ImageIcon(getClass().getResource( 183 "/resources/images/jpgIcon.jpg"))); 184 fileView.putIcon("gif", new ImageIcon(getClass().getResource( 185 "/resources/images/gifIcon.gif"))); 186 187 // Create Custom FileSystemView 188 fileSystemView = new ExampleFileSystemView(); 189 190 // create a radio listener to listen to option changes 191 OptionListener optionListener = new OptionListener(); 192 193 // Create options 194 openRadioButton = new JRadioButton("Open"); 195 openRadioButton.setSelected(true); 196 openRadioButton.addActionListener(optionListener); 197 198 saveRadioButton = new JRadioButton("Save"); 199 saveRadioButton.addActionListener(optionListener); 200 201 customButton = new JRadioButton("Custom"); 202 customButton.addActionListener(optionListener); 203 204 customField = new JTextField(8) { 205 206 @Override 207 public Dimension getMaximumSize() { 208 return new Dimension(getPreferredSize().width, 209 getPreferredSize().height); 210 } 211 }; 212 customField.setText("Doit"); 213 customField.setAlignmentY(JComponent.TOP_ALIGNMENT); 214 customField.setEnabled(false); 215 customField.addActionListener(optionListener); 216 217 ButtonGroup group1 = new ButtonGroup(); 218 group1.add(openRadioButton); 219 group1.add(saveRadioButton); 220 group1.add(customButton); 221 222 // filter buttons 223 showAllFilesFilterCheckBox = new JCheckBox("Show \"All Files\" Filter"); 224 showAllFilesFilterCheckBox.addActionListener(optionListener); 225 showAllFilesFilterCheckBox.setSelected(true); 226 227 showImageFilesFilterCheckBox = new JCheckBox("Show JPG and GIF Filters"); 228 showImageFilesFilterCheckBox.addActionListener(optionListener); 229 showImageFilesFilterCheckBox.setSelected(false); 230 231 accessoryCheckBox = new JCheckBox("Show Preview"); 232 accessoryCheckBox.addActionListener(optionListener); 233 accessoryCheckBox.setSelected(false); 234 235 // more options 236 setHiddenCheckBox = new JCheckBox("Show Hidden Files"); 237 setHiddenCheckBox.addActionListener(optionListener); 238 239 showFullDescriptionCheckBox = new JCheckBox("With File Extensions"); 240 showFullDescriptionCheckBox.addActionListener(optionListener); 241 showFullDescriptionCheckBox.setSelected(true); 242 showFullDescriptionCheckBox.setEnabled(false); 243 244 useFileViewCheckBox = new JCheckBox("Use FileView"); 245 useFileViewCheckBox.addActionListener(optionListener); 246 useFileViewCheckBox.setSelected(false); 247 248 useFileSystemViewCheckBox = new JCheckBox("Use FileSystemView", false); 249 useFileSystemViewCheckBox.addActionListener(optionListener); 250 251 useEmbedInWizardCheckBox = new JCheckBox("Embed in Wizard"); 252 useEmbedInWizardCheckBox.addActionListener(optionListener); 253 useEmbedInWizardCheckBox.setSelected(false); 254 255 useControlsCheckBox = new JCheckBox("Show Control Buttons"); 256 useControlsCheckBox.addActionListener(optionListener); 257 useControlsCheckBox.setSelected(true); 258 259 enableDragCheckBox = new JCheckBox("Enable Dragging"); 260 enableDragCheckBox.addActionListener(optionListener); 261 262 // File or Directory chooser options 263 ButtonGroup group3 = new ButtonGroup(); 264 justFilesRadioButton = new JRadioButton("Just Select Files"); 265 justFilesRadioButton.setSelected(true); 266 group3.add(justFilesRadioButton); 267 justFilesRadioButton.addActionListener(optionListener); 268 269 justDirectoriesRadioButton = new JRadioButton("Just Select Directories"); 270 group3.add(justDirectoriesRadioButton); 271 justDirectoriesRadioButton.addActionListener(optionListener); 272 273 bothFilesAndDirectoriesRadioButton = new JRadioButton( 274 "Select Files or Directories"); 275 group3.add(bothFilesAndDirectoriesRadioButton); 276 bothFilesAndDirectoriesRadioButton.addActionListener(optionListener); 277 278 singleSelectionRadioButton = new JRadioButton("Single Selection", true); 279 singleSelectionRadioButton.addActionListener(optionListener); 280 281 multiSelectionRadioButton = new JRadioButton("Multi Selection"); 282 multiSelectionRadioButton.addActionListener(optionListener); 283 284 ButtonGroup group4 = new ButtonGroup(); 285 group4.add(singleSelectionRadioButton); 286 group4.add(multiSelectionRadioButton); 287 288 289 // Create show button 290 showButton = new JButton("Show FileChooser"); 291 showButton.addActionListener(this); 292 showButton.setMnemonic('s'); 293 294 // Create laf combo box 295 lafComboBox = new JComboBox(supportedLaFs.toArray()); 296 lafComboBox.setSelectedItem(nimbusLaF); 297 lafComboBox.setEditable(false); 298 lafComboBox.addActionListener(optionListener); 299 300 // ******************************************************** 301 // ******************** Dialog Type *********************** 302 // ******************************************************** 303 JPanel control1 = new InsetPanel(insets); 304 control1.setBorder(BorderFactory.createTitledBorder("Dialog Type")); 305 306 control1.setLayout(new BoxLayout(control1, BoxLayout.Y_AXIS)); 307 control1.add(Box.createRigidArea(vpad20)); 308 control1.add(openRadioButton); 309 control1.add(Box.createRigidArea(vpad7)); 310 control1.add(saveRadioButton); 311 control1.add(Box.createRigidArea(vpad7)); 312 control1.add(customButton); 313 control1.add(Box.createRigidArea(vpad4)); 314 JPanel fieldWrapper = new JPanel(); 315 fieldWrapper.setLayout(new BoxLayout(fieldWrapper, BoxLayout.X_AXIS)); 316 fieldWrapper.setAlignmentX(Component.LEFT_ALIGNMENT); 317 fieldWrapper.add(Box.createRigidArea(hpad10)); 318 fieldWrapper.add(Box.createRigidArea(hpad10)); 319 fieldWrapper.add(customField); 320 control1.add(fieldWrapper); 321 control1.add(Box.createRigidArea(vpad20)); 322 control1.add(Box.createGlue()); 323 324 // ******************************************************** 325 // ***************** Filter Controls ********************** 326 // ******************************************************** 327 JPanel control2 = new InsetPanel(insets); 328 control2.setBorder(BorderFactory.createTitledBorder("Filter Controls")); 329 control2.setLayout(new BoxLayout(control2, BoxLayout.Y_AXIS)); 330 control2.add(Box.createRigidArea(vpad20)); 331 control2.add(showAllFilesFilterCheckBox); 332 control2.add(Box.createRigidArea(vpad7)); 333 control2.add(showImageFilesFilterCheckBox); 334 control2.add(Box.createRigidArea(vpad4)); 335 JPanel checkWrapper = new JPanel(); 336 checkWrapper.setLayout(new BoxLayout(checkWrapper, BoxLayout.X_AXIS)); 337 checkWrapper.setAlignmentX(Component.LEFT_ALIGNMENT); 338 checkWrapper.add(Box.createRigidArea(hpad10)); 339 checkWrapper.add(Box.createRigidArea(hpad10)); 340 checkWrapper.add(showFullDescriptionCheckBox); 341 control2.add(checkWrapper); 342 control2.add(Box.createRigidArea(vpad20)); 343 control2.add(Box.createGlue()); 344 345 // ******************************************************** 346 // ****************** Display Options ********************* 347 // ******************************************************** 348 JPanel control3 = new InsetPanel(insets); 349 control3.setBorder(BorderFactory.createTitledBorder("Display Options")); 350 control3.setLayout(new BoxLayout(control3, BoxLayout.Y_AXIS)); 351 control3.add(Box.createRigidArea(vpad20)); 352 control3.add(setHiddenCheckBox); 353 control3.add(Box.createRigidArea(vpad7)); 354 control3.add(useFileViewCheckBox); 355 control3.add(Box.createRigidArea(vpad7)); 356 control3.add(useFileSystemViewCheckBox); 357 control3.add(Box.createRigidArea(vpad7)); 358 control3.add(accessoryCheckBox); 359 control3.add(Box.createRigidArea(vpad7)); 360 control3.add(useEmbedInWizardCheckBox); 361 control3.add(Box.createRigidArea(vpad7)); 362 control3.add(useControlsCheckBox); 363 control3.add(Box.createRigidArea(vpad7)); 364 control3.add(enableDragCheckBox); 365 control3.add(Box.createRigidArea(vpad20)); 366 control3.add(Box.createGlue()); 367 368 // ******************************************************** 369 // ************* File & Directory Options ***************** 370 // ******************************************************** 371 JPanel control4 = new InsetPanel(insets); 372 control4.setBorder(BorderFactory.createTitledBorder( 373 "File and Directory Options")); 374 control4.setLayout(new BoxLayout(control4, BoxLayout.Y_AXIS)); 375 control4.add(Box.createRigidArea(vpad20)); 376 control4.add(justFilesRadioButton); 377 control4.add(Box.createRigidArea(vpad7)); 378 control4.add(justDirectoriesRadioButton); 379 control4.add(Box.createRigidArea(vpad7)); 380 control4.add(bothFilesAndDirectoriesRadioButton); 381 control4.add(Box.createRigidArea(vpad20)); 382 control4.add(singleSelectionRadioButton); 383 control4.add(Box.createRigidArea(vpad7)); 384 control4.add(multiSelectionRadioButton); 385 control4.add(Box.createRigidArea(vpad20)); 386 control4.add(Box.createGlue()); 387 388 389 // ******************************************************** 390 // **************** Look & Feel Switch ******************** 391 // ******************************************************** 392 JPanel panel = new JPanel(); 393 panel.add(new JLabel("Look and Feel: ")); 394 panel.add(lafComboBox); 395 panel.add(showButton); 396 397 // ******************************************************** 398 // ****************** Wrap 'em all up ********************* 399 // ******************************************************** 400 JPanel wrapper = new JPanel(); 401 wrapper.setLayout(new BoxLayout(wrapper, BoxLayout.X_AXIS)); 402 403 add(Box.createRigidArea(vpad20)); 404 405 wrapper.add(Box.createRigidArea(hpad10)); 406 wrapper.add(Box.createRigidArea(hpad10)); 407 wrapper.add(control1); 408 wrapper.add(Box.createRigidArea(hpad10)); 409 wrapper.add(control2); 410 wrapper.add(Box.createRigidArea(hpad10)); 411 wrapper.add(control3); 412 wrapper.add(Box.createRigidArea(hpad10)); 413 wrapper.add(control4); 414 wrapper.add(Box.createRigidArea(hpad10)); 415 wrapper.add(Box.createRigidArea(hpad10)); 416 417 add(wrapper); 418 add(Box.createRigidArea(vpad20)); 419 add(panel); 420 add(Box.createRigidArea(vpad20)); 421 } 422 actionPerformed(ActionEvent e)423 public void actionPerformed(ActionEvent e) { 424 if (customButton.isSelected()) { 425 chooser.setApproveButtonText(customField.getText()); 426 } 427 if (chooser.isMultiSelectionEnabled()) { 428 chooser.setSelectedFiles(null); 429 } else { 430 chooser.setSelectedFile(null); 431 } 432 // clear the preview from the previous display of the chooser 433 JComponent accessory = chooser.getAccessory(); 434 if (accessory != null) { 435 ((FilePreviewer) accessory).loadImage(null); 436 } 437 438 if (useEmbedInWizardCheckBox.isSelected()) { 439 WizardDialog wizard = new WizardDialog(frame, true); 440 wizard.setVisible(true); 441 wizard.dispose(); 442 return; 443 } 444 445 int retval = chooser.showDialog(frame, null); 446 if (retval == APPROVE_OPTION) { 447 JOptionPane.showMessageDialog(frame, getResultString()); 448 } else if (retval == CANCEL_OPTION) { 449 JOptionPane.showMessageDialog(frame, 450 "User cancelled operation. No file was chosen."); 451 } else if (retval == ERROR_OPTION) { 452 JOptionPane.showMessageDialog(frame, 453 "An error occurred. No file was chosen."); 454 } else { 455 JOptionPane.showMessageDialog(frame, "Unknown operation occurred."); 456 } 457 } 458 resetFileFilters(boolean enableFilters, boolean showExtensionInDescription)459 private void resetFileFilters(boolean enableFilters, 460 boolean showExtensionInDescription) { 461 chooser.resetChoosableFileFilters(); 462 if (enableFilters) { 463 FileFilter jpgFilter = createFileFilter( 464 "JPEG Compressed Image Files", 465 showExtensionInDescription, "jpg"); 466 FileFilter gifFilter = createFileFilter("GIF Image Files", 467 showExtensionInDescription, "gif"); 468 FileFilter bothFilter = createFileFilter("JPEG and GIF Image Files", 469 showExtensionInDescription, "jpg", 470 "gif"); 471 chooser.addChoosableFileFilter(bothFilter); 472 chooser.addChoosableFileFilter(jpgFilter); 473 chooser.addChoosableFileFilter(gifFilter); 474 } 475 } 476 createFileFilter(String description, boolean showExtensionInDescription, String... extensions)477 private FileFilter createFileFilter(String description, 478 boolean showExtensionInDescription, String... extensions) { 479 if (showExtensionInDescription) { 480 description = createFileNameFilterDescriptionFromExtensions( 481 description, extensions); 482 } 483 return new FileNameExtensionFilter(description, extensions); 484 } 485 createFileNameFilterDescriptionFromExtensions( String description, String[] extensions)486 private String createFileNameFilterDescriptionFromExtensions( 487 String description, String[] extensions) { 488 String fullDescription = (description == null) ? "(" : description 489 + " ("; 490 // build the description from the extension list 491 fullDescription += "." + extensions[0]; 492 for (int i = 1; i < extensions.length; i++) { 493 fullDescription += ", ."; 494 fullDescription += extensions[i]; 495 } 496 fullDescription += ")"; 497 return fullDescription; 498 } 499 500 501 private class WizardDialog extends JDialog implements ActionListener { 502 503 CardLayout cardLayout; 504 JPanel cardPanel; 505 JLabel messageLabel; 506 JButton backButton, nextButton, closeButton; 507 508 @SuppressWarnings("LeakingThisInConstructor") WizardDialog(JFrame frame, boolean modal)509 WizardDialog(JFrame frame, boolean modal) { 510 super(frame, "Embedded JFileChooser Demo", modal); 511 512 cardLayout = new CardLayout(); 513 cardPanel = new JPanel(cardLayout); 514 getContentPane().add(cardPanel, BorderLayout.CENTER); 515 516 messageLabel = new JLabel("", JLabel.CENTER); 517 cardPanel.add(chooser, "fileChooser"); 518 cardPanel.add(messageLabel, "label"); 519 cardLayout.show(cardPanel, "fileChooser"); 520 chooser.addActionListener(this); 521 522 JPanel buttonPanel = new JPanel(); 523 backButton = new JButton("< Back"); 524 nextButton = new JButton("Next >"); 525 closeButton = new JButton("Close"); 526 527 buttonPanel.add(backButton); 528 buttonPanel.add(nextButton); 529 buttonPanel.add(closeButton); 530 531 getContentPane().add(buttonPanel, BorderLayout.SOUTH); 532 533 backButton.setEnabled(false); 534 getRootPane().setDefaultButton(nextButton); 535 536 backButton.addActionListener(this); 537 nextButton.addActionListener(this); 538 closeButton.addActionListener(this); 539 540 pack(); 541 setLocationRelativeTo(frame); 542 } 543 actionPerformed(ActionEvent evt)544 public void actionPerformed(ActionEvent evt) { 545 Object src = evt.getSource(); 546 String cmd = evt.getActionCommand(); 547 548 if (src == backButton) { 549 back(); 550 } else if (src == nextButton) { 551 FileChooserUI ui = chooser.getUI(); 552 if (ui instanceof BasicFileChooserUI) { 553 // Workaround for bug 4528663. This is necessary to 554 // pick up the contents of the file chooser text field. 555 // This will trigger an APPROVE_SELECTION action. 556 ((BasicFileChooserUI) ui).getApproveSelectionAction(). 557 actionPerformed(null); 558 } else { 559 next(); 560 } 561 } else if (src == closeButton) { 562 close(); 563 } else if (APPROVE_SELECTION.equals(cmd)) { 564 next(); 565 } else if (CANCEL_SELECTION.equals(cmd)) { 566 close(); 567 } 568 } 569 back()570 private void back() { 571 backButton.setEnabled(false); 572 nextButton.setEnabled(true); 573 cardLayout.show(cardPanel, "fileChooser"); 574 getRootPane().setDefaultButton(nextButton); 575 chooser.requestFocus(); 576 } 577 next()578 private void next() { 579 backButton.setEnabled(true); 580 nextButton.setEnabled(false); 581 messageLabel.setText(getResultString()); 582 cardLayout.show(cardPanel, "label"); 583 getRootPane().setDefaultButton(closeButton); 584 closeButton.requestFocus(); 585 } 586 close()587 private void close() { 588 setVisible(false); 589 } 590 591 @Override dispose()592 public void dispose() { 593 chooser.removeActionListener(this); 594 595 // The chooser is hidden by CardLayout on remove 596 // so fix it here 597 cardPanel.remove(chooser); 598 chooser.setVisible(true); 599 600 super.dispose(); 601 } 602 } 603 getResultString()604 private String getResultString() { 605 String resultString; 606 String filter; 607 if (chooser.getFileFilter() == null) { 608 filter = ""; 609 } else { 610 filter = chooser.getFileFilter().getDescription(); 611 } 612 String path = null; 613 boolean isDirMode = (chooser.getFileSelectionMode() == DIRECTORIES_ONLY); 614 boolean isMulti = chooser.isMultiSelectionEnabled(); 615 616 if (isMulti) { 617 File[] files = chooser.getSelectedFiles(); 618 if (files != null && files.length > 0) { 619 path = ""; 620 for (File file : files) { 621 path = path + "<br>" + file.getPath(); 622 } 623 } 624 } else { 625 File file = chooser.getSelectedFile(); 626 if (file != null) { 627 path = "<br>" + file.getPath(); 628 } 629 } 630 if (path != null) { 631 path = path.replace(" ", " "); 632 filter = filter.replace(" ", " "); 633 resultString = 634 "<html>You chose " + (isMulti ? "these" : "this") + " " + (isDirMode ? (isMulti 635 ? "directories" : "directory") 636 : (isMulti ? "files" : "file")) + ": <code>" + path 637 + "</code><br><br>with filter: <br><code>" + filter; 638 } else { 639 resultString = "Nothing was chosen"; 640 } 641 return resultString; 642 } 643 644 645 /** An ActionListener that listens to the radio buttons. */ 646 private class OptionListener implements ActionListener { 647 actionPerformed(ActionEvent e)648 public void actionPerformed(ActionEvent e) { 649 JComponent c = (JComponent) e.getSource(); 650 boolean selected = false; 651 if (c instanceof JToggleButton) { 652 selected = ((JToggleButton) c).isSelected(); 653 } 654 655 if (c == openRadioButton) { 656 chooser.setDialogType(OPEN_DIALOG); 657 customField.setEnabled(false); 658 repaint(); 659 } else if (c == useEmbedInWizardCheckBox) { 660 useControlsCheckBox.setEnabled(!selected); 661 useControlsCheckBox.setSelected(!selected); 662 chooser.setControlButtonsAreShown(!selected); 663 } else if (c == useControlsCheckBox) { 664 chooser.setControlButtonsAreShown(selected); 665 } else if (c == enableDragCheckBox) { 666 chooser.setDragEnabled(selected); 667 } else if (c == saveRadioButton) { 668 chooser.setDialogType(SAVE_DIALOG); 669 customField.setEnabled(false); 670 repaint(); 671 } else if (c == customButton || c == customField) { 672 customField.setEnabled(true); 673 chooser.setDialogType(CUSTOM_DIALOG); 674 repaint(); 675 } else if (c == showAllFilesFilterCheckBox) { 676 chooser.setAcceptAllFileFilterUsed(selected); 677 } else if (c == showImageFilesFilterCheckBox) { 678 resetFileFilters(selected, 679 showFullDescriptionCheckBox.isSelected()); 680 showFullDescriptionCheckBox.setEnabled(selected); 681 } else if (c == setHiddenCheckBox) { 682 chooser.setFileHidingEnabled(!selected); 683 } else if (c == accessoryCheckBox) { 684 if (selected) { 685 chooser.setAccessory(previewer); 686 } else { 687 chooser.setAccessory(null); 688 } 689 } else if (c == useFileViewCheckBox) { 690 if (selected) { 691 chooser.setFileView(fileView); 692 } else { 693 chooser.setFileView(null); 694 } 695 } else if (c == useFileSystemViewCheckBox) { 696 if (selected) { 697 chooser.setFileSystemView(fileSystemView); 698 } else { 699 // Restore default behaviour 700 chooser.setFileSystemView(FileSystemView.getFileSystemView()); 701 } 702 } else if (c == showFullDescriptionCheckBox) { 703 resetFileFilters(showImageFilesFilterCheckBox.isSelected(), 704 selected); 705 } else if (c == justFilesRadioButton) { 706 chooser.setFileSelectionMode(FILES_ONLY); 707 } else if (c == justDirectoriesRadioButton) { 708 chooser.setFileSelectionMode(DIRECTORIES_ONLY); 709 } else if (c == bothFilesAndDirectoriesRadioButton) { 710 chooser.setFileSelectionMode(FILES_AND_DIRECTORIES); 711 } else if (c == singleSelectionRadioButton) { 712 if (selected) { 713 chooser.setMultiSelectionEnabled(false); 714 } 715 } else if (c == multiSelectionRadioButton) { 716 if (selected) { 717 chooser.setMultiSelectionEnabled(true); 718 } 719 } else if (c == lafComboBox) { 720 SupportedLaF supportedLaF = ((SupportedLaF) lafComboBox. 721 getSelectedItem()); 722 LookAndFeel laf = supportedLaF.laf; 723 try { 724 UIManager.setLookAndFeel(laf); 725 SwingUtilities.updateComponentTreeUI(frame); 726 if (chooser != null) { 727 SwingUtilities.updateComponentTreeUI(chooser); 728 } 729 frame.pack(); 730 } catch (UnsupportedLookAndFeelException exc) { 731 // This should not happen because we already checked 732 ((DefaultComboBoxModel) lafComboBox.getModel()). 733 removeElement(supportedLaF); 734 } 735 } 736 737 } 738 } 739 740 741 private class FilePreviewer extends JComponent implements 742 PropertyChangeListener { 743 744 ImageIcon thumbnail = null; 745 746 @SuppressWarnings("LeakingThisInConstructor") FilePreviewer(JFileChooser fc)747 public FilePreviewer(JFileChooser fc) { 748 setPreferredSize(new Dimension(100, 50)); 749 fc.addPropertyChangeListener(this); 750 } 751 loadImage(File f)752 public void loadImage(File f) { 753 if (f == null) { 754 thumbnail = null; 755 } else { 756 ImageIcon tmpIcon = new ImageIcon(f.getPath()); 757 if (tmpIcon.getIconWidth() > 90) { 758 thumbnail = new ImageIcon( 759 tmpIcon.getImage().getScaledInstance(90, -1, 760 Image.SCALE_DEFAULT)); 761 } else { 762 thumbnail = tmpIcon; 763 } 764 } 765 } 766 propertyChange(PropertyChangeEvent e)767 public void propertyChange(PropertyChangeEvent e) { 768 String prop = e.getPropertyName(); 769 if (SELECTED_FILE_CHANGED_PROPERTY.equals(prop)) { 770 if (isShowing()) { 771 loadImage((File) e.getNewValue()); 772 repaint(); 773 } 774 } 775 } 776 777 @Override paint(Graphics g)778 public void paint(Graphics g) { 779 if (thumbnail != null) { 780 int x = getWidth() / 2 - thumbnail.getIconWidth() / 2; 781 int y = getHeight() / 2 - thumbnail.getIconHeight() / 2; 782 if (y < 0) { 783 y = 0; 784 } 785 786 if (x < 5) { 787 x = 5; 788 } 789 thumbnail.paintIcon(this, g, x, y); 790 } 791 } 792 } 793 main(String[] s)794 public static void main(String[] s) { 795 try { 796 SwingUtilities.invokeAndWait(new Runnable() { 797 798 public void run() { 799 /* 800 * NOTE: By default, the look and feel will be set to the 801 * Cross Platform Look and Feel (which is currently Metal). 802 * The following code tries to set the Look and Feel to Nimbus. 803 * https://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/nimbus.html 804 */ 805 try { 806 for (LookAndFeelInfo info : UIManager. 807 getInstalledLookAndFeels()) { 808 if (NIMBUS_LAF_NAME.equals(info.getName())) { 809 UIManager.setLookAndFeel(info.getClassName()); 810 break; 811 } 812 } 813 } catch (Exception ignored) { 814 } 815 816 FileChooserDemo panel = new FileChooserDemo(); 817 818 frame = new JFrame("FileChooserDemo"); 819 frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 820 frame.getContentPane().add("Center", panel); 821 frame.pack(); 822 frame.setVisible(true); 823 } 824 }); 825 } catch (InterruptedException ex) { 826 Logger.getLogger(FileChooserDemo.class.getName()).log(Level.SEVERE, 827 null, 828 ex); 829 } catch (InvocationTargetException ex) { 830 Logger.getLogger(FileChooserDemo.class.getName()).log(Level.SEVERE, 831 null, 832 ex); 833 } 834 } 835 836 837 private static class InsetPanel extends JPanel { 838 839 Insets i; 840 InsetPanel(Insets i)841 InsetPanel(Insets i) { 842 this.i = i; 843 } 844 845 @Override getInsets()846 public Insets getInsets() { 847 return i; 848 } 849 } 850 } 851