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

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

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

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

Swing

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

Q&A

解決済

2回答

1154閲覧

Java Swingを使ったアプリでボタンクリック時の表示方法

k2tail

総合スコア1

Java

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

Swing

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

0グッド

0クリップ

投稿2023/02/17 23:10

javaでカレンダーのGUIアプリケーションに挑戦中です。こちらの翌月ボタンを押したときに、カレンダー表示部分を変更したいのですが、上手く変更ができません。翌月ボタンを押すと新しいframe?(表現があっていますか?)が出てきて翌月のカレンダーが表示されることはできたのですが、何枚も同じframe?を表示させるのではなく。使ってカレンダー部分と左上の年月だけ変えたものを表示させたいです。
あと日にち部分を作成するコードが長く綺麗ではないので上手く書いたり、もっと継承や実装をしてクラスを分けてカプセル化?をしていきたいのですが、今までしたことないのでよくわかっていないです。どなたか教えていただけますでしょうか。何かコード等ヒントもあれば非常に助かります。よろしくお願いします。

package calPro3.calPack; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; public class JFtesttttt extends JFrame implements KeyListener{ JPanel panel_1 = new JPanel(); private JPanel contentPane; public static int curYear; public static int curMonth; // 6×7 42個のJLabel作成 JLabel lbl42 [] = new JLabel[42]; /** * Launch the application. */ public static void main(String[] args) { new JFtesttttt(); } public JFtesttttt() { //Calendarクラスから現在年月日を取得し curYear,curMonthに代入 // Calendar cal = Calendar.getInstance(); curYear = 2023; //cal.get(Calendar.YEAR); curMonth = 2; //cal.get(Calendar.MONTH) +1; int dayNum = 0; System.out.println(curYear+" cuYear 年 "+curMonth +" curMonth 月"); //1月から12月までの一か月の日数を変数dayNumに代入 int jan=31,febHeinen=28,febUruu=29,mar=31,apr=30,may=31,jun=30,jul=31,aug=31,sep=30,oct=31,nov=30,dec=31; //SWITCH文で現在月curMonthから日数を取得 switch(curMonth) { case 1: dayNum = jan; break; //2月が28か29を調べる case 2: dayNum = febHeinen; if(curYear % 4 == 0) { if(curYear % 100 == 0) { if(curYear % 400 ==0) { dayNum = febUruu; } }else { dayNum = febUruu; } } break; case 3: dayNum = mar; break; case 4: dayNum = apr; break; case 5: dayNum = may; break; case 6: dayNum = jun; break; case 7: dayNum = jul; break; case 8: dayNum = aug; break; case 9: dayNum = sep; break; case 10: dayNum = oct; break; case 11: dayNum = nov; break; case 12: dayNum = dec; break; } System.out.println("日数は dayNum "+dayNum); setTitle("万年カレンダー3"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 500, 400); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); //カレンダー日付部 //日にちを表示するためjpanelをインスタンス化、コンテントペインにadd //JPanel panel_1 = new JPanel(); panel_1.setBounds(12, 126, 460, 225); contentPane.add(panel_1); panel_1.setLayout(new GridLayout(6, 7, 0, 0)); //ツェラーの公式を使い何曜日から始まるか firstBlankを求める int tYear = curYear; int tMonth = curMonth; int tDate = 1; if(tMonth == 1 || tMonth == 2) { tYear --; tMonth += 12; } int firstBlank = (tYear + tYear / 4 - tYear / 100 + tYear / 400 + (13 * tMonth + 8) / 5 + tDate) %7; System.out.println("最初の空白は「 " + firstBlank + " 」日分"); // firstBlank の個数分 * をラベルインスタンスを作り、パネルにadd for(int i = 0; i < firstBlank; i++) { String str = "+"; lbl42[i] = new JLabel(str); panel_1.add(lbl42[i]); } // dayNum の個数分 日にちのラベルインスタンスを作りパネルにadd for(int i = 0; i < dayNum;i++) { String str = Integer.toString(i + 1); lbl42[firstBlank + i] = new JLabel(str); panel_1.add(lbl42[firstBlank + i]); } int lastBlank = lbl42.length -dayNum - firstBlank; System.out.println("最後の空白は「 " + lastBlank + " 」日分"); for(int i = 0; i < lastBlank; i++) { String str = "-"; lbl42[firstBlank + dayNum + i] = new JLabel(str); panel_1.add(lbl42[firstBlank + dayNum + i]); } JButton btnNewButton_4 = new JButton("翌月↓"); btnNewButton_4.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // new CalNextMonth2 (); System.out.println("ボタンプッシュ"); String str = "@@@"; lbl42[1] = new JLabel(str); panel_1.add(lbl42[1]); setVisible(true); } }); btnNewButton_4.setBounds(278, 39, 91, 21); contentPane.add(btnNewButton_4); JLabel lblNewLabel_7 = new JLabel(curYear+ "年" + curMonth +"月"); lblNewLabel_7.setBounds(12, 9, 91, 21); contentPane.add(lblNewLabel_7); //最初の表示setVisible キーボードアクション setFocusable設定 setFocusable(true); setVisible(true); addKeyListener(this); } @Override public void keyTyped(KeyEvent e) { // TODO 自動生成されたメソッド・スタブ } @Override public void keyPressed(KeyEvent e) { switch ( e.getKeyCode() ) { case KeyEvent.VK_DOWN: System.out.println("下が押されました"); //new CalNextMonth2 (); break; } } @Override public void keyReleased(KeyEvent e) { // TODO 自動生成されたメソッド・スタブ } }

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

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

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

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

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

jimbe

2023/02/18 05:52

とりあえず変なクラス名とか無意味な変数名とかインデントとか無駄な空行とか、そういった所は直されたほうが良いと思います。
k2tail

2023/02/18 10:38

承知しました。独学ですので基本のアドバイス有難いです。ありがとうございます。
guest

回答2

0

ベストアンサー

Calendar クラスを使いたいのか使いたくないのかよく分かりません…元のコードの感じを残すようには気にしてみましたが…。

java

1import java.awt.Color; 2import java.awt.GridLayout; 3import java.awt.event.ActionEvent; 4import java.awt.event.KeyEvent; 5 6import javax.swing.*; 7import javax.swing.border.EmptyBorder; 8 9public class PerpetualCalendar3 extends JFrame { 10 private static final String ACTION_NEXTMONTH = "NEXT_MONTH"; 11 12 public static void main(String[] args) { 13 SwingUtilities.invokeLater(() -> new PerpetualCalendar3(2023, 2).setVisible(true)); 14 } 15 16 private int curYear, curMonth; 17 private JLabel headerLabel; 18 private CalendarPanel calendarPanel; 19 20 public PerpetualCalendar3(int year, int month) { 21 setTitle("万年カレンダー3"); 22 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 23 setBounds(100, 100, 500, 400); 24 25 curYear = year; 26 curMonth = month; 27 System.out.println(curYear+" curYear 年 "+curMonth +" curMonth 月"); 28 29 Action nextMonthAction = new AbstractAction("翌月↓") { 30 @Override 31 public void actionPerformed(ActionEvent e) { 32 //System.out.println("ボタンプッシュ"); 33 //System.out.println("下が押されました"); 34 System.out.println("翌月処理"); 35 nextMonth(); 36 } 37 }; 38 39 JPanel contentPane = new JPanel(null); 40 contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 41 setContentPane(contentPane); 42 43 headerLabel = new JLabel(); 44 headerLabel.setBounds(12, 9, 91, 21); 45 contentPane.add(headerLabel); 46 47 calendarPanel = new CalendarPanel(); 48 calendarPanel.setBounds(12, 126, 460, 225); 49 contentPane.add(calendarPanel); 50 51 JButton nextMonthButton = new JButton(nextMonthAction); 52 nextMonthButton.setBounds(278, 39, 91, 21); 53 contentPane.add(nextMonthButton); 54 55 setCalendar(curYear, curMonth); 56 57 JRootPane root = getRootPane(); 58 KeyStroke ks = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0); 59 root.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(ks, ACTION_NEXTMONTH); 60 root.getActionMap().put(ACTION_NEXTMONTH, nextMonthAction); 61 } 62 63 private void nextMonth() { 64 if(++curMonth > 12) { 65 curMonth = 1; 66 curYear ++; 67 } 68 setCalendar(curYear, curMonth); 69 } 70 71 private void setCalendar(int year, int month) { 72 headerLabel.setText(year + "年" + month + "月"); 73 calendarPanel.set(year, month); 74 } 75 76 private static class CalendarPanel extends JPanel { 77 private JLabel[] dayLabels; 78 79 CalendarPanel() { 80 super(new GridLayout(6, 7, 0, 0)); 81 82 dayLabels = new JLabel[6 * 7]; 83 for(int i = 0; i < dayLabels.length; i++) { 84 dayLabels[i] = new JLabel(); 85 add(dayLabels[i]); 86 } 87 } 88 89 void set(int year, int month) { 90 int dayNum = getDayNum(year, month); 91 System.out.println("日数は dayNum " + dayNum); 92 93 int firstBlank = getWeekday(year, month, 1); 94 System.out.println("最初の空白は「 " + firstBlank + " 」日分"); 95 96 int lastBlank = dayLabels.length - dayNum - firstBlank; 97 System.out.println("最後の空白は「 " + lastBlank + " 」日分"); 98 99 int i = 0; 100 while(i < firstBlank) setDay(i++, "+", false, false); 101 for(int date = 1; date <= dayNum; date++) setDay(i++, ""+date, true, isHoliday(year, month, date)); 102 while(i < dayLabels.length) setDay(i++, "-", false, false); 103 } 104 105 private int getDayNum(int year, int month) { 106 switch(month) { 107 case 2: 108 return (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)) ? 29 : 28; 109 case 4: 110 case 6: 111 case 9: 112 case 11: 113 return 30; 114 } 115 return 31; 116 } 117 118 /** 曜日 119 * @param year120 * @param month 月(1~12) 121 * @param date 日(1~31) 122 * @return 曜日(0=日, 1=月, ..., 6=土) */ 123 private int getWeekday(int year, int month, int date) { 124 //ツェラーの公式から 125 if(month == 1 || month == 2) { 126 year --; 127 month += 12; 128 } 129 return (year + year / 4 - year / 100 + year / 400 + (13 * month + 8) / 5 + date) % 7; 130 } 131 132 private void setDay(int i, String text, boolean isValidDay, boolean isHoliday) { 133 int weekday = isValidDay ? i % 7 : -1; 134 Color foreground = isHoliday || weekday == 0 ? Color.RED : weekday == 6 ? Color.BLUE : Color.BLACK; 135 dayLabels[i].setForeground(foreground); 136 dayLabels[i].setText(text); 137 } 138 139 /** 祝日 140 * @param year141 * @param month 月(1~12) 142 * @param date 日(1~31) 143 * @return 祝日なら true */ 144 private boolean isHoliday(int year, int month, int date) { 145 //TODO: 祝日判定 146 if(month == 1 & date == 1) return true; //元日 147 return false; 148 } 149 } 150}

投稿2023/02/18 07:04

編集2023/02/20 09:22
jimbe

総合スコア12632

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

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

k2tail

2023/02/18 10:37

すごすぎます。。。カレンダークラスは使わないようにしていましたのでこちらのコード非常に参考になります。きちんと動きを確認して自分に何が足りていないのか把握したいと思います。
jimbe

2023/02/18 12:06

回答本文に書くべきかもしれませんがこちらで…。 メソッド化やクラス化の目安として、コードに書かれたコメントが元に出来ます。 >//1月から12月までの一か月の日数を変数dayNumに代入 → getDayNum メソッド >//ツェラーの公式を使い何曜日から始まるか firstBlankを求める → getWeekday メソッド >//カレンダー日付部 → CalendarPanel クラス どこまでメソッド・クラスにするかは、作る人のそれまでの経験とかセンスとかで色々変わりますので、何が何でもこうでなければ・こうしなければとは思わずに柔軟にやっていくのが良いかもしれません。
k2tail

2023/02/20 07:52

コード模写してみたり、見て学習していくととても勉強になりました。特にメソッドやクラスの作り方が綺麗でまだまだ自分では作るのは難しそうですがどんどん真似していきたいと思います。 あとよろしければ、土曜を青、日曜や祝日を赤で表示させる方法を教えてほしいです。 firstBlankを利用して自分で表示させてみても、色は表示できるのですが、表示がずれたり月末部分は色が変わらなかったりでなかなか上手くいきません。 可能でしたらお願いします。
jimbe

2023/02/20 08:27

JLabel に文字色を指定する setForeground() があります。 曜日は、 JLabel の配列の 0, 7, 14, 21, 28, 35 が日曜日で、 6, 13, 20, 27, 34, 41 が土曜日です。 祝日は、祝日のデータを別途持つ必要がありますので、まずそれを準備してからでしょう。
k2tail

2023/02/21 01:22

ご回答ありがとうございます。空白部分も入れたラベル42個すべてを範囲にしたらいいのですね。JLabelの数字の部分だけを青や赤に変える方法を考えていて、firstBlankが1個の場合は何日目が青、2個の場合は、、と考えていたので難しかったですが、6×7で考えたらすぐできました。アドバイス本当にありがたいです。
guest

0

翌月ボタンを押すと新しいframe?(表現があっていますか?)が出てきて翌月のカレンダーが表示される

提示コードではそのような動作になりませんが、「new CalNextMonth2();があれば」ということでしょうか。

カレンダー部分と左上の年月だけ変えたものを表示させたい

既に追加されているJLabelの、文字を変えるようにします。
JLabel#setText (Java Platform SE 8 )

あと日にち部分を作成するコードが長く綺麗ではない

Calendarクラスを使えばほとんどの計算をせずに済みますが、使ってはいけない縛りがありますか?

もっと継承や実装をしてクラスを分けてカプセル化?をしていきたい

内容的には分けるほどのものには感じません(Calendarクラスを車輪の再発明したいということであれば別ですが^^;

クラス分けより先に、まずメソッドに分けるようにしてみましょう^^

何かコード等ヒントもあれば非常に助かります。

Swingにはカレンダーが用意されていないので、皆さん思い思いに作っておられるようですよ。
java swing calendar - Google 検索

Java

1import javax.swing.*; 2import javax.swing.border.EmptyBorder; 3import java.awt.GridLayout; 4import java.util.Calendar; 5 6 7public class MyCalendar extends JFrame { 8 public static void main(String[] args) { 9 new MyCalendar().setVisible(true); 10 } 11 12 13 private final JLabel label = new JLabel(); 14 private final JLabel[] lbl42 = new JLabel[42]; 15 private final Calendar calendar = Calendar.getInstance(); 16 17 public MyCalendar() { 18 setTitle("万年カレンダー"); 19 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 20 setSize(500, 400); 21 setLocationRelativeTo(null); 22 23 JPanel contentPane = (JPanel) getContentPane(); 24 contentPane.setLayout(null); 25 contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); 26 27 JPanel panel = new JPanel(new GridLayout(6, 7, 0, 0)); 28 panel.setBounds(12, 126, 460, 225); 29 contentPane.add(panel); 30 31 for (int i = 0; i < lbl42.length; i++) { 32 lbl42[i] = new JLabel(); 33 panel.add(lbl42[i]); 34 } 35 36 JButton nextButton = new JButton("翌月↓"); 37 nextButton.setBounds(278, 39, 91, 21); 38 nextButton.addActionListener(e -> { 39 calendar.add(Calendar.MONTH, 1); 40 updateCalendar(); 41 }); 42 contentPane.add(nextButton); 43 44 label.setBounds(12, 9, 91, 21); 45 contentPane.add(label); 46 47 calendar.set(Calendar.DATE, 1); 48 updateCalendar(); 49 } 50 51 private void updateCalendar() { 52 int year = calendar.get(Calendar.YEAR); 53 int month = calendar.get(Calendar.MONTH) + 1; 54 int dayNum = calendar.getActualMaximum(Calendar.DATE); 55 56 int firstBlank = calendar.get(Calendar.DAY_OF_WEEK) - 1; 57 for (int i = 0; i < firstBlank; i++) { 58 lbl42[i].setText("+"); 59 } 60 61 for (int i = 0; i < dayNum; i++) { 62 lbl42[firstBlank + i].setText(Integer.toString(i + 1)); 63 } 64 65 int lastBlank = lbl42.length - dayNum - firstBlank; 66 for (int i = 0; i < lastBlank; i++) { 67 lbl42[firstBlank + dayNum + i].setText("-"); 68 } 69 70 label.setText(year + "年" + month + "月"); 71 } 72}

投稿2023/02/18 01:53

TN8001

総合スコア9317

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

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

k2tail

2023/02/18 10:36

ご回答ありがとうございます。 提示コードではそのような動作になりませんが、「new CalNextMonth2();があれば」ということでしょうか。 →そのとおりです。別のクラスをnew した時に新しいフレームが表示されていたのですが、その仕組みがよくわかっていませんでした。 既に追加されているJLabelの、文字を変えるようにします。 JLabel#setText (Java Platform SE 8 ) →ありがとうございます。まさにsetTextが私が使うべきメソッドだと思います。今から色々調べて試してみたいと思います。 Calendarクラスを使えばほとんどの計算をせずに済みますが、使ってはいけない縛りがありますか? →はい。カレンダークラスを使わずに作ろうとしています。こちらのサイトを使うのは初めてですが、これからはこういう前情報もきちんと説明したいと思います。 アドバイスいただけるだけで一つ解決への道が開けてきました。感謝いたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問