GP-5964 - File Chooser - Accessibility tweaks

This commit is contained in:
dragonmacher 2025-09-09 15:22:03 -04:00
parent 6eab6693fc
commit dd6561807b
6 changed files with 272 additions and 148 deletions

View file

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -27,7 +27,7 @@ import docking.action.DockingActionIf;
import ghidra.docking.util.LookAndFeelUtils;
import ghidra.util.StringUtilities;
class DockingToolBarUtils {
public class DockingToolBarUtils {
private static final String START_KEYBINDING_TEXT = "<BR><HR><CENTER>(";
private static final String END_KEYBINDNIG_TEXT = ")</CENTER>";
@ -37,16 +37,25 @@ class DockingToolBarUtils {
* @param button the button
* @param action the action
*/
static void setToolTipText(JButton button, DockingActionIf action) {
public static void setToolTipText(JButton button, DockingActionIf action) {
String text = createToolTipText(button, action);
button.setToolTipText(text);
}
/**
* Creates tooltip text for the given action and button. This is intended to be used for
* buttons that represent the given action.
* @param button the button that is the target for the text
* @param action the action that is the source of the button
* @return the text
*/
public static String createToolTipText(JButton button, DockingActionIf action) {
String toolTipText = getToolTipText(action);
String keyBindingText = getKeyBindingAcceleratorText(button, action.getKeyBinding());
if (keyBindingText != null) {
button.setToolTipText(combingToolTipTextWithKeyBinding(toolTipText, keyBindingText));
}
else {
button.setToolTipText(toolTipText);
return combingToolTipTextWithKeyBinding(toolTipText, keyBindingText);
}
return toolTipText;
}
private static String combingToolTipTextWithKeyBinding(String toolTipText,

View file

@ -130,7 +130,7 @@ public class EmptyBorderButton extends JButton {
@Override
public void setBorder(Border border) {
// To keep UI from installing a non-appropriate border (such as when switching themes),
// To keep UI from installing an incorrect border (such as when switching themes),
// only allow borders created by this class to be set.
if (border == RAISED_BUTTON_BORDER || border == LOWERED_BUTTON_BORDER ||
border == FOCUSED_BUTTON_BORDER || border == NO_BUTTON_BORDER) {
@ -171,6 +171,12 @@ public class EmptyBorderButton extends JButton {
setBorder(NO_BUTTON_BORDER);
}
@Override
public void setEnabled(boolean b) {
setBorder(NO_BUTTON_BORDER);
super.setEnabled(b);
}
protected void updateBorderBasedOnState() {
if (!isEnabled()) {
return;

View file

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -15,36 +15,45 @@
*/
package docking.widgets.filechooser;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.Color;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.io.File;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.border.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import generic.theme.GColor;
import generic.theme.GThemeDefaults.Colors;
public class FileChooserToggleButton extends JToggleButton {
private static final long serialVersionUID = 1L;
static final Border RAISED_BORDER = BorderFactory.createCompoundBorder(
BorderFactory.createRaisedBevelBorder(),
BorderFactory.createEmptyBorder(1, 1, 1, 1));
//
// All border sizes are based on trial-and-error, adjusted to prevent the UI from moving as the
// user hovers and moves around with the keyboard.
//
private static final Border RAISED_BORDER = BorderFactory.createCompoundBorder(
BorderFactory.createRaisedBevelBorder(), BorderFactory.createEmptyBorder(2, 2, 2, 2));
static final Border NO_BORDER = new EmptyBorder(RAISED_BORDER.getBorderInsets(new JButton()));
private static final Border LOWERED_BORDER = BorderFactory.createCompoundBorder(
BorderFactory.createLoweredBevelBorder(), BorderFactory.createEmptyBorder(2, 2, 2, 2));
static final Border LOWERED_BORDER = BorderFactory.createCompoundBorder(
BorderFactory.createLoweredBevelBorder(),
BorderFactory.createEmptyBorder(1, 1, 1, 1));
// The focused border is a blue line with some padding on the outside so it is easy to see when
// the button has focus. This is similar to other buttons in the system.
private static final Color FOCUS_COLOR = new GColor("color.border.button.focused");
private static final Border FOCUSED_BORDER = BorderFactory.createCompoundBorder(
BorderFactory.createEmptyBorder(1, 1, 1, 1), BorderFactory.createLineBorder(FOCUS_COLOR));
private static final Border UNFOCUSED_BORDER = BorderFactory.createEmptyBorder(2, 2, 2, 2);
public FileChooserToggleButton(String text) {
private static final Border NO_BORDER = new EmptyBorder(4, 4, 4, 4);
private GhidraFileChooser fileChooser;
public FileChooserToggleButton(String text, GhidraFileChooser fileChooser) {
super(text);
initBorder();
}
public FileChooserToggleButton(Action action) {
super(action);
this.fileChooser = fileChooser;
initBorder();
}
@ -59,88 +68,92 @@ public class FileChooserToggleButton extends JToggleButton {
setContentAreaFilled(false);
// changes the border on hover and click
addMouseListener(new ButtonMouseListener());
addChangeListener(new ButtonStateListener());
// works in conjunction with the mouse listener to properly set the border
addChangeListener(e -> {
if (isSelected()) {
setBorder(LOWERED_BORDER);
}
else {
setBorder(NO_BORDER);
}
});
addChangeListener(e -> updateBorderBasedOnState());
setFocusable(false); // this prevents the focus box from being drawn over the button
addFocusListener(new ButtonFocusListener());
updateBorderBasedOnState();
}
void clearBorder() {
@Override
public void setBorder(Border border) {
// To keep UI from installing an incorrect border (such as when switching themes),
// only allow borders created by this class to be set.
if (border == RAISED_BORDER || border == LOWERED_BORDER || border == NO_BORDER ||
border instanceof FocusedBorder) {
super.setBorder(border);
}
}
private void clearBorder() {
setBorder(NO_BORDER);
}
/** Returns the directory with which this button is associated. */
/** {@return Returns the directory with which this button is associated.} */
File getFile() {
return null;
}
private class ButtonMouseListener extends MouseAdapter {
private boolean inside = false;
private void updateBorderBasedOnState() {
if (!isEnabled()) {
return;
}
private Border defaultBorder;
ButtonModel buttonModel = getModel();
boolean pressed = buttonModel.isPressed();
boolean rollover = buttonModel.isRollover();
boolean armed = buttonModel.isArmed();
boolean selected = buttonModel.isSelected();
Border border = NO_BORDER;
if (selected) {
border = LOWERED_BORDER;
}
else if (pressed && (rollover || armed)) {
border = LOWERED_BORDER;
}
else if (rollover) {
border = RAISED_BORDER;
}
border = createFocusedBorder(border, isFocusOwner());
setBorder(border);
}
private Border createFocusedBorder(Border outside, boolean isFocused) {
Border inside = isFocused ? FOCUSED_BORDER : UNFOCUSED_BORDER;
return new FocusedBorder(outside, inside);
}
private class ButtonStateListener implements ChangeListener {
@Override
public void stateChanged(ChangeEvent e) {
updateBorderBasedOnState();
}
}
private class ButtonFocusListener implements FocusListener {
@Override
public void mouseEntered(MouseEvent me) {
if (isSelected()) {
return;
}
defaultBorder = getBorder();
setBorder(RAISED_BORDER);
inside = true;
public void focusGained(FocusEvent e) {
updateBorderBasedOnState();
}
@Override
public void mouseExited(MouseEvent me) {
if (isSelected()) {
return;
}
inside = false;
restoreBorder();
public void focusLost(FocusEvent e) {
updateBorderBasedOnState();
fileChooser.updateShortcutPanel();
}
}
@Override
public void mousePressed(MouseEvent e) {
if (isSelected()) {
return;
}
if (e.getButton() == MouseEvent.BUTTON1) {
setBorder(LOWERED_BORDER);
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (isSelected()) {
return;
}
if (inside) {
setBorder(RAISED_BORDER);
}
else {
restoreBorder();
}
}
private void restoreBorder() {
if (defaultBorder != null) {
setBorder(defaultBorder);
}
else {
setBorder(NO_BORDER);
}
private class FocusedBorder extends CompoundBorder {
FocusedBorder(Border outsideBorder, Border insideBorder) {
super(outsideBorder, insideBorder);
}
}
}

View file

@ -4,9 +4,9 @@
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ -19,7 +19,6 @@ import javax.swing.*;
import docking.ReusableDialogComponentProvider;
import docking.widgets.checkbox.GCheckBox;
import docking.widgets.label.GLabel;
import ghidra.framework.preferences.Preferences;
import ghidra.util.layout.PairLayout;
@ -47,17 +46,13 @@ class GFileChooserOptionsDialog extends ReusableDialogComponentProvider {
private JComponent buildComponent() {
JPanel panel = new JPanel(new PairLayout());
showDotFilesCheckBox = new GCheckBox();
showDotFilesCheckBox = new GCheckBox("Show '.' files");
showDotFilesCheckBox.setToolTipText("When toggled on the file chooser will show files " +
"with names that begin with a '.' character");
showDotFilesCheckBox.getAccessibleContext().setAccessibleName("Show Dot Files");
showDotFilesCheckBox.setSelected(true);
JLabel label = new GLabel("Show '.' files");
label.getAccessibleContext().setAccessibleName("Show Files");
label.setToolTipText("When toggled on the file chooser will show files " +
"with names that begin with a '.' character");
panel.add(showDotFilesCheckBox);
panel.add(label);
panel.getAccessibleContext().setAccessibleName("GFile Chooser Options");
return panel;
}

View file

@ -17,6 +17,8 @@ package docking.widgets.filechooser;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileFilter;
import java.util.*;
@ -35,7 +37,11 @@ import javax.swing.text.DefaultFormatterFactory;
import org.apache.commons.lang3.StringUtils;
import docking.*;
import docking.action.DockingAction;
import docking.action.DockingActionIf;
import docking.action.builder.ActionBuilder;
import docking.actions.KeyBindingUtils;
import docking.menu.DockingToolBarUtils;
import docking.widgets.*;
import docking.widgets.combobox.GComboBox;
import docking.widgets.label.GDLabel;
@ -166,13 +172,19 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
private Component parent;
private JPanel waitPanel;
private EmptyBorderButton backButton;
private EmptyBorderButton forwardButton;
private EmptyBorderButton upLevelButton;
private EmptyBorderButton newFolderButton;
private EmptyBorderButton refreshButton;
private JButton backButton;
private JButton forwardButton;
private JButton upButton;
private JButton newFolderButton;
private JButton refreshButton;
private EmptyBorderToggleButton detailsButton;
private DockingAction upAction;
private DockingAction backAction;
private DockingAction forwardAction;
private KeyBindingChangeListener keyBindingChangeListener = new KeyBindingChangeListener();
private JPanel shortcutPanel;
private UnselectableButtonGroup shortCutButtonGroup;
private FileChooserToggleButton myComputerButton;
private FileChooserToggleButton desktopButton;
@ -261,12 +273,43 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
setPreferredSize(800, 600);
updateDirOnly(newModel.getHomeDirectory(), true);
createActions();
}
//==================================================================================================
// Setup Methods
//==================================================================================================
private void createActions() {
String owner = getClass().getSimpleName();
upAction = new ActionBuilder("Up One Level", owner)
.keyBinding("Alt Up")
.onAction(c -> goUp())
.build();
backAction = new ActionBuilder("Last Folder Visited", owner)
.keyBinding("Alt Left")
.onAction(c -> goBack())
.build();
forwardAction = new ActionBuilder("Previous Folder Visited", owner)
.keyBinding("Alt Right")
.onAction(c -> goForward())
.build();
upAction.addPropertyChangeListener(keyBindingChangeListener);
backAction.addPropertyChangeListener(keyBindingChangeListener);
forwardAction.addPropertyChangeListener(keyBindingChangeListener);
addAction(upAction);
addAction(backAction);
addAction(forwardAction);
updateNavigationButtonToolTips();
}
private JComponent buildWorkPanel() {
buildWaitPanel();
@ -302,7 +345,8 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
}
private JPanel buildShortCutPanel() {
myComputerButton = new FileChooserToggleButton("My Computer") {
myComputerButton = new FileChooserToggleButton("My Computer", this) {
@Override
File getFile() {
return MY_COMPUTER;
@ -314,7 +358,7 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
myComputerButton.addActionListener(e -> updateMyComputer());
myComputerButton.setForeground(FOREROUND_COLOR);
desktopButton = new FileChooserToggleButton("Desktop") {
desktopButton = new FileChooserToggleButton("Desktop", this) {
@Override
File getFile() {
return fileChooserModel.getDesktopDirectory();
@ -327,7 +371,7 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
desktopButton.setForeground(FOREROUND_COLOR);
desktopButton.setEnabled(fileChooserModel.getDesktopDirectory() != null);
homeButton = new FileChooserToggleButton("Home") {
homeButton = new FileChooserToggleButton("Home", this) {
@Override
File getFile() {
return fileChooserModel.getHomeDirectory();
@ -339,7 +383,7 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
homeButton.addActionListener(e -> updateHome());
homeButton.setForeground(FOREROUND_COLOR);
downloadsButton = new FileChooserToggleButton("Downloads") {
downloadsButton = new FileChooserToggleButton("Downloads", this) {
@Override
File getFile() {
return fileChooserModel.getDownloadsDirectory();
@ -350,7 +394,7 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
downloadsButton.addActionListener(e -> updateDownloads());
downloadsButton.setForeground(FOREROUND_COLOR);
recentButton = new FileChooserToggleButton("Recent") {
recentButton = new FileChooserToggleButton("Recent", this) {
@Override
File getFile() {
return RECENT;
@ -369,27 +413,30 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
shortCutButtonGroup.add(downloadsButton);
shortCutButtonGroup.add(recentButton);
JPanel shortCutPanel = new JPanel(new GridLayout(0, 1));
shortCutPanel.getAccessibleContext().setAccessibleName("Short Cut");
DockingUtils.setTransparent(shortCutPanel);
shortCutPanel.add(myComputerButton);
shortCutPanel.add(desktopButton);
shortCutPanel.add(homeButton);
shortCutPanel.add(downloadsButton);
shortCutPanel.add(recentButton);
shortcutPanel = new JPanel(new GridLayout(0, 1));
shortcutPanel.getAccessibleContext().setAccessibleName("Short Cut");
DockingUtils.setTransparent(shortcutPanel);
shortcutPanel.add(myComputerButton);
shortcutPanel.add(desktopButton);
shortcutPanel.add(homeButton);
shortcutPanel.add(downloadsButton);
shortcutPanel.add(recentButton);
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(BorderFactory.createLoweredBevelBorder());
panel.setBackground(SHORTCUT_BACKGROUND_COLOR);
panel.add(shortCutPanel, BorderLayout.NORTH);
panel.add(shortcutPanel, BorderLayout.NORTH);
panel.getAccessibleContext().setAccessibleName("Short Cut");
return panel;
}
private JPanel buildFileNamePanel() {
JLabel filenameLabel = new GDLabel("File name:");
JLabel filenameLabel = new GDLabel("Filename:");
FileDropDownSelectionDataModel model = new FileDropDownSelectionDataModel(this);
filenameTextField = new DropDownSelectionTextField<>(model);
filenameLabel.setLabelFor(filenameTextField);
filenameTextField.setMatchingWindowHeight(200);
filenameTextField.getAccessibleContext().setAccessibleName("Filename");
filenameTextField.addCellEditorListener(new CellEditorListener() {
@ -427,9 +474,10 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
JLabel filterLabel = new GLabel("Type:");
filterLabel.getAccessibleContext().setAccessibleName("Filter");
filterCombo = new GComboBox<>();
filterLabel.setLabelFor(filterCombo);
filterCombo.setRenderer(GListCellRenderer.createDefaultTextRenderer(
fileFilter -> fileFilter != null ? fileFilter.getDescription() : ""));
filterCombo.getAccessibleContext().setAccessibleName("Filter");
filterCombo.getAccessibleContext().setAccessibleName("File Type Filter");
filterModel = (DefaultComboBoxModel<GhidraFileFilter>) filterCombo.getModel();
addFileFilter(GhidraFileFilter.ALL);
filterCombo.addItemListener(e -> rescanCurrentDirectory());
@ -444,22 +492,12 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
return filenamePanel;
}
private class SelectionListener<T> implements DropDownSelectionChoiceListener<File> {
@Override
public void selectionChanged(File file) {
// take the selection and close the dialog
worker.schedule(new SetSelectedFileAndAcceptSelection(file));
}
}
private JPanel buildHeaderPanel() {
JPanel headerPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
// gbc.insets = new Insets(PAD, PAD, PAD, PAD);
JButton[] navButtons = buildNavigationButtons();
for (JButton element : navButtons) {
headerPanel.add(element, gbc);
@ -613,6 +651,7 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
}
private JButton[] buildNavigationButtons() {
backButton = new EmptyBorderButton(ICON_BACK);
backButton.setName("BACK_BUTTON");
backButton.setEnabled(false);
@ -625,12 +664,13 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
forwardButton.setToolTipText("Go to previous folder visited");
forwardButton.addActionListener(e -> goForward());
upLevelButton = new EmptyBorderButton(ICON_UP);
upLevelButton.setName(UP_BUTTON_NAME);
upLevelButton.setToolTipText("Up one level");
upLevelButton.addActionListener(e -> goUpOneDirectoryLevel());
upButton = new EmptyBorderButton(ICON_UP);
upButton.setName(UP_BUTTON_NAME);
upButton.setEnabled(false);
upButton.setToolTipText("Up one level");
upButton.addActionListener(e -> goUp());
return new JButton[] { backButton, forwardButton, upLevelButton };
return new JButton[] { backButton, forwardButton, upButton };
}
private JButton[] buildNonNavigationButtons() {
@ -1382,15 +1422,17 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
}
private void doSetSelectedFileAndUpdateDisplay(File file) {
if (lastInputFocus != null) {
lastInputFocus.requestFocusInWindow();
Component toFocus = getRestoreFocusComponent();
if (toFocus != null) {
toFocus.requestFocusInWindow();
}
if (file == null) {
return;
}
// SCR 4513 - exception if we don't cancel edits before changing the display
// exception if we don't cancel edits before changing the display
cancelEdits();
selectedFiles.setFile(file);
updateTextFieldForFile(file);
@ -1398,6 +1440,22 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
directoryModel.setSelectedFile(file); // the list or table display
}
private Component getRestoreFocusComponent() {
// ensure we transfer focus to the directory or table when the view switches
if (isTableShowing()) {
if (lastInputFocus == directoryList) {
lastInputFocus = directoryTable;
}
}
else {
if (lastInputFocus == directoryTable) {
lastInputFocus = directoryList;
}
}
return lastInputFocus;
}
private void updateTextFieldForFile(File file) {
if (file == null) {
return;
@ -1452,7 +1510,7 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
return false;
}
private void goUpOneDirectoryLevel() {
private void goUp() {
cancelEdits();
if (currentDirectory() == null) {
@ -1521,8 +1579,16 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
updateDirAndSelectFile(currentDir, currentSelectedFile, true, false);
}
private void updateShortcutPanel() {
// make sure that if one of the shortcut buttons is selected, the directory matches that button
void updateShortcutPanel() {
KeyboardFocusManager kfm = KeyboardFocusManager.getCurrentKeyboardFocusManager();
Component focusOwner = kfm.getFocusOwner();
if (focusOwner != null && !SwingUtilities.isDescendingFrom(focusOwner, shortcutPanel)) {
// only synchronize the button state if the user is not interacting with the buttons
return;
}
// make sure the selected button matches the current directory
File currentDirectory = currentDirectory();
checkShortCutButton(myComputerButton, currentDirectory);
checkShortCutButton(homeButton, currentDirectory);
@ -1556,13 +1622,24 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
history.clear();
}
private void updateNavigationButtonToolTips() {
String tip = DockingToolBarUtils.createToolTipText(backButton, backAction);
backButton.setToolTipText(tip);
tip = DockingToolBarUtils.createToolTipText(forwardButton, forwardAction);
forwardButton.setToolTipText(tip);
tip = DockingToolBarUtils.createToolTipText(upButton, upAction);
upButton.setToolTipText(tip);
}
private void updateNavigationButtons() {
backButton.setEnabled(history.hasPrevious());
forwardButton.setEnabled(history.hasNext());
File dir = currentDirectory();
boolean enable = dir != null && dir.getParentFile() != null;
upLevelButton.setEnabled(enable);
upButton.setEnabled(enable);
}
private void updateHistoryWithSelectedFiles(HistoryEntry historyEntry) {
@ -2235,7 +2312,7 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
public void runSwing() {
setDirectoryList(myComputerFile, roots);
setWaitPanelVisible(false);
Swing.runLater(() -> doSetSelectedFileAndUpdateDisplay(null));
setSelectedFileAndUpdateDisplay(null);
}
}
@ -2254,6 +2331,7 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
setCurrentDirectoryDisplay(recentFile, addToHistory);
List<File> list = CollectionUtils.asList(recentList, File.class);
setDirectoryList(recentFile, list);
setSelectedFileAndUpdateDisplay(null);
}
}
@ -2430,4 +2508,26 @@ public class GhidraFileChooser extends ReusableDialogComponentProvider implement
return parentDir.getName() + selectedFilesText;
}
}
private class SelectionListener<T> implements DropDownSelectionChoiceListener<File> {
@Override
public void selectionChanged(File file) {
// take the selection and close the dialog
worker.schedule(new SetSelectedFileAndAcceptSelection(file));
}
}
private class KeyBindingChangeListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent e) {
String name = e.getPropertyName();
if (name.equals(DockingActionIf.KEYBINDING_DATA_PROPERTY)) {
updateNavigationButtonToolTips();
}
}
}
}