file attributes added
This commit is contained in:
parent
0f0b073cf2
commit
2e2f4bd4f5
@ -972,11 +972,14 @@ public class FilePanelTab extends JPanel {
|
|||||||
JMenuItem props = new JMenuItem("Properties");
|
JMenuItem props = new JMenuItem("Properties");
|
||||||
props.addActionListener(ae -> {
|
props.addActionListener(ae -> {
|
||||||
try {
|
try {
|
||||||
|
Window parent = SwingUtilities.getWindowAncestor(FilePanelTab.this);
|
||||||
File f = item.getFile();
|
File f = item.getFile();
|
||||||
String info = String.format("Name: %s\nPath: %s\nSize: %s\nModified: %s\nReadable: %b, Writable: %b, Executable: %b",
|
if (f != null) {
|
||||||
f.getName(), f.getAbsolutePath(), item.isDirectory() ? "<DIR>" : formatSize(f.length()),
|
PropertiesDialog dialog = new PropertiesDialog(parent, f);
|
||||||
new java.util.Date(f.lastModified()).toString(), f.canRead(), f.canWrite(), f.canExecute());
|
dialog.setVisible(true);
|
||||||
JOptionPane.showMessageDialog(FilePanelTab.this, info, "Properties", JOptionPane.INFORMATION_MESSAGE);
|
// Refresh current directory after potential attribute changes
|
||||||
|
loadDirectory(getCurrentDirectory());
|
||||||
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
try { JOptionPane.showMessageDialog(FilePanelTab.this, "Cannot show properties: " + ex.getMessage()); } catch (Exception ignore) {}
|
try { JOptionPane.showMessageDialog(FilePanelTab.this, "Cannot show properties: " + ex.getMessage()); } catch (Exception ignore) {}
|
||||||
}
|
}
|
||||||
|
|||||||
350
src/main/java/com/kfmanager/ui/PropertiesDialog.java
Normal file
350
src/main/java/com/kfmanager/ui/PropertiesDialog.java
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
package com.kfmanager.ui;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.*;
|
||||||
|
import java.nio.file.attribute.*;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class PropertiesDialog extends JDialog {
|
||||||
|
private final File file;
|
||||||
|
private final Path path;
|
||||||
|
|
||||||
|
// Attributes Tab components
|
||||||
|
private JCheckBox[][] permChecks; // [Owner, Group, Other][Read, Write, Execute]
|
||||||
|
private JTextField octalField;
|
||||||
|
private JTextField symbolicField;
|
||||||
|
private JCheckBox suidCheck, sgidCheck, stickyCheck;
|
||||||
|
private JCheckBox recursiveCheck;
|
||||||
|
private JTextField ownerField, groupField;
|
||||||
|
|
||||||
|
public PropertiesDialog(Window owner, File file) {
|
||||||
|
super(owner, "Properties", ModalityType.APPLICATION_MODAL);
|
||||||
|
this.file = file;
|
||||||
|
this.path = file.toPath();
|
||||||
|
|
||||||
|
initComponents();
|
||||||
|
|
||||||
|
pack();
|
||||||
|
setMinimumSize(new Dimension(500, 550));
|
||||||
|
setLocationRelativeTo(owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initComponents() {
|
||||||
|
setLayout(new BorderLayout());
|
||||||
|
|
||||||
|
JTabbedPane tabbedPane = new JTabbedPane();
|
||||||
|
tabbedPane.addTab("Properties", buildPropertiesPanel());
|
||||||
|
tabbedPane.addTab("Attributes", buildAttributesPanel());
|
||||||
|
|
||||||
|
add(tabbedPane, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
||||||
|
JButton okButton = new JButton("OK");
|
||||||
|
JButton cancelButton = new JButton("Cancel");
|
||||||
|
|
||||||
|
okButton.addActionListener(e -> {
|
||||||
|
if (applyChanges()) {
|
||||||
|
dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cancelButton.addActionListener(e -> dispose());
|
||||||
|
|
||||||
|
buttonPanel.add(okButton);
|
||||||
|
buttonPanel.add(cancelButton);
|
||||||
|
add(buttonPanel, BorderLayout.SOUTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JPanel buildPropertiesPanel() {
|
||||||
|
JPanel panel = new JPanel(new GridBagLayout());
|
||||||
|
panel.setBorder(new EmptyBorder(20, 20, 20, 20));
|
||||||
|
GridBagConstraints gbc = new GridBagConstraints();
|
||||||
|
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
gbc.insets = new Insets(5, 5, 5, 5);
|
||||||
|
|
||||||
|
int row = 0;
|
||||||
|
addInfoRow(panel, gbc, row++, "Name:", file.getName());
|
||||||
|
addInfoRow(panel, gbc, row++, "Path:", file.getAbsolutePath());
|
||||||
|
|
||||||
|
String sizeStr = file.isDirectory() ? "Directory" : formatSize(file.length());
|
||||||
|
addInfoRow(panel, gbc, row++, "Size:", sizeStr);
|
||||||
|
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
addInfoRow(panel, gbc, row++, "Modified:", sdf.format(new Date(file.lastModified())));
|
||||||
|
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JPanel buildAttributesPanel() {
|
||||||
|
JPanel panel = new JPanel(new GridBagLayout());
|
||||||
|
panel.setBorder(new EmptyBorder(15, 15, 15, 15));
|
||||||
|
GridBagConstraints gbc = new GridBagConstraints();
|
||||||
|
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
gbc.insets = new Insets(5, 5, 5, 5);
|
||||||
|
|
||||||
|
int row = 0;
|
||||||
|
|
||||||
|
// File name display
|
||||||
|
JLabel nameLabel = new JLabel("File name");
|
||||||
|
gbc.gridx = 0; gbc.gridy = row; gbc.weightx = 0;
|
||||||
|
panel.add(nameLabel, gbc);
|
||||||
|
|
||||||
|
JLabel fileNameValue = new JLabel(file.getName());
|
||||||
|
gbc.gridx = 1; gbc.gridy = row; gbc.weightx = 1; gbc.gridwidth = 3;
|
||||||
|
panel.add(fileNameValue, gbc);
|
||||||
|
gbc.gridwidth = 1;
|
||||||
|
row++;
|
||||||
|
|
||||||
|
panel.add(new JSeparator(), new GridBagConstraints(0, row++, 4, 1, 1.0, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(10, 0, 10, 0), 0, 0));
|
||||||
|
|
||||||
|
// Header: Read, Write, Execute
|
||||||
|
gbc.gridy = row;
|
||||||
|
gbc.weightx = 0;
|
||||||
|
String[] titles = {"", "Read", "Write", "Execute"};
|
||||||
|
for (int i = 1; i < titles.length; i++) {
|
||||||
|
gbc.gridx = i;
|
||||||
|
panel.add(new JLabel(titles[i], SwingConstants.CENTER), gbc);
|
||||||
|
}
|
||||||
|
row++;
|
||||||
|
|
||||||
|
// Rows: Owner, Group, Other
|
||||||
|
String[] labels = {"Owner", "Group", "Other"};
|
||||||
|
permChecks = new JCheckBox[3][3];
|
||||||
|
|
||||||
|
Set<PosixFilePermission> perms = new HashSet<>();
|
||||||
|
String ownerName = "";
|
||||||
|
String groupName = "";
|
||||||
|
try {
|
||||||
|
PosixFileAttributes attrs = Files.readAttributes(path, PosixFileAttributes.class);
|
||||||
|
perms = attrs.permissions();
|
||||||
|
ownerName = attrs.owner().getName();
|
||||||
|
groupName = attrs.group().getName();
|
||||||
|
} catch (Exception ignore) {
|
||||||
|
// Fallback for non-posix systems or permission issues
|
||||||
|
if (file.canRead()) perms.add(PosixFilePermission.OWNER_READ);
|
||||||
|
if (file.canWrite()) perms.add(PosixFilePermission.OWNER_WRITE);
|
||||||
|
if (file.canExecute()) perms.add(PosixFilePermission.OWNER_EXECUTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
gbc.gridx = 0; gbc.gridy = row;
|
||||||
|
panel.add(new JLabel(labels[i]), gbc);
|
||||||
|
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
permChecks[i][j] = new JCheckBox();
|
||||||
|
permChecks[i][j].setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
|
gbc.gridx = j + 1;
|
||||||
|
panel.add(permChecks[i][j], gbc);
|
||||||
|
|
||||||
|
// Set initial state
|
||||||
|
permChecks[i][j].setSelected(hasPermission(perms, i, j));
|
||||||
|
permChecks[i][j].addActionListener(e -> updateOctalAndSymbolic());
|
||||||
|
}
|
||||||
|
row++;
|
||||||
|
}
|
||||||
|
|
||||||
|
panel.add(new JSeparator(), new GridBagConstraints(0, row++, 4, 1, 1.0, 0, GridBagConstraints.CENTER, GridBagConstraints.HORIZONTAL, new Insets(10, 0, 10, 0), 0, 0));
|
||||||
|
|
||||||
|
// Special Bits
|
||||||
|
JPanel bitsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 15, 0));
|
||||||
|
bitsPanel.add(new JLabel("Bits:"));
|
||||||
|
suidCheck = new JCheckBox("SUID");
|
||||||
|
sgidCheck = new JCheckBox("SGID");
|
||||||
|
stickyCheck = new JCheckBox("Sticky");
|
||||||
|
suidCheck.setEnabled(false); // Advanced bits usually require more than just Java basic API or are rare
|
||||||
|
sgidCheck.setEnabled(false);
|
||||||
|
stickyCheck.setEnabled(false);
|
||||||
|
bitsPanel.add(suidCheck);
|
||||||
|
bitsPanel.add(sgidCheck);
|
||||||
|
bitsPanel.add(stickyCheck);
|
||||||
|
|
||||||
|
gbc.gridx = 0; gbc.gridy = row++; gbc.gridwidth = 4;
|
||||||
|
panel.add(bitsPanel, gbc);
|
||||||
|
gbc.gridwidth = 1;
|
||||||
|
|
||||||
|
// Octal and Symbolic
|
||||||
|
gbc.gridy = row;
|
||||||
|
gbc.gridx = 0;
|
||||||
|
panel.add(new JLabel("Octal:"), gbc);
|
||||||
|
|
||||||
|
octalField = new JTextField(5);
|
||||||
|
gbc.gridx = 1;
|
||||||
|
panel.add(octalField, gbc);
|
||||||
|
|
||||||
|
gbc.gridx = 2;
|
||||||
|
panel.add(new JLabel("Text:"), gbc);
|
||||||
|
|
||||||
|
symbolicField = new JTextField(12);
|
||||||
|
symbolicField.setEditable(false);
|
||||||
|
gbc.gridx = 3;
|
||||||
|
panel.add(symbolicField, gbc);
|
||||||
|
row++;
|
||||||
|
|
||||||
|
// Owner/Group Section
|
||||||
|
JPanel ownerGroupPanel = new JPanel(new GridBagLayout());
|
||||||
|
ownerGroupPanel.setBorder(BorderFactory.createTitledBorder("Owner"));
|
||||||
|
GridBagConstraints ogbc = new GridBagConstraints();
|
||||||
|
ogbc.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
ogbc.insets = new Insets(2, 5, 2, 5);
|
||||||
|
|
||||||
|
ogbc.gridx = 0; ogbc.gridy = 0;
|
||||||
|
ownerGroupPanel.add(new JLabel("Owner"), ogbc);
|
||||||
|
ownerField = new JTextField(ownerName);
|
||||||
|
ownerField.setEditable(false);
|
||||||
|
ogbc.gridx = 1; ogbc.weightx = 1.0;
|
||||||
|
ownerGroupPanel.add(ownerField, ogbc);
|
||||||
|
|
||||||
|
ogbc.gridx = 0; ogbc.gridy = 1;
|
||||||
|
ownerGroupPanel.add(new JLabel("Group"), ogbc);
|
||||||
|
groupField = new JTextField(groupName);
|
||||||
|
groupField.setEditable(false);
|
||||||
|
ogbc.gridx = 1;
|
||||||
|
ownerGroupPanel.add(groupField, ogbc);
|
||||||
|
|
||||||
|
gbc.gridx = 0; gbc.gridy = row++; gbc.gridwidth = 4;
|
||||||
|
panel.add(ownerGroupPanel, gbc);
|
||||||
|
gbc.gridwidth = 1;
|
||||||
|
|
||||||
|
// Recursive
|
||||||
|
recursiveCheck = new JCheckBox("Recursive");
|
||||||
|
recursiveCheck.setEnabled(file.isDirectory());
|
||||||
|
gbc.gridx = 0; gbc.gridy = row++; gbc.gridwidth = 4;
|
||||||
|
panel.add(recursiveCheck, gbc);
|
||||||
|
|
||||||
|
updateOctalAndSymbolic();
|
||||||
|
|
||||||
|
// Listener for octal field to update checkboxes
|
||||||
|
octalField.addActionListener(e -> updateFromOctal());
|
||||||
|
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasPermission(Set<PosixFilePermission> perms, int userIdx, int permIdx) {
|
||||||
|
PosixFilePermission p = getPermission(userIdx, permIdx);
|
||||||
|
return p != null && perms.contains(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PosixFilePermission getPermission(int userIdx, int permIdx) {
|
||||||
|
if (userIdx == 0) { // Owner
|
||||||
|
if (permIdx == 0) return PosixFilePermission.OWNER_READ;
|
||||||
|
if (permIdx == 1) return PosixFilePermission.OWNER_WRITE;
|
||||||
|
if (permIdx == 2) return PosixFilePermission.OWNER_EXECUTE;
|
||||||
|
} else if (userIdx == 1) { // Group
|
||||||
|
if (permIdx == 0) return PosixFilePermission.GROUP_READ;
|
||||||
|
if (permIdx == 1) return PosixFilePermission.GROUP_WRITE;
|
||||||
|
if (permIdx == 2) return PosixFilePermission.GROUP_EXECUTE;
|
||||||
|
} else if (userIdx == 2) { // Other
|
||||||
|
if (permIdx == 0) return PosixFilePermission.OTHERS_READ;
|
||||||
|
if (permIdx == 1) return PosixFilePermission.OTHERS_WRITE;
|
||||||
|
if (permIdx == 2) return PosixFilePermission.OTHERS_EXECUTE;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateOctalAndSymbolic() {
|
||||||
|
int octal = 0;
|
||||||
|
if (permChecks[0][0].isSelected()) octal += 0400;
|
||||||
|
if (permChecks[0][1].isSelected()) octal += 0200;
|
||||||
|
if (permChecks[0][2].isSelected()) octal += 0100;
|
||||||
|
if (permChecks[1][0].isSelected()) octal += 0040;
|
||||||
|
if (permChecks[1][1].isSelected()) octal += 0020;
|
||||||
|
if (permChecks[1][2].isSelected()) octal += 0010;
|
||||||
|
if (permChecks[2][0].isSelected()) octal += 0004;
|
||||||
|
if (permChecks[2][1].isSelected()) octal += 0002;
|
||||||
|
if (permChecks[2][2].isSelected()) octal += 0001;
|
||||||
|
|
||||||
|
octalField.setText(String.format("%03o", octal));
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(file.isDirectory() ? 'd' : '-');
|
||||||
|
sb.append(permChecks[0][0].isSelected() ? 'r' : '-');
|
||||||
|
sb.append(permChecks[0][1].isSelected() ? 'w' : '-');
|
||||||
|
sb.append(permChecks[0][2].isSelected() ? 'x' : '-');
|
||||||
|
sb.append(permChecks[1][0].isSelected() ? 'r' : '-');
|
||||||
|
sb.append(permChecks[1][1].isSelected() ? 'w' : '-');
|
||||||
|
sb.append(permChecks[1][2].isSelected() ? 'x' : '-');
|
||||||
|
sb.append(permChecks[2][0].isSelected() ? 'r' : '-');
|
||||||
|
sb.append(permChecks[2][1].isSelected() ? 'w' : '-');
|
||||||
|
sb.append(permChecks[2][2].isSelected() ? 'x' : '-');
|
||||||
|
symbolicField.setText(sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateFromOctal() {
|
||||||
|
try {
|
||||||
|
int val = Integer.parseInt(octalField.getText(), 8);
|
||||||
|
permChecks[0][0].setSelected((val & 0400) != 0);
|
||||||
|
permChecks[0][1].setSelected((val & 0200) != 0);
|
||||||
|
permChecks[0][2].setSelected((val & 0100) != 0);
|
||||||
|
permChecks[1][0].setSelected((val & 0040) != 0);
|
||||||
|
permChecks[1][1].setSelected((val & 0020) != 0);
|
||||||
|
permChecks[1][2].setSelected((val & 0010) != 0);
|
||||||
|
permChecks[2][0].setSelected((val & 0004) != 0);
|
||||||
|
permChecks[2][1].setSelected((val & 0002) != 0);
|
||||||
|
permChecks[2][2].setSelected((val & 0001) != 0);
|
||||||
|
updateOctalAndSymbolic();
|
||||||
|
} catch (Exception ignore) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean applyChanges() {
|
||||||
|
Set<PosixFilePermission> perms = new HashSet<>();
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
if (permChecks[i][j].isSelected()) {
|
||||||
|
perms.add(getPermission(i, j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
applyPermissions(path, perms, recursiveCheck.isSelected());
|
||||||
|
return true;
|
||||||
|
} catch (Exception ex) {
|
||||||
|
JOptionPane.showMessageDialog(this, "Failed to apply permissions: " + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyPermissions(Path p, Set<PosixFilePermission> perms, boolean recursive) throws IOException {
|
||||||
|
try {
|
||||||
|
Files.setPosixFilePermissions(p, perms);
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
// Fallback for non-posix filesystems
|
||||||
|
File f = p.toFile();
|
||||||
|
f.setReadable(perms.contains(PosixFilePermission.OWNER_READ));
|
||||||
|
f.setWritable(perms.contains(PosixFilePermission.OWNER_WRITE));
|
||||||
|
f.setExecutable(perms.contains(PosixFilePermission.OWNER_EXECUTE));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recursive && Files.isDirectory(p)) {
|
||||||
|
try (DirectoryStream<Path> stream = Files.newDirectoryStream(p)) {
|
||||||
|
for (Path entry : stream) {
|
||||||
|
applyPermissions(entry, perms, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addInfoRow(JPanel panel, GridBagConstraints gbc, int row, String label, String value) {
|
||||||
|
gbc.gridx = 0; gbc.gridy = row; gbc.weightx = 0;
|
||||||
|
panel.add(new JLabel(label), gbc);
|
||||||
|
gbc.gridx = 1; gbc.weightx = 1.0;
|
||||||
|
JTextField textField = new JTextField(value);
|
||||||
|
textField.setEditable(false);
|
||||||
|
textField.setBorder(null);
|
||||||
|
textField.setOpaque(false);
|
||||||
|
panel.add(textField, gbc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String formatSize(long bytes) {
|
||||||
|
if (bytes < 1024) return bytes + " B";
|
||||||
|
int exp = (int) (Math.log(bytes) / Math.log(1024));
|
||||||
|
char pre = "KMGTPE".charAt(exp - 1);
|
||||||
|
return String.format("%.1f %cB (%d bytes)", bytes / Math.pow(1024, exp), pre, bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -178,10 +178,20 @@ public class SettingsDialog extends JDialog {
|
|||||||
|
|
||||||
private JPanel buildAppearancePanel() {
|
private JPanel buildAppearancePanel() {
|
||||||
JPanel p = new JPanel(new BorderLayout(8, 8));
|
JPanel p = new JPanel(new BorderLayout(8, 8));
|
||||||
JPanel grid = new JPanel(new GridLayout(4, 2, 8, 8));
|
JPanel grid = new JPanel(new GridBagLayout());
|
||||||
grid.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
|
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;
|
||||||
|
|
||||||
grid.add(new JLabel("Application font:"));
|
// 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 = new JButton(getFontDescription(config.getGlobalFont()));
|
||||||
appearanceFontBtn.addActionListener(e -> {
|
appearanceFontBtn.addActionListener(e -> {
|
||||||
Font nf = FontChooserDialog.showDialog(this, config.getGlobalFont());
|
Font nf = FontChooserDialog.showDialog(this, config.getGlobalFont());
|
||||||
@ -191,37 +201,54 @@ public class SettingsDialog extends JDialog {
|
|||||||
if (onChange != null) onChange.run();
|
if (onChange != null) onChange.run();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
grid.add(appearanceFontBtn);
|
gbc.gridx = 1; gbc.gridy = row++; gbc.weightx = 1.0;
|
||||||
|
grid.add(appearanceFontBtn, gbc);
|
||||||
|
|
||||||
grid.add(new JLabel("Background color:"));
|
// 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 -> {
|
appearanceBgBtn = createColorButton(config.getBackgroundColor(), "Choose background color", c -> {
|
||||||
config.setBackgroundColor(c);
|
config.setBackgroundColor(c);
|
||||||
if (onChange != null) onChange.run();
|
if (onChange != null) onChange.run();
|
||||||
});
|
});
|
||||||
grid.add(appearanceBgBtn);
|
gbc.gridx = 1; gbc.gridy = row++; gbc.weightx = 1.0;
|
||||||
|
grid.add(appearanceBgBtn, gbc);
|
||||||
|
|
||||||
grid.add(new JLabel("Selection color:"));
|
// 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),
|
appearanceSelBtn = createColorButton(config.getSelectionColor() != null ? config.getSelectionColor() : new Color(184, 207, 229),
|
||||||
"Choose selection color", c -> {
|
"Choose selection color", c -> {
|
||||||
config.setSelectionColor(c);
|
config.setSelectionColor(c);
|
||||||
if (onChange != null) onChange.run();
|
if (onChange != null) onChange.run();
|
||||||
});
|
});
|
||||||
grid.add(appearanceSelBtn);
|
gbc.gridx = 1; gbc.gridy = row++; gbc.weightx = 1.0;
|
||||||
|
grid.add(appearanceSelBtn, gbc);
|
||||||
|
|
||||||
grid.add(new JLabel("Marked item color:"));
|
// 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),
|
appearanceMarkBtn = createColorButton(config.getMarkedColor() != null ? config.getMarkedColor() : new Color(204, 153, 0),
|
||||||
"Choose marked item color", c -> {
|
"Choose marked item color", c -> {
|
||||||
config.setMarkedColor(c);
|
config.setMarkedColor(c);
|
||||||
if (onChange != null) onChange.run();
|
if (onChange != null) onChange.run();
|
||||||
});
|
});
|
||||||
grid.add(appearanceMarkBtn);
|
gbc.gridx = 1; gbc.gridy = row++; gbc.weightx = 1.0;
|
||||||
|
grid.add(appearanceMarkBtn, gbc);
|
||||||
|
|
||||||
grid.add(new JLabel("Folder icon color:"));
|
// 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 -> {
|
appearanceFolderBtn = createColorButton(config.getFolderColor(), "Choose folder icon color", c -> {
|
||||||
config.setFolderColor(c);
|
config.setFolderColor(c);
|
||||||
if (onChange != null) onChange.run();
|
if (onChange != null) onChange.run();
|
||||||
});
|
});
|
||||||
grid.add(appearanceFolderBtn);
|
gbc.gridx = 1; gbc.gridy = row++; gbc.weightx = 1.0;
|
||||||
|
grid.add(appearanceFolderBtn, gbc);
|
||||||
|
|
||||||
p.add(grid, BorderLayout.NORTH);
|
p.add(grid, BorderLayout.NORTH);
|
||||||
panels.put("Appearance", p);
|
panels.put("Appearance", p);
|
||||||
@ -262,10 +289,20 @@ public class SettingsDialog extends JDialog {
|
|||||||
|
|
||||||
private JPanel buildEditorPanel() {
|
private JPanel buildEditorPanel() {
|
||||||
JPanel p = new JPanel(new BorderLayout(8, 8));
|
JPanel p = new JPanel(new BorderLayout(8, 8));
|
||||||
JPanel grid = new JPanel(new GridLayout(2, 2, 8, 8));
|
JPanel grid = new JPanel(new GridBagLayout());
|
||||||
grid.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
|
grid.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12));
|
||||||
|
|
||||||
grid.add(new JLabel("Editor font:"));
|
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 = new JButton(getFontDescription(config.getEditorFont()));
|
||||||
editorFontBtn.addActionListener(e -> {
|
editorFontBtn.addActionListener(e -> {
|
||||||
Font nf = FontChooserDialog.showDialog(this, config.getEditorFont());
|
Font nf = FontChooserDialog.showDialog(this, config.getEditorFont());
|
||||||
@ -275,9 +312,13 @@ public class SettingsDialog extends JDialog {
|
|||||||
if (onChange != null) onChange.run();
|
if (onChange != null) onChange.run();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
grid.add(editorFontBtn);
|
gbc.gridx = 1; gbc.gridy = row++; gbc.weightx = 1.0;
|
||||||
|
grid.add(editorFontBtn, gbc);
|
||||||
|
|
||||||
// External editor path
|
// External editor path
|
||||||
grid.add(new JLabel("External editor:"));
|
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));
|
JPanel extPanel = new JPanel(new BorderLayout(6, 0));
|
||||||
externalEditorField = new JTextField(config.getExternalEditorPath());
|
externalEditorField = new JTextField(config.getExternalEditorPath());
|
||||||
JButton browse = new JButton("Browse...");
|
JButton browse = new JButton("Browse...");
|
||||||
@ -295,11 +336,14 @@ public class SettingsDialog extends JDialog {
|
|||||||
externalEditorField.setText(sel.getAbsolutePath());
|
externalEditorField.setText(sel.getAbsolutePath());
|
||||||
config.setExternalEditorPath(sel.getAbsolutePath());
|
config.setExternalEditorPath(sel.getAbsolutePath());
|
||||||
// config.saveConfig() will be called when OK is pressed
|
// config.saveConfig() will be called when OK is pressed
|
||||||
|
if (onChange != null) onChange.run();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
extPanel.add(externalEditorField, BorderLayout.CENTER);
|
extPanel.add(externalEditorField, BorderLayout.CENTER);
|
||||||
extPanel.add(browse, BorderLayout.EAST);
|
extPanel.add(browse, BorderLayout.EAST);
|
||||||
grid.add(extPanel);
|
|
||||||
|
gbc.gridx = 1; gbc.gridy = row++; gbc.weightx = 1.0;
|
||||||
|
grid.add(extPanel, gbc);
|
||||||
|
|
||||||
p.add(grid, BorderLayout.NORTH);
|
p.add(grid, BorderLayout.NORTH);
|
||||||
panels.put("Editor", p);
|
panels.put("Editor", p);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user