通知表によくある所見欄を例に、所定枠に文章を印刷することを考えます。
ある程度長い文章を書いても自動的に改行してくれること、箇条書きのようなものにも対応することが求められます。 出来れば禁則処理もある程度取り込みたいところです。
入力時の操作方法が使い勝手に重要なところですが、帳票印刷がテーマなので、データがあるものとして書くところから始めます。
文章の表現としては、文字列のリストがいいでしょう。
いままでのデータと同様にするなら生徒番号をキーとした文字列のリストのMapとして、SetHRData.javaでデータを用意するという事になります。SetHRData.javaの中に書き込むよりファイルにしておいて読むほうが作成が楽なので、そのようにします。ふと、それならばSetHRData.javaのなかで読むのではなく、ファイル名のMapを渡して書く時に読むので良いのではないかとも考えたのですが、print()内に置くと1人に付き2回は呼ばれますのでこれはやめておきます。
ファイルを読んでリストにするのに、Files.readAllLines()メソッドを使うことにしました。これにについて詳しくは、ファイルから文字列を読んでListに格納を参照してください。
他のデータと同パターンにします
ListなのはFiles.readAllLines()の戻り値がListだからです。
LinkedHashMap<Integer,List<String>> shokenmap;
public SetHRData(int nendo, String HR, int gakki){
....
setNameMap();
nmax = namemap.size();
setSeisekiMap(kams);
setShukketsuMap();
setTanis(kams);
setShokenMap();
}
private void setShokenMap(){
shokenmap = new LinkedHashMap<Integer,List<String>>();
for (int n=1;nmax>=n;n++){
String fname = HR+String.format("%02d",n)+"tsu"+gakki+".txt";
String pwd = getClass().getResource("").getPath()+"/data";
List<String> list = null; //Collections.emptyList();
Path path = Paths.get(pwd,fname);
if(Files.notExists(path)) continue;
try {
list = Files.readAllLines(path, UTF_8 );
if (list.size()>0) shokenmap.put(n,list);
}catch (IOException e) {
System.err.println( e);
}
}
}
public LinkedHashMap<Integer,List<String>> getShokenMap(){
return shokenmap;
}
ファイル名は data/1A03tsu1.txt などとします。
Files.readAllLines()メソッドについて詳しくは、ファイルから文字列を読んでListに格納を参照してください。(再掲)
フィールド、引数、フィールドに代入
LinkedHashMap<Integer,List<String>> shokenmap;
...
LinkedHashMap<Integer,List<String>> shokenmap,
...
this.shokenmap = shokenmap;
mainからの呼び出しはSetHRDataのインスタンスを作って、getShokenMap()メソッドを使う。
public static void createAndShowGUI() {
SetHRData hrdata = new SetHRData(2017,"1A",gakki);
...
LinkedHashMap<Integer,List<String>> shokenmap = hrdata.getShokenMap();
選択の後、選択されたものだけにする。
LinkedHashMap<Integer,List<String>> selshokenmap = new LinkedHashMap<>();
for (int no:selectedno){
selnamemap.put(no,namemap.get(no));
selseisekimap.put(no,seisekimap.get(no));
selshukketsumap.put(no,shukketsumap.get(no));
selshokenmap.put(no,shokenmap.get(no));
}
TsuuchiBun prevPrintable = new TsuuchiBun(
selnamemap,selseisekimap,selshukketsumap,
tanis,selshokenmap,gakki); //printable instance xxx add sel-
枠を作ってその中に入れます。文字数制限はなく、プレビューではみ出さないことを確認します。
行間や、フォントの大きさで調整する余地がありますが、今回は固定としています。
//備考
int bgpt = 0;
g2.setFont(font08);
vm = vtdtop+vptch*9f;
kp = new AjustString(g2,"所見",8f);
kp.drawKintou(hbas2+2f,vm+5f);
g2.setStroke(boldstroke);
line.setLR(hbas2,hbas2+hwhalf);
line.setY(vm);
g2.draw(line); //Rectangle TOP
line.setY(vm+vwbik);
g2.draw(line); //Rectangle bottom
line.setTB(vm,vm+vwbik);
line.setX(hbas2);
g2.draw(line); //Rectangle left
line.setX(hbas2+hwhalf);
g2.draw(line); //Rectangle right
g2.setFont(font10);
float fh10 = (float)(g2.getFontMetrics().getHeight()*pt2mm*1.4f); //改行幅
int ln=0;
vm = vm + fh10+2f;
List<String> bundata;
if( (bundata = shokenmap.get(n))!=null ){
for(String bun :bundata){
kp = new AjustString(g2,bun,hwhalf-4f);
if(kp.hasNext()) kp.drawKintou(hbas2+2f,vm+fh10*(++ln));
else kp.drawLeft (hbas2+2f,vm+fh10*(++ln));
while((bgpt=kp.getNextPt()) > 0){
kp = new AjustString(g2,bun,hwhalf-4f,bgpt);
if(kp.hasNext()) kp.drawKintou(hbas2+2f,vm+fh10*(++ln));
else kp.drawLeft (hbas2+2f,vm+fh10*(++ln));
}
}
}
テキストデータの作成は現時点ではエディタやワープロなどで作成しUTF-8で保存します。専用エディタを用意したいところです。
禁則処理はこれからです。現時点ではプレビューを見ながら文章を勘案して句読点が冒頭に来ないようにすることで回避します。