TOP カテ一覧 スレ一覧 100〜終まで 2ch元 削除依頼
ハァハァ・・・仕事に行きたくない ○| ̄|_12406日目※粉R
おまいら休みの日は何してんのYO?14658日目※粉RR
おなえら相武紗季たんちゅきですかァ(≧〜≦??) 40
1000ゲットとかいつの時代だよw在日ネカマン爺 Part.2
二宮和也好きな毒男34
雑談 コナコナのオフ会
雑談 男ってホント見栄っ張り
雑談 アンチ粉スレももはや粉スレと同じくらい邪魔くさいんだけど
雑談 ドローンで運ばれる少年探偵
雑談 犯罪者顔してるあいつ

System.out.println("またJavaの季節がやってきた!" + 2);


1 :2018/09/13 〜 最終レス :2019/11/28
去年の今頃Java学習開始するも挫折
しかし不屈の闘志をめらめらと燃やしながら
そびえ立つ岩壁にいどむため、再びこの地にやってきたのだ!

プログラミング歴は独学Cチョビッツ+独学VBA少々


きょうかしょ
https://www.amazon.co.jp/dp/484433638X
スッキリわかるJava入門 第2版 (スッキリシリーズ)

2 :
Swingをいれてみた
JavaFXはいろいろエラー吐いてうまく行かないというか原因がよくわからんから
SwingをGUIの部品として採用
Swingのいいテキストあったら買いたかったけど古いのしかないからネットで知識漁ることにした
最初はシンプルな作りで十分だし

https://www.javadrive.jp/tutorial/
ここみながらぼちぼちやっていく

3 :
dat落ちは20までだっけか

4 :
windowsbuilderとかscenebuilderとか使ってウィンドウ作って行くとダメだな
あれは理解出来てる人が使うものだ

5 :
windowbuilder

6 :
手打ちでボタンとかいろいろと・・

7 :
ほう

8 :
ふぅ

9 :
are you fine?

10 :
yea

11 :
いやっほおおおおおおお週末だぜいぃ!
JavaJavaすっかね

12 :
ごく基本的な構造そなえたウィンドウを形成するコードは暗記することにする
何度も繰り返し書くのである

13 :
ActionListener関係はちょっと複雑であり
しかも重要性高いので慎重にいくのであります

原理をちゃんと理解するのである

14 :
ActionListenerと書くと高確率でスペルミスをする
eがなかったり

15 :
多重継承がここででてくるんだよな
いろいろ基本の復習勉強できていいかもしれない

ちなみに継承なのか承継なのかいつも迷う
承継は小計みたいだからだめ!と覚えよう

16 :
extends JFrame implements ActionListener !!!!

17 :
自分自身のクラスのインスタンスを表すのはthis

18 :
GUIの基本であるこの辺でみられる技は見事だな
extendしたJFrameのメソッドをコンストラクタで使うあたりとか
プロの技って感じです
こういう風に使うんだなぁと

19 :
public void actionPerformed(ActionEvent e) {
System.out.println("腹減ったしメシくうか");
}

20 :
GUI分野の部品はこれで大体完成
次は定期処理の部品を学んでいく予定

ざっとみたところ学習する内容は
TimerTask
Timer
ScheduleExecutorService

21 :
あと、前から気づいていたんだけど、クラスを今までに学んだことのない方法で使ってるのをみかける
どうやらこれを無名クラスとか匿名クラスとか呼ぶようだ
わかりにくいから普通の使い方に書き換えて今まで使ってたんだけど
頻繁にでくてくるのでちゃんと頭に入れた方がよさそうな気もする

22 :
今日はこれで終了です
さようなら〜またあした〜

23 :
定時処理難しいな
windowsのタスクスケジューラに任せることにしよう
とするとGUI使わないほうがよさそうだな
まぁ今の段階ではそれでいいか

24 :
GUIアプリで
開始ボタンを押すことで毎日定時に処理するようにする
停止ボタンを押すことで定時処理を停止させる

をやろうとしたんだけど、いろいろとまだ知識足りない
threadとかの知識も必要なんだけど実践編でもあまり書いてなさそう

thread
interrupt

とか使うといけそうなんだけど、いろいろと問題も起きそうで
それを回避するための仕組みがイマイチ難しい

25 :
おれの作った最初のソフトウェアでけたああああ
ショボイけど

グローバルIPアドレスを記録していくプログラム

実行すると、実行ファイルと同じフォルダにテキストファイルを作成し
グローバルIPアドレスを日時とセットでかき込む
(ついでにプライベートIPアドレスもセットでかき込む)
実行するたびに同じファイルに追記していく
年ごとにファイルを新しく作っていく
タイマーは難しかったんでwindowsのタスクスケジューラで毎日定時に実行することにした

おれの環境は時々IPアドレスが変わるんで
いつ変ったのか知りたくて自動で記録していくフリーソフトないかなと探してたんだけど
よさそうなのがなかった
単純な動きなので自分で作れたらなぁと思ってた

26 :
問題はタスクスケジューラが正常に動いているかだ
壊れちゃってたのが治ってなければ意味なし

27 :
どうやらタスクスケジューラでjar実行ファイルを起動するときは
javaw -jar C:\〜パス〜\test.jar
みたいにしないといけないみたいだ
exe化してもいいんだけどどうしようかな

28 :
うーむ
不思議なことにexe化してもしなくてもタスクスケジューラから起動すると挙動がおかしい
一瞬コマンドプロンプトが表示されて、
System.out.prinlnで指定した文字列が見えるからプログラムの一部は動いている感じはする
でもテキストファイルを作ってくれない

