JOptionPane for Errors, general refactoring, deprecated class removed (CameraRenderer) moved into Swing now

modified:
/ SwingCCTVManager ; Error Pane, refactoring
/ WebcamCaptureLoop ; cleanup method for closing cameras reliably, and some MessageDialogs for error handling (just fails lol)
/ SwingCameraWindow ; refactor some legacy code into a "modern" lambda function , Message Dialog for error handling , and some g2d stuff (paintComponent)

removed:
- CameraRenderer.java ; Deprecated Component, was used for SWT GL Surfaces. We dont do that now!

---

rattatwinko
This commit is contained in:
2026-01-13 17:33:47 +01:00
parent 370df03205
commit b767ba27b3
4 changed files with 50 additions and 119 deletions

View File

@@ -31,7 +31,6 @@ public class SwingCCTVManager {
private final JFrame frame; private final JFrame frame;
private final JTable deviceTable; private final JTable deviceTable;
private final DefaultTableModel tableModel; private final DefaultTableModel tableModel;
private Timer autoRefreshTimer;
public SwingCCTVManager() { public SwingCCTVManager() {
frame = new JFrame("dashboard"); frame = new JFrame("dashboard");
@@ -92,7 +91,7 @@ public class SwingCCTVManager {
} }
private void startAutoRefresh() { private void startAutoRefresh() {
autoRefreshTimer = new Timer(5000, e -> refreshTable()); Timer autoRefreshTimer = new Timer(5000, e -> refreshTable());
autoRefreshTimer.start(); autoRefreshTimer.start();
} }
@@ -142,13 +141,10 @@ public class SwingCCTVManager {
if (row == -1) return; if (row == -1) return;
String name = (String) tableModel.getValueAt(row, 1); String name = (String) tableModel.getValueAt(row, 1);
Webcam selected = Webcam.getWebcams().stream() Webcam.getWebcams().stream()
.filter(w -> w.getName().equals(name)) .filter(w -> w.getName().equals(name))
.findFirst().orElse(null); .findFirst().ifPresent(selected -> new Thread(() -> new SwingCameraWindow(selected).open()).start());
if (selected != null) {
new Thread(() -> new SwingCameraWindow(selected).open()).start();
}
} }
private void deleteSelected() { private void deleteSelected() {
@@ -165,7 +161,14 @@ public class SwingCCTVManager {
for (CameraConfig config : CameraSettings.load()) { for (CameraConfig config : CameraSettings.load()) {
try { try {
IpCamDeviceRegistry.register(config.getName(), config.getUrl(), IpCamMode.PUSH); IpCamDeviceRegistry.register(config.getName(), config.getUrl(), IpCamMode.PUSH);
} catch (MalformedURLException e) { e.printStackTrace(); } } catch (MalformedURLException e) {
JOptionPane.showMessageDialog(
null,
"Malformed URL\n"+e.getMessage(),
"Malformed URL",
JOptionPane.ERROR_MESSAGE
);
}
} }
} }

View File

@@ -22,6 +22,7 @@ public class SwingCameraWindow {
public void windowClosing(WindowEvent e) { public void windowClosing(WindowEvent e) {
// clean shit up // clean shit up
frame.dispose(); frame.dispose();
captureLoop.stop(); // be sure to call this! otherwise the camera will stay open!
} }
}); });
@@ -30,18 +31,8 @@ public class SwingCameraWindow {
this.frame.pack(); this.frame.pack();
this.frame.setSize(640, 480); this.frame.setSize(640, 480);
this.captureLoop = new WebcamCaptureLoop(webcam, (BufferedImage img) -> { this.captureLoop = new WebcamCaptureLoop(webcam, (BufferedImage img) -> SwingUtilities.invokeLater(() -> cameraPanel.setImage(img)));
SwingUtilities.invokeLater(() -> {
cameraPanel.setImage(img);
});
});
this.frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
captureLoop.stop();
}
});
} }
public void open() { public void open() {
@@ -61,8 +52,9 @@ public class SwingCameraWindow {
protected void paintComponent(Graphics g) { protected void paintComponent(Graphics g) {
super.paintComponent(g); super.paintComponent(g);
if (currentImage != null) { if (currentImage != null) {
// Draw the image scaled to the panel size Graphics2D g2 = (Graphics2D) g;
g.drawImage(currentImage, 0, 0, getWidth(), getHeight(), null); g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(currentImage, 0, 0, getWidth(), getHeight(), null);
} }
} }
} }
@@ -75,7 +67,12 @@ public class SwingCameraWindow {
SwingCameraWindow window = new SwingCameraWindow(webcam); SwingCameraWindow window = new SwingCameraWindow(webcam);
window.open(); window.open();
} else { } else {
System.err.println("No webcam found!"); JOptionPane.showMessageDialog(
null,
"No Webcam found!",
"Error",
JOptionPane.WARNING_MESSAGE
);
} }
}); });
} }

