How to Map System.out and System.in to SWT control

2019-08-12 07:00发布

问题:

I am working on on a tool to connect to a remote server using jcraft.JSch (ssh to Unix server) and return the output and display its output. The script works fine when channel input outputs are System.in and System.out. But when I try with SWT controls, it is not able to

  1. display the exact output I am getting with System.out
  2. read from SWT Text control emulating System.in

    public void create() {
    
    dialogShell = new Shell(dialogShell, SWT.PRIMARY_MODAL | SWT.SHEET | SWT.RESIZE);
    GridLayout gridLayout = new GridLayout();
    gridLayout.numColumns = 2;
    dialogShell.setLayout(gridLayout);
    final Text logText = new Text(dialogShell, SWT.MULTI | SWT.BORDER| SWT.READ_ONLY);
    GridData gridData0 = new GridData(GridData.FILL,GridData.FILL, true, true);
    gridData0.horizontalSpan = 2;
    logText.setLayoutData(gridData0);
    
    origOutPS = System.out;
    origErrPS = System.err;
    
    
    final Text cmdText = new Text(dialogShell, SWT.BORDER | SWT.V_SCROLL);
    final Button RunButton = new Button(dialogShell, SWT.PUSH);
    GridData gridDatal = new GridData(GridData.BEGINNING, GridData.FILL_HORIZONTAL, true,false);
    GridData gridData2 = new GridData(GridData.END, GridData.CENTER, false,false);
    cmdText.setLayoutData(gridDatal);
    RunButton.setLayoutData(gridData2);
    RunButton.setText("Execute");
    RunButton.addSelectionListener(new runButton(dialogShell,cmdText));
    
    dialogShell.setDefaultButton(RunButton);
    dialogShell.setSize(550, 250);
    dialogShell.setText("Processing....");
    
    OutputStream out = new OutputStream() {
        public void write(int b) throws IOException {
            logText.append(String.valueOf((char) b));
        }
    
        public void write(byte[] b,int off, int len) {
            logText.append(new String(b, off, len));
        }
    };
    PrintStream ps = new PrintStream(out,true);
    System.out.println("Passing the control!");
    System.setOut(ps);
    System.setErr(ps);
    
    
    InputStream in = new InputStream() {
        @Override
        public int read() throws IOException {
            String str = cmdText.getText();
            int pos = 0;
            //test if the available input has reached its end
            //and the EOS should be returned 
            if( str != null && pos == str.length()){
                str =null;
                //this is supposed to return -1 on "end of stream"
                //but I'm having a hard time locating the constant
                return java.io.StreamTokenizer.TT_EOF;
            }
            //no input available, block until more is available because that's
            //the behavior specified in the Javadocs
            while (str == null || pos >= str.length()) {
                try {
                    //according to the docs read() should block until new input is available
                    synchronized (this) {
                        this.wait();
                    }
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
            //read an additional character, return it and increment the index
            return str.charAt(pos++);
        }
    };
    System.setIn(in);
    
    dialogShell.addListener(SWT.Close, new closelistener());
    
    //dialogShell.addShellListener(new MyshellAdapter(logText,cmdText,RunButton));
    dialogShell.open();
    }
    

Above is the dialog and this is the output I am getting

whereas when I connect channel input output to System.in and System.out, the output is as follows