How to execute cmd commands via Java swing

2020-07-25 23:12发布

问题:

I have a file to print and I want to send him a custom water mark via java swing. i have 2 files NewJFrame.java and Test.java

package test;

import java.io.IOException;
import java.io.OutputStream;

/**
 *
 * @author shaharnakash
 */
public class NewJFrame extends javax.swing.JFrame {

    /**
     * Creates new form NewJFrame
     */
    public NewJFrame() {
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jTextField1 = new javax.swing.JTextField();
        jButton1 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jLabel1.setText("whater mark name");

        jTextField1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jTextField1ActionPerformed(evt);
            }
        });

        jButton1.setText("submit");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .add(30, 30, 30)
                .add(jLabel1)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .add(jTextField1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 251, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
            .add(layout.createSequentialGroup()
                .add(17, 17, 17)
                .add(jButton1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 206, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(layout.createSequentialGroup()
                        .add(41, 41, 41)
                        .add(jLabel1))
                    .add(layout.createSequentialGroup()
                        .addContainerGap()
                        .add(jTextField1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 57, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
                .add(112, 112, 112)
                .add(jButton1)
                .addContainerGap(96, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                        

    private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {                                            
        // TODO add your handling code here:
    }                                           

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        String value;
        value = jTextField1.getText();
         try{
            String command = "cmd /c start cmd.exe";
            Process child = Runtime.getRuntime().exec(command);

            OutputStream out = child.getOutputStream();
            out.write("C:/PDF>pdfprint.exe -printer 'docPrint' -firstpage 1 -lastpage 1 -wtext 'value' -wo 100 -wa 50 -wf 'Arial' C:/readme.pdf".getBytes());
                out.close();
        }catch(IOException e){

        }
    }                                        

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify                     
    private javax.swing.JButton jButton1;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JTextField jTextField1;
    // End of variables declaration                   
}

and the main java class Test.java that execute the program

    package test;

/**
 *
 * @author shaharnakash
 */
public class Test {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
         java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame().setVisible(true);
            }
        });
    }
}

the idea is to insert a value to the text field and after that click on the submit button it will execute the cmd command

C:/PDF>pdfprint.exe -printer 'docPrint' -firstpage 1 -lastpage 1 -wtext 'value' -wo 100 -wa 50 -wf 'Arial' C:/readme.pdf

when i execute the program it will open the cmd and will not send the file to the printer

note: draft is the water mark change

i change to Process child = Runtime.getRuntime().exec("\"PDF\pdfprint.exe -printer docPrint -firstpage 1 -lastpage 1 -wtext "+value+" -wo 100 -wa 50 -wf Arial C:\readme.pdf");

and i still not working

回答1:

Personally, I'd use ProcessBuilder, if for no other reason, it reduces a lot of the complexity involved with working with Process.

ProcessBuilder pb = new ProcessBuilder("pdfprint.exe", "-printer", "'docPrint'", "-firstpage", "1", "-lastpage", "1", "-wtext", "'value'", "-wo", "100", "-wa", "50", "-wf", "'Arial'", "C:/readme.pdf");
pb.redirectErrorStream(true);
Process p = pb.start();
InputStream is = p.getInputStream();
int inInt = -1;
while ((inInt = is.read()) != -1) {
    System.out.print((char)inInt);
}

Now, this is a block calling, meaning if you execute this within the context of your UI (AKA The Event Dispatching Thread), the UI will appear to hang until the external process has finished running.

In this case you should call execute the command in the back. Probably the simplest approach would be to use a SwingWorker

public class ExeWorker extends SwingWorker<String, String> {
    public String doInBackground() {
        // Execute command here...
        // Depending on what you want to return, setup a return value
        // This could an error string or the path to the output file for example...

       return result;
    }

    public void done() {
        // Back on the EDT, update the UI ;)
    }
}

Have a read of Concurrency in Swing for more details



回答2:

use Runtime.getRuntime().exec() method. Google about its different variants.