fixed some functionallity added back some which was removed cause of refactoring ...

some new refactoring to make the UI code cleaner

Signed-off-by: rattatwinko <seppmutterman@gmail.com>
This commit is contained in:
2026-01-19 13:04:40 +01:00
parent f6ee3e915e
commit 565a4f3cf3
10 changed files with 393 additions and 373 deletions

View File

@@ -0,0 +1,132 @@
package io.swtc.proccessing.ui.iframe;
import com.github.sarxos.webcam.Webcam;
import io.swtc.proccessing.WebcamCaptureLoop;
import io.swtc.proccessing.CameraPanel;
import io.swtc.recording.VideoRecorder;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.function.Consumer;
public class CameraInternalFrame extends JInternalFrame {
private final WebcamCaptureLoop captureLoop;
private final CameraPanel cameraPanel;
private final VideoRecorder videoRecorder; // Instance of the recorder
private JButton recordBtn;
public CameraInternalFrame(Webcam webcam, Consumer<CameraInternalFrame> onOpenEffects) {
super(webcam.getName(), true, true, true, true);
this.cameraPanel = new CameraPanel();
this.videoRecorder = new VideoRecorder(); // Initialize recorder
// Initialize capture loop
this.captureLoop = new WebcamCaptureLoop(webcam, img ->
SwingUtilities.invokeLater(() -> cameraPanel.setImage(img))
);
setupUI(onOpenEffects);
captureLoop.start();
}
private void setupUI(Consumer<CameraInternalFrame> onOpenEffects) {
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.addTab("View", cameraPanel);
tabbedPane.addTab("Capture", new RecordingPane(cameraPanel, videoRecorder));
tabbedPane.addTab("Effects", new JPanel());
tabbedPane.addChangeListener(e -> {
if (tabbedPane.getSelectedIndex() == 2) {
tabbedPane.setSelectedIndex(0);
onOpenEffects.accept(this);
}
});
add(tabbedPane);
setSize(600, 500);
}
private JPanel createCapturePanel() {
JPanel panel = new JPanel(new GridLayout(2, 1, 10, 10)); // Changed to Grid for better button layout
panel.setBorder(new EmptyBorder(15, 15, 15, 15));
JButton screenshotBtn = new JButton("Take Screenshot");
screenshotBtn.addActionListener(e -> saveSnapshot());
recordBtn = new JButton("Start Recording");
recordBtn.addActionListener(e -> toggleRecording());
panel.add(screenshotBtn);
panel.add(recordBtn);
// Wrap in a wrapper to prevent buttons from stretching too much
JPanel wrapper = new JPanel(new BorderLayout());
wrapper.add(panel, BorderLayout.NORTH);
return wrapper;
}
private void toggleRecording() {
if (!videoRecorder.isRecording()) {
startVideo();
} else {
stopVideo();
}
}
private void startVideo() {
try {
File file = new File(System.getProperty("user.home"), "vid_" + System.currentTimeMillis() + ".mp4");
videoRecorder.startRecording(cameraPanel, file);
recordBtn.setText("Stop Recording");
recordBtn.setForeground(Color.RED);
} catch (IOException ex) {
showError("Failed to start recording", ex);
}
}
private void stopVideo() {
try {
File savedFile = videoRecorder.stopRecording();
recordBtn.setText("Start Recording");
recordBtn.setForeground(Color.BLACK);
JOptionPane.showMessageDialog(this, "Video saved to: " + savedFile.getAbsolutePath());
} catch (IOException ex) {
showError("Failed to stop recording safely", ex);
}
}
private void saveSnapshot() {
BufferedImage img = cameraPanel.getCurrentProcessedImage();
if (img != null) {
try {
File file = new File(System.getProperty("user.home"), "snap_" + System.currentTimeMillis() + ".png");
ImageIO.write(img, "PNG", file);
} catch (Exception ex) {
showError("Snapshot failed", ex);
}
}
}
private void showError(String title, Exception ex) {
JOptionPane.showMessageDialog(this, title + "\n" + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
}
public CameraPanel getCameraPanel() { return cameraPanel; }
@Override
public void dispose() {
// Safety check: stop recording if the window is closed
if (videoRecorder.isRecording()) {
try { videoRecorder.stopRecording(); } catch (IOException ignored) {}
}
captureLoop.stop();
super.dispose();
}
}

View File

@@ -0,0 +1,66 @@
package io.swtc.proccessing.ui.iframe;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.CubicCurve2D;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
public class DesktopPane extends JDesktopPane {
private final Map<JInternalFrame, EffectsPanelFrame> connections;
private final Map<JInternalFrame, Color> connectionColors = new HashMap<>();
public DesktopPane(Map<JInternalFrame, EffectsPanelFrame> connections) {
this.connections = connections;
}
private Color getConnectionColor(JInternalFrame frame) {
return connectionColors.computeIfAbsent(frame, k -> {
Random rand = new Random();
return new Color(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256), 200);
});
}
public void forgetFrame(JInternalFrame frame) {
connectionColors.remove(frame);
}
@Override
protected void paintChildren(Graphics g) {
super.paintChildren(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (Map.Entry<JInternalFrame, EffectsPanelFrame> entry : connections.entrySet()) {
JInternalFrame camera = entry.getKey();
EffectsPanelFrame effects = entry.getValue();
if (camera.isVisible() && effects.isVisible() && !camera.isIcon() && !effects.isIcon()) {
g2d.setColor(getConnectionColor(camera));
drawBezierConnection(g2d, camera, effects);
}
}
g2d.dispose();
}
private void drawBezierConnection(Graphics2D g2d, JInternalFrame from, JInternalFrame to) {
Rectangle f = from.getBounds();
Rectangle t = to.getBounds();
int x1 = f.x + f.width;
int y1 = f.y + (f.height / 2);
int x2 = t.x;
int y2 = t.y + (t.height / 2);
int ctrlOffset = Math.min(Math.abs(x2 - x1) / 2, 150);
CubicCurve2D curve = new CubicCurve2D.Double(x1, y1, x1 + ctrlOffset, y1, x2 - ctrlOffset, y2, x2, y2);
g2d.setStroke(new BasicStroke(3f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g2d.draw(curve);
// Terminals
g2d.fillOval(x1 - 5, y1 - 5, 10, 10);
g2d.fillOval(x2 - 5, y2 - 5, 10, 10);
}
}

View File

@@ -0,0 +1,14 @@
package io.swtc.proccessing.ui.iframe;
import io.swtc.proccessing.CameraPanel;
import io.swtc.proccessing.FilterPanel;
import javax.swing.*;
public class EffectsPanelFrame extends JInternalFrame {
public EffectsPanelFrame(String title, CameraPanel cameraPanel) {
super(title, true, true, true, true);
setDefaultCloseOperation(HIDE_ON_CLOSE);
add(new FilterPanel(cameraPanel));
setSize(350, 600);
}
}

View File

@@ -0,0 +1,126 @@
package io.swtc.proccessing.ui.iframe;
import io.swtc.proccessing.CameraPanel;
import io.swtc.recording.VideoRecorder;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class RecordingPane extends JPanel {
private final VideoRecorder videoRecorder;
private final CameraPanel cameraPanel;
private JTextField pathField;
private JButton recordBtn;
private JLabel statusLabel;
private File outputDirectory;
public RecordingPane(CameraPanel cameraPanel, VideoRecorder videoRecorder) {
this.cameraPanel = cameraPanel;
this.videoRecorder = videoRecorder;
this.outputDirectory = new File(System.getProperty("user.home"));
setLayout(new GridBagLayout());
JPanel contentPanel = new JPanel();
contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS));
contentPanel.setPreferredSize(new Dimension(400, 250));
// Add the functional sections
contentPanel.add(createStoragePanel());
contentPanel.add(Box.createVerticalStrut(15));
contentPanel.add(createActionPanel());
contentPanel.add(Box.createVerticalStrut(15));
contentPanel.add(createStatusPanel());
add(contentPanel);
}
private JPanel createStoragePanel() {
JPanel panel = new JPanel(new BorderLayout(5, 5));
panel.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(), "Storage Settings", TitledBorder.LEFT, TitledBorder.TOP));
pathField = new JTextField(outputDirectory.getAbsolutePath());
pathField.setEditable(false);
JButton browseBtn = new JButton("Browse...");
browseBtn.addActionListener(e -> {
JFileChooser chooser = new JFileChooser(outputDirectory);
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
outputDirectory = chooser.getSelectedFile();
pathField.setText(outputDirectory.getAbsolutePath());
}
});
panel.add(pathField, BorderLayout.CENTER);
panel.add(browseBtn, BorderLayout.EAST);
return panel;
}
private JPanel createActionPanel() {
JPanel panel = new JPanel(new GridLayout(1, 2, 10, 10));
recordBtn = new JButton("start recording");
recordBtn.addActionListener(e -> toggleRecording());
JButton snapBtn = new JButton("take snapshot");
snapBtn.addActionListener(e -> takeSnapshot());
panel.add(recordBtn);
panel.add(snapBtn);
return panel;
}
private JPanel createStatusPanel() {
JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER));
statusLabel = new JLabel("");
statusLabel.setForeground(Color.DARK_GRAY);
panel.add(statusLabel);
return panel;
}
private void toggleRecording() {
if (!videoRecorder.isRecording()) {
try {
File file = new File(outputDirectory, "vid_" + System.currentTimeMillis() + ".mp4");
videoRecorder.startRecording(cameraPanel, file);
recordBtn.setText("stop recording");
statusLabel.setText("recording");
} catch (IOException ex) {
showError("Start Error", ex);
}
} else {
try {
File saved = videoRecorder.stopRecording();
recordBtn.setText("Start Recording");
statusLabel.setText("Status: Saved " + saved.getName());
} catch (IOException ex) {
showError("Stop Error", ex);
}
}
}
private void takeSnapshot() {
BufferedImage img = cameraPanel.getCurrentProcessedImage();
if (img != null) {
try {
File file = new File(outputDirectory, "snap_" + System.currentTimeMillis() + ".png");
ImageIO.write(img, "PNG", file);
statusLabel.setText("captured");
} catch (IOException ex) {
showError("Snapshot Error", ex);
}
}
}
private void showError(String title, Exception ex) {
JOptionPane.showMessageDialog(this, ex.getMessage(), title, JOptionPane.ERROR_MESSAGE);
}
}

