X3NavalD

X3NavalD Notes

I downloaded X3NavalD almost two years ago. This program is as described and when installed seemed to do all of the things that I needed it to do. It is a French program. And it is written and documented in French. The window labels and menus are in French text. I can make this translation and use the program.

But I did discovered at least two problems:
1. Files do not save properly in my Debian Linux.
2. Buttons and controls may need Internationalization.
I worked on 1. first.

Bateau.java is the main class of this application. As the ‘boat’ class, it does most of the actions related to input and output, display, and calculation. A problem with the descriptors in the files (in French, requiring Latin1 codepage) to get them to unicode.

http://www-128.ibm.com/developerworks/eserver/articles/java_code.html discusses this issue and some solutions. While the article is written from a mainframe (ebcdic) perspective, the possible solution may apply.

The input needs to be ISO-8859-1 as does the output.

I am beginning to understand that Java uses the System encoding when it reads a file. Internally Java uses Unicode. But when it reads in, it has to have some mapping of external codes to the internal Unicodes. Even though it is not true for the French language, if the system says that the code is ASCII, an “è” is just an “e” or maybe something else when it gets to Unicode.

I discovered this the wrong way round. I could use X3NavalD to read the supplied sample files. They came into the program and displayed ok. But when I saved them, and then tried to read them again, the back end of the boat was ruined. I determined that this was the portion saved as

[Courbure Avant coté]
2.0
[Courbure Arrière dessus]
2.0
[Courbure Arrière coté]
2.2

comes out like

[Courbure Avant cot?]
2.0
[Courbure Arri?re dessus]
2.0
[Courbure Arri?re cot?]
2.2

It loses something in translation does it not. Note the characters that are changed into ?’s (If you you see ?’s in both samples, your browser may not be supporting ISO 8859-1.(Western European))So I went off to find out how to get the Java to write out properly. The first thing that I found was that the output stream could be encoded. But what was my encoding?

This Java program will tell you what your default encoding is…

/**
 * The EncodingApp prints the character encoding name to standard output.
 */
import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;

class EncodingApp {
	public static void main(String[] args) {
		OutputStreamWriter out = new OutputStreamWriter(new ByteArrayOutputStream());
		System.out.println(out.getEncoding());
		System.out.println("--Done"); // Display the string.
		}
	}

When I run EncodingApp on my system it gives me

mylinux:~/Projects/java/java$ java EncodingApp
ASCII
--Done

Shame on me for not choosing wisely at Debian installation time. But this can be turned into a learning experience.

The original idea for the EncodingApp came from
http://java.sun.com/docs/books/tutorial/i18n/text/convertintro.html

So I poked around through the tutorials. I found that it was fairly straightforward to change from a simple file writer to a filewriter which would do the translation that was needed. This came through changing:

		OutputStreamWriter out = new OutputStreamWriter(new ByteArrayOutputStream());

To something like

		OutputStreamWriter out = new OutputStreamWriter(new ByteArrayOutputStream(),"UTF-8");

Add some catch-throw logic came from
http://java.sun.com/j2se/1.5.0/docs/api/java/net/URLEncoder.html#encode(java.lang.String)
And you end up with something like this.

/**
 * The EncodingApp2 changes the character encoding and then
 * prints the character encoding name to standard output.
 */
import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;

class EncodingApp2 {
	public static void main(String[] args) {
		/* this next does not seem to be effective */
		System.setProperty("file.encoding", "UTF-8");
		/* try-catch is required because adding an encoding to
       * OutputStreamWriter(out, charset) could cause an
       * encoding exception
       */
		try
		{
     //do whatever
		OutputStreamWriter out = new OutputStreamWriter(new ByteArrayOutputStream(),"UTF-8");
		System.out.println(out.getEncoding());
		System.out.println("--Done"); // Display the string.
      }
		catch(java.io.UnsupportedEncodingException e)
		{
     		e.printStackTrace();
		}
	}
}

Trying to set the encoding for the file globally did not seem to make any difference. Setting the coding on the output stream object itself did. You can experiment yourself by changing the encoding in various ways.

as noted in the comments, the try-catch logic for error handling had to be added because it is possible that a specified encoding is not defined as the encoding, here a literal string constant could be a variable. Java will not let you compile without the error handling.