ためしにバッチファイルをかましてみようと思い作成、
ひとまず手動でバッチファイルを起動してみたらバッチファイルが消滅
おいおいアバストさん・・・・

もしやおれのプログラムもまさかこいつが・・・
と思ったがどうやら違う
アバストを停止させてもテキストファイルを作ってくれない

バッチファイル噛ませばいけるならそれでいいか

29 :
1個しょぼいの作ったらPythonに目移りしてきた
どどどどどどどどどどどしようかすら

30 :
GUIを作りたいんだよな
そうするとWPFとかいうのがヒットする
C#なのか
そうなのかそうなのか
どどどどどどどどどどどどどどどしようかすら

31 :
てかもう1個Javaでしょぼいのつくろうかな
今欲しいプログラム思いついた

32 :
時計作った
USA東部時間をサマータイム込みで知りたいこと多いから常時表示させるやつ

いろいろと問題にぶち当たったけど、一応役に立つものができあがったんでOK

あと、アマゾンでプログラミング関連の本注文しまくってしまった
C#
python
javascript

一応しばらくはJava中心だけど気が向いたらほかのもやろう
すっきりの実践編を読み終えたいな
入門編も完全に自分のものにしたとも言えないし

33 :
じゃばじゃば

34 :
HTML・CSS・Javascript関連の初心者本に浮気してる
HTMLはずいぶん昔に多少勉強したことあるんだけど、
当時はいかに見せるかに力点がおかれてたと思う
今は最初から入力欄やボタンやらを紹介するのな
利用してもらうってのが先にある
ずいぶん変ったもんだ

35 :
作った時計プログラムのタイトル消して
ウィンドウごとDDして移動させたり、右クリックメニュー付けて終了できるようにしたりしてるんだけど
なんだかググって適当にコピペしてるだけでなんとなくできてしまうのはいいんだろうか・・・

イマイチ理解できてない部分もあるんで後々ちゃんとやっていこうと思ってはいるんだけど

大体欲しかった機能付けられた
前回閉じた場所で開く機能をつけたらほぼ完成だな

36 :
機能追加のために足りない知識を補う目的で部分的に実践編読んでるんだけど
やっぱネットと違って説明がしっかりしてていいわぁ
ちゃんと読む価値あるなといまさらながら思った
最低限実践編までは読まないと、無駄に時間食う

37 :
前回閉じた場所で開く機能も付けた
iniファイルを作って座標を保存しておくタイプにしたんだけど
ファイルが消えちゃったとか中身がおかしくなっちゃったときとか
いろんなトラブルに対処できるようにするとなかなか難しい
ある程度対処できたけど、まだ完全じゃない

38 :
ファイルのclose()は必ずfinallyで記述するのです

39 :
と思ってたけどエレガントな記述方法があると次のページに!

40 :
ほほ

41 :
単純にテキスト流して読んで問題といて頭に入っていくかというとそうでもない

そこで、
簡単な機能ではあるけど、自分が必要だと思うコードがふんだんに含まれる
プログラムを用意してこれを何度も書いて覚えることにする
学習の骨格がないと肉付けする過程でぐらぐらゆれちゃってなかなか覚えられないんで
骨格部分をちょっと頑張って頭にいれよう

42 :
ウィンドウ操作とかいろいろできるようになってきた
おもろいなぁ
APIレファランスだっけ、だんだん読めるようになってきた
もう一度すっきり入門編の後半読み直したいな
あの辺大事だわ

43 :
ヤフーの天気予報を表示するようなwindowsアプリってどういう風にサーバから情報を得てるんだろうと思ったんだけど、
ヤフーがそのためのAPIを提供してるんだな
おそらくアプリ作った人が自分が運用してるサーバで情報取得する
配布した個別のアプリはそのひとのサーバに接続して情報取得する
こんな感じなのかな
ヤフーに直接接続するとなるとアプリケーションIDとやらが必要となるそうなので現実的ではないんで、こういう感じで間接的に情報取得してそうだ
もし自分だけで利用するアプリつくるなら、ID登録後に直接ヤフーから情報取得すればよさそう

44 :
ヤフーの気象情報API
https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/weather.html

45 :
天気予報を常時表示してくれるソフトは昔から使っているんだけど
そのソフトの情報取得先のヤフーが提供するデータに明日の天気がないらしい
そのため明日の天気が表示されない

そこで、明日の天気だけを表示するちっこいソフトをつくろうかと思う
APIを使うとたぶん同じことになるんでHTMLから適当に抽出してやろうと計画してる
しかしだ、頻繁にHTMLを変えられてしまうとなかなか難しいかもしれない

46 :
http と https ではHTMLの取得方法を変えないといけないのか
文字化けするから文字コードがらみでいろいろ調べてたんだが違っていた

URLクラスではなく
URLConnectionクラスを使ったらHTML取得までうまくいった

47 :
いや、ちがうな・・・
URLクラスでいける
この辺はいつか解決する課題として残そう

char型使って読み込んでいく最も入門的なコードだと、どこかで文字がおかしくなる
StringBuilderが原因かと思ったがそうでもなさそうだ

48 :
ふぅ・・・ひとつひとつ壁があるわい
お天気マークのgifをそのままフレームに表示させようと思ったがなぜかできない
ローカルにある画像ファイルならいける
いろいろ調べたらようやくわかった
URLクラスのインスタンス使わないとだめなようだ
つまり
ImageIcon ii = new ImageIcon("./img/aa.jpg")
はおkだけど
ImageIcon ii = new ImageIcon("http://www.eee.jp/ee/aa.jpg");
はダメ
ローカルにない画像使いたい時は、一旦
URL url = new URL("http://www.eee.jp/ee/aa.jpg");
として
ImageIcon ii = new ImageIcon(url);
とするのが正解

