diff --git a/src/main/java/io/swtc/SwingIFrame.java b/src/main/java/io/swtc/SwingIFrame.java index bf0e269..ff1cc03 100644 --- a/src/main/java/io/swtc/SwingIFrame.java +++ b/src/main/java/io/swtc/SwingIFrame.java @@ -1,9 +1,12 @@ package io.swtc; import com.github.sarxos.webcam.Webcam; -import io.swtc.proccessing.ui.iframe.*; +import io.swtc.proccessing.ui.iframe.*; // Your custom frames import javax.swing.*; import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.util.HashMap; import java.util.Map; @@ -12,14 +15,28 @@ public class SwingIFrame { private final DesktopPane desktopPane; private final Map cameraToEffects = new HashMap<>(); + private boolean fullscreen = false; + private Rectangle windowedBounds; + private boolean blackbg = false; + private final Color bgcolor = Color.decode("#336B6A"); + private final Color defDesktopBg = Color.WHITE; + + private final JPopupMenu popupMenu = new JPopupMenu(); + public SwingIFrame() { mainFrame = new JFrame("Viewer"); mainFrame.setSize(1280, 720); mainFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); desktopPane = new DesktopPane(cameraToEffects); - desktopPane.setBackground(Color.WHITE); + desktopPane.setBackground(defDesktopBg); mainFrame.add(desktopPane, BorderLayout.CENTER); + + setupFullscreenToggle(); + setupBlackBg(); + initPopupMenu(); + + desktopPane.addMouseListener(popupListener()); } public void addCameraInternalFrame(Webcam webcam) { @@ -43,11 +60,20 @@ public class SwingIFrame { EffectsPanelFrame ef = cameraToEffects.remove(cameraFrame); if (ef != null) ef.dispose(); desktopPane.forgetFrame(cameraFrame); + cameraFrame.dispose(); } }); desktopPane.add(cameraFrame); desktopPane.add(effectsFrame); + + // Attach popup menu to frames and content + MouseAdapter popup = popupListener(); + cameraFrame.addMouseListener(popup); + cameraFrame.getContentPane().addMouseListener(popup); + effectsFrame.addMouseListener(popup); + effectsFrame.getContentPane().addMouseListener(popup); + cameraFrame.setVisible(true); } @@ -58,12 +84,92 @@ public class SwingIFrame { try { effectsFrame.setSelected(true); effectsFrame.toFront(); - } catch (java.beans.PropertyVetoException ex) { JOptionPane.showMessageDialog(null,"Exception" + ex.getMessage() , "Exception", JOptionPane.ERROR_MESSAGE); } + } catch (java.beans.PropertyVetoException ex) { + JOptionPane.showMessageDialog(null, "Focus Error: " + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); + } } } + private MouseAdapter popupListener() { + return new MouseAdapter() { + private void showPopup(MouseEvent e) { + if (e.isPopupTrigger()) { // cross-platform trigger + popupMenu.show(e.getComponent(), e.getX(), e.getY()); + } + } + @Override public void mousePressed(MouseEvent e) { showPopup(e); } + @Override public void mouseReleased(MouseEvent e) { showPopup(e); } + }; + } + + private void initPopupMenu() { + popupMenu.removeAll(); // clean slate + + JCheckBoxMenuItem fullscreenItem = new JCheckBoxMenuItem("Fullscreen"); + fullscreenItem.addActionListener(e -> toggleFullscreen()); + + popupMenu.addPopupMenuListener(new javax.swing.event.PopupMenuListener() { + @Override + public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent e) { + fullscreenItem.setState(fullscreen); + } + @Override public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent e) {} + @Override public void popupMenuCanceled(javax.swing.event.PopupMenuEvent e) {} + }); + + popupMenu.add(fullscreenItem); + } + + private void setupBlackBg() { + JRootPane root = mainFrame.getRootPane(); + root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) + .put(KeyStroke.getKeyStroke("B"), "toggleBlackBg"); + root.getActionMap().put("toggleBlackBg", new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + toggleBackground(); + } + }); + } + + private void setupFullscreenToggle() { + JRootPane root = mainFrame.getRootPane(); + root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW) + .put(KeyStroke.getKeyStroke("F11"), "toggleFullscreen"); + root.getActionMap().put("toggleFullscreen", new AbstractAction() { + @Override + public void actionPerformed(ActionEvent e) { + toggleFullscreen(); + } + }); + } + + private void toggleBackground() { + desktopPane.setBackground(blackbg ? defDesktopBg : bgcolor); + blackbg = !blackbg; + desktopPane.repaint(); + } + + /** Toggle fullscreen mode */ + private void toggleFullscreen() { + if (!fullscreen) { + windowedBounds = mainFrame.getBounds(); + mainFrame.dispose(); + mainFrame.setUndecorated(true); + mainFrame.setExtendedState(JFrame.MAXIMIZED_BOTH); + mainFrame.setVisible(true); + } else { + mainFrame.dispose(); + mainFrame.setUndecorated(false); + mainFrame.setExtendedState(JFrame.NORMAL); + mainFrame.setBounds(windowedBounds); + mainFrame.setVisible(true); + } + fullscreen = !fullscreen; + } + public void show() { mainFrame.setLocationRelativeTo(null); mainFrame.setVisible(true); } -} \ No newline at end of file +} diff --git a/src/main/java/io/swtc/proccessing/WebcamCaptureLoop.java b/src/main/java/io/swtc/proccessing/WebcamCaptureLoop.java index fbac654..434b2f4 100644 --- a/src/main/java/io/swtc/proccessing/WebcamCaptureLoop.java +++ b/src/main/java/io/swtc/proccessing/WebcamCaptureLoop.java @@ -43,8 +43,6 @@ public class WebcamCaptureLoop { "WebcamException", JOptionPane.ERROR_MESSAGE ); - } finally { - webcam.open(); } while (running) { diff --git a/src/main/java/io/swtc/proccessing/ui/iframe/DesktopPane.java b/src/main/java/io/swtc/proccessing/ui/iframe/DesktopPane.java index f317395..9fc933d 100644 --- a/src/main/java/io/swtc/proccessing/ui/iframe/DesktopPane.java +++ b/src/main/java/io/swtc/proccessing/ui/iframe/DesktopPane.java @@ -56,11 +56,11 @@ public class DesktopPane extends JDesktopPane { 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); + //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); + //g2d.fillOval(x1 - 5, y1 - 5, 10, 10); + //g2d.fillOval(x2 - 5, y2 - 5, 10, 10); } } \ No newline at end of file