Having worked through that to the point that I had the output stream writing correctly. So now I just need to see if the same sort of coding will do anything for x3Navald.

	/**
	  * Enregistre le bateau actuel vers le fichier spécifié.
	  *
	  * @param    fileName le nom du fichier, chemin compris.
	  */
	public void enregistrer(String fileName) throws IOException {
		PrintWriter out = new PrintWriter(new FileOutputStream(fileName));
		String s;
	...
		out.println("[Courbure Avant coté]\n"+ avz);
		out.println("[Courbure Arrière dessus]\n"+ ary);
		out.println("[Courbure Arrière coté]\n"+ arz);
	...
		out.close();
	}

Changes to something like…

	public void enregistrer(String fileName) throws IOException {
       PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(fileName) , "ISO8859_1"));
	...
	etc.

Writes out the proper characters.

About this time, I noted that the screens were displaying little rectangles instead of the proper characters. This meant that the java program was not properly displaying the characters even though they were encoded in the program. This is because when javac runs, it translates the program using the system character set by default. To get around this, there is a -encoding switch on the javac compiler which is not well documented as to what it actually does. Using it to compile on X3NavalD fixes the labels on the buttons in the gui. But breaks the input side of the file interface. Only the output side was broken before using the -encoding switch.

I updated the com.sh shell script to include the -encoding switch com.sh currently has the switch in place.

mylinux:~/Projects/x3navald/x3navaldv0.2.12/new$ diff ../com.sh com.sh
4c4
< javac -classpath classes -d classes java/bateau/Bateau.java java/ihm/BatFilter.java java/ihm/DeveloppesPanel.java java/ihm/OptionFrame.java java/ihm/PlanPanel.java java/ihm/X3NavalD.java java/outils/Courbe.java java/outils/Point2D.java java/outils/Point3D.java
---
> javac -encoding ISO-8859-1 -classpath classes -d classes java/bateau/Bateau.java java/ihm/BatFilter.java java/ihm/DeveloppesPanel.java java/ihm/OptionFrame.java java/ihm/PlanPanel.java java/ihm/X3NavalD.java java/outils/Courbe.java java/outils/Point2D.java java/outils/Point3D.java

More about the -encoding switch can be found here. This seems to be a good explanation for a variety of platforms including Windows and Eclipse.
http://vietunicode.sourceforge.net/howto/java/encoding.html The modification to the compile shell script reminds me that the very first time I compiled to an empty library, some parts of the objects did not compile correctly. The first time you may need to be careful in the order of compile:

outils Courbe.java Point2D.java Point2DPlan.java Point3D.java Vecteur3D.java

And the rest as

javac -classpath classes -d classes java/ihm/OptionFrame.java java/ihm/DeveloppesPanel.java java/ihm/PlanPanel.java java/ihm/X3NavalD.java java/bateau/Bateau.java

Once they all exist, the problem goes away.

Back to our quest, with the input broken by the input translation, I needed to make a modification to the input stream reader.

First I modified the test program to include the input objects needed for encoding.

/**
 * The EncodingApp3 changes the character encoding and then
 * inputs a test file with oddball characters  and outputs them again and
 * prints the character encoding name to standard output.
 */
import java.io.ByteArrayOutputStream;
import java.io.OutputStreamWriter;
import java.io.InputStreamReader;
import java.io.FileInputStream;

class EncodingApp3 {
	public static void main(String[] args) {
		/* this next does not seem to be effective
		System.setProperty("file.encoding", "UTF-8");
		/* try-catch is required because adding an encoding to
       * OutputStreamWriter(out, charset) could cause an
       * encoding exception
       */
		try
		{
     //do whatever
      InputStreamReader  in  = new InputStreamReader(new
		FileInputStream("test.file"),
		 "ISO-8859-1");
		OutputStreamWriter out = new OutputStreamWriter(new ByteArrayOutputStream(),"UTF-8");
	   System.out.println(in.getEncoding());
		System.out.println(out.getEncoding());
		System.out.println("--Done"); // Display the string.
      }
	   catch(java.io.FileNotFoundException e)
	   {
			System.out.println("in file not found");
			e.printStackTrace();
	   }
		catch(java.io.UnsupportedEncodingException e)
		{
     		e.printStackTrace();
		}
	}
}

Which produces

mylinux:~/Projects/java/java$ java EncodingApp3
ISO8859_1
UTF8
--Done

So I needed to change

332c412
<               CmntrBufferedReader in = new CmntrBufferedReader(new FileReader(fileName));

to

>               CmntrBufferedReader in = new CmntrBufferedReader(new BufferedReader(new  InputStreamReader(new  FileInputStream(fileName), "ISO8859_1")));

This complicates CmntrBufferedReader which is an extends of BufferedReader (< from > to)

