picture viewer added

This commit is contained in:
Radek Davidek 2026-01-20 17:18:07 +01:00
parent 17cdea5857
commit d223d2a2a1

View File

@ -16,6 +16,7 @@ import java.nio.file.Files;
*/ */
public class FileEditor extends JDialog { public class FileEditor extends JDialog {
private JTextArea textArea; private JTextArea textArea;
private JScrollPane scrollPane;
private File file; private File file;
private AppConfig config; private AppConfig config;
private boolean modified = false; private boolean modified = false;
@ -54,10 +55,14 @@ public class FileEditor extends JDialog {
this.readOnly = readOnly; this.readOnly = readOnly;
initComponents(); initComponents();
loadFile(); loadFile();
// Final window positioning and visibility - only set default size if NOT an image
if (!isImageFile(file)) {
setSize(800, 600);
setLocationRelativeTo(parent);
}
setSize(800, 600);
setLocationRelativeTo(parent);
// Intercept window close (X) so we run the same save-confirm flow as other close actions // Intercept window close (X) so we run the same save-confirm flow as other close actions
setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
addWindowListener(new java.awt.event.WindowAdapter() { addWindowListener(new java.awt.event.WindowAdapter() {
@ -250,7 +255,7 @@ public class FileEditor extends JDialog {
}); });
} }
JScrollPane scrollPane = new JScrollPane(textArea); scrollPane = new JScrollPane(textArea);
add(scrollPane, BorderLayout.CENTER); add(scrollPane, BorderLayout.CENTER);
// Status bar (position, selection) // Status bar (position, selection)
JPanel statusPanel = new JPanel(new BorderLayout()); JPanel statusPanel = new JPanel(new BorderLayout());
@ -385,6 +390,7 @@ public class FileEditor extends JDialog {
} }
private void createMenuBar() { private void createMenuBar() {
if (isImageFile(file)) return;
JMenuBar menuBar = new JMenuBar(); JMenuBar menuBar = new JMenuBar();
// File menu // File menu
@ -528,7 +534,7 @@ public class FileEditor extends JDialog {
// ESC - Zavřít nebo skrýt hledání // ESC - Zavřít nebo skrýt hledání
rootPane.registerKeyboardAction(e -> { rootPane.registerKeyboardAction(e -> {
if (searchPanel.isVisible()) { if (searchPanel != null && searchPanel.isVisible()) {
hideSearchPanel(); hideSearchPanel();
} else { } else {
closeEditor(); closeEditor();
@ -580,7 +586,9 @@ public class FileEditor extends JDialog {
}, KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW); }, KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW);
// Hledání // Hledání
rootPane.registerKeyboardAction(e -> showSearchPanel(), rootPane.registerKeyboardAction(e -> {
if (!isImageFile(file)) showSearchPanel();
},
KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_DOWN_MASK), KeyStroke.getKeyStroke(KeyEvent.VK_F, InputEvent.CTRL_DOWN_MASK),
JComponent.WHEN_IN_FOCUSED_WINDOW); JComponent.WHEN_IN_FOCUSED_WINDOW);
@ -771,6 +779,10 @@ public class FileEditor extends JDialog {
} }
private void loadFile() { private void loadFile() {
if (isImageFile(file)) {
loadImage();
return;
}
try { try {
// Determine file size first to decide streaming vs full load // Determine file size first to decide streaming vs full load
long size = Files.size(file.toPath()); long size = Files.size(file.toPath());
@ -844,6 +856,79 @@ public class FileEditor extends JDialog {
return nonPrintable > (len / 4); return nonPrintable > (len / 4);
} }
private boolean isImageFile(File f) {
String name = f.getName().toLowerCase();
return name.endsWith(".jpg") || name.endsWith(".jpeg") ||
name.endsWith(".png") || name.endsWith(".gif") ||
name.endsWith(".bmp");
}
private void loadImage() {
try {
ImageIcon icon = new ImageIcon(file.getAbsolutePath());
if (icon.getImageLoadStatus() == MediaTracker.COMPLETE) {
JLabel label = new JLabel(icon);
label.setHorizontalAlignment(JLabel.CENTER);
scrollPane.setViewportView(label);
statusPosLabel.setText(String.format("Obraz: %d x %d px",
icon.getIconWidth(), icon.getIconHeight()));
statusSelLabel.setText(String.format("Velikost: %s", formatSize(file.length())));
// Adjust window size based on image size
adjustWindowSizeForImage(icon.getIconWidth(), icon.getIconHeight());
// Disable search and hex for images
if (northPanel != null) {
searchPanel.setVisible(false);
if (hexControlPanel != null) hexControlPanel.setVisible(false);
}
} else {
textArea.setText("Chyba: Nepodařilo se načíst obrázek.");
}
} catch (Exception e) {
textArea.setText("Chyba při načítání obrázku: " + e.getMessage());
}
}
private void adjustWindowSizeForImage(int imgWidth, int imgHeigth) {
// First pack to get valid insets
pack();
// Get screen size
GraphicsConfiguration gc = getGraphicsConfiguration();
Rectangle screenBounds = gc.getBounds();
Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
int maxW = screenBounds.width - screenInsets.left - screenInsets.right - 20;
int maxH = screenBounds.height - screenInsets.top - screenInsets.bottom - 20;
// Use actual insets from title bar and borders after pack()
Insets winInsets = getInsets();
// Add space for title bar (top), status bar (bottom), and borders + 15px extra
int winW = imgWidth + winInsets.left + winInsets.right + 15;
int winH = imgHeigth + winInsets.top + winInsets.bottom + statusPosLabel.getParent().getHeight() + 15;
if (winW > maxW) winW = maxW;
if (winH > maxH) winH = maxH;
// Ensure minimum size
if (winW < 400) winW = 400;
if (winH < 300) winH = 300;
setPreferredSize(new Dimension(winW, winH));
setSize(winW, winH);
validate();
setLocationRelativeTo(getOwner());
}
private String formatSize(long size) {
if (size < 1024) return size + " B";
int exp = (int) (Math.log(size) / Math.log(1024));
String pre = "KMGTPE".charAt(exp-1) + "";
return String.format("%.1f %sB", size / Math.pow(1024, exp), pre);
}
private void saveFile() { private void saveFile() {
try { try {
String content = textArea.getText(); String content = textArea.getText();