简体   繁体   中英

How do I automatically execute a method in a java application on startup?

I'm building a small java application to load images from a USB camera or display an error message (image) if the USB camera is not found. The application needs to load and start 'CaptureImage()' automatically, but I'm getting NullPointerException error under my 'CaptureImage()' method.

If I call 'CaptureImage()' from a button click on the gui (instead of trying to kick it off in 'initialize()' via starting a thread), then it works properly. Any guidance on how to handle properly would be most appreciated.


public class WebcamCapture_gui {
    
    JFrame frmWebcamCapture_gui;
    static Canvas canvas = new Canvas();
    JPanel panel = new JPanel();
    static Image notFound = null;
    static boolean running = true;

    
    public static void main(String[] args) {
        
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    WebcamCapture_gui window = new WebcamCapture_gui();
                    window.frmWebcamCapture_gui.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    
    public WebcamCapture_gui() throws IOException {
        initialize();
    }


    private void initialize() {

        JButton btnNewButton = new JButton("OK", new ImageIcon(WebcamCapture_gui.class.getResource("/resources/ok-32.png")));
        btnNewButton.setFont(new Font("Lucida Grande", Font.BOLD, 16));
        btnNewButton.setMnemonic('o');
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                
                CaptureImage();
            }
        });
        btnNewButton.setBounds(918, 573, 156, 83);
        
        canvas.setBounds(6, 6, 1052, 547);
        
        frmWebcamCapture_gui = new JFrame();
        frmWebcamCapture_gui.setResizable(false);
        frmWebcamCapture_gui.setUndecorated(true);
        frmWebcamCapture_gui.setTitle("Camera Test");
        frmWebcamCapture_gui.setSize(1080, 662);
        frmWebcamCapture_gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmWebcamCapture_gui.getContentPane().setLayout(null);
        
        panel.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
        panel.setBounds(6, 6, 1068, 563);
        panel.setLayout(null);
        panel.add(canvas);
        frmWebcamCapture_gui.getContentPane().add(panel);
        frmWebcamCapture_gui.getContentPane().add(btnNewButton);
        
        File classPathInput = new File(WebcamCapture_gui.class.getResource("/resources/USB_not_found.png").getFile());
        try {
            notFound = ImageIO.read(classPathInput);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        /*
        *  If I remove this Thread start and use the button to call 'CaptureImage()' instead, then the images will load and no NPE.
        */
        Thread t1 = new Thread(new thread1());
        
        t1.start();
        
        try { 
            t1.join();
        } catch (Exception e1) {
            System.out.println(e1);
        }
    }
    
    
    public static class thread1 implements Runnable {
        @Override
        public void run() {
            
            CaptureImage();
            
        }
    }

    
    public static void CaptureImage() {
        
        Graphics g = canvas.getGraphics();
        
        Webcam webcam = Webcam.getDefault();
        
        if (webcam != null) {
            webcam.open();
            g.drawImage(webcam.getImage(), 0, 0, 1060, 554, null);
            webcam.close();
        } else {
            g.drawImage(notFound, 0, 0, 1060, 547, null);
        }
    }
}

Stack Trace:

javax.imageio.IIOException: Can't read input file!
    at java.desktop/javax.imageio.ImageIO.read(ImageIO.java:1308)
    at webcamCapture.WebcamCapture_gui.initialize(WebcamCapture_gui.java:80)
    at webcamCapture.WebcamCapture_gui.<init>(WebcamCapture_gui.java:44)
    at webcamCapture.WebcamCapture_gui$1.run(WebcamCapture_gui.java:34)
    at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:316)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
[Thread-0] INFO com.github.sarxos.webcam.Webcam - WebcamDefaultDriver capture driver will be used
[Thread-0] WARN com.github.sarxos.webcam.Webcam - No webcam has been detected!
Exception in thread "Thread-0" java.lang.NullPointerException: Cannot invoke "java.awt.Graphics.drawImage(java.awt.Image, int, int, int, int, java.awt.image.ImageObserver)" because "g" is null
    at webcamCapture.WebcamCapture_gui.CaptureImage(WebcamCapture_gui.java:120)
    at webcamCapture.WebcamCapture_gui$thread1.run(WebcamCapture_gui.java:102)
    at java.base/java.lang.Thread.run(Thread.java:832)

Notice that the error is not just caused by the image.

Exception in thread "Thread-0" java.lang.NullPointerException: Cannot invoke "java.awt.Graphics.drawImage(java.awt.Image, int, int, int, int, java.awt.image.ImageObserver)" because "g" is null
    at webcamCapture.WebcamCapture_gui.CaptureImage(WebcamCapture_gui.java:120)
    at webcamCapture.WebcamCapture_gui$thread1.run(WebcamCapture_gui.java:102)
    at java.base/java.lang.Thread.run(Thread.java:832)

When you start the thread immediately, the canvas graphics might not have been initialised and calling the drawImage method raises the NPE.

To circumvent the NPE, you could replace

t1.start();

with

SwingUtilities.invokeLater(t1); 

Another "dirty" workaround would be to leave t1.start(); but force the app to load it's components by adding frmWebcamCapture_gui.setVisible(true); in the run method of thread1

  public class thread1 implements Runnable {
    @Override
    public void run() {
     frmWebcamCapture_gui.setVisible(true);
      CaptureImage();
    }
  }

This is mainly for demonstration and explonatory purposes, so I will suggest you adopt the first method of using SwingUtilities . You can read more about SwingUtilities.invokeLater on this post and the documentation

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM