質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

Q&A

解決済

1回答

6091閲覧

カレンダーを作成中ですが、祝日の色変更をしようとしています。

shuriboo

総合スコア9

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

0グッド

0クリップ

投稿2018/08/16 10:14

編集2018/08/17 09:23

Java

1import java.awt.Color; 2import java.awt.Dimension; 3import java.awt.GridLayout; 4import java.util.Calendar; 5 6import javax.swing.BoxLayout; 7import javax.swing.JFrame; 8import javax.swing.JLabel; 9import javax.swing.JPanel; 10import javax.swing.SwingConstants; 11import javax.swing.UIManager; 12import javax.swing.UnsupportedLookAndFeelException; 13import javax.swing.border.LineBorder; 14 15public class debugTest { 16 public static void main(String[] args) { 17 JFrame frame = new JFrame("Swing Calender"); 18 frame.add(new SwingCalendar()); 19 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 20 frame.pack(); 21 frame.setVisible(true); 22 } 23} 24 25class SwingCalendar extends JPanel { 26 private JLabel monthLabel = new JLabel(); 27 private JLabel yearLabel = new JLabel(); 28 Calendar cal = Calendar.getInstance(); 29 30 //曜日、日付ラベル作成 31 private JLabel[] weekLabels = new JLabel[7]; 32 private JLabel[][] dayLabels = new JLabel[6][7]; 33 34 //各パーツのColorの作成 35 private static final Color WEEK_BG = new Color(102,102,102); 36 //private static final LineBorder WEEK_BORDER = new LineBorder(new  Color(160,160,230), 2, false); 37 38 //日付パネルの色 39 private static final Color DAY_BG = new Color(102,102,102); 40 private static final Color DAY_FG = Color.BLACK; 41 private static final LineBorder DAY_BORDER = new LineBorder(new Color(102,102,102), 2, false); 42 43 //日付のLabel 44 private static final Dimension DAY_LABEL_SIZE = new Dimension(50,50); 45 private static final String[] WEEK_NAMES = new String[] {"日", "月", "火", "水", "木", "金", "土"}; 46 private static final String[] MONTH_NAMES = new String[] {"1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"}; 47 48 public SwingCalendar() { 49 try { 50 UIManager.setLookAndFeel( 51 "javax.swing.plaf.nimbus.NimbusLookAndFeel" 52 ); 53 } catch (ClassNotFoundException | InstantiationException 54 | IllegalAccessException | UnsupportedLookAndFeelException e) { 55 e.printStackTrace(); 56 } 57 58 /* MONTH Label */ 59 Dimension dm = monthLabel.getPreferredSize(); 60 dm.width += 10; //dm.height += 1; 61 monthLabel.setPreferredSize(dm); 62 monthLabel.setForeground(DAY_FG); 63 64 /* YEAR Label */ 65 Dimension dy = yearLabel.getPreferredSize(); 66 dy.width += 10; //dy.height += 1; 67 yearLabel.setPreferredSize(dy); 68 yearLabel.setForeground(DAY_FG); 69 70 /* DAY PANEL */ 71 JPanel dayPanel = new JPanel(); 72 GridLayout layout = new GridLayout(7, 7); 73 layout.setHgap(0); 74 layout.setVgap(0); 75 dayPanel.setLayout(layout); 76 dayPanel.setBackground(DAY_BG); 77 78 //曜日の配列 79 for( int i=0; i<7; i++) { 80  weekLabels[i] = new JLabel(WEEK_NAMES[i]); 81  weekLabels[i].setHorizontalAlignment(SwingConstants.CENTER); 82  weekLabels[i].setVerticalAlignment(SwingConstants.CENTER); 83  weekLabels[i].setPreferredSize(DAY_LABEL_SIZE); 84  weekLabels[i].setOpaque(true); 85  weekLabels[i].setBackground(WEEK_BG); 86  87  if( i == 0 ) { 88    weekLabels[i].setForeground(Color.RED); 89  } else if ( i == 6 ) { 90    weekLabels[i].setForeground(Color.BLUE); 91  } 92 93  System.out.println("kakunin" + i); 94  dayPanel.add(weekLabels[i]); 95 } 96 97 98 //日付の配列 99 for( int i=0; i<6; i++) { 100    for( int j=0; j<7; j++) { 101  dayLabels[i][j] = new DayLabel("test"); 102 103 if(j == 0 ) { 104   dayLabels[i][j].setForeground(Color.RED); 105 } else if (j == 6 ) { 106   dayLabels[i][j].setForeground(Color.BLUE); 107 } 108 109      dayPanel.add(dayLabels[i][j]); 110     } 111      System.out.println("i" + i); //確認 112  System.out.println("j" + j); //確認 113  } 114 115  JPanel monthPanel = new JPanel(); 116  monthPanel.setLayout(new GridLayout()); 117  monthPanel.add(yearLabel); 118  monthPanel.add(monthLabel); 119  monthPanel.setBackground(DAY_BG); 120 121  setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 122  GridLayout gl = new GridLayout(1,2); 123  gl.setHgap(10); gl.setVgap(10); 124 125  //年月ボタン表示パネル、日にちパネルの追加 126  add(monthPanel); 127  add(dayPanel); 128 129 } 130 131} 132 133

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

opyon

2018/08/16 10:22

コードが枠内に入っていないようなので修正して頂けませんか?
shuriboo

2018/08/16 10:30

@opyonさん ご指摘ありがとうございます。修正いたしました。
m.ts10806

2018/08/16 13:18

コードブロック内はコードだけを書いてください。コード以外のものが入ると再現確認の際の弊害にしかなりません。また、インデントが全くない状態なので非常に読みづらいですし、ミスが起きやすくなっています。調整してください。あと「うまくいきません」では何が起きているか伝わらないのて起きている現象を具体的に記載してください。このあたりは「質問するときのヒント」を熟読して質問内容を調整すると良いです(質問内容が充実することで的確な回答を得やすくなります) https://teratail.com/help/question-tips
m.ts10806

2018/08/17 10:54

説明文全部削除したらただコード投げただけのも丸投げですよ・・・。コードも大事ですがそのコードで起きている現象やエラー、何がどう想定通りにできていないのか具体的に書くのも必要です。
guest

回答1

0

ベストアンサー

曜日の日付部分を色替えしたいという仕様と想定して回答いたします。
一般的なDatepickerのコードからやりたい事を憶測して
コードを見た感じでは

Java

1 //日付の配列 2 for( int i=0; i<6; i++) { 3  for( int j=0; j<7; j++) { 4 // ↓ ※1 JLabelのテキスト文字を設定していません。 5 dayLabels[i][j] = new JLabel(); //String.valueOf(i),(j) 6 // 中略 7    if( i == 0 && j == 0 ) { // ← ※2 8      dayLabels[i][j].setForeground(Color.RED); 9    } else if ( i == 6 && j == 0 ) { // ← ※3 10      dayLabels[i][j].setForeground(Color.BLUE); 11    }

この3箇所が変です。j==0の時しか前景色が変わりません。
あとi == 6と判定していますが、変数:iがループの中で6になることはfor( int i=0; i<6; i++)ループ上ありえないかと。

というわけでこんな感じでは。

Java

1    if(j == 0) { 2      dayLabels[i][j].setForeground(Color.RED); 3    } else if (j == 6) { 4      dayLabels[i][j].setForeground(Color.BLUE); 5    }

土、日の判定はこれで大丈夫ですが、
春分の日と秋分の日が年によって違うので祝日を判定するにはこれではダメです。
祝日の情報をどこかに持つ必要があります。
LocalDateを使って、LocalDate#plusDays
で日付を1づつ加算して表を作るのをお勧めいたします。


余談
以下のようなコードは、JLabelを継承したクラスを1個作るとコード記述が減らせます。

Java

1   dayLabels[i][j] = new JLabel(); //String.valueOf(i),(j) 2   dayLabels[i][j].setHorizontalAlignment(SwingConstants.CENTER); 3   dayLabels[i][j].setVerticalAlignment(SwingConstants.CENTER); 4   dayLabels[i][j].setOpaque(true); 5   dayLabels[i][j].setBackground(DAY_BG); 6   dayLabels[i][j].setPreferredSize(DAY_LABEL_SIZE);

Java

1class DayLabel extends JLabel { 2   public DayLabel(String s) { 3      super(s); 4      this.setHorizontalAlignment(SwingConstants.CENTER); 5      this.setVerticalAlignment(SwingConstants.CENTER); 6      this.setOpaque(true); 7      this.setBackground(DAY_BG); 8      this.setPreferredSize(DAY_LABEL_SIZE); 9   } 10} 11// 使い方 12dayLabels[i][j] = new DayLabel("test");

曜日とコードがほぼ同じなので、コンストラクタを改良して共通化するのも一つの手かと。


LocalDateを使ったサンプルコードです、あとは自力で頑張ってくださいな。

Java

1import java.time.LocalDate; 2import java.time.temporal.TemporalAdjusters; 3import java.util.ArrayList; 4import java.util.Calendar; 5import java.util.List; 6import java.util.stream.Collectors; 7import java.util.stream.IntStream; 8import java.util.stream.Stream; 9 10class SwingCalendar extends JPanel { 11 private JLabel[] dayLabels; // 一次元配列(0オリジン) 12 public SwingCalendar() { 13 // 前略 14 dayPanel.setBackground(DAY_BG); 15 // 当月1日 16 final LocalDate firstDay = LocalDate.now().with(TemporalAdjusters.firstDayOfMonth()); 17 // 一ヶ月間のラベルのリスト(最後に配列化) 18 final List<JLabel> dayList = new ArrayList<>(); 19 20 for (LocalDate day : getDateList(firstDay)) { 21 final int d = day.getDayOfMonth(); 22 System.out.println(d); 23 JLabel label = new JLabel(String.valueOf(d)); 24 label.setHorizontalAlignment(SwingConstants.CENTER); 25 label.setVerticalAlignment(SwingConstants.CENTER); 26 label.setOpaque(true); 27 label.setBackground(DAY_BG); 28 label.setPreferredSize(DAY_LABEL_SIZE); 29 // 土、日の判定のみなので、ここに祝日判定が必要 30 switch (day.getDayOfWeek()) { 31 case SUNDAY: 32 label.setForeground(Color.RED); 33 break; 34 case SATURDAY: 35 label.setForeground(Color.BLUE); 36 break; 37 default: 38 label.setForeground(Color.WHITE); 39 break; 40 } 41 dayList.add(label); 42 dayPanel.add(label); 43 } 44 45 // GridLayoutが7*7=49で残りをFillする。 46 IntStream.range(0, 49 - dayList.size()).forEach(x -> { 47 // GridLayoutに項目を追加する。 48 dayPanel.add(new JLabel("")); 49 }); 50 // リストから配列に変換 51 dayLabels = dayList.toArray(new JLabel[0]); 52 JPanel monthPanel = new JPanel(); 53 // 以下省略 54 } 55 public static List<LocalDate> getDateList(final LocalDate start) { 56 final int days = start.lengthOfMonth(); 57 return Stream.iterate(start, d -> d.plusDays(1)).limit(days).collect(Collectors.toList()); 58 }

投稿2018/08/17 08:27

編集2018/08/17 11:17
umyu

総合スコア5846

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shuriboo

2018/08/17 09:26

@umyuさん ご丁寧な回答ありがとうございます。 // ↓ ※1 JLabelのテキスト文字を設定していません。 この部分について、配列[j]がテキストとして表示されていないということでしょうか? 度々で申し訳ありませんが、もう少し詳しくご説明いただけると助かります。
umyu

2018/08/17 09:32 編集

いえ、コード実行すると分かりますが、ラベルに日(1~31)の文字出てないですよね。 JLabel#setTextを行うか、JLabelのコンストラクタに日(1~31)の文字が必要なのではというだけなのですが。
umyu

2018/08/17 09:35

個人的にはLocalDateを使ってループを回して1次元配列で管理するほうが、iとjの2重ループで2次元配列で管理するより楽なのではないかと思うのですが。
shuriboo

2018/08/17 09:50

@umyuさん LocalDateで書き直してみます。 ありがとうございます!
shuriboo

2018/08/20 04:29

@umyuさん 重ね重ねありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問