49 :
おれさま!がんばってるな!見ているからこれからも頑張って

50 :
おーさんくすあろっと!

51 :
https://dotup.org/uploda/dotup.org1654406.jpg
まだ途中だけど、こんな感じでいく
アイコンはヤフー天気からそのまま借用
データは全部普通にヤフー天気開いた時に取得するHTMLから
必要な部分切り出して利用した
ヤフーがURLやらHTMLの中身を変えちゃうと表示できなくなる
でも自分で作って自分でしか利用しないからこれで十分だ

あと付け足さないといけない機能は
数時間おきにデータとりに行く機能と右クリメニューから閉じる機能
あと、前回閉じた場所で開く機能

どの機能もいままで作った2つのプログラムから借用できるので大した事はない

52 :
機能完備して完成



なんだけど、さっきググってたら面白そうなの見つけた
おれのお天気表示プログラムはヤフー天気のHTMLを取得して特定ルールのもとで
splitを使って分割、配列に格納してる
この特定ルールなんだけど、できたらタグを目印にぶつぶつと小間切れにしていく方向でやりたかった
しかしだ、正規表現<.*>を使って表現したタグでsplitすると
たとえば、このHTML

<div>ちんちん</div>
<p>まんまん</p>

を配列に格納すると
要素番号0 ちんちん</div><p>まんまん
要素番号1 (なし)

となってしまう
本来は

要素番号0 ちんちん
要素番号1 まんまん

とならなければならない

どうやら * は「よくばり」らしくて、途中で > が表われてももっと後ろに > があれば
まだまだいけるだろーとどんどん先へ進んで行ってしまうようだ
それが分かったあと、まぁ正確にタグで区切る必要も無いだろうと考えて
< 記号でsplitしてたんだけど・・・・・

53 :
<.*?>

という書き方があるそうだ
これでやると

要素番号0 ちんちん
要素番号1 まんまん

が実現できるそうだ
この ? 記号は普通の ? 記号(直前パターンの0回か1回の繰り返し)ではなく
* の「よくばり」を消し去る効果をもつらしい
つまり、タグの中を * が進んで行く途中で、 > が現れた瞬間にそれ以上進むのを諦めてくれるそうだ

これを「最短一致」という
デフォルトは「最長一致」なのだが、最長もこれはこれで使えそうだ
最短一致は正確には→の方向に進んでいく場合の最短一致で
逆方向には働かないので注意

54 :
>>52を修正
要素番号0 ちんちん</div><p>まんまん
要素番号1 (なし)

↑間違い 正確には↓

要素番号0 div>ちんちん</div> (改行記号が入る) <p>まんまん</div
要素番号1 (なし)

55 :
せっかくだからこれで書き直してみようかとおもおとる

56 :
おれが今使わせてもらってる誰かが作ったお天気表示ソフトなんだけど
iniファイルをみたら、おれが利用してるヤフー天気のHTMLと同じURLが書いてあった
とすると、このソフトはおれと同じようにHTMLを加工して作っているのでは・・・

もしそうならヤフーがHTMLを改変し、おれのお天気表示ソフトが正確に表示されなくなったタイミングで
このソフトも同じ症状を見せるんではないかと思う
もちろんHTMLの分析の仕方いかんで、そうとも言い切れないだろうけど、観察してみる価値ありだ

57 :
ちなみにだけど、
<.*?> でタグを表現する方法は不完全らしい
しかし、その不完全さを理解するにはもうちとHTMLやらweb系の知識がいるようなので後回しにしていこう

58 :
>>54を修正
要素番号0 div>ちんちん</div> (改行記号が入る) <p>まんまん</p
要素番号1 (なし)

59 :
そういや気温表示がなかった
これ付けておきたいな
特にこれからの季節寒いんで

60 :
複数ラベルについてforやら使ってまとめてコード書こうとしたら大変な目にあった

ラベル名の一部に数字使ってこれを変数に置換えてforで回す方法はないかと模索したができないようだ
つまり
for (int i = 0; i < 5; i++) {
label_i.setText("おほほ");
}
みたいのはだめ

配列使う方法で代用できそうなので試してみたが、ここでまた問題勃発

JLabel[] lbl = new JLabel[5];
for (JLabel bb : lbl) {
bb.setText("むほほ");
}

これでだめときた
あの有名な ぬるぽ が出てしまう
ぐぐりまくってようやくわかったのが
このコードではJLabelのインスタンス化が済んでいないということ。
配列の作り方とインスタンス化が結構似てるんで両方が組み合わさると混同してしまうのがポイント
正解は

JLabel[] lbl = new JLabel[5]; //←ここでは配列変数と配列の実体が作られただけ
for (JLabel bb : lbl) {
bb = new JLabel(); //←JLabelのインスタンス化のためこの1行が必要!
bb.setText("むほほ");
}


さらにforの中でswitchを使ったのだが
案の定break;を忘れて、忘れたことに気づかずに試行錯誤1時間ですわ

61 :
main factory already defined

exewrapを使って作ったexe実行時にこのエラーが出るのは
実行可能jarファイルをエクスポートするときライブラリー処理を
上から2番目の選択肢にするから。
一番下を選択すること

隣のサブフォルダにコピーするとかなんたらこうたらのを選択

62 :
カレンダーをデスクトップに表示してるんだけど
こいつ、祝日を判定できない
次はカレンダーづくりか・・・?

祝日のAPIも誰かが作ってくれているようだ
http://s-proj.com/utils/holiday.html
便利だの〜

63 :
祝日自体そう多いわけでもないから
内閣府が出してる振替休日込み祝日等のcsvをそのまま使うっていう手もあるな




