DenisLAD / twain4java

Pure JAVA Twain library
39 stars 19 forks source link

Crashing behavior #3

Open ahmadkisswany opened 1 month ago

ahmadkisswany commented 1 month ago

When we calling the scanning action to the second time the application get crashed

DenisLAD commented 1 month ago

Can you provide additional information?

Kind error: ?

Log outputs: ?

Scanner vendor: HP, Canon, ...

JVM Version: JDK? 32 or 64 bits VM?

Windows version: ?

ahmadkisswany commented 1 month ago

JDK 1.8 64x The way you calling the functions Like singleton utility class using windows 10 Testing using epson DS-530


/**
 * Singleton class for managing Twain operations.
 *
 * Author: ahmad.a
 */
public final class RFTwainManager {

    // The single instance of the RFTwainManager class
    private static RFTwainManager instance;

    private int color = 0;
   boolean acquisitionComplete = false;

    private final Object lock = new Object();
      private CountDownLatch latch = new CountDownLatch(1);

    // Private constructor to prevent instantiation from outside the class
    private RFTwainManager() {
    }

    /**
     * Get the singleton instance of RFTwainManager.
     *
     * @return the singleton instance
     */
    public static synchronized RFTwainManager getInstance() {
        if (instance == null) {
            instance = new RFTwainManager();
        }
        return instance;
    }

    /**
     * Get a list of available Twain sources.
     *
     * @return a list of available sources
     */
    public List<Source> getAvailableSources() {
        List<Source> lsSource = new ArrayList<>();
        try {
            lsSource = SourceManager.instance().getSources();
        } catch (TwainException ex) {
            Logger.getLogger(RFTwainManager.class.getName()).log(Level.SEVERE, null, ex);
        }
        return lsSource;
    }

    public boolean selectSourceDevice(String sourceName) {
        if (sourceName == null) {
            return false;
        }
        try {

            TwainScanner.getScanner().select(sourceName);

            TwainSource ts = Twain.getSourceManager().selectSource(sourceName);
            ts.open();
            ts.setState(4);

            if (!ts.isDeviceOnline()) {
                return false;
            }
            try {
                // get  the available resolutions if need it  
                TwainCapability tc = ts.getCapability(Twain.ICAP_XRESOLUTION);
                //get the color mode :
                tc = ts.getCapability(Twain.ICAP_PIXELTYPE);
                for (Object t : tc.getItems()) {
                    color = (Integer) t;
                    if (color == 1) { // color mode support colors
                        break;
                    }

                }
                if (ts.getCapability(Twain.CAP_FEEDERENABLED).intValue() == 1) {

                }
                return true;
            } finally {
                ts.close();
                ts.setState(3);
            }

        } catch (TwainException ex) {
            Message.showMessageDialog(MessageType.Error, "Error", ex.getMessage());

        }
        return false;
    }

    /**
     * Acquire an image from the specified source.
     *
     * @param sourceName the name of the Twain source
     * @return the path of the acquired image
     */
    public String acquireImage(String sourceName) {

        List<File> files = new ArrayList<>();
        final TwainScanner scanner = TwainScanner.getScanner();

         // Runnable to handle Twain events
        Runnable listenerRunnable = new Runnable() {
            @Override
            public void run() {
                TwainListener listener = new TwainListener() {
                    @Override
                    public void update(TwainIOMetadata.Type type, TwainIOMetadata metadata) {
                        if (type == TwainIOMetadata.EXCEPTION) {
                            Message.showMessageDialog(MessageType.Warning, "Warning", metadata.getException().getMessage());
                            return;
                        }

                        if (type == TwainIOMetadata.NEGOTIATE && metadata.getState() == 4) {
                            TwainSource ts = metadata.getSource();
                            ts.setXferMech(Twain.TWSX_NATIVE);
                            try {
                                ts.setShowUI(false);
                                ts.setShowProgressBar(false);
                                ts.setCapability(Twain.ICAP_PIXELTYPE, color);
                                ts.setCapability(Twain.CAP_FEEDERENABLED, false);
                            } catch (Exception e) {
                                scanner.removeListener(this);
                                ts.setCancel(true);
                            }
                        }

                        boolean finish = false;
                        if (type == TwainIOMetadata.MEMORY || (type == TwainIOMetadata.ACQUIRED && metadata.getState() == 7)) {
                            finish = true;
                        }

                        if (finish) {
                            final BufferedImage img = metadata.getImage();
                            metadata.setImage(null);
                            try {
                                File f = File.createTempFile("scan", ".png");
                                try (ImageOutputStream ios = new FileImageOutputStream(f)) {
                                    ImageIO.write(img, "PNG", ios);
                                }

                                synchronized (lock) {
                                    files.add(f);
                                    acquisitionComplete = true;
                                    scanner.removeListener(this);
                                    latch.countDown(); // Signal that acquisition is complete

                                }

                            } catch (IOException e) {
                                Message.showMessageDialog(MessageType.Warning, "Warning", e.getMessage());
                            }
                        }
                    }
                };

                scanner.addListener(listener);
            }
        };

        Thread listenerThread = new Thread(listenerRunnable);
        listenerThread.start();

        try {
            scanner.select(sourceName);
            scanner.acquire();

            // Wait until the image acquisition is complete
            waitForAcquisition();

        } catch (TwainException ex) {
            Logger.getLogger(RFTwainManager.class.getName()).log(Level.SEVERE, null, ex);
        } finally {

        }

        return files.isEmpty() ? "" : files.get(0).getAbsolutePath();
    }

    private void waitForAcquisition( ) {
        synchronized (lock) {
            while (!acquisitionComplete) {
                try {
                    lock.wait(); // Wait until notified
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt(); // Restore interrupted status
                    // Optionally, handle interruption
                }
            }
        }
    }
}
ahmadkisswany commented 1 month ago

Thank you for this project now after some Changing of my code it's working perfect But when I try to pass show UI flag true it's not working and not shown any action