UI changes

This commit is contained in:
Radek Davidek 2026-03-26 15:51:15 +01:00
parent 8776836fae
commit 1ba568fb88
2 changed files with 71 additions and 14 deletions

View File

@ -76,6 +76,8 @@ public class FilePanel extends JPanel {
private void initComponents() { private void initComponents() {
tabbedPane = new JTabbedPane(); tabbedPane = new JTabbedPane();
tabbedPane.putClientProperty("JTabbedPane.showTabSeparators", true);
tabbedPane.putClientProperty("JTabbedPane.hasFullBorder", true);
setLayout(new BorderLayout()); setLayout(new BorderLayout());
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
@ -627,10 +629,12 @@ public class FilePanel extends JPanel {
// Inactive indicator is subtle dark gray // Inactive indicator is subtle dark gray
Color inactiveColor = new Color(60, 60, 60); Color inactiveColor = new Color(60, 60, 60);
Color targetColor = active ? activeColor : inactiveColor; Color targetColor = active ? activeColor : inactiveColor;
// Apply a matte border to the top of tabbedPane - this places it between // Remove the horizontal line above tabs.
// the topPanel (dropdown) and the tabs themselves. tabbedPane.setBorder(null);
tabbedPane.setBorder(BorderFactory.createMatteBorder(3, 0, 0, 0, targetColor));
// No panel border highlight.
setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
// Propagate active state to all tabs // Propagate active state to all tabs
for (int i = 0; i < tabbedPane.getTabCount(); i++) { for (int i = 0; i < tabbedPane.getTabCount(); i++) {
@ -650,6 +654,13 @@ public class FilePanel extends JPanel {
private void updateTabStyles() { private void updateTabStyles() {
if (tabbedPane == null) return; if (tabbedPane == null) return;
int selectedIndex = tabbedPane.getSelectedIndex(); int selectedIndex = tabbedPane.getSelectedIndex();
Color baseTabColor = UIManager.getColor("TabbedPane.background");
if (baseTabColor == null) {
baseTabColor = tabbedPane.getBackground();
}
Color inactiveTabColor = adjustBrightness(baseTabColor, -0.08f);
Color activeTabColor = adjustBrightness(baseTabColor, 0.10f);
for (int i = 0; i < tabbedPane.getTabCount(); i++) { for (int i = 0; i < tabbedPane.getTabCount(); i++) {
Component c = tabbedPane.getComponentAt(i); Component c = tabbedPane.getComponentAt(i);
if (c instanceof FilePanelTab tab) { if (c instanceof FilePanelTab tab) {
@ -657,17 +668,29 @@ public class FilePanel extends JPanel {
String title = getTabTitle(dir != null ? dir.getAbsolutePath() : ""); String title = getTabTitle(dir != null ? dir.getAbsolutePath() : "");
if (i == selectedIndex) { if (i == selectedIndex) {
// Active tab: bold font and dark blue color // Active tab: bold font
tabbedPane.setTitleAt(i, "<html><b>" + title + "</b></html>"); tabbedPane.setTitleAt(i, "<html><b>" + title + "</b></html>");
tabbedPane.setForegroundAt(i, new Color(0, 51, 153)); tabbedPane.setForegroundAt(i, null);
tabbedPane.setBackgroundAt(i, activeTabColor);
} else { } else {
// Inactive tab: normal font and default color // Inactive tab: normal font and default color
tabbedPane.setTitleAt(i, title); tabbedPane.setTitleAt(i, title);
tabbedPane.setForegroundAt(i, null); tabbedPane.setForegroundAt(i, null);
tabbedPane.setBackgroundAt(i, inactiveTabColor);
} }
} }
} }
} }
private Color adjustBrightness(Color color, float delta) {
if (color == null) {
return null;
}
float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), null);
float newBrightness = Math.max(0f, Math.min(1f, hsb[2] + delta));
int rgb = Color.HSBtoRGB(hsb[0], hsb[1], newBrightness);
return new Color((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF);
}
/** /**
* Remove the current tab * Remove the current tab
@ -965,6 +988,15 @@ public class FilePanel extends JPanel {
} }
public void applySelectionColor(Color sel) { public void applySelectionColor(Color sel) {
if (sel != null) {
tabbedPane.putClientProperty("FlatLaf.style", "underlineColor: " + toHexColor(sel) + ";");
} else {
tabbedPane.putClientProperty("FlatLaf.style", null);
}
// Fallback for non-FlatLaf implementations
tabbedPane.putClientProperty("JTabbedPane.underlineColor", sel);
updateTabStyles();
tabbedPane.repaint();
for (int i = 0; i < tabbedPane.getTabCount(); i++) { for (int i = 0; i < tabbedPane.getTabCount(); i++) {
Component c = tabbedPane.getComponentAt(i); Component c = tabbedPane.getComponentAt(i);
if (c instanceof FilePanelTab tab) { if (c instanceof FilePanelTab tab) {
@ -973,6 +1005,11 @@ public class FilePanel extends JPanel {
} }
} }
private String toHexColor(Color color) {
if (color == null) return "#000000";
return "#%02x%02x%02x".formatted(color.getRed(), color.getGreen(), color.getBlue());
}
public void applyMarkedColor(Color mark) { public void applyMarkedColor(Color mark) {
for (int i = 0; i < tabbedPane.getTabCount(); i++) { for (int i = 0; i < tabbedPane.getTabCount(); i++) {
Component c = tabbedPane.getComponentAt(i); Component c = tabbedPane.getComponentAt(i);

View File

@ -51,7 +51,9 @@ public class FilePanelTab extends JPanel {
private JPanel cardPanel; private JPanel cardPanel;
private CardLayout cardLayout; private CardLayout cardLayout;
private JTextArea infoTextArea; private JTextArea infoTextArea;
private JScrollPane tableScrollPane;
private JScrollPane infoScrollPane; private JScrollPane infoScrollPane;
private javax.swing.border.Border defaultTableScrollBorder;
private int briefCurrentColumn = 0; private int briefCurrentColumn = 0;
private Runnable onDirectoryChanged; private Runnable onDirectoryChanged;
private Runnable onSwitchPanelRequested; private Runnable onSwitchPanelRequested;
@ -269,6 +271,7 @@ public class FilePanelTab extends JPanel {
public void applySelectionColor(Color sel) { public void applySelectionColor(Color sel) {
if (sel == null) return; if (sel == null) return;
this.selectionColor = sel; this.selectionColor = sel;
updateContentBorder();
fileTable.repaint(); fileTable.repaint();
} }
@ -291,11 +294,27 @@ public class FilePanelTab extends JPanel {
public void setActive(boolean active) { public void setActive(boolean active) {
this.active = active; this.active = active;
updateContentBorder();
if (fileTable != null) { if (fileTable != null) {
fileTable.repaint(); fileTable.repaint();
} }
} }
private void updateContentBorder() {
if (tableScrollPane == null) {
return;
}
if (active && selectionColor != null) {
tableScrollPane.setBorder(BorderFactory.createLineBorder(selectionColor, 1));
return;
}
if (defaultTableScrollBorder != null) {
tableScrollPane.setBorder(defaultTableScrollBorder);
return;
}
tableScrollPane.setBorder(UIManager.getBorder("ScrollPane.border"));
}
/** /**
* Return true when focus belongs to one of the BRIEF sorting controls. * Return true when focus belongs to one of the BRIEF sorting controls.
*/ */
@ -781,15 +800,16 @@ public class FilePanelTab extends JPanel {
} }
}); });
JScrollPane scrollPane = new JScrollPane(fileTable); tableScrollPane = new JScrollPane(fileTable);
defaultTableScrollBorder = tableScrollPane.getBorder();
// Enable horizontal scrollbar when needed so BRIEF mode can scroll left-right // Enable horizontal scrollbar when needed so BRIEF mode can scroll left-right
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); tableScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
// Increase scroll speed // Increase scroll speed
scrollPane.getVerticalScrollBar().setUnitIncrement(30); tableScrollPane.getVerticalScrollBar().setUnitIncrement(30);
scrollPane.getHorizontalScrollBar().setUnitIncrement(30); tableScrollPane.getHorizontalScrollBar().setUnitIncrement(30);
scrollPane.getVerticalScrollBar().setBlockIncrement(200); tableScrollPane.getVerticalScrollBar().setBlockIncrement(200);
scrollPane.getHorizontalScrollBar().setBlockIncrement(200); tableScrollPane.getHorizontalScrollBar().setBlockIncrement(200);
// Info panel for Quick View (Ctrl+Q) // Info panel for Quick View (Ctrl+Q)
infoTextArea = new JTextArea(); infoTextArea = new JTextArea();
@ -800,7 +820,7 @@ public class FilePanelTab extends JPanel {
cardLayout = new CardLayout(); cardLayout = new CardLayout();
cardPanel = new JPanel(cardLayout); cardPanel = new JPanel(cardLayout);
cardPanel.add(scrollPane, "TABLE"); cardPanel.add(tableScrollPane, "TABLE");
cardPanel.add(infoScrollPane, "INFO"); cardPanel.add(infoScrollPane, "INFO");
// Implement mouse wheel scrolling without changing selection // Implement mouse wheel scrolling without changing selection
@ -926,7 +946,7 @@ public class FilePanelTab extends JPanel {
add(statusLabel, BorderLayout.SOUTH); add(statusLabel, BorderLayout.SOUTH);
// Add listener to handle panel resize // Add listener to handle panel resize
scrollPane.addComponentListener(new java.awt.event.ComponentAdapter() { tableScrollPane.addComponentListener(new java.awt.event.ComponentAdapter() {
@Override @Override
public void componentResized(java.awt.event.ComponentEvent e) { public void componentResized(java.awt.event.ComponentEvent e) {
if (viewMode == ViewMode.BRIEF) { if (viewMode == ViewMode.BRIEF) {