ん〜
そういえば定期的な実行にthreadとsleep使ってたんだけど
これはあまり良くないとかいうのを読んだ
もう少し基礎力アップさせてから次のソフトに挑んだ方が良いのかもしれない
今のままでもいろいろ作れることは分かったけど、もう少し基礎知識の幅の広さが欲しい

64 :
Swingを使ったWindowsアプリを作っていると
継承の知識をちゃんと生かしていかないと理解できなくなる
右クリックメニューの項目を作るためのメソッドがあるんだけど、
これにActionListenerクラス型変数「のようなもの」を引き渡さないといけなかったりする

「ようなもの」というのは、そもそもActionListenerはインターフェースでインスタンス化できない
今の知識ではこれをなんと呼ぶのかよく分からない

ここで、引き渡す際の実引数にthisを使うとなぜかうまくいく
適当にやったらうまくいったのだが、自分でやっていて頭が混乱してしまう

落ち着いて考えてみたら理解できた

つまり、まず、
クラスの宣言でこうやってる
public class Main extends JFrame implements ActionListener

そしてmainメソッドで
Main mm = new Main();
のようにインスタンスを生成している

ここでthisとは何を指すのかと言えば
Main型変数mmということになる
このmm、実はActionListener型変数(のようなもの)でもある
なぜかというとMainクラスはActionListenerを実装しているからだ

