Browse Source

FileChooser: Replace old implementation by patching the components of MetalFileChooserUI. This removed the dependency on swing internal apis.

pull/245/head
weisj 3 years ago
parent
commit
69f94c7f3f
No known key found for this signature in database
GPG Key ID: 31124CB75461DA2A
  1. 7
      core/src/main/java/com/github/weisj/darklaf/delegate/TableCellEditorDelegate.java
  2. 601
      core/src/main/java/com/github/weisj/darklaf/ui/filechooser/DarkFileChooserUI.java
  3. 1111
      core/src/main/java/com/github/weisj/darklaf/ui/filechooser/DarkFileChooserUIBridge.java
  4. 523
      core/src/main/java/com/github/weisj/darklaf/ui/filechooser/DarkFilePane.java
  5. 1559
      core/src/main/java/com/github/weisj/darklaf/ui/filechooser/DarkFilePaneUIBridge.java
  6. 37
      core/src/main/java/com/github/weisj/darklaf/ui/filechooser/FileTextField.java
  7. 4
      core/src/main/resources/com/github/weisj/darklaf/properties/platform/windows.properties
  8. 1
      core/src/main/resources/com/github/weisj/darklaf/properties/ui/fileChooser.properties

7
core/src/main/java/com/github/weisj/darklaf/delegate/TableCellEditorDelegate.java