2644c2944
<       public CmntrBufferedReader(FileReader fr) {
---
>       public CmntrBufferedReader(BufferedReader fr) {

And a few of other places…

2132c2395
<                               new PrintWriter(new FileOutputStream(nomFichier + ".txt"));
---
>                               new PrintWriter(new OutputStreamWriter(new FileOutputStream(nomFichier + ".txt")));
2470c2761
<                               new PrintWriter(new FileOutputStream(nomFichier + ".wrl"));
---
>                               new PrintWriter(new OutputStreamWriter(new FileOutputStream(nomFichier + ".wrl")));
2510a2802,2803
>         * Export a hull in the format DXF (profile view).
>         *
2529c2822
<                               new PrintWriter(new FileOutputStream(nomFichier + ".dxf"));
---
>                               new PrintWriter(new OutputStreamWriter(new FileOutputStream(nomFichier + ".dxf")));

The input stream reader stuff came from
http://java.sun.com/j2se/1.4.2/docs/api/java/io/InputStreamReader.html#InputStreamReader(java.io.InputStream,%20java.nio.charset.Charset)

And some other internationalization info at http://java.sun.com/docs/books/tutorial/i18n/text/stream.html

I will add more on the compile and documentation processes when I get some more time.

X3NavalD is now working as expected with Debian sarge with the default US installation.Unfortunately I applied maintenance to Debian that included an upgrade to hotplug which caused device definition task at boot time to fail to add my disks. Since my son had been on my case to use Ubuntu (I think he just wants to see what it is like and get more bullets for his resume) I downloaded it and installed it.

It seems to have many of the same problems as the Debian from which it derives. It is a bit better in that it seems to have UTF-8 instead of ASCII but it still does not do right for compile of 8859-1 source code nor the display of screens in French characters. The adjustments I have made should allow X3NavalD to work regardless of the Linux desktop. One of these days I will tar it up and put it over on Windows and check it out there.

I have almost completed the documentation. I think that there is English for each of the French program comments. At least it seems so in the docs/…html’s. It still needs a nouveaux function to create a boat from scratch.

It is also lacking a print function which I really need to create models.

17 March, I copied the whole project to a new directory ../pr The purpose of this is to add the print function. I found a function here http://www.apl.jhu.edu/~hall/java/Swing-Tutorial/Swing-Tutorial-Printing.html
That might do the trick.
First I tried the short way by taking the link to Print.Utilities.java I added a menu item to ../pr/java/ihm/X3NavalD.java and a routine to call the print utilities. Also fixed a couple of comments. Next I updated the com.sh and doc.sh utilities to compile the PrintUtilities object with the rest of the project. arc.sh needs no modification as it deals with the packages. Did the compiles and voila… (don’t for get to put in the import the import and save the file) (and don’t forget to add package ihm to PrintUtilities.java) Voila…

cbcalvin@natalie:~/Projects/x3navald/pr$ com.sh
-- debut de la compilation
java/ihm/X3NavalD.java:643: cannot find symbol
symbol  : class PrintUtilities
location: class ihm.X3NavalD
                PrintUtilities printHelper = new PrintUtilities(bateau);
                ^
java/ihm/X3NavalD.java:643: cannot find symbol
symbol  : class PrintUtilities
location: class ihm.X3NavalD
                PrintUtilities printHelper = new PrintUtilities(bateau);
                                                 ^
Note: java/bateau/Bateau.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
2 errors
-- fin compilation

Make sure that PrintUtilities has been compiled and exists as a class before you try and use it.

-- debut de la compilation
java/ihm/X3NavalD.java:644: printComponent(java.awt.Component) in ihm.PrintUtilities cannot be applied to (bateau.Bateau)
                PrintUtilities.printComponent(bateau);
                              ^
Note: java/bateau/Bateau.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error
-- fin compilation

The bateau object of class bateau.Bateau is not an appropriate component for printing. So change that to PrintUtilities.printComponent(planPanel); And this compiles clean (with the unchecked note. See above). But when run and a print is attempted, a message box “No print service found” appears. I put some diagnostic prints in to find it and it appears when the print function is called in the PrintUtilities code. It turns out after some learning that it is a Cups setup problem in Ubuntu that is easy to correct. Please review this http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6181488 and pay special attention to the part about /etc/cups/cupsd.conf X3NavalD now prints for me but only part of the drawing. I have determined that this is a ratio between the size of the panel on the screen and the size of the print area. Now to get that in control…

In the meantime, I was wondering about Génératrices and found this great site: http://www.mathcurve.com/surfaces/developpable/developpable.shtml