0

I'm trying to make a Java program which calls some other software as a command from cmd, receives the output, and prints it in a Jframe. The problem is that when it prints there are some characters (Which seem to be just spaces) which become squares. I think these characters are not recognized correctly. The homsimpl command is just from CHOMP (Computational Homology Project).

I tried to remove all the HTML code from the Strings, the squared characters were still there. When I put System.out.println(s) or System.out.println(Outp) it prints correctly in the output, without the squared characters. I also tried to change the font, but with any font I tried to use, the squared characters were still squared in the JFrame. If I copy the output text and paste it to be in the JFrame the squared characters disappear, but I can't solve the problem like that.

The JFrame appears like this: Jframe

and the Output shows:

HOMSIMPL, ver. 0.01, 11/09/04. Copyright (C) 1997-2013 by Pawel Pilarczyk.

This is free software. No warranty. Consult 'license.txt' for details.

[Tech info: simpl 4, chain 12, addr 4, intgr 2.]

Reading simplices to X from 'Simplicial.sim'... 4 simplices read.

Collapsing faces in X... .. 0 removed, 14 left.

Creating the chain complex of X... .. Done.

Time used so far: 0.00 sec (0.000 min).

Computing the homology of X over the ring of integers...

Reducing D_2: 0 + 3 reductions made. 

Reducing D_1: 3 + 0 reductions made. 

H_0 = Z

H_1 = 0

H_2 = Z

Saving generators of X to 'Simplicial.txt'... Done.

Total time used: 0.02 sec (0.000 min).

[Press Ctrl-C to exit.]

Thank you for using this software. We appreciate your business.

