1 /* 
   2  * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 package com.sun.java.swing.plaf.windows;
  26 
  27 import static com.sun.java.swing.plaf.windows.WindowsFileChooserUI.WindowsFileListUI.HOVER_CELL_PROPERTY;
  28 import static com.sun.java.swing.plaf.windows.WindowsFileChooserUI.WindowsFileListUI.ITEM_SELECTED_BORDER_COLOR;
  29 import javax.swing.*;
  30 import javax.swing.border.*;
  31 import javax.swing.filechooser.*;
  32 import javax.swing.event.*;
  33 import javax.swing.plaf.*;
  34 import javax.swing.plaf.basic.*;
  35 import java.awt.*;
  36 import static java.awt.Color.WHITE;
  37 import java.awt.event.*;
  38 import java.awt.geom.Point2D;
  39 import java.awt.image.BufferedImage;
  40 import java.beans.*;
  41 import java.io.File;
  42 import static java.lang.Boolean.TRUE;
  43 import java.util.*;
  44 import sun.swing.*;
  45 
  46 import javax.accessibility.*;
  47 import static javax.swing.Action.NAME;
  48 import static javax.swing.DefaultButtonModel.ARMED;
  49 import static javax.swing.DefaultButtonModel.PRESSED;
  50 import static javax.swing.SwingConstants.RIGHT;
  51 import sun.awt.OSInfo;
  52 import sun.awt.Win32GraphicsEnvironment;
  53 import sun.swing.FilePane.ViewType;
  54 
  55 /**
  56  * Windows L&F implementation of a FileChooser.
  57  *
  58  * @author Jeff Dinkins
  59  */
  60 public class WindowsFileChooserUI extends BasicFileChooserUI {
  61 
  62     private WindowsAddressBar addressBar;
  63 
  64     private FilterComboBoxModel filterComboBoxModel;
  65 
  66     private JTextField filenameTextField;
  67     private FilePane filePane;
  68     private WindowsNavigationTree navTree;
  69 
  70     private JButton approveButton;
  71     private JButton cancelButton;
  72 
  73     private JToolBar bottomToolbar;
  74     private JPanel bottomPanel;
  75 
  76     private final JPanel centerSplitPaneContainer = new JPanel(new BorderLayout());
  77     private final JSplitPane centerSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true) {{
  78         setUI(new BasicSplitPaneUI(){
  79             @Override
  80             public BasicSplitPaneDivider createDefaultDivider() {
  81                 return new BasicSplitPaneDivider(this){
  82                 
  83                     @Override
  84                     public void paint(Graphics g) {
  85                         Color color = new Color(214, 229, 245);
  86                         if(OSInfo.getWindowsVersion().compareTo(OSInfo.WINDOWS_7)>0)
  87                             color = SystemColor.control;
  88         
  89                         g.setColor(WHITE);
  90                         g.fillRect(0, 0, getWidth(), getHeight());
  91 
  92                         g.setColor(color);
  93                         int lineX = Math.max(getWidth() / 2, 0);
  94                         g.drawLine(lineX, 0, lineX, getHeight());
  95                     }
  96                  };
  97             }
  98             
  99         });
 100     }};
 101 
 102     private JComboBox<FileFilter> filterComboBox;
 103 
 104     private static final Dimension hstrut10 = new Dimension(10, 1);
 105 
 106     private static final Dimension vstrut4 = new Dimension(1, 4);
 107     private static final Dimension vstrut6 = new Dimension(1, 6);
 108     private static final Dimension vstrut8 = new Dimension(1, 8);
 109 
 110     private static final Insets shrinkwrap = new Insets(0, 0, 0, 0);
 111 
 112     // Preferred and Minimum sizes for the dialog box
 113     private static int PREF_WIDTH = 425;
 114     private static int PREF_HEIGHT = 245;
 115     private static Dimension PREF_SIZE = new Dimension(PREF_WIDTH, PREF_HEIGHT);
 116 
 117     private static int MIN_WIDTH = 425;
 118     private static int MIN_HEIGHT = 245;
 119 
 120     // Windows 10 values
 121     private static int LIST_PREF_WIDTH = 638; 
 122     private static int LIST_PREF_HEIGHT = 590;
 123     private static Dimension LIST_PREF_SIZE = new Dimension(LIST_PREF_WIDTH, LIST_PREF_HEIGHT);
 124 
 125     private static final Insets UTILITY_TOOLBAR_BUTTON_MARGIN = new Insets(7, 11, 7, 11);
 126 
 127     private int fileNameLabelMnemonic = 0;
 128     private String fileNameLabelText = null;
 129     private int folderNameLabelMnemonic = 0;
 130     private String folderNameLabelText = null;
 131 
 132     private int filesOfTypeLabelMnemonic = 0;
 133     private String filesOfTypeLabelText = null;
 134 
 135     private String upFolderToolTipText = null;
 136     private String upFolderAccessibleName = null;
 137 
 138     private String newFolderToolTipText = null;
 139     private String newFolderAccessibleName = null;
 140 
 141     private String viewMenuButtonToolTipText = null;
 142     private String viewMenuButtonAccessibleName = null;
 143 
 144     private BasicFileChooserUI.BasicFileView fileView = new WindowsFileView();
 145 
 146     private JLabel fileNameLabel;
 147 
 148     private void populateFileNameLabel() {
 149         if (getFileChooser().getFileSelectionMode() == JFileChooser.DIRECTORIES_ONLY) {
 150             fileNameLabel.setText(folderNameLabelText);
 151             fileNameLabel.setDisplayedMnemonic(folderNameLabelMnemonic);
 152         } else {
 153             fileNameLabel.setText(fileNameLabelText);
 154             fileNameLabel.setDisplayedMnemonic(fileNameLabelMnemonic);
 155         }
 156     }
 157 
 158     //
 159     // ComponentUI Interface Implementation methods
 160     //
 161     public static ComponentUI createUI(JComponent c) {
 162         return new WindowsFileChooserUI((JFileChooser) c);
 163     }
 164 
 165     public WindowsFileChooserUI(JFileChooser filechooser) {
 166         super(filechooser);
 167     }
 168 
 169     public void installUI(JComponent c) {
 170         super.installUI(c);
 171     }
 172 
 173     public void uninstallComponents(JFileChooser fc) {
 174         fc.removeAll();
 175     }
 176     private Deque<File> historyBack = new LinkedList<>();
 177     private Deque<File> historyForward = new LinkedList<>();
 178     private boolean isInBack;
 179     private final Action backAction = new AbstractAction() {
 180         {
 181             putValue(NAME, "Back");
 182             setEnabled(false);
 183         }
 184 
 185         @Override
 186         public void actionPerformed(ActionEvent e) {
 187             File dir = historyBack.pop();
 188             historyForward.push(getFileChooser().getCurrentDirectory());
 189 
 190             isInBack = true;
 191             getFileChooser().setCurrentDirectory(dir);
 192             isInBack = false;
 193         }
 194     };
 195     private final Action forwardAction = new AbstractAction() {
 196 
 197         {
 198             putValue(NAME, "Forward");
 199             setEnabled(false);
 200         }
 201 
 202         @Override
 203         public void actionPerformed(ActionEvent e) {
 204             assert isEnabled();
 205 
 206             File dir = historyForward.peek();
 207             getFileChooser().setCurrentDirectory(dir);
 208         }
 209     };
 210 
 211     private Action getBackAction() {
 212         return backAction;
 213     }
 214 
 215     private Action getForwardAction() {
 216         return forwardAction;
 217     }
 218 
 219     private class WindowsFileChooserUIAccessor implements FilePane.FileChooserUIAccessor {
 220 
 221         public JFileChooser getFileChooser() {
 222             return WindowsFileChooserUI.this.getFileChooser();
 223         }
 224 
 225         public BasicDirectoryModel getModel() {
 226             return WindowsFileChooserUI.this.getModel();
 227         }
 228 
 229         public JPanel createList() {
 230             return WindowsFileChooserUI.this.createList(getFileChooser());
 231         }
 232 
 233         public JPanel createDetailsView() {
 234             return WindowsFileChooserUI.this.createDetailsView(getFileChooser());
 235         }
 236 
 237         public boolean isDirectorySelected() {
 238             return WindowsFileChooserUI.this.isDirectorySelected();
 239         }
 240 
 241         public File getDirectory() {
 242             return WindowsFileChooserUI.this.getDirectory();
 243         }
 244 
 245         public Action getChangeToParentDirectoryAction() {
 246             return WindowsFileChooserUI.this.getChangeToParentDirectoryAction();
 247         }
 248 
 249         public Action getApproveSelectionAction() {
 250             return WindowsFileChooserUI.this.getApproveSelectionAction();
 251         }
 252 
 253         public Action getNewFolderAction() {
 254             return WindowsFileChooserUI.this.getNewFolderAction();
 255         }
 256 
 257         public MouseListener createDoubleClickListener(JList list) {
 258             return WindowsFileChooserUI.this.createDoubleClickListener(getFileChooser(),
 259                     list);
 260         }
 261 
 262         public ListSelectionListener createListSelectionListener() {
 263             return WindowsFileChooserUI.this.createListSelectionListener(getFileChooser());
 264         }
 265     }
 266 
 267     public void installComponents(JFileChooser fc) {
 268         filePane = new FilePane(new WindowsFileChooserUIAccessor());
 269         fc.addPropertyChangeListener(filePane);
 270 
 271         fc.setLayout(new BorderLayout());
 272 
 273         centerSplitPane.setBorder(null);
 274         
 275         centerSplitPaneContainer.add(centerSplitPane, BorderLayout.CENTER);
 276         fc.add(centerSplitPaneContainer, BorderLayout.CENTER);
 277 
 278         if (!UIManager.getBoolean("FileChooser.noPlacesBar")) {
 279             navTree = new WindowsNavigationTree(this);
 280             navTreeScrollPane = new JScrollPane(navTree);
 281             navTreeScrollPane.setBorder(null);
 282             centerSplitPane.add(navTreeScrollPane, JSplitPane.LEFT);
 283             fc.addPropertyChangeListener(navTree);
 284         }
 285             
 286         // ********************************* //
 287         // **** Construct the top panel **** //
 288         // ********************************* //
 289         
 290         // Add the top panel to the fileChooser
 291         fc.add(createTopContainer(fc), BorderLayout.NORTH);
 292 
 293         // ************************************** //
 294         // ******* Add the directory pane ******* //
 295         // ************************************** //
 296         JComponent accessory = fc.getAccessory();
 297         if (accessory != null) {
 298             getAccessoryPanel().add(accessory);
 299         }
 300         filePane.setPreferredSize(LIST_PREF_SIZE);
 301         centerSplitPane.add(filePane, JSplitPane.RIGHT);
 302         // Add the bottom panel to file chooser
 303         fc.add(getBottomPanel(), BorderLayout.SOUTH);
 304         setupBottomPanel(fc);
 305     }
 306 
 307     private void setupBottomPanel(JFileChooser fc) {
 308         getBottomPanel().setLayout(new BorderLayout());
 309         getBottomPanel().setBorder(new EmptyBorder(5, 5, 5, 5));
 310         getBottomPanel().setFont(Font.decode("Segoe UI-PLAIN-12.5"));
 311 
 312         // labels
 313         JPanel labelPanel = new JPanel();
 314         labelPanel.setOpaque(false);
 315         labelPanel.setLayout(new GridBagLayout());
 316 
 317         GridBagConstraints cons = new GridBagConstraints();
 318         cons.insets = new Insets(0, 0, 0, 5);
 319         cons.fill = GridBagConstraints.HORIZONTAL;
 320         cons.weightx = 1;
 321         cons.gridx = 0;
 322 
 323         setupFileNameLabel();
 324         labelPanel.add(fileNameLabel, cons);
 325 
 326         labelPanel.add(new JPanel(null), cons);
 327 
 328         JLabel ftl = createFileTypeLabel();
 329         labelPanel.add(ftl, cons);
 330 
 331         cons.gridx = 1;
 332         cons.insets = new Insets(0, 0, 0, 2);
 333 
 334         getBottomPanel().add(labelPanel);
 335 
 336         setupFileNameTextField();
 337 
 338         if (fc.isMultiSelectionEnabled()) {
 339             setFileName(fileNameString(fc.getSelectedFiles()));
 340         } else {
 341             setFileName(fileNameString(fc.getSelectedFile()));
 342         }
 343 
 344         labelPanel.add(filenameTextField, cons);
 345 
 346         JPanel spacer = new JPanel(null);
 347         spacer.setPreferredSize(new Dimension(0, 3));
 348         labelPanel.add(spacer, cons);
 349 
 350         createFilterComboBox(fc, ftl);
 351         labelPanel.add(filterComboBox, cons);
 352 
 353         getBottomToolbar().setBorder(new EmptyBorder(20, 4, 4, 4));
 354         getBottomToolbar().setFloatable(false);
 355 
 356         getBottomToolbar().add(Box.createHorizontalGlue());
 357 
 358         getBottomToolbar().add(new JPanel() {
 359             
 360             {
 361                 GroupLayout buttonPanelLayout = new GroupLayout(this);
 362                 setLayout(buttonPanelLayout);
 363 
 364                 setupApproveButton();
 365                 setupCancelButton();
 366 
 367                 add(approveButton);
 368                 add(cancelButton);
 369 
 370                 buttonPanelLayout.setHorizontalGroup(
 371                 buttonPanelLayout.createSequentialGroup().
 372                         addComponent(approveButton).
 373                         addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).
 374                         addComponent(cancelButton)
 375                 );
 376                 buttonPanelLayout.setVerticalGroup(
 377                     buttonPanelLayout.createParallelGroup().
 378                         addComponent(approveButton).
 379                         addComponent(cancelButton)
 380                 );
 381                 buttonPanelLayout.linkSize(approveButton, cancelButton);
 382             }
 383             
 384             private void setupApproveButton() {
 385                 approveButton = new JButton(getApproveButtonText(fc));
 386                 approveButton.setMnemonic(getApproveButtonMnemonic(fc));
 387                 approveButton.addActionListener(getApproveSelectionAction());
 388                 approveButton.setToolTipText(getApproveButtonToolTipText(fc));
 389                 approveButton.setMargin(new Insets(3, 15, 3, 15));
 390                 approveButton.setFont(getFont());
 391             }
 392 
 393             private Insets setupCancelButton() {
 394                 cancelButton = new JButton(cancelButtonText) {
 395                     public Dimension getMaximumSize() {
 396                         return approveButton.getPreferredSize().width > cancelButton.getPreferredSize().width
 397                             ? approveButton.getPreferredSize() : cancelButton.getPreferredSize();
 398                     }
 399                 };
 400                 
 401                 Insets buttonMargin = approveButton.getMargin();
 402                 cancelButton.setFont(getFont());
 403                 cancelButton.setMargin(buttonMargin);
 404                 cancelButton.setToolTipText(cancelButtonToolTipText);
 405                 cancelButton.addActionListener(getCancelSelectionAction());
 406                 return buttonMargin;
 407             }
 408 
 409         });
 410 
 411         if (fc.getControlButtonsAreShown()) {
 412             addControlButtons();
 413         }
 414     }
 415 
 416     private void createFilterComboBox(JFileChooser fc, JLabel ftl) {
 417         filterComboBoxModel = createFilterComboBoxModel();
 418         fc.addPropertyChangeListener(filterComboBoxModel);
 419         filterComboBox = new JComboBox<FileFilter>(filterComboBoxModel);
 420         ftl.setLabelFor(filterComboBox);
 421         filterComboBox.setRenderer(createFilterComboBoxRenderer());
 422         
 423         filterComboBox.setFont(bottomPanel.getFont());
 424     }
 425 
 426     private JLabel createFileTypeLabel() {
 427         JLabel ftl = new JLabel(filesOfTypeLabelText);
 428         ftl.setDisplayedMnemonic(filesOfTypeLabelMnemonic);
 429         ftl.setHorizontalAlignment(RIGHT);
 430         ftl.setFont(getBottomPanel().getFont());
 431         return ftl;
 432     }
 433 
 434     private void setupFileNameTextField() {
 435         // file entry and filters
 436         filenameTextField = new JTextField(35) {
 437             public Dimension getMaximumSize() {
 438                 return new Dimension(Short.MAX_VALUE, super.getPreferredSize().height);
 439             }
 440         };
 441 
 442         fileNameLabel.setLabelFor(filenameTextField);
 443         filenameTextField.addFocusListener(
 444                 new FocusAdapter() {
 445             @Override
 446             public void focusGained(FocusEvent e) {
 447                 if (!getFileChooser().isMultiSelectionEnabled()) {
 448                     filePane.clearSelection();
 449                 }
 450             }
 451         });
 452         
 453         filenameTextField.setFont(bottomPanel.getFont());
 454         filenameTextField.setMargin(new Insets(2, 4, 2, 4));
 455     }
 456 
 457     private void setupFileNameLabel() {
 458         fileNameLabel = new JLabel();
 459         populateFileNameLabel();
 460         fileNameLabel.setHorizontalAlignment(RIGHT);
 461         fileNameLabel.setAlignmentY(0);
 462         fileNameLabel.setFont(getBottomPanel().getFont());
 463     }
 464 
 465     private JPanel createTopContainer(JFileChooser fc) {
 466         JPanel topContainer = new JPanel(new BorderLayout());
 467 
 468         JToolBar topPanel = new JToolBar() {
 469 
 470             private boolean isWin7GradientBackground = false;
 471 
 472             {
 473                 setOpaque(true);
 474 
 475 /*                switch (getType()) {
 476                     case WIN7:
 477                         isWin7GradientBackground
 478                                 = Win32GraphicsEnvironment.isDWMCompositionEnabled();
 479                         setBackground(new Color(185, 209, 234));
 480                         // TODO: ablak unfókuszálásakor más szín kell
 481                         Win32GraphicsEnvironment.addDwmCompositionChangeListener(() -> {
 482                             isWin7GradientBackground
 483                                     = Win32GraphicsEnvironment.isDWMCompositionEnabled();
 484                             repaint();
 485                         });
 486 
 487                         //setBackground(new Color(230, 240, 250));
 488                         break;
 489                     case WIN10:*/
 490                         setBackground(WHITE);/*
 491                         break;
 492                     case CLASSIC:
 493                         setBackground(SystemColor.control);
 494                         break;
 495                     default:
 496                         throw new UnsupportedOperationException();
 497                 }*/
 498             }
 499 
 500             @Override
 501             protected void paintComponent(Graphics g) {
 502                 if (!isWin7GradientBackground) {
 503                     super.paintComponent(g);
 504                     return;
 505                 }
 506 
 507                 Graphics2D g2d = (Graphics2D) g;
 508 
 509                 g2d.setPaint(new GradientPaint(
 510                         0, 0,
 511                         new Color(250, 252, 253),
 512                         0, getHeight() / 2,
 513                         new Color(230, 240, 250)
 514                 ));
 515                 g2d.fillRect(0, 0, getWidth(), getHeight());
 516             }
 517 
 518         };
 519         topPanel.setBorder(new EmptyBorder(0, 4, 0, 0));
 520         topPanel.setFloatable(false);
 521         topPanel.putClientProperty("JToolBar.isRollover", Boolean.TRUE);
 522         topPanel.setMaximumSize(new Dimension(0, 12));
 523         topContainer.add(topPanel, BorderLayout.NORTH);
 524 
 525         JToolBar utilityToolBar = new JToolBar() {
 526 
 527             private boolean isWin7Background;
 528 
 529             {
 530 /*                switch (getType()) {
 531                     case WIN7:
 532                         isWin7Background = true;
 533                         break;
 534                     case WIN10:*/
 535                         setBackground(new Color(245, 246, 247));/*
 536                         break;
 537                 }*/
 538             }
 539 
 540             @Override
 541             protected void paintComponent(Graphics g) {
 542                 if (!isWin7Background) {
 543                     super.paintComponent(g);
 544                     return;
 545                 }
 546 
 547                 Graphics2D g2d = (Graphics2D) g;
 548 
 549                 g2d.setPaint(new LinearGradientPaint(
 550                         new Point2D.Double(0, 0),
 551                         new Point2D.Double(0, getHeight() / 2),
 552                         new float[]{0, 1},
 553                         new Color[]{new Color(250, 252, 253), new Color(230, 240, 250)}
 554                 ));
 555                 g2d.fillRect(0, 0, getWidth(), getHeight() / 2);
 556 
 557                 g2d.setPaint(new LinearGradientPaint(
 558                         new Point2D.Double(0, 0),
 559                         new Point2D.Double(0, getHeight() / 2),
 560                         new float[]{0, 1},
 561                         new Color[]{new Color(220, 230, 244), new Color(221, 233, 247)}
 562                 ));
 563                 g2d.fillRect(0, getHeight() / 2, getWidth(), getHeight() / 2);
 564             }
 565 
 566             @Override
 567             protected void addImpl(Component comp, Object constraints, int index) {
 568                 super.addImpl(comp, constraints, index);
 569                 if(comp instanceof JButton) {
 570                     JButton btn = (JButton) comp;
 571                     btn.setBorder(new EmptyBorder(btn.getInsets()));
 572                 }
 573             }
 574 
 575         };
 576         utilityToolBar.setForeground(new Color(30, 57, 91));
 577         utilityToolBar.setFloatable(false);
 578         utilityToolBar.setOpaque(true);
 579         utilityToolBar.setBorder(new MatteBorder(0, 0, 1, 0, new Color(232, 233, 234)));
 580         topContainer.add(utilityToolBar, BorderLayout.CENTER);
 581 
 582         // Back Button
 583         JButton backFolderButton = createToolButton(getBackAction(),
 584                 new ImageIcon(initBackArrowImage()),
 585                 "BACKBUTTON TOOLTIP", "BACKBUTTON ACCESSIBLENAME");
 586         topPanel.add(backFolderButton);
 587 
 588         // Forward Button
 589         JButton forwardFolderButton = createToolButton(getForwardAction(),
 590                 new ImageIcon(initForwardArrowImage()),
 591                 "FWBUTTON TOOLTIP", "FWBUTTON ACCESSIBLENAME");
 592         topPanel.add(forwardFolderButton);
 593 
 594         // Up Button
 595         JButton upFolderButton = createToolButton(getChangeToParentDirectoryAction(),
 596                 new ImageIcon(initUpArrowImage()),
 597                 upFolderToolTipText, upFolderAccessibleName);
 598         topPanel.add(upFolderButton);
 599         
 600         // Refresh Button 
 601         JButton refreshButton = new JButton(getUpdateAction());
 602         refreshButton.putClientProperty("WindowsButtonUI.displayAsInToolbar", TRUE);
 603         refreshButton.putClientProperty("WindowsButtonUI.animateStateChange", TRUE);
 604         refreshButton.setBackground(WHITE);
 605         refreshButton.setPreferredSize(new Dimension(20, 22));
 606         refreshButton.setBorder(new MatteBorder(1, 0, 1, 1, 
 607                 new Color(217, 217, 217)));
 608 
 609         // AddressBar
 610         addressBar = new WindowsAddressBar(fc);
 611 
 612         JPanel addressBarContainer = new JPanel(new BorderLayout());
 613         addressBarContainer.setBorder(new EmptyBorder(5, 3, 7, 4));
 614         addressBarContainer.setOpaque(false);
 615         addressBarContainer.add(newSpaceFiller(), BorderLayout.NORTH);
 616         addressBarContainer.add(addressBar, BorderLayout.CENTER);
 617         addressBarContainer.add(newSpaceFiller(), BorderLayout.SOUTH);
 618         addressBarContainer.add(refreshButton, BorderLayout.EAST);
 619         topPanel.add(addressBarContainer);
 620         topPanel.add(Box.createRigidArea(hstrut10));
 621 
 622         // New Directory Button
 623         if (!UIManager.getBoolean("FileChooser.readOnly")) {
 624             JButton newFolderButton = new JButton(filePane.getNewFolderAction());
 625             newFolderButton.setForeground(utilityToolBar.getForeground());
 626             newFolderButton.setOpaque(false);
 627             newFolderButton.setMargin(UTILITY_TOOLBAR_BUTTON_MARGIN);
 628             newFolderButton.setToolTipText(newFolderToolTipText);
 629             newFolderButton.getAccessibleContext().setAccessibleName(newFolderAccessibleName);
 630             utilityToolBar.add(newFolderButton);
 631         }
 632         
 633         JPanel filler = new JPanel();
 634         filler.setOpaque(false);
 635         utilityToolBar.add(filler);
 636         
 637         JButton viewMenuButton = createDetailsButton(createViewTypePopupMenu());
 638         viewMenuButton.setForeground(utilityToolBar.getForeground());
 639         viewMenuButton.setMargin(UTILITY_TOOLBAR_BUTTON_MARGIN);
 640         utilityToolBar.add(viewMenuButton);
 641 
 642         initViewTypeMenuIcon();
 643 
 644         return topContainer;
 645     }
 646 
 647     private static JPanel newSpaceFiller() {
 648         JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
 649         panel.setOpaque(false);
 650         return panel;
 651     }
 652 
 653     private void initViewTypeMenuIcon() {
 654         // Create icon for viewMenuButton
 655         BufferedImage image = new BufferedImage(viewMenuIcon.getIconWidth() + 7, viewMenuIcon.getIconHeight(),
 656                 BufferedImage.TYPE_INT_ARGB);
 657         Graphics graphics = image.getGraphics();
 658         viewMenuIcon.paintIcon(filePane, graphics, 0, 0);
 659         int x = image.getWidth() - 5;
 660         int y = image.getHeight() / 2 - 1;
 661         graphics.setColor(Color.BLACK);
 662         graphics.fillPolygon(new int[]{x, x + 5, x + 2}, new int[]{y, y, y + 3}, 3);
 663     }
 664 
 665     private JPopupMenu createViewTypePopupMenu() {
 666         // View button group
 667         ButtonGroup viewButtonGroup = new ButtonGroup();
 668 
 669         // Popup Menu
 670         final JPopupMenu viewTypePopupMenu = new JPopupMenu();
 671 
 672         Map<ViewType, JRadioButtonMenuItem> viewTypeMenuItems
 673                 = new EnumMap<>(ViewType.class);
 674 
 675         for (ViewType viewType : ViewType.values()) {
 676             final JRadioButtonMenuItem menuItem = new JRadioButtonMenuItem(
 677                     filePane.getViewTypeAction(viewType));
 678             menuItem.setSelected(filePane.getViewType() == viewType);
 679             viewTypePopupMenu.add(menuItem);
 680             viewButtonGroup.add(menuItem);
 681 
 682             viewTypeMenuItems.put(viewType, menuItem);
 683         }
 684 
 685         filePane.addPropertyChangeListener(evt -> {
 686             if ("viewType".equals(evt.getPropertyName())) {
 687                 viewTypeMenuItems.get(filePane.getViewType()).setSelected(true);
 688             }
 689         });
 690 
 691         return viewTypePopupMenu;
 692     }
 693 
 694     private JButton createDetailsButton(final JPopupMenu viewTypePopupMenu) {
 695         // Details Button
 696         final JButton viewMenuButton = createToolButton(new AbstractAction("Rendezés"){
 697             @Override
 698             public void actionPerformed(ActionEvent e) {
 699             }
 700         }, null, viewMenuButtonToolTipText,
 701                 viewMenuButtonAccessibleName);
 702         viewMenuButton.addActionListener(evt->{
 703             viewTypePopupMenu.show(viewMenuButton, 0, viewMenuButton.getHeight());
 704         });
 705         viewMenuButton.setOpaque(false);
 706         viewMenuButton.setMargin(UTILITY_TOOLBAR_BUTTON_MARGIN);
 707         viewTypePopupMenu.addPopupMenuListener(new PopupMenuListener() {
 708             public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
 709                 viewMenuButton.setSelected(true);
 710             }
 711 
 712             public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
 713                 SwingUtilities.invokeLater(new Runnable() {
 714                     public void run() {
 715                         viewMenuButton.setSelected(false);
 716                     }
 717                 });
 718             }
 719 
 720             public void popupMenuCanceled(PopupMenuEvent e) {
 721             }
 722         });
 723         return viewMenuButton;
 724     }
 725 
 726     private JScrollPane navTreeScrollPane;
 727 
 728     protected JToolBar getBottomToolbar() {
 729         if (bottomToolbar == null) {
 730             bottomToolbar = new JToolBar();
 731         }
 732         return bottomToolbar;
 733     }
 734 
 735     protected JPanel getBottomPanel() {
 736         if (bottomPanel == null) {
 737             bottomPanel = new JPanel();
 738         }
 739         return bottomPanel;
 740     }
 741 
 742     protected void installStrings(JFileChooser fc) {
 743         super.installStrings(fc);
 744 
 745         Locale l = fc.getLocale();
 746 
 747         fileNameLabelMnemonic = getMnemonic("FileChooser.fileNameLabelMnemonic", l);
 748         fileNameLabelText = UIManager.getString("FileChooser.fileNameLabelText", l);
 749 
 750         filesOfTypeLabelMnemonic = getMnemonic("FileChooser.filesOfTypeLabelMnemonic", l);
 751         filesOfTypeLabelText = UIManager.getString("FileChooser.filesOfTypeLabelText", l);
 752 
 753         upFolderToolTipText = UIManager.getString("FileChooser.upFolderToolTipText", l);
 754         upFolderAccessibleName = UIManager.getString("FileChooser.upFolderAccessibleName", l);
 755 
 756         newFolderToolTipText = UIManager.getString("FileChooser.newFolderToolTipText", l);
 757         newFolderAccessibleName = UIManager.getString("FileChooser.newFolderAccessibleName", l);
 758 
 759         viewMenuButtonToolTipText = UIManager.getString("FileChooser.viewMenuButtonToolTipText", l);
 760         viewMenuButtonAccessibleName = UIManager.getString("FileChooser.viewMenuButtonAccessibleName", l);
 761     }
 762 
 763     private Integer getMnemonic(String key, Locale l) {
 764         return SwingUtilities2.getUIDefaultsInt(key, l);
 765     }
 766 
 767     protected void installListeners(JFileChooser fc) {
 768         super.installListeners(fc);
 769         ActionMap actionMap = getActionMap();
 770         SwingUtilities.replaceUIActionMap(fc, actionMap);
 771 
 772         fc.addPropertyChangeListener(JFileChooser.DIRECTORY_CHANGED_PROPERTY, evt -> {
 773             if (!isInBack) {
 774                 if (!historyForward.isEmpty()) {
 775                     if (historyForward.peek().equals(evt.getNewValue())) {
 776                         historyForward.pop();
 777                     } else {
 778                         historyForward.clear();
 779                     }
 780                 }
 781 
 782                 if (evt.getOldValue() != null) {
 783                     historyBack.push((File) evt.getOldValue());
 784                 }
 785             }
 786 
 787             getBackAction().setEnabled(!historyBack.isEmpty());
 788             getForwardAction().setEnabled(!historyForward.isEmpty());
 789         });
 790     }
 791 
 792     protected ActionMap getActionMap() {
 793         return createActionMap();
 794     }
 795 
 796     protected ActionMap createActionMap() {
 797         ActionMap map = new ActionMapUIResource();
 798         FilePane.addActionsToMap(map, filePane.getActions());
 799         FilePane.addActionsToMap(map, new Action[]{getChangeToParentDirectoryAction()});
 800         return map;
 801     }
 802 
 803     protected JPanel createList(JFileChooser fc) {
 804         return filePane.createList();
 805     }
 806 
 807     protected JPanel createDetailsView(JFileChooser fc) {
 808         return filePane.createDetailsView();
 809     }
 810 
 811     /**
 812      * Creates a selection listener for the list of files and directories.
 813      *
 814      * @param fc a <code>JFileChooser</code>
 815      * @return a <code>ListSelectionListener</code>
 816      */
 817     public ListSelectionListener createListSelectionListener(JFileChooser fc) {
 818         return super.createListSelectionListener(fc);
 819     }
 820 
 821     public void uninstallUI(JComponent c) {
 822         // Remove listeners
 823         c.removePropertyChangeListener(filterComboBoxModel);
 824         c.removePropertyChangeListener(filePane);
 825         if (navTree != null) {
 826             c.removePropertyChangeListener(navTree);
 827         }
 828         cancelButton.removeActionListener(getCancelSelectionAction());
 829         approveButton.removeActionListener(getApproveSelectionAction());
 830         filenameTextField.removeActionListener(getApproveSelectionAction());
 831 
 832         if (filePane != null) {
 833             filePane.uninstallUI();
 834             filePane = null;
 835         }
 836 
 837         super.uninstallUI(c);
 838     }
 839 
 840     /**
 841      * Returns the preferred size of the specified <code>JFileChooser</code>.
 842      * The preferred size is at least as large, in both height and width, as the
 843      * preferred size recommended by the file chooser's layout manager.
 844      *
 845      * @param c a <code>JFileChooser</code>
 846      * @return a <code>Dimension</code> specifying the preferred width and
 847      * height of the file chooser
 848      */
 849     @Override
 850     public Dimension getPreferredSize(JComponent c) {
 851         int prefWidth = PREF_SIZE.width;
 852         Dimension d = c.getLayout().preferredLayoutSize(c);
 853         if (d != null) {
 854             return new Dimension(d.width < prefWidth ? prefWidth : d.width,
 855                     d.height < PREF_SIZE.height ? PREF_SIZE.height : d.height);
 856         } else {
 857             return new Dimension(prefWidth, PREF_SIZE.height);
 858         }
 859     }
 860 
 861     /**
 862      * Returns the minimum size of the <code>JFileChooser</code>.
 863      *
 864      * @param c a <code>JFileChooser</code>
 865      * @return a <code>Dimension</code> specifying the minimum width and height
 866      * of the file chooser
 867      */
 868     @Override
 869     public Dimension getMinimumSize(JComponent c) {
 870         return new Dimension(MIN_WIDTH, MIN_HEIGHT);
 871     }
 872 
 873     /**
 874      * Returns the maximum size of the <code>JFileChooser</code>.
 875      *
 876      * @param c a <code>JFileChooser</code>
 877      * @return a <code>Dimension</code> specifying the maximum width and height
 878      * of the file chooser
 879      */
 880     @Override
 881     public Dimension getMaximumSize(JComponent c) {
 882         return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
 883     }
 884 
 885     private String fileNameString(File file) {
 886         if (file == null) {
 887             return null;
 888         } else {
 889             JFileChooser fc = getFileChooser();
 890             if ((fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled())
 891                     || (fc.isDirectorySelectionEnabled() && fc.isFileSelectionEnabled() && fc.getFileSystemView().isFileSystemRoot(file))) {
 892                 return file.getPath();
 893             } else {
 894                 return file.getName();
 895             }
 896         }
 897     }
 898 
 899     private String fileNameString(File[] files) {
 900         StringBuffer buf = new StringBuffer();
 901         for (int i = 0; files != null && i < files.length; i++) {
 902             if (i > 0) {
 903                 buf.append(" ");
 904             }
 905             if (files.length > 1) {
 906                 buf.append("\"");
 907             }
 908             buf.append(fileNameString(files[i]));
 909             if (files.length > 1) {
 910                 buf.append("\"");
 911             }
 912         }
 913         return buf.toString();
 914     }
 915 
 916     /* The following methods are used by the PropertyChange Listener */
 917     private void doSelectedFileChanged(PropertyChangeEvent e) {
 918         File f = (File) e.getNewValue();
 919         JFileChooser fc = getFileChooser();
 920         if (f != null
 921                 && ((fc.isFileSelectionEnabled() && !f.isDirectory())
 922                 || (f.isDirectory() && fc.isDirectorySelectionEnabled()))) {
 923 
 924             setFileName(fileNameString(f));
 925         }
 926     }
 927 
 928     private void doSelectedFilesChanged(PropertyChangeEvent e) {
 929         File[] files = (File[]) e.getNewValue();
 930         JFileChooser fc = getFileChooser();
 931         if (files != null
 932                 && files.length > 0
 933                 && (files.length > 1 || fc.isDirectorySelectionEnabled() || !files[0].isDirectory())) {
 934             setFileName(fileNameString(files));
 935         }
 936     }
 937 
 938     private void doDirectoryChanged(PropertyChangeEvent e) {
 939         JFileChooser fc = getFileChooser();
 940         FileSystemView fsv = fc.getFileSystemView();
 941 
 942         clearIconCache();
 943         File currentDirectory = fc.getCurrentDirectory();
 944         if (currentDirectory != null) {
 945             if (fc.isDirectorySelectionEnabled() && !fc.isFileSelectionEnabled()) {
 946                 if (fsv.isFileSystem(currentDirectory)) {
 947                     setFileName(currentDirectory.getPath());
 948                 } else {
 949                     setFileName(null);
 950                 }
 951             }
 952         }
 953     }
 954 
 955     private void doFilterChanged(PropertyChangeEvent e) {
 956         clearIconCache();
 957     }
 958 
 959     private void doFileSelectionModeChanged(PropertyChangeEvent e) {
 960         if (fileNameLabel != null) {
 961             populateFileNameLabel();
 962         }
 963         clearIconCache();
 964 
 965         JFileChooser fc = getFileChooser();
 966         File currentDirectory = fc.getCurrentDirectory();
 967         if (currentDirectory != null
 968                 && fc.isDirectorySelectionEnabled()
 969                 && !fc.isFileSelectionEnabled()
 970                 && fc.getFileSystemView().isFileSystem(currentDirectory)) {
 971 
 972             setFileName(currentDirectory.getPath());
 973         } else {
 974             setFileName(null);
 975         }
 976     }
 977 
 978     private void doAccessoryChanged(PropertyChangeEvent e) {
 979         if (getAccessoryPanel() != null) {
 980             if (e.getOldValue() != null) {
 981                 getAccessoryPanel().remove((JComponent) e.getOldValue());
 982             }
 983             JComponent accessory = (JComponent) e.getNewValue();
 984             if (accessory != null) {
 985                 getAccessoryPanel().add(accessory, BorderLayout.CENTER);
 986             }
 987         }
 988     }
 989 
 990     private void doApproveButtonTextChanged(PropertyChangeEvent e) {
 991         JFileChooser chooser = getFileChooser();
 992         approveButton.setText(getApproveButtonText(chooser));
 993         approveButton.setToolTipText(getApproveButtonToolTipText(chooser));
 994         approveButton.setMnemonic(getApproveButtonMnemonic(chooser));
 995     }
 996 
 997     private void doDialogTypeChanged(PropertyChangeEvent e) {
 998         JFileChooser chooser = getFileChooser();
 999         approveButton.setText(getApproveButtonText(chooser));
1000         approveButton.setToolTipText(getApproveButtonToolTipText(chooser));
1001         approveButton.setMnemonic(getApproveButtonMnemonic(chooser));
1002     }
1003 
1004     private void doApproveButtonMnemonicChanged(PropertyChangeEvent e) {
1005         approveButton.setMnemonic(getApproveButtonMnemonic(getFileChooser()));
1006     }
1007 
1008     private void doControlButtonsChanged(PropertyChangeEvent e) {
1009         if (getFileChooser().getControlButtonsAreShown()) {
1010             addControlButtons();
1011         } else {
1012             removeControlButtons();
1013         }
1014     }
1015 
1016     /*
1017      * Listen for filechooser property changes, such as
1018      * the selected file changing, or the type of the dialog changing.
1019      */
1020     public PropertyChangeListener createPropertyChangeListener(JFileChooser fc) {
1021         return (PropertyChangeEvent e) -> {
1022             String s = e.getPropertyName();
1023             switch (s) {
1024                 case JFileChooser.SELECTED_FILE_CHANGED_PROPERTY:
1025                     doSelectedFileChanged(e);
1026                     break;
1027                 case JFileChooser.SELECTED_FILES_CHANGED_PROPERTY:
1028                     doSelectedFilesChanged(e);
1029                     break;
1030                 case JFileChooser.DIRECTORY_CHANGED_PROPERTY:
1031                     doDirectoryChanged(e);
1032                     break;
1033                 case JFileChooser.FILE_FILTER_CHANGED_PROPERTY:
1034                     doFilterChanged(e);
1035                     break;
1036                 case JFileChooser.FILE_SELECTION_MODE_CHANGED_PROPERTY:
1037                     doFileSelectionModeChanged(e);
1038                     break;
1039                 case JFileChooser.ACCESSORY_CHANGED_PROPERTY:
1040                     doAccessoryChanged(e);
1041                     break;
1042                 case JFileChooser.APPROVE_BUTTON_TEXT_CHANGED_PROPERTY:
1043                 case JFileChooser.APPROVE_BUTTON_TOOL_TIP_TEXT_CHANGED_PROPERTY:
1044                     doApproveButtonTextChanged(e);
1045                     break;
1046                 case JFileChooser.DIALOG_TYPE_CHANGED_PROPERTY:
1047                     doDialogTypeChanged(e);
1048                     break;
1049                 case JFileChooser.APPROVE_BUTTON_MNEMONIC_CHANGED_PROPERTY:
1050                     doApproveButtonMnemonicChanged(e);
1051                     break;
1052                 case JFileChooser.CONTROL_BUTTONS_ARE_SHOWN_CHANGED_PROPERTY:
1053                     doControlButtonsChanged(e);
1054                     break;
1055                 case "FileChooser.useShellFolder":
1056                     doDirectoryChanged(e);
1057                     break;
1058                 case "componentOrientation":
1059                     ComponentOrientation o = (ComponentOrientation) e.getNewValue();
1060                     JFileChooser cc = (JFileChooser) e.getSource();
1061                     if (o != e.getOldValue()) {
1062                         cc.applyComponentOrientation(o);
1063                     }
1064                     break;
1065                 case "ancestor":
1066                     if (e.getOldValue() == null && e.getNewValue() != null) {
1067                         // Ancestor was added, set initial focus
1068                         filenameTextField.selectAll();
1069                         filenameTextField.requestFocus();
1070                     }
1071                     break;
1072             }
1073         };
1074     }
1075 
1076     protected void removeControlButtons() {
1077         getBottomPanel().remove(getBottomToolbar());
1078     }
1079 
1080     protected void addControlButtons() {
1081         getBottomPanel().add(getBottomToolbar(), BorderLayout.SOUTH);
1082     }
1083 
1084     public void ensureFileIsVisible(JFileChooser fc, File f) {
1085         filePane.ensureFileIsVisible(fc, f);
1086     }
1087 
1088     public void rescanCurrentDirectory(JFileChooser fc) {
1089         filePane.rescanCurrentDirectory();
1090     }
1091 
1092     public String getFileName() {
1093         if (filenameTextField != null) {
1094             return filenameTextField.getText();
1095         } else {
1096             return null;
1097         }
1098     }
1099 
1100     @Override
1101     public void setFileName(String filename) {
1102         if (filenameTextField != null) {
1103             filenameTextField.setText(filename);
1104         }
1105     }
1106 
1107     /**
1108      * Property to remember whether a directory is currently selected in the UI.
1109      * This is normally called by the UI on a selection event.
1110      *
1111      * @param directorySelected if a directory is currently selected.
1112      * @since 1.4
1113      */
1114     @Override
1115     protected void setDirectorySelected(boolean directorySelected) {
1116         super.setDirectorySelected(directorySelected);
1117         JFileChooser chooser = getFileChooser();
1118         if (directorySelected) {
1119             approveButton.setText(directoryOpenButtonText);
1120             approveButton.setToolTipText(directoryOpenButtonToolTipText);
1121             approveButton.setMnemonic(directoryOpenButtonMnemonic);
1122         } else {
1123             approveButton.setText(getApproveButtonText(chooser));
1124             approveButton.setToolTipText(getApproveButtonToolTipText(chooser));
1125             approveButton.setMnemonic(getApproveButtonMnemonic(chooser));
1126         }
1127     }
1128 
1129     @Override
1130     public Action getUpdateAction() {
1131         return new UpdateAction() {
1132             
1133             {
1134                 putValue(Action.SMALL_ICON, new ImageIcon(initRefreshImage()));
1135             }
1136             
1137             @Override
1138             public void actionPerformed(ActionEvent e) {
1139                 rescanCurrentDirectory(getFileChooser());
1140             }
1141             
1142         };
1143     }
1144 
1145     
1146     public String getDirectoryName() {
1147         System.out.println(getFileChooser().getCurrentDirectory().getPath());
1148         return getFileChooser().getCurrentDirectory().getPath();
1149     }
1150 
1151     public void setDirectoryName(String dirname) {
1152         // PENDING(jeff) - set the name in the directory combobox
1153     }
1154 
1155     private static JButton createToolButton(Action a, Icon defaultIcon, String toolTipText, String accessibleName) {
1156         final JButton result = new JButton(a);
1157 
1158         if (defaultIcon != null) {
1159             result.setText(null);
1160             result.setIcon(defaultIcon);
1161         }
1162         result.setToolTipText(toolTipText);
1163         result.setRequestFocusEnabled(false);
1164         result.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, accessibleName);
1165         result.putClientProperty(WindowsLookAndFeel.HI_RES_DISABLED_ICON_CLIENT_KEY, Boolean.TRUE);
1166         result.setAlignmentX(JComponent.LEFT_ALIGNMENT);
1167         result.setAlignmentY(JComponent.CENTER_ALIGNMENT);
1168         result.setMargin(new Insets(5, 5, 5, 5));
1169         result.setOpaque(false);
1170         result.setFocusPainted(false);
1171 
1172         result.setModel(new DefaultButtonModel() {
1173             @Override
1174             public void setPressed(boolean b) {
1175                 // Forbid keyboard actions if the button is not in rollover state
1176                 if (!b || isRollover()) {
1177                     super.setPressed(b);
1178                 }
1179             }
1180 
1181             @Override
1182             public void setRollover(boolean b) {
1183                 if (b && !isRollover()) {
1184                     // Reset other buttons
1185                     for (Component component : result.getParent().getComponents()) {
1186                         if (component instanceof JButton && component != result) {
1187                             ((JButton) component).getModel().setRollover(false);
1188                         }
1189                     }
1190                 }
1191 
1192                 super.setRollover(b);
1193             }
1194 
1195             public void setSelected(boolean b) {
1196                 super.setSelected(b);
1197 
1198                 if (b) {
1199                     stateMask |= PRESSED | ARMED;
1200                 } else {
1201                     stateMask &= ~(PRESSED | ARMED);
1202                 }
1203             }
1204         });
1205         result.getModel().setEnabled(a.isEnabled());
1206 
1207         result.addFocusListener(new FocusAdapter() {
1208             public void focusGained(FocusEvent e) {
1209                 result.getModel().setRollover(true);
1210             }
1211 
1212             public void focusLost(FocusEvent e) {
1213                 result.getModel().setRollover(false);
1214             }
1215         });
1216 
1217         return result;
1218     }
1219 
1220     //
1221     // Renderer for Types ComboBox
1222     //
1223     protected FilterComboBoxRenderer createFilterComboBoxRenderer() {
1224         return new FilterComboBoxRenderer();
1225     }
1226 
1227     /**
1228      * Render different type sizes and styles.
1229      */
1230     public class FilterComboBoxRenderer extends DefaultListCellRenderer {
1231         public Component getListCellRendererComponent(JList<?> list,
1232                 Object value, int index, boolean isSelected,
1233                 boolean cellHasFocus) {
1234 
1235             super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
1236 
1237             if (value != null && value instanceof FileFilter) {
1238                 setText(((FileFilter)value).getDescription());
1239             }
1240 
1241             return this;
1242         }
1243     }
1244 
1245     //
1246     // DataModel for Types Comboxbox
1247     //
1248     protected FilterComboBoxModel createFilterComboBoxModel() {
1249         return new FilterComboBoxModel();
1250     }
1251 
1252     /**
1253      * Data model for a type-face selection combo-box.
1254      */
1255     @SuppressWarnings("serial") // Superclass is not serializable across versions
1256     protected class FilterComboBoxModel extends AbstractListModel<FileFilter> implements ComboBoxModel<FileFilter>,
1257             PropertyChangeListener {
1258         protected FileFilter[] filters;
1259         protected FilterComboBoxModel() {
1260             super();
1261             filters = getFileChooser().getChoosableFileFilters();
1262         }
1263 
1264         public void propertyChange(PropertyChangeEvent e) {
1265             String prop = e.getPropertyName();
1266             if(prop == JFileChooser.CHOOSABLE_FILE_FILTER_CHANGED_PROPERTY) {
1267                 filters = (FileFilter[]) e.getNewValue();
1268                 fireContentsChanged(this, -1, -1);
1269             } else if (prop == JFileChooser.FILE_FILTER_CHANGED_PROPERTY) {
1270                 fireContentsChanged(this, -1, -1);
1271             }
1272         }
1273 
1274         public void setSelectedItem(Object filter) {
1275             if(filter != null) {
1276                 getFileChooser().setFileFilter((FileFilter) filter);
1277                 fireContentsChanged(this, -1, -1);
1278             }
1279         }
1280 
1281         public Object getSelectedItem() {
1282             // Ensure that the current filter is in the list.
1283             // NOTE: we shouldnt' have to do this, since JFileChooser adds
1284             // the filter to the choosable filters list when the filter
1285             // is set. Lets be paranoid just in case someone overrides
1286             // setFileFilter in JFileChooser.
1287             FileFilter currentFilter = getFileChooser().getFileFilter();
1288             boolean found = false;
1289             if(currentFilter != null) {
1290                 for (FileFilter filter : filters) {
1291                     if (filter == currentFilter) {
1292                         found = true;
1293                     }
1294                 }
1295                 if(found == false) {
1296                     getFileChooser().addChoosableFileFilter(currentFilter);
1297                 }
1298             }
1299             return getFileChooser().getFileFilter();
1300         }
1301 
1302         public int getSize() {
1303             if(filters != null) {
1304                 return filters.length;
1305             } else {
1306                 return 0;
1307             }
1308         }
1309 
1310         public FileFilter getElementAt(int index) {
1311             if(index > getSize() - 1) {
1312                 // This shouldn't happen. Try to recover gracefully.
1313                 return getFileChooser().getFileFilter();
1314             }
1315             if(filters != null) {
1316                 return filters[index];
1317             } else {
1318                 return null;
1319             }
1320         }
1321     }
1322 
1323     public void valueChanged(ListSelectionEvent e) {
1324         JFileChooser fc = getFileChooser();
1325         File f = fc.getSelectedFile();
1326         if (!e.getValueIsAdjusting() && f != null && !getFileChooser().isTraversable(f)) {
1327             setFileName(fileNameString(f));
1328         }
1329     }
1330 
1331     protected JButton getApproveButton(JFileChooser fc) {
1332         return approveButton;
1333     }
1334 
1335     public FileView getFileView(JFileChooser fc) {
1336         return fileView;
1337     }
1338 
1339     // ***********************
1340     // * FileView operations *
1341     // ***********************
1342     protected class WindowsFileView extends BasicFileView {
1343         /* FileView type descriptions */
1344 
1345         public Icon getIcon(File f) {
1346             Icon icon = getCachedIcon(f);
1347             if (icon != null) {
1348                 return icon;
1349             }
1350             if (f != null) {
1351                 icon = getFileChooser().getFileSystemView().getSystemIcon(f);
1352             }
1353             if (icon == null) {
1354                 icon = super.getIcon(f);
1355             }
1356             cacheIcon(f, icon);
1357             return icon;
1358         }
1359     }
1360 
1361     public static class WindowsFileListUI extends BasicListUI {
1362 
1363         public static final Color ITEM_SELECTED_COLOR = new Color(204, 232, 255);
1364         public static final Color ITEM_HOVERED_COLOR = new Color(229, 243, 255);
1365         public static final Color ITEM_SELECTED_UNFOCUSED_COLOR = new Color(217, 217, 217);
1366         public static final Color ITEM_SELECTED_BORDER_COLOR = new Color(153, 209, 255);
1367         public static final Border ITEM_SELECTED_BORDER
1368                 = new LineBorder(ITEM_SELECTED_BORDER_COLOR);
1369 
1370         public static final String HOVER_CELL_PROPERTY = "WindowsFileListUI.hoverCell";
1371         public static final String CELL_WIDTH_PROPERTY = "WindowsFileListUI.cellWidth";
1372 
1373         private Rectangle selectionRectangle;
1374         private final JFileChooser fileChooser;
1375 
1376         public WindowsFileListUI(JFileChooser fileChooser) {
1377             this.fileChooser = fileChooser;
1378         }
1379 
1380         @Override
1381         protected void installListeners() {
1382             super.installListeners();
1383 
1384             MouseAdapter mouseListener = new MouseAdapter() {
1385                 @Override
1386                 public void mouseExited(MouseEvent e) {
1387                     setHoverCell(-1);
1388                 }
1389 
1390                 @Override
1391                 public void mouseMoved(MouseEvent e) {
1392                     int hoverCell = list.locationToIndex(e.getPoint());
1393                     if (hoverCell != -1 && !list.getCellBounds(
1394                             hoverCell, hoverCell).contains(e.getPoint())) {
1395                         hoverCell = -1;
1396                     }
1397                     setHoverCell(hoverCell);
1398                 }
1399 
1400                 private void setHoverCell(int hoverCell) {
1401                     list.putClientProperty(HOVER_CELL_PROPERTY, hoverCell);
1402                     list.repaint();
1403                 }
1404                 private Point press;
1405 
1406                 @Override
1407                 public void mousePressed(MouseEvent e) {
1408                     press = e.getPoint();
1409                 }
1410 
1411                 @Override
1412                 public void mouseDragged(MouseEvent e) {
1413                     if (!fileChooser.isMultiSelectionEnabled()) {
1414                         return;
1415                     }
1416 
1417                     int x = press.x, y = press.y, w, h;
1418 
1419                     if (e.getX() < x) {
1420                         w = x - e.getX();
1421                         x -= w;
1422                     } else {
1423                         w = e.getX() - x;
1424                     }
1425 
1426                     if (e.getY() < y) {
1427                         h = y - e.getY();
1428                         y -= h;
1429                     } else {
1430                         h = e.getY() - y;
1431                     }
1432 
1433                     selectionRectangle = new Rectangle(x, y, w, h);
1434 
1435                     Set<Integer> toBeSelected = new HashSet<>();
1436                     for (int i = 0; i < list.getModel().getSize(); i++) {
1437                         if (list.getCellBounds(i, i).intersects(selectionRectangle)) {
1438                             toBeSelected.add(i);
1439                         }
1440                     }
1441                     list.getSelectionModel().clearSelection();
1442                     for (Integer cell : toBeSelected) {
1443                         list.getSelectionModel().addSelectionInterval(cell, cell);
1444                     }
1445                     list.repaint();
1446                 }
1447 
1448                 @Override
1449                 public void mouseReleased(MouseEvent e) {
1450                     selectionRectangle = null;
1451                     list.repaint();
1452                 }
1453 
1454             };
1455 
1456             list.addMouseListener(mouseListener);
1457             list.addMouseMotionListener(mouseListener);
1458 
1459             list.addFocusListener(new FocusListener() {
1460                 @Override
1461                 public void focusGained(FocusEvent e) {
1462                     list.repaint();
1463                 }
1464 
1465                 @Override
1466                 public void focusLost(FocusEvent e) {
1467                     list.repaint();
1468                 }
1469 
1470             });
1471         }
1472 
1473         @Override
1474         protected void updateLayoutState() {
1475             super.updateLayoutState();
1476             list.putClientProperty(CELL_WIDTH_PROPERTY, cellWidth);
1477         }
1478 
1479         @Override
1480         public void paint(Graphics g, JComponent c) {
1481             super.paint(g, c);
1482 
1483             if (selectionRectangle != null) {
1484                 g.setColor(new Color(0, 102, 204, 85));
1485                 g.fillRect(selectionRectangle.x, selectionRectangle.y,
1486                         selectionRectangle.width, selectionRectangle.height);
1487 
1488                 g.setColor(new Color(0, 128, 255, 204));
1489                 g.drawRect(selectionRectangle.x, selectionRectangle.y,
1490                         selectionRectangle.width, selectionRectangle.height);
1491             }
1492         }
1493 
1494     }
1495 
1496     public static class WindowsFileTableUI extends BasicTableUI {
1497 
1498         public static final Border ITEM_SELECTED_BORDER_LEFT_CELL
1499                 = new CompoundBorder(
1500                         new MatteBorder(1, 1, 1, 0, ITEM_SELECTED_BORDER_COLOR), 
1501                         new EmptyBorder(0, 0, 0, 1)
1502                 );
1503 
1504         public static final Border ITEM_SELECTED_BORDER_MID_CELL
1505                 = new CompoundBorder(
1506                        new MatteBorder(1, 0, 1, 0, ITEM_SELECTED_BORDER_COLOR),
1507                        new EmptyBorder(0, 1, 0, 1)
1508                 );
1509         
1510 
1511         public static final Border ITEM_SELECTED_BORDER_RIGHT_CELL
1512                 = new CompoundBorder(
1513                         new MatteBorder(1, 0, 1, 1, ITEM_SELECTED_BORDER_COLOR),
1514                         new EmptyBorder(0, 1, 0, 0)
1515                 );
1516                         
1517         private Rectangle selectionRectangle;
1518         private final JFileChooser fileChooser;
1519 
1520         public WindowsFileTableUI(JFileChooser fileChooser) {
1521             this.fileChooser = fileChooser;
1522         }
1523 
1524         @Override
1525         protected void installListeners() {
1526             super.installListeners();
1527 
1528             MouseAdapter mouseListener = new MouseAdapter() {
1529                 @Override
1530                 public void mouseExited(MouseEvent e) {
1531                     setHoverCell(-1);
1532                 }
1533 
1534                 @Override
1535                 public void mouseMoved(MouseEvent e) {
1536                     int hoverRow = table.rowAtPoint(e.getPoint());
1537                     if (hoverRow != -1 && !containsIgnoreX(
1538                             table.getCellRect(hoverRow, 0, true),
1539                             e.getPoint())) {
1540                         hoverRow = -1; // outside any row
1541                     }
1542                     setHoverCell(hoverRow);
1543                 }
1544                 
1545                 private boolean containsIgnoreX(Rectangle rect, Point p) {
1546                     return p.y >= rect.y && p.y < rect.y + rect.height;
1547                 }
1548 
1549                 private void setHoverCell(int hoverCell) {
1550                     table.putClientProperty(HOVER_CELL_PROPERTY, hoverCell);
1551                     table.repaint();
1552                 }
1553                 
1554                 private Point press;
1555 
1556                 @Override
1557                 public void mousePressed(MouseEvent e) {
1558                     press = e.getPoint();
1559                 }
1560 
1561                 @Override
1562                 public void mouseDragged(MouseEvent e) {
1563                     if (!fileChooser.isMultiSelectionEnabled()) {
1564                         return;
1565                     }
1566 
1567                     int x = press.x, y = press.y, w, h;
1568 
1569                     if (e.getX() < x) {
1570                         w = x - e.getX();
1571                         x -= w;
1572                     } else {
1573                         w = e.getX() - x;
1574                     }
1575 
1576                     if (e.getY() < y) {
1577                         h = y - e.getY();
1578                         y -= h;
1579                     } else {
1580                         h = e.getY() - y;
1581                     }
1582 
1583                     Rectangle rect = selectionRectangle == null ? new Rectangle()
1584                             : new Rectangle(selectionRectangle);
1585                     selectionRectangle = new Rectangle(x, y, w, h);
1586 
1587                     Rectangle union = selectionRectangle.union(rect);
1588                     union.x--;
1589                     union.y--;
1590                     union.width += 2;
1591                     union.height += 2;
1592                     table.paintImmediately(union);
1593                 }
1594 
1595                 @Override
1596                 public void mouseReleased(MouseEvent e) {
1597                     selectionRectangle = null;
1598                     table.repaint();
1599                 }
1600 
1601             };
1602             table.addMouseListener(mouseListener);
1603             table.addMouseMotionListener(mouseListener);
1604             
1605             table.putClientProperty("FileChooser.supportsFileDrop", TRUE);
1606             table.putClientProperty("FileChooser.instance", fileChooser);
1607             table.putClientProperty("Table.noOutsideChecking", TRUE);
1608             table.putClientProperty("Table.showWholeRowAsDropTarget", TRUE);
1609             table.putClientProperty("BasicTableUI.cellWidthHack", Boolean.TRUE);
1610         
1611             table.setDropMode(DropMode.ON);
1612         }
1613 
1614         @Override
1615         public void paint(Graphics g, JComponent c) {
1616             super.paint(g, c);
1617 
1618             if (selectionRectangle != null) {
1619                 g.setColor(new Color(0, 102, 204, 85));
1620                 g.fillRect(selectionRectangle.x, selectionRectangle.y,
1621                         selectionRectangle.width, selectionRectangle.height);
1622 
1623                 g.setColor(new Color(0, 128, 255, 204));
1624                 g.drawRect(selectionRectangle.x, selectionRectangle.y,
1625                         selectionRectangle.width, selectionRectangle.height);
1626             }
1627         }
1628     }
1629 
1630     private static Image initBackArrowImage() {
1631         BufferedImage img = new BufferedImage(12, 12, 6);
1632         img.setRGB(0, 4, 16777216);
1633         img.setRGB(0, 5, 1476395008);
1634         img.setRGB(0, 6, 1409286144);
1635         img.setRGB(0, 7, 16777216);
1636         img.setRGB(1, 3, 16777216);
1637         img.setRGB(1, 4, 1476395008);
1638         img.setRGB(1, 5, 2130706432);
1639         img.setRGB(1, 6, 2130706432);
1640         img.setRGB(1, 7, 1409286144);
1641         img.setRGB(1, 8, 16777216);
1642         img.setRGB(2, 2, 16777216);
1643         img.setRGB(2, 3, 1476395008);
1644         img.setRGB(2, 4, 2130706432);
1645         img.setRGB(2, 5, 2130706432);
1646         img.setRGB(2, 6, 2130706432);
1647         img.setRGB(2, 7, 2130706432);
1648         img.setRGB(2, 8, 1409286144);
1649         img.setRGB(2, 9, 16777216);
1650         img.setRGB(3, 1, 16777216);
1651         img.setRGB(3, 2, 1476395008);
1652         img.setRGB(3, 3, 2130706432);
1653         img.setRGB(3, 4, 1459617792);
1654         img.setRGB(3, 5, 2130706432);
1655         img.setRGB(3, 6, 2130706432);
1656         img.setRGB(3, 7, 1509949440);
1657         img.setRGB(3, 8, 2130706432);
1658         img.setRGB(3, 9, 1409286144);
1659         img.setRGB(3, 10, 16777216);
1660         img.setRGB(4, 0, 16777216);
1661         img.setRGB(4, 1, 1476395008);
1662         img.setRGB(4, 2, 2130706432);
1663         img.setRGB(4, 3, 1459617792);
1664         img.setRGB(4, 4, 16777216);
1665         img.setRGB(4, 5, 2130706432);
1666         img.setRGB(4, 6, 2130706432);
1667         img.setRGB(4, 7, 16777216);
1668         img.setRGB(4, 8, 1509949440);
1669         img.setRGB(4, 9, 2130706432);
1670         img.setRGB(4, 10, 1409286144);
1671         img.setRGB(4, 11, 16777216);
1672         img.setRGB(5, 0, 452984832);
1673         img.setRGB(5, 1, 2130706432);
1674         img.setRGB(5, 2, 1459617792);
1675         img.setRGB(5, 3, 16777216);
1676         img.setRGB(5, 5, 2130706432);
1677         img.setRGB(5, 6, 2130706432);
1678         img.setRGB(5, 8, 16777216);
1679         img.setRGB(5, 9, 1509949440);
1680         img.setRGB(5, 10, 2130706432);
1681         img.setRGB(5, 11, 402653184);
1682         img.setRGB(6, 1, 469762048);
1683         img.setRGB(6, 2, 16777216);
1684         img.setRGB(6, 5, 2130706432);
1685         img.setRGB(6, 6, 2130706432);
1686         img.setRGB(6, 9, 16777216);
1687         img.setRGB(6, 10, 419430400);
1688         img.setRGB(7, 5, 2130706432);
1689         img.setRGB(7, 6, 2130706432);
1690         img.setRGB(8, 5, 2130706432);
1691         img.setRGB(8, 6, 2130706432);
1692         img.setRGB(9, 5, 2130706432);
1693         img.setRGB(9, 6, 2130706432);
1694         img.setRGB(10, 5, 2130706432);
1695         img.setRGB(10, 6, 2130706432);
1696         img.setRGB(11, 5, 2130706432);
1697         img.setRGB(11, 6, 2130706432);
1698         return img;
1699     }
1700 
1701     private static Image initForwardArrowImage() {
1702         BufferedImage img = new BufferedImage(12, 12, 6);
1703         img.setRGB(0, 5, 2130706432);
1704         img.setRGB(0, 6, 2130706432);
1705         img.setRGB(1, 5, 2130706432);
1706         img.setRGB(1, 6, 2130706432);
1707         img.setRGB(2, 5, 2130706432);
1708         img.setRGB(2, 6, 2130706432);
1709         img.setRGB(3, 5, 2130706432);
1710         img.setRGB(3, 6, 2130706432);
1711         img.setRGB(4, 5, 2130706432);
1712         img.setRGB(4, 6, 2130706432);
1713         img.setRGB(5, 1, 452984832);
1714         img.setRGB(5, 2, 16777216);
1715         img.setRGB(5, 5, 2130706432);
1716         img.setRGB(5, 6, 2130706432);
1717         img.setRGB(5, 9, 16777216);
1718         img.setRGB(5, 10, 419430400);
1719         img.setRGB(6, 0, 452984832);
1720         img.setRGB(6, 1, 2130706432);
1721         img.setRGB(6, 2, 1442840576);
1722         img.setRGB(6, 3, 16777216);
1723         img.setRGB(6, 5, 2130706432);
1724         img.setRGB(6, 6, 2130706432);
1725         img.setRGB(6, 8, 16777216);
1726         img.setRGB(6, 9, 1509949440);
1727         img.setRGB(6, 10, 2130706432);
1728         img.setRGB(6, 11, 402653184);
1729         img.setRGB(7, 0, 16777216);
1730         img.setRGB(7, 1, 1476395008);
1731         img.setRGB(7, 2, 2130706432);
1732         img.setRGB(7, 3, 1442840576);
1733         img.setRGB(7, 4, 16777216);
1734         img.setRGB(7, 5, 2130706432);
1735         img.setRGB(7, 6, 2130706432);
1736         img.setRGB(7, 7, 16777216);
1737         img.setRGB(7, 8, 1509949440);
1738         img.setRGB(7, 9, 2130706432);
1739         img.setRGB(7, 10, 1392508928);
1740         img.setRGB(7, 11, 16777216);
1741         img.setRGB(8, 1, 16777216);
1742         img.setRGB(8, 2, 1476395008);
1743         img.setRGB(8, 3, 2130706432);
1744         img.setRGB(8, 4, 1442840576);
1745         img.setRGB(8, 5, 2130706432);
1746         img.setRGB(8, 6, 2130706432);
1747         img.setRGB(8, 7, 1509949440);
1748         img.setRGB(8, 8, 2130706432);
1749         img.setRGB(8, 9, 1409286144);
1750         img.setRGB(8, 10, 16777216);
1751         img.setRGB(9, 2, 16777216);
1752         img.setRGB(9, 3, 1476395008);
1753         img.setRGB(9, 4, 2130706432);
1754         img.setRGB(9, 5, 2130706432);
1755         img.setRGB(9, 6, 2130706432);
1756         img.setRGB(9, 7, 2130706432);
1757         img.setRGB(9, 8, 1409286144);
1758         img.setRGB(9, 9, 16777216);
1759         img.setRGB(10, 3, 16777216);
1760         img.setRGB(10, 4, 1476395008);
1761         img.setRGB(10, 5, 2130706432);
1762         img.setRGB(10, 6, 2130706432);
1763         img.setRGB(10, 7, 1409286144);
1764         img.setRGB(10, 8, 16777216);
1765         img.setRGB(11, 4, 16777216);
1766         img.setRGB(11, 5, 1476395008);
1767         img.setRGB(11, 6, 1409286144);
1768         img.setRGB(11, 7, 16777216);
1769         return img;
1770     }
1771 
1772     private static Image initUpArrowImage() {
1773         BufferedImage img = new BufferedImage(12, 13, 6);
1774         img.setRGB(0, 5, 167772160);
1775         img.setRGB(0, 6, 1325400064);
1776         img.setRGB(0, 7, 117440512);
1777         img.setRGB(1, 4, 167772160);
1778         img.setRGB(1, 5, 1778384896);
1779         img.setRGB(1, 6, 2130706432);
1780         img.setRGB(1, 7, 1308622848);
1781         img.setRGB(2, 3, 167772160);
1782         img.setRGB(2, 4, 1778384896);
1783         img.setRGB(2, 5, 2130706432);
1784         img.setRGB(2, 6, 1778384896);
1785         img.setRGB(2, 7, 167772160);
1786         img.setRGB(3, 2, 167772160);
1787         img.setRGB(3, 3, 1778384896);
1788         img.setRGB(3, 4, 2130706432);
1789         img.setRGB(3, 5, 1778384896);
1790         img.setRGB(3, 6, 167772160);
1791         img.setRGB(4, 1, 167772160);
1792         img.setRGB(4, 2, 1778384896);
1793         img.setRGB(4, 3, 2130706432);
1794         img.setRGB(4, 4, 1778384896);
1795         img.setRGB(4, 5, 167772160);
1796         img.setRGB(5, 0, 167772160);
1797         img.setRGB(5, 1, 1778384896);
1798         img.setRGB(5, 2, 2130706432);
1799         img.setRGB(5, 3, 2130706432);
1800         img.setRGB(5, 4, 2130706432);
1801         img.setRGB(5, 5, 2130706432);
1802         img.setRGB(5, 6, 2130706432);
1803         img.setRGB(5, 7, 2130706432);
1804         img.setRGB(5, 8, 2130706432);
1805         img.setRGB(5, 9, 2130706432);
1806         img.setRGB(5, 10, 2130706432);
1807         img.setRGB(5, 11, 2130706432);
1808         img.setRGB(5, 12, 2130706432);
1809         img.setRGB(6, 0, 167772160);
1810         img.setRGB(6, 1, 1778384896);
1811         img.setRGB(6, 2, 2130706432);
1812         img.setRGB(6, 3, 2130706432);
1813         img.setRGB(6, 4, 2130706432);
1814         img.setRGB(6, 5, 2130706432);
1815         img.setRGB(6, 6, 2130706432);
1816         img.setRGB(6, 7, 2130706432);
1817         img.setRGB(6, 8, 2130706432);
1818         img.setRGB(6, 9, 2130706432);
1819         img.setRGB(6, 10, 2130706432);
1820         img.setRGB(6, 11, 2130706432);
1821         img.setRGB(6, 12, 2130706432);
1822         img.setRGB(7, 1, 184549376);
1823         img.setRGB(7, 2, 1778384896);
1824         img.setRGB(7, 3, 2130706432);
1825         img.setRGB(7, 4, 1761607680);
1826         img.setRGB(7, 5, 167772160);
1827         img.setRGB(8, 2, 184549376);
1828         img.setRGB(8, 3, 1778384896);
1829         img.setRGB(8, 4, 2130706432);
1830         img.setRGB(8, 5, 1744830464);
1831         img.setRGB(8, 6, 167772160);
1832         img.setRGB(9, 3, 184549376);
1833         img.setRGB(9, 4, 1795162112);
1834         img.setRGB(9, 5, 2130706432);
1835         img.setRGB(9, 6, 1728053248);
1836         img.setRGB(9, 7, 150994944);
1837         img.setRGB(10, 4, 201326592);
1838         img.setRGB(10, 5, 1795162112);
1839         img.setRGB(10, 6, 2130706432);
1840         img.setRGB(10, 7, 1258291200);
1841         img.setRGB(11, 5, 201326592);
1842         img.setRGB(11, 6, 1308622848);
1843         img.setRGB(11, 7, 83886080);
1844         return img;
1845     }
1846     
1847     private static Image initRefreshImage() {
1848         BufferedImage img = new BufferedImage(10, 11, 6);
1849         img.setRGB(0, 3, 385875968);
1850         img.setRGB(0, 4, 1325400064);
1851         img.setRGB(0, 5, 1778384896);
1852         img.setRGB(0, 6, 1761607680);
1853         img.setRGB(0, 7, 1308622848);
1854         img.setRGB(0, 8, 369098752);
1855         img.setRGB(1, 0, 2130706432);
1856         img.setRGB(1, 1, 989855744);
1857         img.setRGB(1, 2, 805306368);
1858         img.setRGB(1, 3, 2097152000);
1859         img.setRGB(1, 4, 2130706432);
1860         img.setRGB(1, 5, 2013265920);
1861         img.setRGB(1, 6, 1996488704);
1862         img.setRGB(1, 7, 2130706432);
1863         img.setRGB(1, 8, 2080374784);
1864         img.setRGB(1, 9, 788529152);
1865         img.setRGB(2, 0, 2130706432);
1866         img.setRGB(2, 1, 1191182336);
1867         img.setRGB(2, 2, 2097152000);
1868         img.setRGB(2, 3, 1962934272);
1869         img.setRGB(2, 4, 620756992);
1870         img.setRGB(2, 7, 603979776);
1871         img.setRGB(2, 8, 1979711488);
1872         img.setRGB(2, 9, 2097152000);
1873         img.setRGB(2, 10, 352321536);
1874         img.setRGB(3, 0, 2130706432);
1875         img.setRGB(3, 1, 1660944384);
1876         img.setRGB(3, 2, 2130706432);
1877         img.setRGB(3, 3, 637534208);
1878         img.setRGB(3, 8, 687865856);
1879         img.setRGB(3, 9, 2130706432);
1880         img.setRGB(3, 10, 1308622848);
1881         img.setRGB(4, 0, 2130706432);
1882         img.setRGB(4, 1, 2097152000);
1883         img.setRGB(4, 2, 1996488704);
1884         img.setRGB(4, 3, 1006632960);
1885         img.setRGB(4, 4, 1006632960);
1886         img.setRGB(4, 9, 1996488704);
1887         img.setRGB(4, 10, 1761607680);
1888         img.setRGB(5, 0, 2130706432);
1889         img.setRGB(5, 1, 2130706432);
1890         img.setRGB(5, 2, 2130706432);
1891         img.setRGB(5, 3, 2130706432);
1892         img.setRGB(5, 4, 2130706432);
1893         img.setRGB(5, 9, 1996488704);
1894         img.setRGB(5, 10, 1761607680);
1895         img.setRGB(6, 8, 687865856);
1896         img.setRGB(6, 9, 2130706432);
1897         img.setRGB(6, 10, 1308622848);
1898         img.setRGB(7, 3, 587202560);
1899         img.setRGB(7, 4, 603979776);
1900         img.setRGB(7, 7, 603979776);
1901         img.setRGB(7, 8, 1979711488);
1902         img.setRGB(7, 9, 2097152000);
1903         img.setRGB(7, 10, 369098752);
1904         img.setRGB(8, 2, 150994944);
1905         img.setRGB(8, 3, 1996488704);
1906         img.setRGB(8, 4, 2130706432);
1907         img.setRGB(8, 5, 1996488704);
1908         img.setRGB(8, 6, 1996488704);
1909         img.setRGB(8, 7, 2130706432);
1910         img.setRGB(8, 8, 2080374784);
1911         img.setRGB(8, 9, 788529152);
1912         img.setRGB(9, 3, 369098752);
1913         img.setRGB(9, 4, 1325400064);
1914         img.setRGB(9, 5, 1778384896);
1915         img.setRGB(9, 6, 1761607680);
1916         img.setRGB(9, 7, 1308622848);
1917         img.setRGB(9, 8, 369098752);
1918         return img;
1919     }
1920 }