530 lines
23 KiB
Java
530 lines
23 KiB
Java
package com.kfmanager.ui;
|
|
|
|
import com.kfmanager.config.AppConfig;
|
|
|
|
import javax.swing.*;
|
|
import java.awt.*;
|
|
import java.io.File;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
import java.util.function.Consumer;
|
|
|
|
/**
|
|
* Settings dialog with categories on the left and parameters on the right.
|
|
*/
|
|
public class SettingsDialog extends JDialog {
|
|
private final AppConfig config;
|
|
private final Runnable onChange;
|
|
private final JList<String> categoryList;
|
|
private final JPanel cards;
|
|
private final CardLayout cardLayout;
|
|
|
|
// Original values for cancellation
|
|
private final Color originalBg;
|
|
private final Color originalSel;
|
|
private final Color originalMark;
|
|
private final Color originalFolder;
|
|
private final Font originalGlobalFont;
|
|
private final Font originalEditorFont;
|
|
private final String originalExternalEditorPath;
|
|
private final int originalToolbarButtonSize;
|
|
private final int originalToolbarIconSize;
|
|
|
|
// Appearance controls
|
|
private JButton appearanceFontBtn;
|
|
private JButton appearanceBgBtn;
|
|
private JButton appearanceSelBtn;
|
|
private JButton appearanceMarkBtn;
|
|
private JButton appearanceFolderBtn;
|
|
|
|
// Editor controls
|
|
private JButton editorFontBtn;
|
|
private JTextField externalEditorField;
|
|
|
|
private final Map<String, JPanel> panels = new HashMap<>();
|
|
|
|
public SettingsDialog(Window parent, AppConfig config, Runnable onChange) {
|
|
super(parent, "Settings", ModalityType.APPLICATION_MODAL);
|
|
this.config = config;
|
|
this.onChange = onChange;
|
|
|
|
// Store original values
|
|
this.originalBg = config.getBackgroundColor();
|
|
this.originalSel = config.getSelectionColor();
|
|
this.originalMark = config.getMarkedColor();
|
|
this.originalFolder = config.getFolderColor();
|
|
this.originalGlobalFont = config.getGlobalFont();
|
|
this.originalEditorFont = config.getEditorFont();
|
|
this.originalExternalEditorPath = config.getExternalEditorPath();
|
|
this.originalToolbarButtonSize = config.getToolbarButtonSize();
|
|
this.originalToolbarIconSize = config.getToolbarIconSize();
|
|
|
|
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
|
|
setSize(700, 420);
|
|
setLocationRelativeTo(parent);
|
|
|
|
// Left: categories
|
|
DefaultListModel<String> model = new DefaultListModel<>();
|
|
model.addElement("Appearance");
|
|
model.addElement("Editor");
|
|
model.addElement("Sorting");
|
|
model.addElement("Toolbar");
|
|
categoryList = new JList<>(model);
|
|
categoryList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
|
categoryList.setSelectedIndex(0);
|
|
|
|
cardLayout = new CardLayout();
|
|
cards = new JPanel(cardLayout);
|
|
|
|
// Build category panels
|
|
cards.add(buildAppearancePanel(), "Appearance");
|
|
cards.add(buildEditorPanel(), "Editor");
|
|
cards.add(buildSortingPanel(), "Sorting");
|
|
cards.add(buildToolbarPanel(), "Toolbar");
|
|
|
|
categoryList.addListSelectionListener(e -> {
|
|
if (!e.getValueIsAdjusting()) {
|
|
String sel = categoryList.getSelectedValue();
|
|
if (sel != null) cardLayout.show(cards, sel);
|
|
}
|
|
});
|
|
|
|
JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
|
|
new JScrollPane(categoryList), cards);
|
|
split.setResizeWeight(0);
|
|
split.setDividerLocation(160);
|
|
|
|
add(split, BorderLayout.CENTER);
|
|
|
|
JPanel btns = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
|
JButton ok = new JButton("OK");
|
|
ok.addActionListener(e -> {
|
|
// Collect sorting settings from the Sorting panel (if present)
|
|
JPanel sortingHolder = (JPanel) panels.get("Sorting");
|
|
if (sortingHolder != null) {
|
|
try {
|
|
JComboBox<?> pf = (JComboBox<?>) sortingHolder.getClientProperty("primaryField");
|
|
JComboBox<?> po = (JComboBox<?>) sortingHolder.getClientProperty("primaryOrder");
|
|
JComboBox<?> sf = (JComboBox<?>) sortingHolder.getClientProperty("secondaryField");
|
|
JComboBox<?> so = (JComboBox<?>) sortingHolder.getClientProperty("secondaryOrder");
|
|
JComboBox<?> tf = (JComboBox<?>) sortingHolder.getClientProperty("tertiaryField");
|
|
JComboBox<?> to = (JComboBox<?>) sortingHolder.getClientProperty("tertiaryOrder");
|
|
|
|
java.util.List<String> criteria = new java.util.ArrayList<>();
|
|
|
|
if (pf != null && po != null) {
|
|
String f = pf.getSelectedItem() != null ? pf.getSelectedItem().toString().toLowerCase() : "";
|
|
String ord = po.getSelectedItem() != null && po.getSelectedItem().toString().equalsIgnoreCase("Descending") ? "desc" : "asc";
|
|
if (!f.isEmpty()) criteria.add(f + ":" + ord);
|
|
}
|
|
|
|
if (sf != null && so != null) {
|
|
String s = sf.getSelectedItem() != null ? sf.getSelectedItem().toString() : "(none)";
|
|
if (!"(none)".equals(s)) {
|
|
String field = s.toLowerCase();
|
|
String ord = so.getSelectedItem() != null && so.getSelectedItem().toString().equalsIgnoreCase("Descending") ? "desc" : "asc";
|
|
criteria.add(field + ":" + ord);
|
|
}
|
|
}
|
|
|
|
if (tf != null && to != null) {
|
|
String t = tf.getSelectedItem() != null ? tf.getSelectedItem().toString() : "(none)";
|
|
if (!"(none)".equals(t)) {
|
|
String field = t.toLowerCase();
|
|
String ord = to.getSelectedItem() != null && to.getSelectedItem().toString().equalsIgnoreCase("Descending") ? "desc" : "asc";
|
|
criteria.add(field + ":" + ord);
|
|
}
|
|
}
|
|
|
|
config.setMultipleSortCriteria(criteria);
|
|
|
|
// save extra sorting options
|
|
JComboBox<?> hiddenOrder = (JComboBox<?>) sortingHolder.getClientProperty("hiddenOrder");
|
|
JCheckBox uppercasePriority = (JCheckBox) sortingHolder.getClientProperty("uppercasePriority");
|
|
JCheckBox numericAware = (JCheckBox) sortingHolder.getClientProperty("numericAware");
|
|
if (hiddenOrder != null) {
|
|
boolean hiddenLast = "Hidden last".equals(hiddenOrder.getSelectedItem());
|
|
config.setHiddenFilesLast(hiddenLast);
|
|
}
|
|
if (uppercasePriority != null) {
|
|
config.setUppercasePriority(uppercasePriority.isSelected());
|
|
}
|
|
if (numericAware != null) {
|
|
config.setNumericSortEnabled(numericAware.isSelected());
|
|
}
|
|
JCheckBox ignoreLeadingDot = (JCheckBox) sortingHolder.getClientProperty("ignoreLeadingDot");
|
|
if (ignoreLeadingDot != null) {
|
|
config.setIgnoreLeadingDot(ignoreLeadingDot.isSelected());
|
|
}
|
|
} catch (Exception ignore) {}
|
|
}
|
|
|
|
// Collect Toolbar settings
|
|
JPanel toolbarHolder = (JPanel) panels.get("Toolbar");
|
|
if (toolbarHolder != null) {
|
|
try {
|
|
JSpinner bs = (JSpinner) toolbarHolder.getClientProperty("buttonSize");
|
|
JSpinner is = (JSpinner) toolbarHolder.getClientProperty("iconSize");
|
|
if (bs != null) config.setToolbarButtonSize((Integer) bs.getValue());
|
|
if (is != null) config.setToolbarIconSize((Integer) is.getValue());
|
|
} catch (Exception ignore) {}
|
|
}
|
|
|
|
// Save external editor path
|
|
if (externalEditorField != null) {
|
|
config.setExternalEditorPath(externalEditorField.getText());
|
|
}
|
|
|
|
// Persist config and notify caller
|
|
config.saveConfig();
|
|
if (onChange != null) onChange.run();
|
|
dispose();
|
|
});
|
|
JButton cancel = new JButton("Cancel");
|
|
cancel.addActionListener(e -> {
|
|
// Restore original values
|
|
config.setBackgroundColor(originalBg);
|
|
config.setSelectionColor(originalSel);
|
|
config.setMarkedColor(originalMark);
|
|
config.setFolderColor(originalFolder);
|
|
config.setGlobalFont(originalGlobalFont);
|
|
config.setEditorFont(originalEditorFont);
|
|
config.setExternalEditorPath(originalExternalEditorPath);
|
|
config.setToolbarButtonSize(originalToolbarButtonSize);
|
|
config.setToolbarIconSize(originalToolbarIconSize);
|
|
|
|
// Notify UI to revert changes
|
|
if (onChange != null) onChange.run();
|
|
|
|
dispose();
|
|
});
|
|
btns.add(ok);
|
|
btns.add(cancel);
|
|
add(btns, BorderLayout.SOUTH);
|
|
}
|
|
|
|
private JPanel buildAppearancePanel() {
|
|
JPanel p = new JPanel(new BorderLayout(8, 8));
|
|
JPanel grid = new JPanel(new GridBagLayout());
|
|
grid.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
|
|
|
|
GridBagConstraints gbc = new GridBagConstraints();
|
|
gbc.fill = GridBagConstraints.HORIZONTAL;
|
|
gbc.insets = new Insets(4, 4, 4, 4);
|
|
gbc.weightx = 1.0;
|
|
|
|
int row = 0;
|
|
|
|
// Application font
|
|
gbc.gridx = 0; gbc.gridy = row; gbc.weightx = 0.0;
|
|
grid.add(new JLabel("Application font:"), gbc);
|
|
|
|
appearanceFontBtn = new JButton(getFontDescription(config.getGlobalFont()));
|
|
appearanceFontBtn.addActionListener(e -> {
|
|
Font nf = FontChooserDialog.showDialog(this, config.getGlobalFont());
|
|
if (nf != null) {
|
|
config.setGlobalFont(nf);
|
|
appearanceFontBtn.setText(getFontDescription(nf));
|
|
if (onChange != null) onChange.run();
|
|
}
|
|
});
|
|
gbc.gridx = 1; gbc.gridy = row++; gbc.weightx = 1.0;
|
|
grid.add(appearanceFontBtn, gbc);
|
|
|
|
// Background color
|
|
gbc.gridx = 0; gbc.gridy = row; gbc.weightx = 0.0;
|
|
grid.add(new JLabel("Background color:"), gbc);
|
|
|
|
appearanceBgBtn = createColorButton(config.getBackgroundColor(), "Choose background color", c -> {
|
|
config.setBackgroundColor(c);
|
|
if (onChange != null) onChange.run();
|
|
});
|
|
gbc.gridx = 1; gbc.gridy = row++; gbc.weightx = 1.0;
|
|
grid.add(appearanceBgBtn, gbc);
|
|
|
|
// Selection color
|
|
gbc.gridx = 0; gbc.gridy = row; gbc.weightx = 0.0;
|
|
grid.add(new JLabel("Selection color:"), gbc);
|
|
|
|
appearanceSelBtn = createColorButton(config.getSelectionColor() != null ? config.getSelectionColor() : new Color(184, 207, 229),
|
|
"Choose selection color", c -> {
|
|
config.setSelectionColor(c);
|
|
if (onChange != null) onChange.run();
|
|
});
|
|
gbc.gridx = 1; gbc.gridy = row++; gbc.weightx = 1.0;
|
|
grid.add(appearanceSelBtn, gbc);
|
|
|
|
// Marked item color
|
|
gbc.gridx = 0; gbc.gridy = row; gbc.weightx = 0.0;
|
|
grid.add(new JLabel("Marked item color:"), gbc);
|
|
|
|
appearanceMarkBtn = createColorButton(config.getMarkedColor() != null ? config.getMarkedColor() : new Color(204, 153, 0),
|
|
"Choose marked item color", c -> {
|
|
config.setMarkedColor(c);
|
|
if (onChange != null) onChange.run();
|
|
});
|
|
gbc.gridx = 1; gbc.gridy = row++; gbc.weightx = 1.0;
|
|
grid.add(appearanceMarkBtn, gbc);
|
|
|
|
// Folder icon color
|
|
gbc.gridx = 0; gbc.gridy = row; gbc.weightx = 0.0;
|
|
grid.add(new JLabel("Folder icon color:"), gbc);
|
|
|
|
appearanceFolderBtn = createColorButton(config.getFolderColor(), "Choose folder icon color", c -> {
|
|
config.setFolderColor(c);
|
|
if (onChange != null) onChange.run();
|
|
});
|
|
gbc.gridx = 1; gbc.gridy = row++; gbc.weightx = 1.0;
|
|
grid.add(appearanceFolderBtn, gbc);
|
|
|
|
p.add(grid, BorderLayout.NORTH);
|
|
panels.put("Appearance", p);
|
|
return p;
|
|
}
|
|
|
|
private JButton createColorButton(Color initialColor, String title, Consumer<Color> onColorChosen) {
|
|
JButton btn = new JButton(" ") {
|
|
@Override
|
|
public void paintComponent(Graphics g) {
|
|
g.setColor(getBackground());
|
|
g.fillRect(0, 0, getWidth(), getHeight());
|
|
if (getModel().isRollover()) {
|
|
g.setColor(new Color(255, 255, 255, 60));
|
|
g.fillRect(0, 0, getWidth(), getHeight());
|
|
}
|
|
if (getModel().isPressed()) {
|
|
g.setColor(new Color(0, 0, 0, 60));
|
|
g.fillRect(0, 0, getWidth(), getHeight());
|
|
}
|
|
}
|
|
};
|
|
btn.setOpaque(true);
|
|
btn.setContentAreaFilled(false);
|
|
btn.setFocusPainted(false);
|
|
btn.setBorder(BorderFactory.createLineBorder(Color.GRAY));
|
|
btn.setPreferredSize(new Dimension(80, 25));
|
|
btn.setBackground(initialColor != null ? initialColor : UIManager.getColor("Panel.background"));
|
|
btn.addActionListener(e -> {
|
|
Color chosen = JColorChooser.showDialog(this, title, btn.getBackground());
|
|
if (chosen != null) {
|
|
btn.setBackground(chosen);
|
|
onColorChosen.accept(chosen);
|
|
}
|
|
});
|
|
return btn;
|
|
}
|
|
|
|
private JPanel buildEditorPanel() {
|
|
JPanel p = new JPanel(new BorderLayout(8, 8));
|
|
JPanel grid = new JPanel(new GridBagLayout());
|
|
grid.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
|
|
|
|
GridBagConstraints gbc = new GridBagConstraints();
|
|
gbc.fill = GridBagConstraints.HORIZONTAL;
|
|
gbc.insets = new Insets(4, 4, 4, 4);
|
|
gbc.weightx = 1.0;
|
|
|
|
int row = 0;
|
|
|
|
// Editor font
|
|
gbc.gridx = 0; gbc.gridy = row; gbc.weightx = 0.0;
|
|
grid.add(new JLabel("Editor font:"), gbc);
|
|
|
|
editorFontBtn = new JButton(getFontDescription(config.getEditorFont()));
|
|
editorFontBtn.addActionListener(e -> {
|
|
Font nf = FontChooserDialog.showDialog(this, config.getEditorFont());
|
|
if (nf != null) {
|
|
config.setEditorFont(nf);
|
|
editorFontBtn.setText(getFontDescription(nf));
|
|
if (onChange != null) onChange.run();
|
|
}
|
|
});
|
|
gbc.gridx = 1; gbc.gridy = row++; gbc.weightx = 1.0;
|
|
grid.add(editorFontBtn, gbc);
|
|
|
|
// External editor path
|
|
gbc.gridx = 0; gbc.gridy = row; gbc.weightx = 0.0;
|
|
grid.add(new JLabel("External editor:"), gbc);
|
|
|
|
JPanel extPanel = new JPanel(new BorderLayout(6, 0));
|
|
externalEditorField = new JTextField(config.getExternalEditorPath());
|
|
JButton browse = new JButton("Browse...");
|
|
browse.addActionListener(e -> {
|
|
JFileChooser fc = new JFileChooser();
|
|
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
|
fc.setDialogTitle("Select external editor executable");
|
|
if (!externalEditorField.getText().isEmpty()) {
|
|
File f = new File(externalEditorField.getText());
|
|
if (f.exists()) fc.setSelectedFile(f);
|
|
}
|
|
int r = fc.showOpenDialog(this);
|
|
if (r == JFileChooser.APPROVE_OPTION) {
|
|
File sel = fc.getSelectedFile();
|
|
externalEditorField.setText(sel.getAbsolutePath());
|
|
config.setExternalEditorPath(sel.getAbsolutePath());
|
|
// config.saveConfig() will be called when OK is pressed
|
|
if (onChange != null) onChange.run();
|
|
}
|
|
});
|
|
extPanel.add(externalEditorField, BorderLayout.CENTER);
|
|
extPanel.add(browse, BorderLayout.EAST);
|
|
|
|
gbc.gridx = 1; gbc.gridy = row++; gbc.weightx = 1.0;
|
|
grid.add(extPanel, gbc);
|
|
|
|
p.add(grid, BorderLayout.NORTH);
|
|
panels.put("Editor", p);
|
|
return p;
|
|
}
|
|
|
|
private JPanel buildSortingPanel() {
|
|
JPanel p = new JPanel(new BorderLayout(8, 8));
|
|
JPanel grid = new JPanel();
|
|
grid.setLayout(new BoxLayout(grid, BoxLayout.Y_AXIS));
|
|
grid.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
|
|
|
|
// Helper to add a label above a control for single-column layout
|
|
java.util.function.BiConsumer<String, JComponent> addLabeled = (labelText, comp) -> {
|
|
JPanel row = new JPanel();
|
|
row.setLayout(new BoxLayout(row, BoxLayout.Y_AXIS));
|
|
JLabel lbl = new JLabel(labelText);
|
|
lbl.setAlignmentX(Component.LEFT_ALIGNMENT);
|
|
comp.setAlignmentX(Component.LEFT_ALIGNMENT);
|
|
row.add(lbl);
|
|
row.add(Box.createVerticalStrut(4));
|
|
row.add(comp);
|
|
row.setAlignmentX(Component.LEFT_ALIGNMENT);
|
|
grid.add(row);
|
|
grid.add(Box.createVerticalStrut(8));
|
|
};
|
|
|
|
JComboBox<String> primaryField = new JComboBox<>(new String[]{"Name", "Size", "Date"});
|
|
JComboBox<String> primaryOrder = new JComboBox<>(new String[]{"Ascending", "Descending"});
|
|
JPanel primaryPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 6, 0));
|
|
primaryPanel.add(primaryField);
|
|
primaryPanel.add(primaryOrder);
|
|
addLabeled.accept("Primary sort:", primaryPanel);
|
|
|
|
JComboBox<String> secondaryField = new JComboBox<>(new String[]{"(none)", "Name", "Size", "Date"});
|
|
JComboBox<String> secondaryOrder = new JComboBox<>(new String[]{"Ascending", "Descending"});
|
|
JPanel secondaryPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 6, 0));
|
|
secondaryPanel.add(secondaryField);
|
|
secondaryPanel.add(secondaryOrder);
|
|
addLabeled.accept("Secondary sort:", secondaryPanel);
|
|
|
|
JComboBox<String> tertiaryField = new JComboBox<>(new String[]{"(none)", "Name", "Size", "Date"});
|
|
JComboBox<String> tertiaryOrder = new JComboBox<>(new String[]{"Ascending", "Descending"});
|
|
JPanel tertiaryPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 6, 0));
|
|
tertiaryPanel.add(tertiaryField);
|
|
tertiaryPanel.add(tertiaryOrder);
|
|
addLabeled.accept("Tertiary sort:", tertiaryPanel);
|
|
|
|
// Additional sorting options (each as own labeled row)
|
|
JComboBox<String> hiddenOrder = new JComboBox<>(new String[]{"Hidden last", "Hidden first"});
|
|
hiddenOrder.setSelectedIndex(config.getHiddenFilesLast() ? 0 : 1);
|
|
addLabeled.accept("Hidden files:", hiddenOrder);
|
|
|
|
JCheckBox uppercasePriority = new JCheckBox("Prefer uppercase first");
|
|
uppercasePriority.setSelected(config.getUppercasePriority());
|
|
addLabeled.accept("Uppercase priority:", uppercasePriority);
|
|
|
|
JCheckBox numericAware = new JCheckBox("Enable natural numeric sorting");
|
|
numericAware.setSelected(config.getNumericSortEnabled());
|
|
addLabeled.accept("Numeric-aware names:", numericAware);
|
|
|
|
JCheckBox ignoreLeadingDot = new JCheckBox("Ignore leading dot in names (treat '.name' as 'name')");
|
|
ignoreLeadingDot.setSelected(config.getIgnoreLeadingDot());
|
|
addLabeled.accept("Ignore leading dot:", ignoreLeadingDot);
|
|
|
|
// Load existing criteria from config
|
|
java.util.List<String> crit = config.getMultipleSortCriteria();
|
|
if (crit != null && !crit.isEmpty()) {
|
|
try {
|
|
// parse strings like "name:asc"
|
|
if (crit.size() > 0) {
|
|
String[] parts = crit.get(0).split(":");
|
|
if (parts.length >= 1) primaryField.setSelectedItem(capitalize(parts[0]));
|
|
if (parts.length == 2 && parts[1].equalsIgnoreCase("desc")) primaryOrder.setSelectedItem("Descending");
|
|
}
|
|
if (crit.size() > 1) {
|
|
String[] parts = crit.get(1).split(":");
|
|
if (parts.length >= 1) secondaryField.setSelectedItem("(" + parts[0] + ")");
|
|
if (parts.length == 2 && parts[1].equalsIgnoreCase("desc")) secondaryOrder.setSelectedItem("Descending");
|
|
}
|
|
if (crit.size() > 2) {
|
|
String[] parts = crit.get(2).split(":");
|
|
if (parts.length >= 1) tertiaryField.setSelectedItem("(" + parts[0] + ")");
|
|
if (parts.length == 2 && parts[1].equalsIgnoreCase("desc")) tertiaryOrder.setSelectedItem("Descending");
|
|
}
|
|
} catch (Exception ignore) {}
|
|
}
|
|
|
|
p.add(grid, BorderLayout.NORTH);
|
|
|
|
// Save action will be done on OK; store controls in panels map so OK handler can read them
|
|
JPanel holder = new JPanel();
|
|
holder.putClientProperty("primaryField", primaryField);
|
|
holder.putClientProperty("primaryOrder", primaryOrder);
|
|
holder.putClientProperty("secondaryField", secondaryField);
|
|
holder.putClientProperty("secondaryOrder", secondaryOrder);
|
|
holder.putClientProperty("tertiaryField", tertiaryField);
|
|
holder.putClientProperty("tertiaryOrder", tertiaryOrder);
|
|
holder.putClientProperty("hiddenOrder", hiddenOrder);
|
|
holder.putClientProperty("uppercasePriority", uppercasePriority);
|
|
holder.putClientProperty("numericAware", numericAware);
|
|
holder.putClientProperty("ignoreLeadingDot", ignoreLeadingDot);
|
|
panels.put("Sorting", holder);
|
|
|
|
return p;
|
|
}
|
|
|
|
private JPanel buildToolbarPanel() {
|
|
JPanel p = new JPanel(new BorderLayout(8, 8));
|
|
JPanel grid = new JPanel(new GridBagLayout());
|
|
grid.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
|
|
|
|
GridBagConstraints gbc = new GridBagConstraints();
|
|
gbc.fill = GridBagConstraints.HORIZONTAL;
|
|
gbc.insets = new Insets(4, 4, 4, 4);
|
|
gbc.weightx = 1.0;
|
|
|
|
int row = 0;
|
|
|
|
// Button size
|
|
gbc.gridx = 0; gbc.gridy = row; gbc.weightx = 0.0;
|
|
grid.add(new JLabel("Button size (px):"), gbc);
|
|
|
|
JSpinner buttonSizeSpinner = new JSpinner(new SpinnerNumberModel(config.getToolbarButtonSize(), 16, 128, 1));
|
|
gbc.gridx = 1; gbc.gridy = row++; gbc.weightx = 1.0;
|
|
grid.add(buttonSizeSpinner, gbc);
|
|
|
|
// Icon size
|
|
gbc.gridx = 0; gbc.gridy = row; gbc.weightx = 0.0;
|
|
grid.add(new JLabel("Icon size (px):"), gbc);
|
|
|
|
JSpinner iconSizeSpinner = new JSpinner(new SpinnerNumberModel(config.getToolbarIconSize(), 16, 128, 1));
|
|
gbc.gridx = 1; gbc.gridy = row++; gbc.weightx = 1.0;
|
|
grid.add(iconSizeSpinner, gbc);
|
|
|
|
p.add(grid, BorderLayout.NORTH);
|
|
|
|
// Save action will be done on OK; store controls in a holder
|
|
JPanel holder = new JPanel();
|
|
holder.putClientProperty("buttonSize", buttonSizeSpinner);
|
|
holder.putClientProperty("iconSize", iconSizeSpinner);
|
|
panels.put("Toolbar", holder);
|
|
|
|
return p;
|
|
}
|
|
|
|
private static String capitalize(String s) {
|
|
if (s == null || s.isEmpty()) return s;
|
|
return s.substring(0,1).toUpperCase() + s.substring(1).toLowerCase();
|
|
}
|
|
|
|
private String getFontDescription(Font f) {
|
|
if (f == null) return "(default)";
|
|
return String.format("%s %dpt", f.getName(), f.getSize());
|
|
}
|
|
}
|