A simplified version of my program follows:

    import java.io.*;
    import javax.swing.*;
    public class Test {
        public static void main(String[] args) 
                throws IOException {
            PrintWriter Cod = new PrintWriter("Simplicial.sim");
            Cod.println("{1,2,3}");
            Cod.println("{1,2,4}");
            Cod.println("{1,3,4}");
            Cod.println("{2,3,4}");
            Cod.close();
            Process p = Runtime.getRuntime().exec("cmd /c \"homsimpl Simplicial.sim -g Simplicial.txt\"");
            BufferedReader stdInput = new BufferedReader(new 
            InputStreamReader(p.getInputStream()));
            BufferedReader stdError = new BufferedReader(new 
            InputStreamReader(p.getErrorStream()));
            String s = null;
            JFrame f = new JFrame();
            JPanel pa = new JPanel();
            JLabel la = new JLabel();
            f.setSize(500, 500);
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.add(pa);
            String Outp="";
            JScrollPane pane = new JScrollPane(pa);
            pa.add(la);
            f.setContentPane(pane);
            f.setVisible(true);
            while ((s = stdInput.readLine()) != null) {
                Outp=Outp+"<br/>"+s;
                la.setText("<html>"+Outp+"</html>");
                System.out.println(s);
            }
            while ((s = stdError.readLine()) != null) {
                System.out.println(s);
            }
        } 
    }
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • If you debug, you can see exactly what these characters are (look at char-by-char representation). –  Jul 30 '19 at 02:21
  • @dyukha how do I check the characters in a JFrame using the debugger? – LeviathanTheEsper Jul 30 '19 at 02:40
  • I think I got it. It seems I was able to copy the squared characters from the debugger. But I still don't know how to remove it, or repair it, since in some cases a few characters disappear. They still appear as squares in the debugger. – LeviathanTheEsper Jul 30 '19 at 02:48
  • Good. If you further expand characters in the debugger, it should also show you its code. Now, if all these characters have the same code, you can use `String.replace` to remove them. –  Jul 30 '19 at 02:58
  • @dyukha I currently have a window called value with the content of the JLabel inside the JFrame, and I can see the squared characters there. How can I see the code of the characters from there? – LeviathanTheEsper Jul 30 '19 at 03:17
  • [this](https://stackoverflow.com/questions/12902529/jtextpane-jtextfield-strange-behaviour-with-rare-characters) may be relevant – c0der Jul 30 '19 at 03:41

1 Answers1

1

Actually, this is a problem that has nothing to do with Swing. As far as i can see from the name of the file you are writing to ("Simplicial.sim), your OS language is not English. This is a usual problem when executing a command to a windows console. In order to make myself clear, i will use an example of a command that will cause a problem like this. Lets take the command that (indirectly) gives you the installed version of Microsoft Office in a windows PC. This command is reg query \"HKEY_CLASSES_ROOT\\Word.Application\\CurVer\".

Now, let's execute it to CMD:

cmd

You can easily see that there are Greek words in the answer we get. (So in your case, something similar but not English).

This is the problem. When you new BufferedReader(new InputStreamReader(p.getInputStream())); you take the exact same input with console. Since the InputStream does not use UTF-8 encoding, it cannot read Greek. So, the problem becomes now Reading InputStream as UTF-8.

Without loosing any time, let's change new BufferedReader(new InputStreamReader(p.getInputStream())); to new BufferedReader(new InputStreamReader(p.getInputStream(), StandardCharsets.UTF-8));

Guess what? Its a loss. We are still getting the same characters (a bit different actually but still not readable). I wish i could explain why...

The solution you have to follow here is writing a batch that will change the code page of the console to UTF-8 and then execute the command you want. After that, the input is being read flawlessly.

You can run this example (do not ignore comments) in order to see it better:

public class CmdUnicode {
    private final static String COMMAND = "reg query \"HKEY_CLASSES_ROOT\\Word.Application\\CurVer\"";

    public static void main(String[] args) throws IOException {
        System.out.println(executeCmd());
        System.out.println();
        System.out.println("-------------");
        System.out.println();
        System.out.println(executeCmdBat());
    }

    private static String executeCmdBat() throws IOException {
        File batFile = writeBatchFile();
        Runtime rt = Runtime.getRuntime();
        Process proc = rt.exec("cmd /c " + batFile.getAbsolutePath());
        return streamToString(proc.getInputStream());
    }

    private static File writeBatchFile() throws IOException {
        File file = File.createTempFile("test", ".bat");
        StringBuilder sb = new StringBuilder();
        sb.append("@echo off"); // Do not show cmd window
        sb.append(System.lineSeparator());
        sb.append("chcp 65001"); // Enable unicode to cmd
        sb.append(System.lineSeparator());
        sb.append(COMMAND);
        try (PrintWriter out = new PrintWriter(file)) {
            out.write(sb.toString());
            out.flush(); // Is this required? :P
        }
        return file;
    }

    private static String executeCmd() throws IOException {
        Runtime rt = Runtime.getRuntime();
        Process proc = rt.exec(COMMAND);
        return streamToString(proc.getInputStream());
    }

    private static String streamToString(InputStream stream) throws IOException {
        StringBuilder sb = new StringBuilder();
        String line = null;
        try (BufferedReader stdInput = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) {
            while ((line = stdInput.readLine()) != null) {
                sb.append(line);
                sb.append(System.lineSeparator());
            }
        }
        return sb.toString();
    }
}

The console prints to me:

HKEY_CLASSES_ROOT\Word.Application\CurVer
    (??????????)    REG_SZ    Word.Application.16



-------------

Active code page: 65001

HKEY_CLASSES_ROOT\Word.Application\CurVer
    (Default)    REG_SZ    Word.Application.16

If you insist of getting the input after executing the command in your language you will have to search somewhere else (or probably make another topic here) and if you find anything that works, let me know....

And just for the record Προεπιλογή translates to Default :)

George Z.
  • 6,643
  • 4
  • 27
  • 47
  • I don't know how you concluded from Simplicial that the OS language is not english. I use simplicial because of something called simplicial complex https://en.wikipedia.org/wiki/Simplicial_complex. But you're right. My OS is not in English. It's in Spanish. I'll check this. – LeviathanTheEsper Aug 05 '19 at 01:58
  • @DavidMolano This is actually insane. I had no idea... Anyway let me know if it worked for you. – George Z. Aug 05 '19 at 02:13