だからthisでうまくいくのだ・・・・(と今のところ思っておこう

65 :
インターフェースはインスタンス化できないだけで
インターフェースの変数は作れるということかな
ActionListener al
みたいのはそういうもんか


あと、
インターフェースのインスタンス化に絡んで分からなくなるのが匿名クラス

JButton btn = new JButton();
btn.addActionListener(
 new ActionListener() {
  public void actionPerformed(ActionEvent e) {

  }
 }
);
みたいなやつ
これもActionListenerをnewしてるからおかしいじゃん!って思うんだけど
ぐぐってみたら、これは、みためはインターフェースActionListenerをnewしてるようで
実はActionListenerを継承した匿名クラスをnewしてるんだそうだ

66 :
すっきり入門を読んでいる段階では、
オブジェクト指向というものはわかりやすくメンテしやすいコードを書くための技法であって
一歩先へ進みたいなら理解しておいたほうがいいよって程度に思えたんだけど

実際windowsアプリ作り始めると、基本的なコードを理解するのに必須な知識だと分かる
理解できてないと話にならないというレベル

まぁまだ理解仕切れてないし忘れちゃってる部分もあるんで読みなおそっと

67 :
MainクラスにActionListenerを実装させない方法だと、

btn.addActionListener(new al());
として、これとは別に実際の処理を任せるクラスをつくる
public class al implements ActionListener {
 public void actionPerformed(ActionEvent e) {
 
 }
}
こういうのがどちらかというと基本のコードだから
>>65の匿名クラスのnewというのは、ここでいう al みたいのをnewしてるってことか

68 :
jarのままだとタスクマネージャやらにファイル名が表示されないから
基本的にはexewrapを使ってexe化している
しかし何度もコマンドプロンプト開いてうだうだ繰り返しやってると煩わしいので
D&Dして処理するできるようバッチファイルを作った

@echo off
if %~x1 == .jar (
 exewrap -g %1
) else (
 echo .jarではありません。
)
pause

久々にバッチファイルについてぐぐってみたんだけど
意外といろいろ出来ちゃうんだということを思い出した

69 :
パネルの上にもう一枚枠線だけで中身は透明のパネルをかぶせることで
すこしだけおしゃれにしてみた

この2枚重ねのパネル、簡単だと思ったのだが以外とつまずきが多かった

JPanel pnl_1 = new JPanel();
Jpanel pnl_2 = new JPanel();//こいつを透明化して枠線だけ設定することにする
pnl2.setOpaque(false);//透明化

Container contentPane = getContentPane();
contentPane.add(pnl_1);
contentPane.add(pnl_2);

でいけるだろ〜と思ったら大間違いだった
こんだけやったら思い通りになった↓もしかしたら不必要なものもあるのかもしれないが

・pnl_2はcontentPaneにaddするのではなく、pnl_1にaddする pnl_1.add(pnl_2);
・pnl_1はsetSize()でフレームと同じ大きさにサイズ設定 pnl_1.setSize(100, 100);
・pnl_2はsetBounds()で位置サイズ固定。
 ぴったりpnl_1にかぶせるのであれば pnl_2.setBounds(0, 0, 100, 100);

70 :
たぶんLayoutにも関連してくるんだと思う
今のところだけど、

contentPaneは setLayout(new BorderLayout());
pnl_1は pnl_1.setLayout(null);

としてある

71 :
フォントの種類っていろいろあるけど今までほとんど気にしたことなかった
デフォルトで表示される日本語フォントがあまりに変なのでメイリオっていうのに変更した

72 :
すっきり入門読み直してるんだけど
windowsアプリ作ってる時になんどかstatic関連のエラーが出た
なんとなく適当にやったら切り抜けられたんだけど
ちゃんと頭に入れないといけない

いつも忘れるのは

「staticメソッドからはstaticではないメンバを呼び出せない」

ということ。
何度かこれでつまずいたんだけど、そのうちの一つがthread関連の処理をしたとき
threadはまだちゃんと理解できてなくて、それが原因というのもある
threadを使うだけの簡単なプログラムをつくれと言われたら簡単なんだけど
自分がそれまで書いたコードを前提にして、そこにthreadを組み込もうとするといろいろ制約が出てきて難しくなっていくのだ

73 :
そもそもスレッドは鬼門なのだ
すっきりでも実践編の最後に触れているだけで
入門編しか読んでないおれが立ち入ってはいけない領域だったのだ
しかしスレッドを利用しないとなるとさらに難しいコードを書かなければならなさそうだったので
あえて踏み込まざるを得なかった

まず第一の制約がこれだった

メインに使うクラスをMainとした場合、このMainクラスはこう宣言されている
public class Main extends JFrame

普通スレッドを使う時は extends Thread を使うのだが
しかしextendsによる多重継承はゆるされないため、Runnableを使う事になる
public class Main extends JFrame implements Runnable
と宣言することになる

と書いたのだが、実は
ごく基本的なコードを書くのであればRunnableはメインのクラスに実装するものではない
それはあとになって分かったことなのだが、基本レベルではこう書く
もちろんSwingを使ってwindowsアプリをつくる前提で。

public class Main extends JFrame {
 public static void main(String[] args) {
  Main mm = new Main();
  Aa aa = new Aa();
  Thread thrd = new Thread(aa);
  thrd.start();
 }
}

public class Aa implements Runnable {
 public void run() {
  System.out.println("この辺に処理内容を書く");
 }
}

つまり、Mainとは別に処理系のクラスを作って、これにRunnableを実装するのだ
そしてmainスレッドでThreadクラスのインスタンスを生成するときに
処理系クラスのインスタンス変数を引数として渡すことになる

74 :
しかし、おれが何もわからないまま参考にしたコードではメインのクラスはこう宣言されていたのだ
先ほど書いたものをもう一度書くが、これだ

public class Main extends JFrame implements Runnable

つまり、本来メインのクラスとは別にRunnableをimplementsするクラスをつくるはずが
そのクラスをメインのクラスに吸収するような形で合体させてしまっているのだ
その結果、メインのクラスにRunnableをimplementsさせてしまっているわけだ

これはextends JFrameと同じ構造だ
これも基本レベルではメインのクラスとは別のクラスを作ってextends JFrameとすべきところを
メインのクラスに合体させてしまった結果なのだ

MainクラスがAaクラスを吸収合体した結果上のコードはこう変ることになる

public class Main extends JFrame implements Runnable {
 public static void main(String[] args) {
  Main mm = new Main();//この一行にAa aa = new Aa();も一緒に入っていることになる
  Thread thrd = new Thread(mm);//mmにはaaも一緒に入っていることになる
  thrd.start();
 }
 public void run() {
  System.out.println("この辺に処理内容を書く");
 }
}

75 :
で、結局なんの話だったかというと
そう、staticの話なのだ
static などどこにも出てきてないぢゃないか!
その通り、これから出てくるのだ

時計やら定時処理系をthreadを使って書くと
sleepメソッドを使う事になる
もちろんrunメソッドの中に書いていくことになる

public class Main extends JFrame implements Runnable {
 public static void main(String[] args) {
  Main mm = new Main();//この一行にAa aa = new Aa();も一緒に入っていることになる
  Thread thrd = new Thread(mm);//mmにはaaも一緒に入っていることになる
  thrd.start();
 }
 public void run() {
  try {
   thrd.sleep(1000); //ここ!注目
  } catch(InterruptedException e) {
   e.printStackTrace();
  }
 }
}

が、これはエラーが出てしまうのだ

76 :
thrd が犯人なのだ

なぜならthrdはmainメソッド内で宣言されている変数であるため
runメソッドではスコープの外に置かれている
そのため利用できないのだ!

そこで、しゃーないので、こう書く

public class Main extends JFrame implements Runnable {

 Thread thrd = new Thread(mm);//←クラスブロックに移動!
 
 public static void main(String[] args) {
  Main mm = new Main();//この一行にAa aa = new Aa();も一緒に入っていることになる
  thrd.start();
 }
 public void run() {
  try {
   thrd.sleep(1000); //←thrdがスコープ内に入る!
  } catch(InterruptedException e) {
   e.printStackTrace();
  }
 }
}

しかしだ!これでもエラーが出てしまい頭を抱えてしまうだ

77 :
犯人は mm である

Threadインスタンス宣言Thread thrd = new Thread(mm);が
クラスブロックに移動してしまったため、引数として渡しているmmが
スコープから外れてしまい、ここからではみえなくなってしまったのだ

そこでmmを定義する一行もクラスブロックに持ってくることにする


public class Main extends JFrame implements Runnable {

 Main mm = new Main();//←クラスブロックに移動! 
 Thread thrd = new Thread(mm);//←mmがスコープ内に入る!

 public static void main(String[] args) {
  thrd.start();
 }
 public void run() {
  try {
   thrd.sleep(1000);
  } catch(InterruptedException e) {
   e.printStackTrace();
  }
 }
}

しかしだ〜、まだこれでもエラーが出てしまう

78 :
ようやくここで、static の話になるのだ

最後の犯人は、またもや thrd である

mainメソッド内の
thrd.start();
である

>>72 「staticメソッドからはstaticではないメンバを呼び出せない」

mainメソッドはstaticメソッドである
にも関わらず、staticではない thrd を thrd.start(); で呼び出しているのだ

この問題を解決するには
Thread thrd = new Thread(mm);

static Thread thrd = new Thread(mm);
とするだけではダメだ

今度はstaticな「メソッド」ではないものの、static から 非static を呼ぶという同じ現象が
static Thread thrd = new Thread(mm);
の中で起きてしまっている
staticなthrdを定義するのに非staticなmmを呼んで引数にしてしまっているのだ
そこでmmを定義する一行にもstaticを付けることにする

public class Main extends JFrame implements Runnable {

 static Main mm = new Main();//←static 
 static Thread thrd = new Thread(mm);//←static

 public static void main(String[] args) {
  thrd.start();
 }
 public void run() {
  try {
   thrd.sleep(1000);
  } catch(InterruptedException e) {
   e.printStackTrace();
  }
 }
}

これでようやく解決したのだ、ちゃんちゃん!

79 :
こやって書いているとあやふやだったところが見えてくる
実際のコードはずっと長く複雑なので、焦点を絞って小さく書き直すとなかなかいい
解決策はいろいろあるんだろうが、今の知識の範囲内で理解のできる解決策を見つけられるといいのではないかと思っている

間違えて理解しているところはあるだろうが
こうやって書いて残しておけば、そのうち気づくときもくるだろう

80 :
スコープ VS static の戦い

81 :
staticがつくと、インスタンスが全く生成されてないのにアクセスできることになる
そのためインスタンス生成されて始めて使えるようなメンバを呼び出すことはできないし
許してはだめなのだ
だからエラーがでるのだ!

82 :
ボタン押すと・・・・系

最も基礎レベルのコードがこれ

public class Main extends JFrame {
 Main() {
  setSize(200, 200);
  setLocationRelativeTo(null);
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  JPanel pnl = new JPanel();
  JButton btn = new JButton("押して・・・・");
  pnl.add(btn);
  Container contentPane = getContentPane();
  contentPane.add(pnl, BorderLayout.CNETER);
 
  MyListener ml = new MyListener();//@
  btn.addActionListener(ml);//A
 }
 public static void main(String[] args) {
  Main ma = new Main();
  ma.setVisible(true);
 }
}
class MyListener implements ActionListener {//B
 public void actionPerformed(ActionEvent e) {
  System.out.println("あ〜ん");
 }
}

83 :
おれのイメージだと
Aを媒介にして
@のbtnさんがBの処理系全体を背負ってるような感じ
まずこういう骨格を作る

class MyListener implements ActionListener {//B
 public void actionPerformed(ActionEvent e) {
  System.out.println("あ〜ん");
 }
} 

  __r'⌒'⌒'⌒ヽ,,_
  (,三∧_∧::: 4三) 
   ~(´∀` )爻丗 ~   MyListener ml = new MyListener();//@
   とll   lと),幵+!
((  ◯,,_ , ソ,王ノ  btn.addActionListener(ml);//A
       し"

モナーがbtnでリュックが処理系MyListener全体
リュックの肩紐がインスタンス生成の式

みたいな・・・

84 :
ボタンを押すと・・・

モナーbtnがぴょんと飛ぶ
 ↓
するとモナーの足元で震動ActionEventのインスタンスeが自動生成されて、
 ↓
震動 e は肩紐を介してリュックに伝わる
 ↓
そしてリュックの中で震動 e を actionPerformedメソッドがキャッチして
処理が始まるみたいな・・・・



これが基礎の基礎のイメージ
ここがちゃんとできてないとすらすら書けない

85 :
https://www.javadrive.jp/tutorial/event/index1.html
イベント処理の流れを間単に確認しておきます。

まずボタンやテキストなどのコンポーネントが何のイベントを受け取るのかを指定します。
これは例えばボタンについて考えてみると、ボタンが押されたとか、ボタンの上でマウスが
動いたなどの様々なイベントが絶えず発生していますが、必要の無いイベントについては
処理する必要が無いため、自分で処理したいイベントだけ受け取るようにするためです。


おれのSwingの教科書的サイト



ボタン押すと、ボタンからActionEentのインスタンス e が自動生成されるイメージ・・・・

86 :
>>82-85 が一番の基礎で・・・

次がこんなの
少し変るだけ
肩紐の@がAに吸収された感じ

public class Main extends JFrame {
 Main() {
  setSize(200, 200);
  setLocationRelativeTo(null);
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  JPanel pnl = new JPanel();
  JButton btn = new JButton("押して・・・・");
  pnl.add(btn);
  Container contentPane = getContentPane();
  contentPane.add(pnl, BorderLayout.CNETER);
 
  
  btn.addActionListener(new MyListener());//A
 }
 public static void main(String[] args) {
  Main ma = new Main();
  ma.setVisible(true);
 }
}
class MyListener implements ActionListener {//B
 public void actionPerformed(ActionEvent e) {
  System.out.println("あ〜ん");
 }
}

87 :
>>86 とはちょっと別系統の発展系で、
BをMainクラスに合体させる形も考えられる

public class Main extends JFrame implements ActionListener { //BがMainに合体!
 Main() {
  setSize(200, 200);
  setLocationRelativeTo(null);
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  JPanel pnl = new JPanel();
  JButton btn = new JButton("押して・・・・");
  pnl.add(btn);
  Container contentPane = getContentPane();
  contentPane.add(pnl, BorderLayout.CNETER);
 
  
  btn.addActionListener(this);//Aモナーbtn
 }
 public static void main(String[] args) {
  Main ma = new Main();//@肩紐生成はここにふくまれることになる
  ma.setVisible(true);
 }
 public void actionPerformed(ActionEvent e) {
  System.out.println("あ〜ん");
 }
}

88 :
今は覚えちゃったから迷わないけど
ここはよく迷った

btn.addActionListener(this);//Aモナーbtn

ここのthis
このコードの体系なら

btn.addActionListener(ma); でもいいんじゃないかとか
btn.addActionListener(new Main()); とか?どうや!とかやったけどダメだった

thisにしたらうまくいったんで、そのまま思考停止してthisのままきたわけだ
ところでこのthisとは

●「自分自身のクラスのインスタンス」

そして、Main()、つまり、コンストラクタとは

●「インスタンスが生まれた直後に自動実行されるプログラム」

である。
基礎の基礎である>>82を思い出すと、thisの位置にくるのは本来は
ActionListenerを実装したクラスのインスタンス変数 ml である
>>87ではこのクラスはMainに合体しているため、ml生成の式は
Main ma = new Main(); に含まれていることになる
そしてこの式が生成されるちょうどその時に、コンストラクタMain()が呼び出されることになるのだ
いわば、maを作る時にその材料づくりとしてコンストラクタMain()の内容が処理されることになる
btn.addActionListener(ma); とすると、maをつくる材料にmaが含まれるというおかしなことになってしまうが
これは問題ない。問題なのはその書き方である
maの作成途中でmaを引き渡そうとしても、まだmaはできあがってないので引き渡せないのである
そこでthisという特殊な書き方をするのだ (とおれは考えているのだ
そもそもthisというのはそーゆーときに使うのだ! (とおれはかんがえている
わかったか!

btn.addActionListener(new Main()); はもう少しわかりやすい問題が起こる
今つくろうとしているインスタンスを引き渡したいのに、new Main()としてしまうと
別のインスタンスをあらためて作って引き渡すということになる。これはダメだ。
ちなみに、この「別のインスタンス」だが、生成するときにコンストラクタMain()を呼び出してしまう
するとまた異なるインスタンスをMainクラスから生成しようとする。そしてこのインスタンスはまた・・・・以下同様

このさまは実際にコードを実行してみるとコンソールでみられる

89 :
ちなみにおれはSwing Javaと格闘してるのだが
最近よくきいている音楽はSwing Jazz


だから何?????とか言わないで

90 :
>>88
> btn.addActionListener(ma); とすると、maをつくる材料にmaが含まれるというおかしなことになってしまうが
> これは問題ない。問題なのはその書き方である
> maの作成途中でmaを引き渡そうとしても、まだmaはできあがってないので引き渡せないのである
> そこでthisという特殊な書き方をするのだ (とおれは考えているのだ
> そもそもthisというのはそーゆーときに使うのだ! (とおれはかんがえている
> わかったか!。

を修正

btn.addActionListener(ma); とすると、maをつくる材料にmaが含まれるというおかしなことになってしまうが
これは問題ない。問題なのはその書き方である
thisというのはそもそもまだインスタンス化がされる前にコードに書かれるものである
基礎レベルのクラスの使い方を思い出してみるとわかるのだが
本来はMainクラスとは別のクラスファイルに書かれたクラス、
例えばHeroクラスの中でthisは使われる
そしていつかHeroクラスがインスタンス化されたときに、インスタンスが自らを利用するためにthisとして控えているのだ
thisというものはそういうものなのだ!

何が大事なのかというと、もう一度繰り返すが、thisを書いた時点では普通インスタンスは生成されていないのだ
よってインスタンス変数名など分かるはずがないのである

>>87のコードはその辺が非常に特殊であって、クラスの中で自らのインスタンスを生成しちゃってたりする
だからわかりにくい
本来はMain ma = new Main();みたいのは別のクラスに書かれるようなものなのだ
それに備えてMain側では将来作られるであろう自らのクラスのインスタンスを表す名称として
thisを使うわけだ

確かにbtn.addActionListener(ma);とするのは理屈としては間違えていないのだが
本来の使われ方からするとおかしいのでじゃばがくるくるぱ〜になってしまうのである

91 :
あーそういえば思い出した

この前こういうの書いてみたんだ

>>87に少し付け足し
public class Main extends JFrame implements ActionListener { 
 Main() {
  setSize(200, 200);
  setLocationRelativeTo(null);
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  JPanel pnl = new JPanel();
  JButton btn = new JButton("押して・・・・");
  pnl.add(btn);
  Container contentPane = getContentPane();
  contentPane.add(pnl, BorderLayout.CNETER);
 
  
  btn.addActionListener(this);
 }
 public static void main(String[] args) {
  Main ma = new Main();
  ma.setVisible(true);
  Main ma2 = new Main();//←ここ
  ma2.setVisible(true);//←ここ
 }
 public void actionPerformed(ActionEvent e) {
  System.out.println("あ〜ん");
 }
}

このときにさっきの話でthisの代りにmaを使ってしまうとma2には対応できなくなってしまうんだ
だからやっぱりthisでないとダメなのだ!

ちなみにこのコードだとウィンドウが2枚開くことになって面白い
そういうプログラム作る時に使えそうだ

92 :
そして最後に、
>>86を発展させたのが下のコード
@だけではなくBまでもAに合体してしまう


public class Main extends JFrame {
 Main() {
  setSize(200, 200);
  setLocationRelativeTo(null);
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  JPanel pnl = new JPanel();
  JButton btn = new JButton("押して・・・・");
  pnl.add(btn);
  Container contentPane = getContentPane();
  contentPane.add(pnl, BorderLayout.CNETER);
  
  //@+A+B
  btn.addActionListener(
   new ActionListener() {
    public void actionPerformed(ActionEvnet e) {
     System.out.println("あ〜ん");
    }
   }
  );

 }
 public static void main(String[] args) {
  Main ma = new Main();
  ma.setVisible(true);
 }
}

93 :
  //@+A+B
  btn.addActionListener(
   new ActionListener() {
    public void actionPerformed(ActionEvnet e) {
     System.out.println("あ〜ん");
    }
   }
  );

この部分はモナーbtnがリュックを背負ってる部分がセットで表現されている
発展形態とはいえ、もっともわかりやすい
しかし、ここで、あれ?っと疑問が出てくる
@、A、Bが結合しているあたりのコードがおかしいのではないか
本来こう書かなければいけないのではないか?

  //@+A+B
  btn.addActionListener(
   new MyListener() implements ActionListener { //←このへん
    public void actionPerformed(ActionEvnet e) {
     System.out.println("あ〜ん");
    }
   }
  );

ActionListenerのインスタンスではなくActionListenerを実装したクラスのインスタンスを
生成しなければならないのだから。

しかし、このように書くとエラーが生じる 👀
Rock54: Caution(BBR-MD5:1341adc37120578f18dba9451e6c8c3b)


94 :
この辺を理解するにはある原則的なルールを覚える必要が出てくる

このようなbtnにクラスから全部背負わせてしまうようなコードには名称がついている
正確には、背負われているクラスの名称なのだが、「匿名クラス」とか「無名クラス」と呼ばれる

匿名クラスには大事なルールがある。
それは、
「new クラスA(インターフェースA)」 とした場合
クラスAをnewすることにはならないのだ(インターフェースはそもそもnew出来ないのが基本)
そうではなく、
●「クラスAまたはインターフェースAを継承または実装した」クラス をnewすることになるのだ

なぜだか理由はよく分からないが
>>93の下の方のコードにエラーが出てしまうように、implementsを記述できないからなのだろうか

なにはともあれ、このルールを前提に考えれば

  btn.addActionListener(
   new ActionListener() {

の2行目は、「インターフェースActionListenerを実装したクラスをnewする」、という意味になる
つまり最も基礎的なコードである>>82の@new MyListenerと全く同じことを意味するのだ

参考までにいえば、
もしスーパークラス(ここでいうならActionListener)の中で
private修飾子のついたフィールドが宣言されていると、
newしたあとのブロック内ではこのフィールドにアクセスできないことになってしまうのだ

ちゃんと書こう
クラスAAでaというフィールドがこう宣言されていたとする
private int a;
このとき匿名クラスを利用し、こう書いたとする

new AA() {
 public void bb() {
  a = 10;
 }
}

これはエラーが生じてしまう
なぜならnewしたのはAAのように見えて実はAAを継承した別の(名無しの)クラスだからだ
名無しの別のクラスからはAA内に宣言されたprivate変数にアクセスすることは許されないのだ

95 :
まぁだからこそ「匿名」クラスという名前がついている

new AA が
クラスAAをnewするというのであれば
AAって名前あるじゃん・・・となる
しかし
new AA が
クラスAAを継承した名無しクラス
または
インターフェースAAを実装した名無しクラス
をnewするという意味だとしたら
まさに匿名っすよね!

96 :
がんばってるなぁ…

97 :
( ^ー゚)b

98 :
( ^ー゚)b

99 :
さて、今日からは

フレーム上で右クリックメニューを表示させ、
「閉じる」の項目を選択・クリックしてプログラムを終了させる処理

について再考する

この処理はすでに作ったソフトで利用してはいるが
理解を深めるために他の処理とは独立した形でとりだして分析すべきだと思っている
先を急いだため、コピペでしのいだ部分もあり、
部分的には理解できていない可能性があるのだ

100 :
ところで、なぜ右クリからの終了処理が必要になったのかというと
windowsアプリは通常タイトルが表示される枠部分がある
そしてこのタイトルの右の端には最小化・最大化・閉じるボタンがあるのだ
閉じるボタンがあればわざわざ右クリから閉じる機能を作る必要もない

しかし、小さなウィンドウのプログラムを作るときは、このタイトルバーが邪魔になってしまう
右端の3つのボタンはウィンドウをより小さくする時に障害となってしまうのだ

おれが作ったものはこういうもの
https://dotup.org/uploda/dotup.org1659204.jpg
昭和チックな絵柄でデザインセンスが皆無なのが分かるだろうか
いやそういう話ではなく、ウィンドウを小さくするためにタイトルバーを取り外してしまったわけだ
すると、
setDefaultCloseOperation(true); が機能しなくなってしまうのだ

それどころか、ウィンドウの位置を動かすことすら出来なくなってしまう
つまり、タイトルバーを消してしまった代償として、以下の2つの機能を実装する必要があるのだ

1.閉じる機能を右クリメニューに加える
2.ウィンドウをD&Dにより動かせるようにする

今回は1.について分析をしていこうとおもうとる


100〜のスレッドの続きを読む
雑談 2020も俺らはひとりぼっち
雑談 コマメ隊と玉子麺
雑談0025
女優の有村架純さん
雑談 運河の街からこんにちわ
雑談 男子に混じってドッジボールをする哀c
雑談 光彦くんの可愛らしさ
雑談 探偵なのよ
粉の恥ずかしい書き込みを転載するスレ 3
雑談 探偵なのよ
--------------------
キックサーブを会得するスレ
ラグビー経験者に質問をぶつけていくスレ
銅鑼全尻33
△▲△ 仙台空港 Runway31 △▲△
50ccエンジンのある生活 原付をまたーり楽しく179
【伊福部崇】POARO ポアロスレ52【鷲崎健】
A.B.C-Z橋本良亮14
【コロナ速報】米国で1日に100人以上の死者 23日
【Mobage】糞ゴミアバ不正者永久晒し22【叩き潰し】
🌸第1023回トンスレ入学式🌸
【エレスト】エレメンタルストーリーPart235【バグ多発癒着運営】
何のために生きているか分からない喪女 part24
【バランス】リケーブルスレ★23【MMCX】
【聞きたい】奥様アンケート(IDあり) 138【知りたい】
愛媛FC実況スレ vs大宮
D&D 5e ダンジョンズ&ドラゴンズ第5版 #28
★【YouTube】Reon Nekosky 2【ゲーム実況】
天皇制と身分制度について持論を吐き出すスレ
世界最低のヤオ 白鵬翔
【風前の灯火】650MB CD-R【絶滅寸前】
TOP カテ一覧 スレ一覧 100〜終まで 2ch元 削除依頼