前提
現在お小遣い帳を作成しており、入力した値をObject型の配列に格納し、名目を判別後各Wallet,FoodExpences,BookFee,DailyCost型(各クラスはスーパークラスItemのサブクラス)にキャストしたものを表に表示させようとしています。
(残額の行はまだ計算式を書いていないためずっと空白のままです。)
表はハイフンなどを用いて自作の枠組みを作っているのですが、表の枠を一定の大きさで保つために入力した値のByte数を判定するメソッドを用い、(表の枠の大きさ)ー(入力した値のByte数)を計算しformatを用いてその数だけ空白を値の右側に出力しようとしています。AddSort2クラスで作っている枠に最終的に合わせようと思っています。
しかし、収入、支出の行がByte数を判定したものを出力した場合予想通りの値(例:全角で20000と入力されていれば10)が出力されたのですが、formatを用い表形式で出力しようとした際に、入力した値の桁数が違う場合に出力される空白の数が変わり表の枠(|部分)がガタガタになってしまいます。
formatに関して詳しく調べたつもりなのですがどうしてこのような問題が発生してしまうかわからなかったため質問させていただきました。説明が長くなってしまい申し訳ございません。よろしくお願いします。
csvファイルの内容
お財布 収 20000 N/A
食費 支 2000 N/A
書籍 支 1500 N/A
日用品費 支 500 N/A
お財布 収 5000 N/A
お財布 収 1 N/A
お財布 収 10000 N/A
食費 支 10000 N/A
追記:
表での表示はターミナル内で行いたいと考えています。
実現したいこと
(表の枠の大きさ)ー(入力した値のByte数)の差だけ空白を値の右側に出力
発生している問題・エラーメッセージ
空白の数の計算まではできているのだがその数だけの空白の出力ができていないため表の縦に分割する場所がガタガタになっている。
該当のソースコード
AddSort2.java
Java
1package bookmoney; 2 3 4public class AddSort2 { 5 private int balance = 0; 6 public void getTableParts(Object [] itemArray) { 7 8 String format = "|%1$-10s|%2$-12s|%3$-12s|%4$-4s|%5$-20s|\n"; 9 System.out.format(format, "名目", "収入", "支出", "残額", "補足"); 10 11 System.out.println("-------------+--------------+--------------+------+-----------------------"); 12 13 for (int i = 0; i < itemArray.length; i++) { 14 if (itemArray[i] instanceof Wallet) { 15 Wallet wallet = (Wallet)itemArray[i]; 16 System.out.println(wallet.getTableParts()); 17 System.out.println("-------------+--------------+--------------+------+-----------------------"); 18 } else if (itemArray[i] instanceof FoodExpences) { 19 FoodExpences foodExpences = (FoodExpences)itemArray[i]; 20 System.out.println(foodExpences.getTableParts()); 21 System.out.println("-------------+--------------+--------------+------+-----------------------"); 22 } else if (itemArray[i] instanceof BookFee) { 23 BookFee bookFee = (BookFee) itemArray[i]; 24 System.out.println(bookFee.getTableParts()); 25 System.out.println("-------------+--------------+--------------+------+-----------------------"); 26 } else if (itemArray[i] instanceof DailyCost) { 27 DailyCost dailyCost = (DailyCost) itemArray[i]; 28 System.out.println(dailyCost.getTableParts()); 29 System.out.println("-------------+--------------+--------------+------+-----------------------"); 30 } 31 } 32 } 33 }
Wallet.java これと型の名前だけが違うクラスが各名目ごとにあります。
Java
1package bookmoney; 2 3import java.util.*; 4public class Wallet extends Item{ 5 private String wallet; 6 7 public Wallet (String name, String flag, String amount, String wallet) { 8 super(name, flag, amount); 9 this.name = getName(); 10 this.flag = getFlag(); 11 this.amount = getAmount(); 12 this.wallet = wallet; 13 } 14 15 public String getWallet() { 16 return this.wallet; 17 } 18 19 public String getTableParts() { 20 String lineTable = null; 21 HanZen2 han1Zen2 = new HanZen2(); 22 23 String name = this.name; 24 String flag = this.flag; 25 String amountStr = this.amount; 26 String note = this.wallet; 27 String amount = ""; 28 String in = ""; 29 String out = ""; 30 if (flag.equals("収")) { 31 in = amountStr; 32 } else if (flag.equals("支")) { 33 out = amountStr; 34 } 35 36 int nameBlank = 15 - han1Zen2.getHan1Zen2(name); 37 int inBlank = 14 - han1Zen2.getHan1Zen2(in); 38 int outBlank = 14 - han1Zen2.getHan1Zen2(out); 39 int noteBlank = 25- han1Zen2.getHan1Zen2(note); 40 // String inBlankStr = String.valueOf(inBlank); 41 42 String namelineTable = name.format(("|%-" + nameBlank + "s"), name); 43 String inlineTable = in.format(("|%-" + inBlank + "s" ), in); 44 String outlineTable = out.format(("|%-" + outBlank + "s" ), out); 45 String amountTable = amount.format(("|%-6s"), amount); 46 String notelineTable = note.format(("|%-" + noteBlank + "s|" ), note); 47 lineTable = namelineTable + inlineTable + outlineTable + amountTable + notelineTable; 48 // lineTable = String.valueOf(inBlank ); 49 50 51 return lineTable; 52 } 53 } 54 55
DataLoad2.java クラスを判定しキャストさせる
Java
1package bookmoney; 2 3import java.io.BufferedReader; 4import java.io.FileReader; 5import java.io.*; 6import java.nio.file.Files; 7import java.nio.file.Path; 8import java.nio.file.Paths; 9 10public class DataLoad2 { 11 private Object [] itemArray; 12 13 public Object[] dataLoadMethod() { 14 15 try (BufferedReader br = new BufferedReader(new FileReader("bookmoney/PocketMoney.csv"))) { 16 int count = 0; 17//ファイルの行数取得 18 Path file = Paths.get("bookmoney/PocketMoney.csv"); 19 long lineNum = Files.lines(file).count(); 20 int lineInt = Math.toIntExact(lineNum); 21 22 itemArray = new Object[lineInt]; 23 24 String s; 25 while ((s = br.readLine()) != null) { 26 // 読み込んだ行を、「,」で分割する 27 String data[] = s.split(","); 28 if (data[0].equals("お財布")) { 29 itemArray[count] = new Wallet(data[0], data[1], data[2], data[3]); 30 } else if (data[0].equals("食費")) { 31 itemArray[count] = new FoodExpences(data[0], data[1], data[2], data[3]); 32 } else if (data[0].equals("書籍")) { 33 itemArray[count] = new BookFee(data[0], data[1], data[2], data[3]); 34 } else if (data[0].equals("日用品費")) { 35 itemArray[count] = new DailyCost(data[0], data[1], data[2], data[3]); 36 } 37 count++; 38 } 39 } catch (IOException e) { 40 System.out.println("入出力エラーです"); 41 } 42 return itemArray; 43 } 44}
HanZen2.java 値のByte数取得
Java
1package bookmoney; 2 3public class HanZen2 { 4 public static int getHan1Zen2(String str) { 5 //戻り値 6 int ret = 0; 7 8 //全角半角判定 9 char [] c = str.toCharArray(); 10 for (int i = 0; i < c.length; i++) { 11 if (String.valueOf(c[i]).getBytes().length <= 1) { 12 ret += 1; //半角なら+1 13 } else { 14 ret += 2;//全角なら+2 15 } 16 } 17 return ret; 18 } 19} 20
Item.java
Java
1package bookmoney; 2 3public class Item { 4 protected String name; 5 protected String flag; 6 protected String amount; 7 8 public Item (String name, String flag, String amount) { 9 this.name = name; 10 this.flag = flag; 11 this.amount = amount; 12 } 13 //getter 14 public String getName() { 15 return this.name; 16 } 17 public String getFlag() { 18 return this.flag; 19 } 20 public String getAmount() { 21 return this.amount; 22 } 23}
実行するクラス(該当箇所を抜粋しています)
Java
1 case 1: 2 3 System.out.println("《データロード》"); 4 DataLoad2 data = new DataLoad2(); 5 itemArray = data.dataLoadMethod(); 6 System.out.println("データロードが完了しました。"); 7 8 break; 9 case 2: 10 11 System.out.println("《表表示》"); 12 AddSort2 addSort2 = new AddSort2(); 13 addSort2.getTableParts(itemArray); 14 15 break;
試したこと
空白の出力数を確認したが予想通りの値が出力された
補足情報(FW/ツールのバージョンなど)
IntelliJを使用しています。
回答2件
あなたの回答
tips
プレビュー