View File

@@ -1,96 +0,0 @@
package io.swtc.proccessing;
import org.eclipse.swt.opengl.GLCanvas;
import org.eclipse.swt.widgets.Composite;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
import java.awt.image.BufferedImage;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class CameraRenderer {
private final GLCanvas canvas;
private int textureId = -1;
private ByteBuffer pixelBuffer;
private final AutoGainProcessor gainProcessor;
public CameraRenderer(Composite parent, org.eclipse.swt.opengl.GLData data) {
this.canvas = new GLCanvas(parent, 0, data);
this.gainProcessor = new AutoGainProcessor();
// Initialize OpenGL context immediately
this.canvas.setCurrent();
GL.createCapabilities();
initGL();
}
public GLCanvas getCanvas() {
return canvas;
}
private void initGL() {
GL11.glEnable(GL11.GL_TEXTURE_2D);
textureId = GL11.glGenTextures();
}
public void render(BufferedImage img) {
if (canvas.isDisposed()) return;
canvas.setCurrent();
int width = img.getWidth();
int height = img.getHeight();
int[] rgbArray = new int[width * height];
// this is hellishly unefficcient but who cares.
img.getRGB(0, 0, width, height, rgbArray, 0, width);
float[] gains = gainProcessor.calculateAutoGains(rgbArray);
int bufferSize = width * height * 3;
if (pixelBuffer == null || pixelBuffer.capacity() < bufferSize) {
pixelBuffer = ByteBuffer.allocateDirect(bufferSize);
pixelBuffer.order(ByteOrder.nativeOrder());
}
pixelBuffer.clear();
for (int pixel : rgbArray) {
int r = (pixel >> 16) & 0xFF;
int g = (pixel >> 8) & 0xFF;
int b = pixel & 0xFF;
r = Math.min(255, (int)(r * gains[0]));
g = Math.min(255, (int)(g * gains[1]));
b = Math.min(255, (int)(b * gains[2]));
pixelBuffer.put((byte) r);
pixelBuffer.put((byte) g);
pixelBuffer.put((byte) b);
}
pixelBuffer.flip();
// this is just gl stuff
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
GL11.glViewport(0, 0, canvas.getClientArea().width, canvas.getClientArea().height);
GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureId);
GL11.glPixelStorei(GL11.GL_UNPACK_ALIGNMENT, 1);
GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGB, width, height,
0, GL11.GL_RGB, GL11.GL_UNSIGNED_BYTE, pixelBuffer);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
GL11.glColor3f(1.0f, 1.0f, 1.0f);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0, 0); GL11.glVertex2f(-1, 1);
GL11.glTexCoord2f(1, 0); GL11.glVertex2f(1, 1);
GL11.glTexCoord2f(1, 1); GL11.glVertex2f(1, -1);
GL11.glTexCoord2f(0, 1); GL11.glVertex2f(-1, -1);
GL11.glEnd();
canvas.swapBuffers();
}
}

View File

@@ -1,9 +1,12 @@
package io.swtc.proccessing; package io.swtc.proccessing;
import com.github.sarxos.webcam.Webcam; import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamException;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.util.function.Consumer; import java.util.function.Consumer;
import javax.swing.JOptionPane;
public class WebcamCaptureLoop { public class WebcamCaptureLoop {
private final Webcam webcam; private final Webcam webcam;
@@ -46,15 +49,39 @@ public class WebcamCaptureLoop {
} }
try { try {
webcam.close(); webcam.close();
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
e.printStackTrace(); // show a error message from javax.swing.awt.JOptionPane
JOptionPane.showMessageDialog(
null,
"IllegalStateException@"+e,
"IllegalStateException",
JOptionPane.ERROR_MESSAGE
);
} }
}); });
captureThread.setName("cam_cap_thread"); captureThread.setName("cam_cap_thread");
captureThread.start(); captureThread.start();
} }
// method for cleaning up
private synchronized void cleanup() {
try {
// if the camera is open try to cloes it!
webcam.close();
} catch (WebcamException exception) {
JOptionPane.showMessageDialog(
null,
"Cleanup failed \nWebCamException@"+exception.getMessage(),
"WebCamException",
JOptionPane.ERROR_MESSAGE
);
}
}
public void stop() { public void stop() {
running = false; running = false;
cleanup();
} }
} }