@ -23,6 +23,7 @@ package com.github.weisj.darklaf.delegate;
import java.awt.*;
import java.util.EventObject;
import java.util.Objects;
import javax.swing.*;
import javax.swing.event.CellEditorListener;
@ -30,7 +31,7 @@ import javax.swing.table.TableCellEditor;
public class TableCellEditorDelegate implements TableCellEditor {
private final TableCellEditor delegate;
private TableCellEditor delegate;
public TableCellEditorDelegate(final TableCellEditor editor) {
this.delegate = editor;
@ -40,6 +41,10 @@ public class TableCellEditorDelegate implements TableCellEditor {
return delegate;
}
public void setDelegate(TableCellEditor delegate) {
this.delegate = Objects.requireNonNull(delegate);
}
@Override
public Component getTableCellEditorComponent(final JTable table, final Object value, final boolean isSelected,
final int row, final int column) {

601
core/src/main/java/com/github/weisj/darklaf/ui/filechooser/DarkFileChooserUI.java

@ -21,44 +21,83 @@
*/
package com.github.weisj.darklaf.ui.filechooser;
import java.awt.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.LayoutManager;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ContainerAdapter;
import java.awt.event.ContainerEvent;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import javax.accessibility.AccessibleContext;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import java.util.function.Supplier;
import javax.swing.AbstractButton;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import javax.swing.filechooser.FileSystemView;
import javax.swing.filechooser.FileView;
import javax.swing.plaf.ComponentUI;
import sun.swing.FilePane;
import com.github.weisj.darklaf.components.tooltip.TooltipAwareButton;
import com.github.weisj.darklaf.components.tooltip.TooltipAwareToggleButton;
import javax.swing.plaf.metal.MetalFileChooserUI;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.text.JTextComponent;
import com.github.weisj.darklaf.components.OverlayScrollPane;
import com.github.weisj.darklaf.listener.AncestorAdapter;
import com.github.weisj.darklaf.ui.button.DarkButtonUI;
import com.github.weisj.darklaf.ui.combobox.ComboBoxConstants;
import com.github.weisj.darklaf.ui.table.DarkTableUI;
import com.github.weisj.darklaf.ui.table.TextTableCellEditorBorder;
import com.github.weisj.darklaf.ui.table.renderer.DarkTableCellEditor;
import com.github.weisj.darklaf.ui.table.renderer.DarkTableCellEditorDelegate;
import com.github.weisj.darklaf.ui.table.renderer.DarkTableCellRenderer;
import com.github.weisj.darklaf.ui.text.DarkTextUI;
import com.github.weisj.darklaf.ui.tooltip.ToolTipConstants;
import com.github.weisj.darklaf.util.AlignmentExt;
import com.github.weisj.darklaf.util.SystemInfo;
public class DarkFileChooserUI extends DarkFileChooserUIBridge {
public class DarkFileChooserUI extends MetalFileChooserUI {
public static final String KEY_VIEW_TYPE = "viewType";
private static final String MIME_TEXT = "text/";
private static final String MIME_IMAGE = "image/";
private static final int COLUMN_FILENAME = 0;
private final DarkFileView fileView = createFileView();
public DarkFileChooserUI(final JFileChooser b) {
super(b);
}
private Icon textFileIcon;
private Icon imageFileIcon;
protected AlignedLabel filesOfTypeLabel;
protected BasicFileView fileView;
protected Icon textFileIcon;
protected Icon imageFileIcon;
private final AncestorListener editorAncestorListener = new AncestorAdapter() {
@Override
public void ancestorAdded(final AncestorEvent event) {
SwingUtilities.invokeLater(() -> {
JComponent component = event.getComponent();
component.requestFocusInWindow();
if (component instanceof JTextComponent) ((JTextComponent) component).selectAll();
});
}
};
public DarkFileChooserUI(final JFileChooser fileChooser) {
super(fileChooser);
}
public static ComponentUI createUI(final JComponent c) {
return new DarkFileChooserUI((JFileChooser) c);
@ -71,314 +110,249 @@ public class DarkFileChooserUI extends DarkFileChooserUIBridge {
imageFileIcon = UIManager.getIcon("FileView.imageFileIcon");
}
@Override
protected void uninstallIcons(final JFileChooser fc) {
super.uninstallIcons(fc);
textFileIcon = null;
imageFileIcon = null;
}
@Override
public void installComponents(final JFileChooser fc) {
fc.setBorder(new EmptyBorder(10, 10, 7, 10));
fc.setLayout(new BorderLayout(0, 7));
filePane = createFilePane(fc);
fc.add(createTopPanel(fc), BorderLayout.NORTH);
fc.add(filePane, BorderLayout.CENTER);
fc.add(createBottomPanel(fc), BorderLayout.SOUTH);
fc.add(createControlPanel(fc), BorderLayout.AFTER_LINE_ENDS);
setupButtonPanel(fc);
if (fc.getControlButtonsAreShown()) {
addControlButtons();
}
groupLabels(new AlignedLabel[] {fileNameLabel, filesOfTypeLabel});
super.installComponents(fc);
adjustComponents(fc);
}
protected void setupButtonPanel(final JFileChooser fileChooser) {
JComponent buttonPanel = getButtonPanel();
buttonPanel.setLayout(new DarkButtonAreaLayout());
approveButton = new TooltipAwareButton(getApproveButtonText(fileChooser));
approveButton.putClientProperty(DarkButtonUI.KEY_NO_BORDERLESS_OVERWRITE, true);
approveButton.addActionListener(getApproveSelectionAction());
approveButton.setToolTipText(getApproveButtonToolTipText(fileChooser));
cancelButton = new TooltipAwareButton(cancelButtonText);
cancelButton.putClientProperty(DarkButtonUI.KEY_NO_BORDERLESS_OVERWRITE, true);
cancelButton.setToolTipText(cancelButtonToolTipText);
cancelButton.addActionListener(getCancelSelectionAction());
buttonPanel.add(approveButton);
buttonPanel.add(cancelButton);
}
protected JComponent createControlPanel(final JFileChooser fileChooser) {
JComponent accessoryPanel = getAccessoryPanel();
JComponent accessory = fileChooser.getAccessory();
if (accessory != null) accessoryPanel.add(accessory);
return accessoryPanel;
}
protected DarkFilePaneUIBridge createFilePane(final JFileChooser fileChooser) {
DarkFilePaneUIBridge filePane = new DarkFilePane(new MetalFileChooserUIAccessor());
fileChooser.addPropertyChangeListener(filePane);
// ComboBox Label
filePane.addPropertyChangeListener(e -> {
if (KEY_VIEW_TYPE.equals(e.getPropertyName())) {
int viewType = filePane.getViewType();
switch (viewType) {
case FilePane.VIEWTYPE_LIST:
listViewButton.setSelected(true);
break;
case FilePane.VIEWTYPE_DETAILS:
detailsViewButton.setSelected(true);
break;
private void adjustComponents(final JFileChooser fc) {
JPanel topPanel = getComponentWithLayout(fc, 0, JPanel.class, BorderLayout.class);
if (topPanel != null) {
JComponent buttonPanel = getComponentWithLayout(topPanel, 0, JComponent.class, BoxLayout.class);
if (buttonPanel != null) {
Component[] comps = buttonPanel.getComponents();
int firstButtonIndex = -1;
int secondButtonIndex = -1;
for (int i = comps.length - 1; i >= 0; i--) {
Component c = comps[i];
if (c instanceof AbstractButton) {
AbstractButton b = (AbstractButton) c;
b.setMargin(null);
b.putClientProperty(DarkButtonUI.KEY_NO_BORDERLESS_OVERWRITE, true);
b.putClientProperty(DarkButtonUI.KEY_SQUARE, true);
b.putClientProperty(DarkButtonUI.KEY_THIN, true);
b.putClientProperty(ToolTipConstants.KEY_STYLE, ToolTipConstants.VARIANT_BALLOON);
if (secondButtonIndex < 0 && firstButtonIndex >= 0) {
secondButtonIndex = i;
}
if (firstButtonIndex < 0) {
firstButtonIndex = i;
}
} else if (c instanceof Box.Filler && secondButtonIndex < 0) {
buttonPanel.remove(i);
}
}
if (firstButtonIndex >= 0 && secondButtonIndex >= 0) {
AbstractButton detailsViewButton = (AbstractButton) comps[firstButtonIndex];
AbstractButton listViewButton = (AbstractButton) comps[secondButtonIndex];
detailsViewButton.setSelectedIcon(UIManager.getIcon("FileChooser.detailsViewSelectedIcon"));
detailsViewButton.putClientProperty(DarkButtonUI.KEY_CORNER, AlignmentExt.RIGHT);
detailsViewButton.putClientProperty(DarkButtonUI.KEY_LEFT_NEIGHBOUR, listViewButton);
listViewButton.setSelectedIcon(UIManager.getIcon("FileChooser.listViewSelectedIcon"));
listViewButton.putClientProperty(DarkButtonUI.KEY_CORNER, AlignmentExt.LEFT);
listViewButton.putClientProperty(DarkButtonUI.KEY_RIGHT_NEIGHBOUR, detailsViewButton);
}
}
});
filePane.setPreferredSize(LIST_PREF_SIZE);
return filePane;
JComboBox<?> directoryComboBox = getComponentWithLayout(topPanel, 2, JComboBox.class, null);
if (directoryComboBox != null) {
int maximumRowCount = UIManager.getInt("ComboBox.maximumRowCount");
if (maximumRowCount > 0)
directoryComboBox.setMaximumRowCount(maximumRowCount);
}
}
for (Component comp : fc.getComponents()) {
if (comp.isPreferredSizeSet()) {
comp.setPreferredSize(null);
}
}
}
protected JComponent createBottomPanel(final JFileChooser fileChooser) {
JPanel bottomPanel = getBottomPanel();
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS));
bottomPanel.add(createFileNamePanel(fileChooser));
bottomPanel.add(makeVerticalSpacer());
bottomPanel.add(createFileTypePanel(fileChooser));
return bottomPanel;
@Override
protected FilterComboBoxRenderer createFilterComboBoxRenderer() {
ListCellRenderer<Object> realRenderer = new DarkFilterComboBoxRenderer();
return new FilterComboBoxRenderer() {
@Override
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected,
boolean cellHasFocus) {
return realRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
}
};
}
protected JComponent createFileNamePanel(final JFileChooser fileChooser) {
JPanel fileNamePanel = new JPanel();
fileNamePanel.setLayout(new BoxLayout(fileNamePanel, BoxLayout.LINE_AXIS));
fileNameLabel = new AlignedLabel();
populateFileNameLabel();
fileNamePanel.add(fileNameLabel);
fileNameTextField = new FileTextField();
fileNamePanel.add(fileNameTextField);
fileNameLabel.setLabelFor(fileNameTextField);
fileNameTextField.addFocusListener(new FocusAdapter() {
public void focusGained(final FocusEvent e) {
if (!getFileChooser().isMultiSelectionEnabled()) {
filePane.clearSelection();
}
@Override
protected JPanel createDetailsView(final JFileChooser fc) {
JPanel p = super.createDetailsView(fc);
p = wrapInOverlayScrollPane(p);
OverlayScrollPane sp = getComponentWithLayout(p, 0, OverlayScrollPane.class, null);
if (sp != null) {
Component cTable = sp.getScrollPane().getViewport().getView();
if (cTable instanceof JTable) {
patchDetailsView((JTable) cTable);
}
});
if (fileChooser.isMultiSelectionEnabled()) {
setFileName(fileNameString(fileChooser.getSelectedFiles()));
} else {
setFileName(fileNameString(fileChooser.getSelectedFile()));
}
return fileNamePanel;
return p;
}
protected Component createFileTypePanel(final JFileChooser fileChooser) {
JPanel filesOfTypePanel = new JPanel();
filesOfTypePanel.setLayout(new BoxLayout(filesOfTypePanel, BoxLayout.LINE_AXIS));
filesOfTypeLabel = new AlignedLabel(filesOfTypeLabelText);
filesOfTypeLabel.setDisplayedMnemonic(filesOfTypeLabelMnemonic);
filesOfTypePanel.add(filesOfTypeLabel);
filterComboBoxModel = createFilterComboBoxModel();
fileChooser.addPropertyChangeListener(filterComboBoxModel);
filterComboBox = createFilterComboBox(filterComboBoxModel);
filesOfTypeLabel.setLabelFor(filterComboBox);
filesOfTypePanel.add(filterComboBox);
private void patchDetailsView(final JTable table) {
TableCellRenderer defaultRenderer = table.getDefaultRenderer(Object.class);
table.setDefaultRenderer(Object.class, new DarkTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
// remove left-to-right and right-to-left mark characters
if (SystemInfo.isWindows) {
// on Windows 10, the date may contain left-to-right (0x200e) and right-to-left (0x200f)
// mark characters (see https://en.wikipedia.org/wiki/Left-to-right_mark)
// when the "current user" item is selected in the "look in" combobox
// --> remove them
if (value instanceof String && ((String) value).startsWith("\u200e")) {
String str = (String) value;
char[] buf = new char[str.length()];
int j = 0;
for (int i = 0; i < buf.length; i++) {
char ch = str.charAt(i);
if (ch != '\u200e' && ch != '\u200f')
buf[j++] = ch;
}
value = new String(buf, 0, j);
}
}
return filesOfTypePanel;
}
JLabel comp = (JLabel) super.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
JLabel defaultComp = (JLabel) defaultRenderer.getTableCellRendererComponent(
table, value, isSelected, hasFocus, row, column);
protected JComboBox<Object> createFilterComboBox(final ComboBoxModel<Object> model) {
JComboBox<Object> comboBox = new JComboBox<>(model);
model.addListDataListener(new ListDataListener() {
@Override
public void intervalAdded(final ListDataEvent e) {
comboBox.setEnabled(comboBox.getItemCount() > 1);
comp.setIcon(defaultComp.getIcon());
comp.setDisabledIcon(defaultComp.getDisabledIcon());
comp.setText(defaultComp.getText());
comp.setHorizontalAlignment(defaultComp.getHorizontalAlignment());
return comp;
}
@Override
public void intervalRemoved(final ListDataEvent e) {
comboBox.setEnabled(comboBox.getItemCount() > 1);
});
table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
table.putClientProperty(DarkTableUI.KEY_FULL_ROW_FOCUS_BORDER, true);
table.putClientProperty(DarkTableUI.KEY_FILE_CHOOSER_PARENT,
(Supplier<JFileChooser>) this::getFileChooser);
table.putClientProperty("JTable.fileNameColumnIndex", COLUMN_FILENAME);
table.doLayout();
int rowHeight = UIManager.getInt("FileChooser.rowHeight");
table.addPropertyChangeListener(e -> {
String name = e.getPropertyName();
if ("rowHeight".equals(name)) {
if (table.getRowHeight() != rowHeight) {
table.setRowHeight(rowHeight);
}
}
@Override
public void contentsChanged(final ListDataEvent e) {
comboBox.setEnabled(comboBox.getItemCount() > 1);
});
TableColumn column = table.getColumnModel().getColumn(0);
column.setCellEditor(new FileTableEditor(column.getCellEditor()));
column.addPropertyChangeListener(e -> {
if ("cellEditor".equals(e.getPropertyName())) {
if (!(column.getCellEditor() instanceof FileTableEditor)) {
column.setCellEditor(new FileTableEditor(column.getCellEditor()));
}
}
});
comboBox.putClientProperty(ComboBoxConstants.KEY_DO_NOT_UPDATE_WHEN_SCROLLED, true);
comboBox.putClientProperty(AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY, filesOfTypeLabelText);
comboBox.setRenderer(createFilterComboBoxRenderer());
return comboBox;
}
protected JComponent createTopPanel(final JFileChooser fileChooser) {
JPanel topPanel = new JPanel(new BorderLayout(10, 0));
lookInLabel = new JLabel(lookInLabelText);
lookInLabel.setDisplayedMnemonic(lookInLabelMnemonic);
directoryComboBox = createDirectoryComboBox(fileChooser);
lookInLabel.setLabelFor(directoryComboBox);
directoryComboBoxModel = createDirectoryComboBoxModel(fileChooser);
directoryComboBox.setModel(directoryComboBoxModel);
topPanel.add(lookInLabel, BorderLayout.BEFORE_LINE_BEGINS);
topPanel.add(directoryComboBox, BorderLayout.CENTER);
topPanel.add(createTopButtonArea(), BorderLayout.AFTER_LINE_ENDS);
return topPanel;
table.setShowGrid(true);
table.setShowGrid(false);
}
private JComboBox<Object> createDirectoryComboBox(final JFileChooser fileChooser) {
JComboBox<Object> comboBox = new JComboBox<Object>() {
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
// Must be small enough to not affect total width.
d.width = 150;
return d;
@Override
protected JPanel createList(final JFileChooser fc) {
JPanel p = super.createList(fc);
p = wrapInOverlayScrollPane(p);
OverlayScrollPane sp = getComponentWithLayout(p, 0, OverlayScrollPane.class, null);
if (sp != null) {
Component cList = sp.getScrollPane().getViewport().getView();
if (cList instanceof JList) {
patchListView((JList<?>) cList);
}
};
comboBox.putClientProperty(ComboBoxConstants.KEY_DO_NOT_UPDATE_WHEN_SCROLLED, true);
comboBox.putClientProperty(AccessibleContext.ACCESSIBLE_DESCRIPTION_PROPERTY, lookInLabelText);
comboBox.addActionListener(directoryComboBoxAction);
comboBox.setRenderer(createDirectoryComboBoxRenderer(fileChooser));
comboBox.setAlignmentX(JComponent.LEFT_ALIGNMENT);
comboBox.setAlignmentY(JComponent.TOP_ALIGNMENT);
comboBox.setMaximumRowCount(8);
return comboBox;
}
protected Component createTopButtonArea() {
Box box = Box.createHorizontalBox();
box.add(createUpFolderButton());
box.add(makeHorizontalSpacer());
box.add(createHomeButton());
box.add(makeHorizontalSpacer());
if (!UIManager.getBoolean("FileChooser.readOnly")) {
box.add(createNewDirectoryButton());
box.add(makeHorizontalSpacer());
}
box.add(createViewButtonArea());
box.add(Box.createGlue());
return box;
}
protected Component makeHorizontalSpacer() {
return Box.createRigidArea(hstrut5);
return p;
}
protected Component makeVerticalSpacer() {
return Box.createRigidArea(vstrut5);
}
protected JComponent createViewButtonArea() {
Box box = Box.createHorizontalBox();
listViewButton = createListViewButton();
detailsViewButton = createDetailsViewButton();
listViewButton.putClientProperty(DarkButtonUI.KEY_RIGHT_NEIGHBOUR, detailsViewButton);
detailsViewButton.putClientProperty(DarkButtonUI.KEY_LEFT_NEIGHBOUR, listViewButton);
box.add(listViewButton);
box.add(detailsViewButton);
listViewButton.addItemListener(e -> detailsViewButton.setSelected(!listViewButton.isSelected()));
detailsViewButton.addItemListener(e -> listViewButton.setSelected(!detailsViewButton.isSelected()));
return box;
}
protected JButton createNewDirectoryButton() {
JButton b = new TooltipAwareButton(filePane.getNewFolderAction());
setupButton(b, newFolderAccessibleName, newFolderToolTipText);
b.setText(null);
b.setIcon(newFolderIcon);
return b;
}
protected JButton createHomeButton() {
JButton b = new TooltipAwareButton(homeFolderIcon);
setupButton(b, homeFolderAccessibleName, homeFolderToolTipText);
b.addActionListener(getGoHomeAction());
return b;
}
protected JButton createUpFolderButton() {
JButton upFolderButton = new TooltipAwareButton(getChangeToParentDirectoryAction());
setupButton(upFolderButton, upFolderAccessibleName, upFolderToolTipText);
upFolderButton.setText(null);
upFolderButton.setIcon(upFolderIcon);
return upFolderButton;
}
protected JToggleButton createDetailsViewButton() {
JToggleButton button = new TooltipAwareToggleButton(detailsViewIcon);
setupButton(button, detailsViewButtonAccessibleName, detailsViewButtonToolTipText);
Icon selectedDetailsViewIcon = UIManager.getIcon("FileChooser.detailsViewSelectedIcon");
button.setSelectedIcon(selectedDetailsViewIcon);
button.putClientProperty(DarkButtonUI.KEY_CORNER, AlignmentExt.RIGHT);
button.addActionListener(filePane.getViewTypeAction(FilePane.VIEWTYPE_DETAILS));
return button;
}
protected JToggleButton createListViewButton() {
JToggleButton button = new TooltipAwareToggleButton(listViewIcon);
setupButton(button, listViewButtonAccessibleName, listViewButtonToolTipText);
Icon selectedListViewIcon = UIManager.getIcon("FileChooser.listViewSelectedIcon");
button.setSelectedIcon(selectedListViewIcon);
button.putClientProperty(DarkButtonUI.KEY_CORNER, AlignmentExt.LEFT);
button.addActionListener(filePane.getViewTypeAction(FilePane.VIEWTYPE_LIST));
button.setSelected(true);
return button;
}
protected void setupButton(final AbstractButton button, final String accessibleName, final String tipText) {
button.putClientProperty(DarkButtonUI.KEY_NO_BORDERLESS_OVERWRITE, true);
button.putClientProperty(DarkButtonUI.KEY_SQUARE, true);
button.setAlignmentX(JComponent.LEFT_ALIGNMENT);
button.setAlignmentY(JComponent.CENTER_ALIGNMENT);
button.setToolTipText(tipText);
button.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, accessibleName);
}
@Override
protected ListCellRenderer<Object> createFilterComboBoxRenderer() {
return new DarkFilterComboBoxRenderer();
private void patchListView(final JList<?> list) {
list.setCellRenderer(new DarkFileRenderer());
list.putClientProperty("JList.fullRowSelection", true);
list.addContainerListener(new ContainerAdapter() {
@Override
public void componentAdded(final ContainerEvent e) {
Component c = e.getChild();
if (c instanceof JTextComponent) {
c.addComponentListener(new ComponentAdapter() {
@Override
public void componentMoved(final ComponentEvent e) {
c.removeComponentListener(this);
ListCellRenderer<?> renderer = list.getCellRenderer();
if (renderer instanceof JLabel) {
int gap = ((JLabel) renderer).getIconTextGap() - 1;
if (c.getComponentOrientation().isLeftToRight()) {
c.setBounds(c.getX() + gap, c.getY(),
c.getWidth() - gap, c.getHeight());
} else {
c.setBounds(c.getX(), c.getY(),
c.getWidth() - gap, c.getHeight());
}
}
}
});
c.setName("FileChooser.listEditCell");
((JTextComponent) c).setBorder(new TextTableCellEditorBorder());
((JTextComponent) c).putClientProperty("JTextField.listCellEditor", true);
((JTextComponent) c).putClientProperty(DarkTextUI.KEY_IS_LIST_EDITOR, true);
}
}
});
}
protected static class DarkButtonAreaLayout extends ButtonAreaLayout {
protected DarkButtonAreaLayout() {
topMargin = 5;
private JPanel wrapInOverlayScrollPane(final JPanel panel) {
JPanel p = panel;
JScrollPane sp = getComponentWithLayout(p, 0, JScrollPane.class, null);
if (sp != null) {
p = new JPanel(new BorderLayout());
OverlayScrollPane osp = new OverlayScrollPane(sp);
p.setPreferredSize(UIManager.getDimension("FileChooser.prefContentSize"));
osp.setAddHorizontalScrollBarSize(true);
osp.setAddHorizontalScrollBarSize(true);
p.add(osp);
}
return p;
}
public void clearIconCache() {
getFileView().clearIconCache();
private <T extends JComponent, L extends LayoutManager> T getComponentWithLayout(final Container parent,
final int index,
final Class<T> type, final Class<L> layoutType) {
try {
Component c = parent.getComponent(index);
if (type.isInstance(c) && (layoutType == null || layoutType.isInstance(((JComponent) c).getLayout())))
return type.cast(c);
} catch (IndexOutOfBoundsException ignored) {
}
return null;
}
public BasicFileView getFileView() {
if (fileView == null) fileView = createFileView();
@Override
public FileView getFileView(JFileChooser fc) {
return fileView;
}
@Override
public FileView getFileView(final JFileChooser fc) {
return getFileView();
public void clearIconCache() {
fileView.clearIconCache();
}
protected BasicFileView createFileView() {
protected DarkFileView createFileView() {
return new DarkFileView();
}
protected class DarkFileView extends BasicFileView {
private class DarkFileView extends BasicFileView {
private static final String MIME_TEXT = "text/";
private static final String MIME_IMAGE = "image/";
public Icon getIcon(final File f) {
Icon icon = getCachedIcon(f);
@ -415,4 +389,49 @@ public class DarkFileChooserUI extends DarkFileChooserUIBridge {
return icon;
}
}
private class FileTableEditor extends DarkTableCellEditorDelegate {
private FileTableEditor(final TableCellEditor delegate) {
super(delegate);
if (delegate instanceof DefaultCellEditor) {
DefaultCellEditor editor = (DefaultCellEditor) delegate;
Component component = editor.getComponent();
if (component instanceof JTextField) {
JTextField tf = (JTextField) component;
tf.removeAncestorListener(editorAncestorListener);
tf.addAncestorListener(editorAncestorListener);
setDelegate(new DarkTableCellEditor(tf) {
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column) {
Object realValue = value instanceof File ? getFileChooser().getName((File) value) : value;
return super.getTableCellEditorComponent(table, realValue, isSelected, row, column);
}
});
}
}
}
}
private class DarkFileRenderer extends DefaultListCellRenderer {
@Override
public Component getListCellRendererComponent(final JList<?> list, final Object value, final int index,
final boolean isSelected, final boolean cellHasFocus) {
Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (comp instanceof JLabel) {
File file = (File) value;
String fileName = getFileChooser().getName(file);
((JLabel) comp).setText(fileName);
Icon icon = getFileChooser().getIcon(file);
if (icon != null) {
((JLabel) comp).setIcon(icon);
} else {
if (getFileChooser().getFileSystemView().isTraversable(file)) {
((JLabel) comp).setText(fileName + File.separator);
}
}
}
return comp;
}
}
}

1111
core/src/main/java/com/github/weisj/darklaf/ui/filechooser/DarkFileChooserUIBridge.java

File diff suppressed because it is too large Load Diff

523
core/src/main/java/com/github/weisj/darklaf/ui/filechooser/DarkFilePane.java

@ -1,523 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2021 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package com.github.weisj.darklaf.ui.filechooser;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.function.Supplier;
import javax.accessibility.AccessibleContext;
import javax.swing.*;
import javax.swing.event.AncestorEvent;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.TableModelEvent;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.text.JTextComponent;
import javax.swing.text.Position;
import com.github.weisj.darklaf.components.OverlayScrollPane;
import com.github.weisj.darklaf.listener.AncestorAdapter;
import com.github.weisj.darklaf.ui.table.DarkTableUI;
import com.github.weisj.darklaf.ui.table.TextTableCellEditorBorder;
import com.github.weisj.darklaf.ui.table.renderer.DarkTableCellEditor;
import com.github.weisj.darklaf.ui.table.renderer.DarkTableCellEditorDelegate;
import com.github.weisj.darklaf.ui.text.DarkTextUI;
import com.github.weisj.darklaf.util.DarkUIUtil;
import com.github.weisj.darklaf.util.SwingUtil;
public class DarkFilePane extends DarkFilePaneUIBridge {
protected TableCellEditor tableCellEditor;
public DarkFilePane(final FileChooserUIAccessor fileChooserUIAccessor) {
super(fileChooserUIAccessor);
}
@Override
protected void installDefaults() {
super.installDefaults();
kiloByteString = UIManager.getString("FileChooser.fileSizeKiloBytes");
megaByteString = UIManager.getString("FileChooser.fileSizeMegaBytes");
gigaByteString = UIManager.getString("FileChooser.fileSizeGigaBytes");
editCell = new JTextField();
editCell.setName("FileChooser.listEditCell");
editCell.addActionListener(new EditActionListener());
editCell.setBorder(new TextTableCellEditorBorder());
editCell.putClientProperty("JTextField.listCellEditor", true);
editCell.putClientProperty(DarkTextUI.KEY_IS_LIST_EDITOR, true);
}
public JPanel createList() {
JPanel p = new JPanel(new BorderLayout());
final JFileChooser fileChooser = getFileChooser();
@SuppressWarnings("serial") // anonymous class
final JList<Object> list = new JList<Object>() {
public int getNextMatch(final String prefix, final int startIndex, final Position.Bias bias) {
ListModel<?> model = getModel();
int max = model.getSize();
if (prefix == null || startIndex < 0 || startIndex >= max) {
throw new IllegalArgumentException();
}
// start search from the next element before/after the selected element
boolean backwards = (bias == Position.Bias.Backward);
for (int i = startIndex; backwards ? i >= 0 : i < max; i += (backwards ? -1 : 1)) {
String filename = fileChooser.getName((File) model.getElementAt(i));
if (filename.regionMatches(true, 0, prefix, 0, prefix.length())) {
return i;
}
}
return -1;
}
};
list.setCellRenderer(new DarkFileRenderer());
list.setLayoutOrientation(JList.VERTICAL_WRAP);
LookAndFeel.installColors(list, "FileView.background", "FileView.foreground");
// 4835633 : tell BasicListUI that this is a file list
list.putClientProperty("List.isFileList", Boolean.TRUE);
list.putClientProperty("JList.fullRowSelection", fullRowSelection);
if (listViewWindowsStyle) {
list.addFocusListener(repaintListener);
}
updateListRowCount(list);
getModel().addListDataListener(new ListDataListener() {
public void intervalAdded(final ListDataEvent e) {
updateListRowCount(list);
}
public void intervalRemoved(final ListDataEvent e) {
updateListRowCount(list);
}
public void contentsChanged(final ListDataEvent e) {
if (isShowing()) {
clearSelection();
}
updateListRowCount(list);
}
});
getModel().addPropertyChangeListener(this);
if (fileChooser.isMultiSelectionEnabled()) {
list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
} else {
list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}
list.setModel(new SortableListModel());
list.addListSelectionListener(createListSelectionListener());
list.addMouseListener(getMouseHandler());
OverlayScrollPane overlayScrollPane = new OverlayScrollPane(list);
JScrollPane scrollPane = overlayScrollPane.getScrollPane();
if (listViewBackground != null) {
list.setBackground(listViewBackground);
p.setBackground(listViewBackground);
}
if (listViewBorder != null) {
scrollPane.setBorder(listViewBorder);
}
list.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, filesListAccessibleName);
p.add(overlayScrollPane, BorderLayout.CENTER);
return p;
}
@Override
public JPanel createDetailsView() {
final JFileChooser chooser = getFileChooser();
JPanel p = new JPanel(new BorderLayout());
@SuppressWarnings("serial") // anonymous class
final JTable detailsTable = new JTable(getDetailsTableModel()) {
public void tableChanged(final TableModelEvent e) {
super.tableChanged(e);
if (e.getFirstRow() == TableModelEvent.HEADER_ROW) {
// update header with possibly changed column set
updateDetailsColumnModel(this);
}
}
// Handle Escape key events here
protected boolean processKeyBinding(final KeyStroke ks, final KeyEvent e, final int condition,
final boolean pressed) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE && getCellEditor() == null) {
// We are not editing, forward to filechooser.
chooser.dispatchEvent(e);
return true;
}
return super.processKeyBinding(ks, e, condition, pressed);
}
};
int rowHeight = UIManager.getInt("FileChooser.rowHeight");
if (rowHeight > 0) {
detailsTable.setRowHeight(rowHeight);
}
detailsTable.setRowSorter(getRowSorter());
detailsTable.setAutoCreateColumnsFromModel(false);
detailsTable.setComponentOrientation(chooser.getComponentOrientation());
detailsTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
detailsTable.setRowSelectionAllowed(true);
detailsTable.setShowGrid(false);
detailsTable.putClientProperty("JTable.autoStartsEdit", Boolean.FALSE);
detailsTable.addKeyListener(detailsKeyListener);
detailsTable.putClientProperty(DarkTableUI.KEY_FULL_ROW_FOCUS_BORDER, true);
detailsTable.putClientProperty(DarkTableUI.KEY_FILE_CHOOSER_PARENT,
(Supplier<JFileChooser>) this::getFileChooser);
detailsTable.putClientProperty("JTable.fileNameColumnIndex", COLUMN_FILENAME);
Font font = list.getFont();
detailsTable.setFont(font);
TableCellRenderer headerRenderer =
new AlignableTableHeaderRenderer(detailsTable.getTableHeader().getDefaultRenderer());
detailsTable.getTableHeader().setDefaultRenderer(headerRenderer);
TableCellRenderer cellRenderer = new DetailsTableCellRenderer(chooser);
detailsTable.setDefaultRenderer(Object.class, cellRenderer);
if (getFileChooser().isMultiSelectionEnabled()) {
detailsTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
} else {
detailsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
}
detailsTable.addMouseListener(getMouseHandler());
// 4835633 : tell BasicTableUI that this is a file list
detailsTable.putClientProperty(DarkTableUI.KEY_IS_FILE_LIST, Boolean.TRUE);
if (listViewWindowsStyle) {
detailsTable.addFocusListener(repaintListener);
}
// TAB/SHIFT-TAB should transfer focus and ENTER should select an item.
// We don't want them to navigate within the table
ActionMap am = SwingUtilities.getUIActionMap(detailsTable);
am.remove("selectNextRowCell");
am.remove("selectPreviousRowCell");
am.remove("selectNextColumnCell");
am.remove("selectPreviousColumnCell");
detailsTable.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null);
detailsTable.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null);
OverlayScrollPane overlayScrollPane = new OverlayScrollPane(detailsTable);
JScrollPane scrollPane = overlayScrollPane.getScrollPane();
scrollPane.setComponentOrientation(chooser.getComponentOrientation());
LookAndFeel.installColors(scrollPane.getViewport(), "FileView.background", "FileView.foreground");
LookAndFeel.installColors(detailsTable, "FileView.background", "FileView.foreground");
// Adjust width of first column so the table fills the viewport when
// first displayed (temporary listener).
scrollPane.addComponentListener(new ComponentAdapter() {
public void componentResized(final ComponentEvent e) {
JScrollPane sp = (JScrollPane) e.getComponent();
fixNameColumnWidth(sp.getViewport().getSize().width);
sp.removeComponentListener(this);
}
});
detailsTable.setForeground(list.getForeground());
detailsTable.setBackground(list.getBackground());
if (listViewBorder != null) {
scrollPane.setBorder(listViewBorder);
}
p.add(overlayScrollPane, BorderLayout.CENTER);
detailsTableModel.fireTableStructureChanged();
detailsTable.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, filesDetailsAccessibleName);
return p;
}
protected void cancelEdit() {
if (editFile != null) {
editFile = null;
list.remove(editCell);
list.putClientProperty("JList.isEditing", false);
repaint();
} else if (detailsTable != null && detailsTable.isEditing()) {
detailsTable.getCellEditor().cancelCellEditing();
}
}
protected void editFileName(final int index) {
JFileChooser chooser = getFileChooser();
File currentDirectory = chooser.getCurrentDirectory();
if (readOnly || !canWrite(currentDirectory, chooser)) {
return;
}
ensureIndexIsVisible(index);
switch (viewType) {
case VIEWTYPE_LIST:
editFile = (File) getModel().getElementAt(getRowSorter().convertRowIndexToModel(index));
Rectangle r = list.getCellBounds(index, index);
list.add(editCell);
editCell.setText(chooser.getName(editFile));
ComponentOrientation orientation = list.getComponentOrientation();
editCell.setComponentOrientation(orientation);
Icon icon = chooser.getIcon(editFile);
// PENDING - grab padding (4) below from defaults table.
int editX = icon == null ? 20 : icon.getIconWidth() + 4;
int gap = 0;
ListCellRenderer<?> renderer = list.getCellRenderer();
if (renderer instanceof JLabel) {
gap = ((JLabel) renderer).getIconTextGap() - 1;
}
if (orientation.isLeftToRight()) {
editCell.setBounds(editX + r.x + gap, r.y, r.width - editX - gap, r.height);
} else {
editCell.setBounds(r.x, r.y, r.width - editX - gap, r.height);
}
list.putClientProperty("JList.isEditing", true);
editCell.requestFocusInWindow();
editCell.selectAll();
break;
case VIEWTYPE_DETAILS:
detailsTable.editCellAt(index, COLUMN_FILENAME);
break;
}
}
public JPopupMenu getComponentPopupMenu() {
JPopupMenu popupMenu = getFileChooser().getComponentPopupMenu();
if (popupMenu != null) {
return popupMenu;
}
JMenu viewMenu = getViewMenu();
if (contextMenu == null) {
contextMenu = new JPopupMenu();
if (viewMenu != null) {
contextMenu.add(viewMenu);
if (listViewWindowsStyle) {
contextMenu.addSeparator();
}
}
ActionMap actionMap = getActionMap();
Action refreshAction = actionMap.get(ACTION_REFRESH);
Action newFolderAction = actionMap.get(ACTION_NEW_FOLDER);
Action renameAction = actionMap.get(ACTION_EDIT_FILE_NAME);
if (refreshAction != null) {
contextMenu.add(refreshAction).setIcon(UIManager.getIcon("FileChooser.refreshIcon"));
}
if (renameAction != null) {
JMenuItem menuItem = new JMenuItem(renameAction);
menuItem.setText("Rename");
contextMenu.add(menuItem);
}
if (newFolderAction != null) {
contextMenu.add(newFolderAction).setIcon(UIManager.getIcon("FileChooser.newFolderIcon"));
}
}
if (viewMenu != null) {
viewMenu.getPopupMenu().setInvoker(viewMenu);
}
return contextMenu;
}
@Override
public JMenu getViewMenu() {
if (viewMenu == null) {
viewMenu = new JMenu(viewMenuLabelText);
ButtonGroup viewButtonGroup = new ButtonGroup();
for (int i = 0; i < VIEWTYPE_COUNT; i++) {
JRadioButtonMenuItem mi = new JRadioButtonMenuItem(new ViewTypeAction(i));
switch (i) {
case VIEWTYPE_DETAILS:
mi.setIcon(UIManager.getIcon("FileChooser.detailsViewIcon"));
break;
case VIEWTYPE_LIST:
mi.setIcon(UIManager.getIcon("FileChooser.listViewIcon"));
break;
default:
break;
}
viewButtonGroup.add(mi);
viewMenu.add(mi);
}
updateViewMenu();
}
return viewMenu;
}
@Override
protected void updateViewMenu() {
if (viewMenu != null) {
Component[] comps = viewMenu.getMenuComponents();
for (Component comp : comps) {
if (comp instanceof JRadioButtonMenuItem) {
JRadioButtonMenuItem mi = (JRadioButtonMenuItem) comp;
if (((ViewTypeAction) mi.getAction()).viewType == viewType) {
mi.setSelected(true);
}
}
}
}
}
@Override
protected Handler getMouseHandler() {
if (handler == null) {
handler = new DarkHandler();
}
return handler;
}
protected class DarkHandler extends Handler {
@Override
public void mouseClicked(MouseEvent evt) {
JComponent source = (JComponent) evt.getSource();
int index;
if (source instanceof JList) {
index = list.locationToIndex(evt.getPoint());
} else if (source instanceof JTable) {
JTable table = (JTable) source;
Point p = evt.getPoint();
index = table.rowAtPoint(p);
boolean pointOutsidePrefSize = SwingUtil.pointOutsidePrefSize(table, index, table.columnAtPoint(p), p);
if (pointOutsidePrefSize && !fullRowSelection) {
return;
}
// Translate point from table to list
if (index >= 0 && list != null && listSelectionModel.isSelectedIndex(index)) {
// Make a new event with the list as source, placing the
// click in the corresponding list cell.
Rectangle r = list.getCellBounds(index, index);
MouseEvent newEvent = new MouseEvent(list, evt.getID(), evt.getWhen(), evt.getModifiersEx(),
r.x + 1, r.y + r.height / 2, evt.getXOnScreen(), evt.getYOnScreen(), evt.getClickCount(),
evt.isPopupTrigger(), evt.getButton());
SwingUtilities.convertMouseEvent(list, newEvent, list);
evt = newEvent;
}
} else {
return;
}
if (index >= 0 && SwingUtilities.isLeftMouseButton(evt)) {
JFileChooser fc = getFileChooser();
// For single click, we handle editing file name
if (evt.getClickCount() == 1 && source instanceof JList) {
if ((!fc.isMultiSelectionEnabled() || fc.getSelectedFiles().length <= 1)
&& listSelectionModel.isSelectedIndex(index) && getEditIndex() == index && editFile == null
&& DarkUIUtil.isOverText(evt, index, list)) {
editFileName(index);
} else {
setEditIndex(index);
}
} else if (evt.getClickCount() == 2) {
// on double click (open or drill down one directory) be
// sure to clear the edit index
resetEditIndex();
}
}
// Forward event to Basic
if (getDoubleClickListener() != null) {
list.putClientProperty("List.isFileList", false);
getDoubleClickListener().mouseClicked(evt);
list.putClientProperty("List.isFileList", true);
}
}
}
public class DarkFileRenderer extends DefaultListCellRenderer {
@Override
public Component getListCellRendererComponent(final JList<?> list, final Object value, final int index,
final boolean isSelected, final boolean cellHasFocus) {
Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (comp instanceof JLabel) {
File file = (File) value;
String fileName = getFileChooser().getName(file);
((JLabel) comp).setText(fileName);
Icon icon = getFileChooser().getIcon(file);
if (icon != null) {
((JLabel) comp).setIcon(icon);
} else {
if (getFileChooser().getFileSystemView().isTraversable(file)) {
((JLabel) comp).setText(fileName + File.separator);
}
}
}
return comp;
}
}
protected TableCellEditor getDetailsTableCellEditor() {
if (tableCellEditor == null) {
tableCellEditor = new DarkTableCellEditorDelegate(new DetailsTableCellEditor());
}
return tableCellEditor;
}
protected class DetailsTableCellEditor extends DarkTableCellEditor {
public DetailsTableCellEditor() {
editorComponent.addFocusListener(editorFocusListener);
editorComponent.addAncestorListener(new AncestorAdapter() {
@Override
public void ancestorAdded(final AncestorEvent event) {
SwingUtilities.invokeLater(() -> {
editorComponent.requestFocusInWindow();
((JTextComponent) editorComponent).selectAll();
});
}
});
}
public Component getTableCellEditorComponent(final JTable table, final Object value, final boolean isSelected,
final int row, final int column) {
Object realValue = value instanceof File ? getFileChooser().getName((File) value) : value;
return super.getTableCellEditorComponent(table, realValue, isSelected, row, column);
}
}
}

1559
core/src/main/java/com/github/weisj/darklaf/ui/filechooser/DarkFilePaneUIBridge.java

File diff suppressed because it is too large Load Diff

37
core/src/main/java/com/github/weisj/darklaf/ui/filechooser/FileTextField.java

@ -1,37 +0,0 @@
/*
* MIT License
*
* Copyright (c) 2021 Jannis Weis
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
* associated documentation files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package com.github.weisj.darklaf.ui.filechooser;
import java.awt.*;
import javax.swing.*;
public class FileTextField extends JTextField {
public FileTextField() {
super(35);
}
public Dimension getMaximumSize() {
return new Dimension(Short.MAX_VALUE, super.getPreferredSize().height);
}
}

4
core/src/main/resources/com/github/weisj/darklaf/properties/platform/windows.properties

@ -24,12 +24,12 @@
#
# suppress inspection "UnusedProperty" for whole file
#
FileChooser.listViewWindowsStyle = true
FileChooser.listViewWindowsStyle = false
TitlePane.unifiedMenuBar = true
Table.alternateRowColor = false
Tree.alternateRowColor = false
List.alternateRowColor = false
List.alternateRowColor = true
PopupMenu.defaultLightWeightPopups = true
PopupMenu.defaultLightWeightPopups.windows10 = false

1
core/src/main/resources/com/github/weisj/darklaf/properties/ui/fileChooser.properties

@ -38,6 +38,7 @@ FileChooser.listViewIcon = menu/groupBy.svg[themed]
FileChooser.listViewSelectedIcon = menu/groupBySelected.svg[themed]
FileChooser.borderColor = %border
FileChooser.prefContentSize = 500,200
FileChooser.rowHeight = 20
FileChooser.minEditDelay = 200
FileChooser.maxEditDelay = 600

Loading…
Cancel
Save