Merge remote-tracking branch 'origin/GP-7094-dragonmacher-file-chooser-tooltips--SQUASHED' into patch

This commit is contained in:
Ryan Kurtz
2026-07-29 10:10:19 -04:00
3 changed files with 58 additions and 15 deletions

View File

@@ -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

View File

@@ -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<File> {
@@ -43,26 +40,43 @@ class FileListCellRenderer extends GListCellRenderer<File> {
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<? extends File> 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;
}

View File

@@ -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<E> 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.
* <p>
* 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<E> 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<E> 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() {