View File

@@ -16,7 +16,6 @@ public class DNRSection extends FilterSection {
spatial = addSlider("Spatial Strength", 0, 100, 30, "%");
temporal = addSlider("Temporal Strength", 0, 100, 50, "%");
// Logic: Disable sliders if DNR is off
enabled.addActionListener(e -> {
updateEnabledStates();
onUpdate.run();
@@ -25,7 +24,7 @@ public class DNRSection extends FilterSection {
spatial.addChangeListener(e -> { if(!spatial.getSlider().getValueIsAdjusting()) onUpdate.run(); });
temporal.addChangeListener(e -> { if(!temporal.getSlider().getValueIsAdjusting()) onUpdate.run(); });
add(enabled, 0); // Checkbox at top
add(enabled, 0);
updateEnabledStates();
}
@@ -35,9 +34,18 @@ public class DNRSection extends FilterSection {
temporal.getSlider().setEnabled(active);
}
public boolean isDnrEnabled() { return enabled.isSelected(); }
public int getSpatial() { return spatial.getValue(); }
public int getTemporal() { return temporal.getValue(); }
@Override
public boolean isEnabled() {
return enabled.isSelected();
}
public int getSpatial() {
return enabled.isSelected() ? spatial.getValue() : 0;
}
public int getTemporal() {
return enabled.isSelected() ? temporal.getValue() : 0;
}
public void setState(boolean isEnabled, int s, int t) {
enabled.setSelected(isEnabled);

View File

@@ -23,8 +23,13 @@ public class DetailSection extends FilterSection {
add(edgeEnhance);
}
public int getSharpness() { return sharpness.getValue(); }
public boolean isEdgeEnhanceEnabled() { return edgeEnhance.isSelected(); }
public int getSharpness() {
return sharpness.getValue();
}
public boolean isEdgeEnhanceEnabled() {
return edgeEnhance != null && edgeEnhance.isSelected();
}
public void setState(int sharpVal, boolean edgeActive) {
sharpness.setValue(sharpVal);

View File

@@ -38,8 +38,14 @@ public class WhiteBalanceSection extends FilterSection {
balanceBtn.setEnabled(active);
}
public boolean isEnabled() { return enabled.isSelected(); }
public int getStrength() { return strength.getValue(); }
@Override
public boolean isEnabled() {
return enabled != null && enabled.isSelected();
}
public int getStrength() {
return enabled.isSelected() ? strength.getValue() : 0;
}
public void setState(boolean isEnabled, int str) {
enabled.setSelected(isEnabled);