diff --git a/Ghidra/Framework/Docking/data/docking.theme.properties b/Ghidra/Framework/Docking/data/docking.theme.properties index a883784345..fcda9ff118 100644 --- a/Ghidra/Framework/Docking/data/docking.theme.properties +++ b/Ghidra/Framework/Docking/data/docking.theme.properties @@ -108,6 +108,7 @@ icon.help.navigation.aid.enabled = software-update-available.png icon.filechooser.default.directory = icon.folder.closed icon.filechooser.default.file = [icon]laf.icon.FileView.fileIcon + icon.filechooser.places.my.computer = computer.png icon.filechooser.places.desktop = desktop.png icon.filechooser.places.home = user-home.png @@ -214,3 +215,8 @@ color.bg.widget.tabs.selected.inactive = #696969 // dimgray color.border.button.focused = [color]laf.color.TabbedPane.focus +[Nimbus] + +// The Nimbus LaF makes a key for laf.icon.FileView.fileIcon, but we are not correctly finding it +icon.filechooser.default.file = [icon]laf.icon.FileChooser.fileIcon + diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/filechooser/FileListCellRenderer.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/filechooser/FileListCellRenderer.java index 0cf7e290fc..df23d6d423 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/filechooser/FileListCellRenderer.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/filechooser/FileListCellRenderer.java @@ -21,10 +21,7 @@ import java.io.File; import javax.swing.JList; -import org.bouncycastle.crypto.generators.DHBasicKeyPairGenerator; - import docking.widgets.list.GListCellRenderer; -import ghidra.util.Msg; import ghidra.util.filechooser.GhidraFileChooserModel; class FileListCellRenderer extends GListCellRenderer { @@ -43,26 +40,43 @@ class FileListCellRenderer extends GListCellRenderer { return chooser.getDisplayName(file); } + @Override + public Dimension getPreferredSize() { + /* + The preferred size is used by the UI to pre-calculate the list's cell width to use while + rendering. The default preferred size does not account for the border insets. Some LaFs + appreciably change border size when focused. If the size of the cell is pre-calculated + using the smaller border size, then when the cell is focused text may be clipped, as the + cell size does not get updated when the border is changed. Start with the biggest known + border size to prevent clipping. + */ + Dimension d = super.getPreferredSize(); + int borderWidth = getMaxBorderWidth(); + d.width += borderWidth; + return d; + } + @Override public Component getListCellRendererComponent(JList list, File file, int index, boolean isSelected, boolean cellHasFocus) { super.getListCellRendererComponent(list, file, index, isSelected, cellHasFocus); + setIcon(model.getIcon(file)); - // The file chooser's list will sometimes set a fixed width. When that happens, the text - // may get clipped. When we get clipped text, add a tooltip to show the full text. + setToolTipText(null); // clear out previous cell's tool tip + + // As a performance tweak, the file chooser's list will get set to a fixed width when the + // number of directory items is large. (Clients may also choose to set a fixed width value.) + // Setting a fixed width may cause a cell's text to get clipped. When we get clipped text, + // add a tooltip to show the full text. int fixedWidth = list.getFixedCellWidth(); if (fixedWidth > 0) { Dimension d = getPreferredSize(); if (d.getWidth() > fixedWidth) { setToolTipText(getText()); - } - else { - setToolTipText(null); } } - return this; } diff --git a/Ghidra/Framework/Docking/src/main/java/docking/widgets/list/GListCellRenderer.java b/Ghidra/Framework/Docking/src/main/java/docking/widgets/list/GListCellRenderer.java index 03f5ddddb7..c274b28590 100644 --- a/Ghidra/Framework/Docking/src/main/java/docking/widgets/list/GListCellRenderer.java +++ b/Ghidra/Framework/Docking/src/main/java/docking/widgets/list/GListCellRenderer.java @@ -15,8 +15,7 @@ */ package docking.widgets.list; -import java.awt.Color; -import java.awt.Component; +import java.awt.*; import java.util.function.Function; import javax.swing.*; @@ -38,7 +37,7 @@ public class GListCellRenderer extends AbstractGCellRenderer implements ListC private static final Color LIST_BACKGROUND_COLOR = new GColor("color.bg.list.row"); /** - * Returns a new ListCellRenderer that maps the list's data instance to a string used in the cell. + * Returns a new renderer that maps the list's data instance to a string used in the cell. *

* Use this if you only need to provide a way to get the string value from the type being shown * in the list. @@ -56,20 +55,25 @@ public class GListCellRenderer extends AbstractGCellRenderer implements ListC }; } - /** - * Constructs a new GListCellRenderer. - */ public GListCellRenderer() { // lists don't need alternation for rows, as they don't use long columnar data setShouldAlternateRowBackgroundColors(false); + } + protected void initBorders() { // Base our borders on those used by the list. ComboBoxes do not change the list borders in // the Look and Feel. noFocusBorder = getBorder("List.noFocusBorder"); focusBorder = getBorder("List.focusCellHighlightBorder"); } + @Override + public void updateUI() { + super.updateUI(); + initBorders(); + } + private Border getBorder(String id) { Border border = UIManager.getBorder(id); if (border == null) { @@ -79,6 +83,25 @@ public class GListCellRenderer extends AbstractGCellRenderer implements ListC return border; } + /** + * Gets the max border size for the default borders used by this renderer. If any subclass or + * client uses borders other than 'noFocusBorder' or 'focusBorder', then they will need to + * override this method if any of their borders have bigger insets than the default borders of + * this class. + * @return the largest known border width + */ + protected int getMaxBorderWidth() { + Insets insets = noFocusBorder.getBorderInsets(this); + int left = insets.left; + int right = insets.right; + int width = left + right; + + insets = focusBorder.getBorderInsets(this); + left = Math.max(left, insets.left); + right = Math.max(right, insets.right); + return Math.max(width, left + right); + } + // overridden to return the list-specific background color @Override protected Color getDefaultBackgroundColor() {