例えば、 Calender には日付に加算する機能があり、必要なら内部の月や曜日等を自動で更新してくれます。これを利用すると、カレンダーを「月の開始日の属する週の日曜日」に設定し、その日から日付を1ずつ足していって月を調べ、表示対象月なら日を表示、対象月で無ければスペースを表示し、土曜日表示の後(もしくは日曜の前)には改行を行い、月が対象月の翌月になったら終了する・・・といったことが出来ます。
java
1 import java . util . Calendar ;
2
3 public class カレンダー {
4 public static void main ( String [ ] args ) {
5 for ( int month = 1 ; month <= 12 ; month ++ ) print ( 2022 , month ) ;
6 }
7
8 private static void print ( int year , int month ) {
9 System . out . println ( year + "年" + month + "月" ) ;
10 System . out . print ( " 日 月 火 水 木 金 土" ) ; //改行しない(後の for で最初に改行するため)
11
12 for ( Calendar cal = getStart ( year , month , Calendar . SUNDAY ) ; ! isEnd ( cal , month ) ; cal . add ( Calendar . DATE , 1 ) ) {
13 if ( cal . get ( Calendar . DAY_OF_WEEK ) == Calendar . SUNDAY ) System . out . println ( ) ;
14 System . out . printf ( cal . get ( Calendar . MONTH ) == month - 1 ? " %2d" : " " , cal . get ( Calendar . DATE ) ) ;
15 }
16
17 System . out . println ( ) ;
18 }
19
20 private static Calendar getStart ( int year , int month , int dayOfWeek ) {
21 Calendar cal = Calendar . getInstance ( ) ;
22 cal . set ( year , month - 1 , 1 ) ;
23 while ( cal . get ( Calendar . DAY_OF_WEEK ) != dayOfWeek ) cal . add ( Calendar . DATE , - 1 ) ; //指定曜日まで戻る
24 return cal ;
25 }
26
27 private static boolean isEnd ( Calendar cal , int month ) {
28 return cal . get ( Calendar . MONTH ) != month - 1 && cal . get ( Calendar . DATE ) == 1 ;
29 }
30 }
plain
1 2022年1月
2 日 月 火 水 木 金 土
3 1
4 2 3 4 5 6 7 8
5 9 10 11 12 13 14 15
6 16 17 18 19 20 21 22
7 23 24 25 26 27 28 29
8 30 31
9 2022年2月
10 日 月 火 水 木 金 土
11 1 2 3 4 5
12 6 7 8 9 10 11 12
13 13 14 15 16 17 18 19
14 20 21 22 23 24 25 26
15 27 28
16 2022年3月
17 日 月 火 水 木 金 土
18 1 2 3 4 5
19 6 7 8 9 10 11 12
20 13 14 15 16 17 18 19
21 20 21 22 23 24 25 26
22 27 28 29 30 31
23 2022年4月
24 日 月 火 水 木 金 土
25 1 2
26 3 4 5 6 7 8 9
27 10 11 12 13 14 15 16
28 17 18 19 20 21 22 23
29 24 25 26 27 28 29 30
30 2022年5月
31 日 月 火 水 木 金 土
32 1 2 3 4 5 6 7
33 8 9 10 11 12 13 14
34 15 16 17 18 19 20 21
35 22 23 24 25 26 27 28
36 29 30 31
37 2022年6月
38 日 月 火 水 木 金 土
39 1 2 3 4
40 5 6 7 8 9 10 11
41 12 13 14 15 16 17 18
42 19 20 21 22 23 24 25
43 26 27 28 29 30
44 2022年7月
45 日 月 火 水 木 金 土
46 1 2
47 3 4 5 6 7 8 9
48 10 11 12 13 14 15 16
49 17 18 19 20 21 22 23
50 24 25 26 27 28 29 30
51 31
52 2022年8月
53 日 月 火 水 木 金 土
54 1 2 3 4 5 6
55 7 8 9 10 11 12 13
56 14 15 16 17 18 19 20
57 21 22 23 24 25 26 27
58 28 29 30 31
59 2022年9月
60 日 月 火 水 木 金 土
61 1 2 3
62 4 5 6 7 8 9 10
63 11 12 13 14 15 16 17
64 18 19 20 21 22 23 24
65 25 26 27 28 29 30
66 2022年10月
67 日 月 火 水 木 金 土
68 1
69 2 3 4 5 6 7 8
70 9 10 11 12 13 14 15
71 16 17 18 19 20 21 22
72 23 24 25 26 27 28 29
73 30 31
74 2022年11月
75 日 月 火 水 木 金 土
76 1 2 3 4 5
77 6 7 8 9 10 11 12
78 13 14 15 16 17 18 19
79 20 21 22 23 24 25 26
80 27 28 29 30
81 2022年12月
82 日 月 火 水 木 金 土
83 1 2 3
84 4 5 6 7 8 9 10
85 11 12 13 14 15 16 17
86 18 19 20 21 22 23 24
87 25 26 27 28 29 30 31
コメントに書いた、 i に下駄を履かせる(「0~(月初の曜日値-1) は前月を表す」)としたら…です。
(ご質問のコードの一部)
java
1 //月初日が何曜日なのか設定
2 int startDay = cal . get ( java . util . Calendar . DAY_OF_WEEK ) - 1 ; //0=日曜, 1=月曜, ..., 6=土曜
3 int lastDay = cal . getActualMaximum ( java . util . Calendar . DATE ) ;
4
5 for ( int i = 0 ; i < startDay + lastDay ; i ++ ) {
6 if ( i > 0 && i % 7 == 0 ) {
7 System . out . println ( ) ;
8 }
9
10 if ( i < startDay ) {
11 System . out . print ( " " ) ;
12 } else {
13 System . out . printf ( " %2d" , ( i - startDay + 1 ) ) ;
14 }
15 }