X



トップページ独身男性
660コメント436KB
System.out.println("またJavaの季節がやってきた!" + 2);
■ このスレッドは過去ログ倉庫に格納されています
0001おれさま ◆6CTEZS59O00a
垢版 |
2018/09/13(木) 10:42:14.49
去年の今頃Java学習開始するも挫折
しかし不屈の闘志をめらめらと燃やしながら
そびえ立つ岩壁にいどむため、再びこの地にやってきたのだ!

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


きょうかしょ
https://www.amazon.co.jp/dp/484433638X
スッキリわかるJava入門 第2版 (スッキリシリーズ)
0002Mr.名無しさん
垢版 |
2018/09/13(木) 10:42:29.06
Swingをいれてみた
JavaFXはいろいろエラー吐いてうまく行かないというか原因がよくわからんから
SwingをGUIの部品として採用
Swingのいいテキストあったら買いたかったけど古いのしかないからネットで知識漁ることにした
最初はシンプルな作りで十分だし

https://www.javadrive.jp/tutorial/
ここみながらぼちぼちやっていく
0004おれさま ◆6CTEZS59O00a
垢版 |
2018/09/13(木) 11:40:09.85
windowsbuilderとかscenebuilderとか使ってウィンドウ作って行くとダメだな
あれは理解出来てる人が使うものだ
0011Mr.名無しさん
垢版 |
2018/09/15(土) 09:04:17.52
いやっほおおおおおおお週末だぜいぃ!
JavaJavaすっかね
0012おれさま ◆6CTEZS59O00a
垢版 |
2018/09/15(土) 09:21:27.49
ごく基本的な構造そなえたウィンドウを形成するコードは暗記することにする
何度も繰り返し書くのである
0013Mr.名無しさん
垢版 |
2018/09/15(土) 14:03:30.15
ActionListener関係はちょっと複雑であり
しかも重要性高いので慎重にいくのであります

原理をちゃんと理解するのである
0015おれさま ◆6CTEZS59O00a
垢版 |
2018/09/15(土) 15:15:50.52
多重継承がここででてくるんだよな
いろいろ基本の復習勉強できていいかもしれない

ちなみに継承なのか承継なのかいつも迷う
承継は小計みたいだからだめ!と覚えよう
0018おれさま ◆6CTEZS59O00a
垢版 |
2018/09/15(土) 15:21:50.64
GUIの基本であるこの辺でみられる技は見事だな
extendしたJFrameのメソッドをコンストラクタで使うあたりとか
プロの技って感じです
こういう風に使うんだなぁと
0019おれさま ◆6CTEZS59O00a
垢版 |
2018/09/15(土) 15:24:56.13
public void actionPerformed(ActionEvent e) {
System.out.println("腹減ったしメシくうか");
}
0020おれさま ◆6CTEZS59O00a
垢版 |
2018/09/15(土) 16:17:07.63
GUI分野の部品はこれで大体完成
次は定期処理の部品を学んでいく予定

ざっとみたところ学習する内容は
TimerTask
Timer
ScheduleExecutorService
0021おれさま ◆6CTEZS59O00a
垢版 |
2018/09/15(土) 16:21:40.66
あと、前から気づいていたんだけど、クラスを今までに学んだことのない方法で使ってるのをみかける
どうやらこれを無名クラスとか匿名クラスとか呼ぶようだ
わかりにくいから普通の使い方に書き換えて今まで使ってたんだけど
頻繁にでくてくるのでちゃんと頭に入れた方がよさそうな気もする
0023おれさま ◆6CTEZS59O00a
垢版 |
2018/09/16(日) 05:03:22.53
定時処理難しいな
windowsのタスクスケジューラに任せることにしよう
とするとGUI使わないほうがよさそうだな
まぁ今の段階ではそれでいいか
0024おれさま ◆6CTEZS59O00a
垢版 |
2018/09/16(日) 05:24:18.81
GUIアプリで
開始ボタンを押すことで毎日定時に処理するようにする
停止ボタンを押すことで定時処理を停止させる

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

thread
interrupt

とか使うといけそうなんだけど、いろいろと問題も起きそうで
それを回避するための仕組みがイマイチ難しい
0025おれさま ◆6CTEZS59O00a
垢版 |
2018/09/16(日) 06:31:50.45
おれの作った最初のソフトウェアでけたああああ
ショボイけど

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

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

おれの環境は時々IPアドレスが変わるんで
いつ変ったのか知りたくて自動で記録していくフリーソフトないかなと探してたんだけど
よさそうなのがなかった
単純な動きなので自分で作れたらなぁと思ってた
0026おれさま ◆6CTEZS59O00a
垢版 |
2018/09/16(日) 06:52:59.02
問題はタスクスケジューラが正常に動いているかだ
壊れちゃってたのが治ってなければ意味なし
0027おれさま ◆6CTEZS59O00a
垢版 |
2018/09/16(日) 06:57:46.00
どうやらタスクスケジューラでjar実行ファイルを起動するときは
javaw -jar C:\〜パス〜\test.jar
みたいにしないといけないみたいだ
exe化してもいいんだけどどうしようかな
0028おれさま ◆6CTEZS59O00a
垢版 |
2018/09/16(日) 08:38:25.45
うーむ
不思議なことにexe化してもしなくてもタスクスケジューラから起動すると挙動がおかしい
一瞬コマンドプロンプトが表示されて、
System.out.prinlnで指定した文字列が見えるからプログラムの一部は動いている感じはする
でもテキストファイルを作ってくれない

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

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

バッチファイル噛ませばいけるならそれでいいか
0029Mr.名無しさん
垢版 |
2018/09/16(日) 12:25:29.72
1個しょぼいの作ったらPythonに目移りしてきた
どどどどどどどどどどどしようかすら
0030Mr.名無しさん
垢版 |
2018/09/16(日) 12:52:03.01
GUIを作りたいんだよな
そうするとWPFとかいうのがヒットする
C#なのか
そうなのかそうなのか
どどどどどどどどどどどどどどどしようかすら
0031おれさま ◆6CTEZS59O00a
垢版 |
2018/09/16(日) 12:54:51.38
てかもう1個Javaでしょぼいのつくろうかな
今欲しいプログラム思いついた
0032Mr.名無しさん
垢版 |
2018/09/17(月) 16:17:28.90
時計作った
USA東部時間をサマータイム込みで知りたいこと多いから常時表示させるやつ

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

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

一応しばらくはJava中心だけど気が向いたらほかのもやろう
すっきりの実践編を読み終えたいな
入門編も完全に自分のものにしたとも言えないし
0034おれさま ◆6CTEZS59O00a
垢版 |
2018/09/19(水) 18:17:12.26
HTML・CSS・Javascript関連の初心者本に浮気してる
HTMLはずいぶん昔に多少勉強したことあるんだけど、
当時はいかに見せるかに力点がおかれてたと思う
今は最初から入力欄やボタンやらを紹介するのな
利用してもらうってのが先にある
ずいぶん変ったもんだ
0035おれさま ◆6CTEZS59O00a
垢版 |
2018/09/20(木) 14:35:13.38
作った時計プログラムのタイトル消して
ウィンドウごとDDして移動させたり、右クリックメニュー付けて終了できるようにしたりしてるんだけど
なんだかググって適当にコピペしてるだけでなんとなくできてしまうのはいいんだろうか・・・

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

大体欲しかった機能付けられた
前回閉じた場所で開く機能をつけたらほぼ完成だな
0036おれさま ◆6CTEZS59O00a
垢版 |
2018/09/22(土) 04:29:28.68
機能追加のために足りない知識を補う目的で部分的に実践編読んでるんだけど
やっぱネットと違って説明がしっかりしてていいわぁ
ちゃんと読む価値あるなといまさらながら思った
最低限実践編までは読まないと、無駄に時間食う
0037おれさま ◆6CTEZS59O00a
垢版 |
2018/09/22(土) 06:21:38.35
前回閉じた場所で開く機能も付けた
iniファイルを作って座標を保存しておくタイプにしたんだけど
ファイルが消えちゃったとか中身がおかしくなっちゃったときとか
いろんなトラブルに対処できるようにするとなかなか難しい
ある程度対処できたけど、まだ完全じゃない
0041おれさま ◆6CTEZS59O00a
垢版 |
2018/09/23(日) 17:37:04.06
単純にテキスト流して読んで問題といて頭に入っていくかというとそうでもない

そこで、
簡単な機能ではあるけど、自分が必要だと思うコードがふんだんに含まれる
プログラムを用意してこれを何度も書いて覚えることにする
学習の骨格がないと肉付けする過程でぐらぐらゆれちゃってなかなか覚えられないんで
骨格部分をちょっと頑張って頭にいれよう
0042おれさま ◆6CTEZS59O00a
垢版 |
2018/09/26(水) 12:35:48.85
ウィンドウ操作とかいろいろできるようになってきた
おもろいなぁ
APIレファランスだっけ、だんだん読めるようになってきた
もう一度すっきり入門編の後半読み直したいな
あの辺大事だわ
0043おれさま ◆6CTEZS59O00a
垢版 |
2018/09/26(水) 14:23:00.29
ヤフーの天気予報を表示するようなwindowsアプリってどういう風にサーバから情報を得てるんだろうと思ったんだけど、
ヤフーがそのためのAPIを提供してるんだな
おそらくアプリ作った人が自分が運用してるサーバで情報取得する
配布した個別のアプリはそのひとのサーバに接続して情報取得する
こんな感じなのかな
ヤフーに直接接続するとなるとアプリケーションIDとやらが必要となるそうなので現実的ではないんで、こういう感じで間接的に情報取得してそうだ
もし自分だけで利用するアプリつくるなら、ID登録後に直接ヤフーから情報取得すればよさそう
0045おれさま ◆6CTEZS59O00a
垢版 |
2018/09/28(金) 11:52:36.88
天気予報を常時表示してくれるソフトは昔から使っているんだけど
そのソフトの情報取得先のヤフーが提供するデータに明日の天気がないらしい
そのため明日の天気が表示されない

そこで、明日の天気だけを表示するちっこいソフトをつくろうかと思う
APIを使うとたぶん同じことになるんでHTMLから適当に抽出してやろうと計画してる
しかしだ、頻繁にHTMLを変えられてしまうとなかなか難しいかもしれない
0046おれさま ◆6CTEZS59O00a
垢版 |
2018/09/28(金) 14:08:41.84
http と https ではHTMLの取得方法を変えないといけないのか
文字化けするから文字コードがらみでいろいろ調べてたんだが違っていた

URLクラスではなく
URLConnectionクラスを使ったらHTML取得までうまくいった
0047おれさま ◆6CTEZS59O00a
垢版 |
2018/09/28(金) 14:22:15.84
いや、ちがうな・・・
URLクラスでいける
この辺はいつか解決する課題として残そう

char型使って読み込んでいく最も入門的なコードだと、どこかで文字がおかしくなる
StringBuilderが原因かと思ったがそうでもなさそうだ
0048おれさま ◆6CTEZS59O00a
垢版 |
2018/09/28(金) 15:50:56.60
ふぅ・・・ひとつひとつ壁があるわい
お天気マークの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);
とするのが正解
0049Mr.名無しさん
垢版 |
2018/09/28(金) 21:36:43.11
おれさま!がんばってるな!見ているからこれからも頑張って
0051おれさま ◆6CTEZS59O00a
垢版 |
2018/09/29(土) 12:41:59.91
https://dotup.org/uploda/dotup.org1654406.jpg
まだ途中だけど、こんな感じでいく
アイコンはヤフー天気からそのまま借用
データは全部普通にヤフー天気開いた時に取得するHTMLから
必要な部分切り出して利用した
ヤフーがURLやらHTMLの中身を変えちゃうと表示できなくなる
でも自分で作って自分でしか利用しないからこれで十分だ

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

どの機能もいままで作った2つのプログラムから借用できるので大した事はない
0052おれさま ◆6CTEZS59O00a
垢版 |
2018/09/30(日) 08:09:39.53
機能完備して完成



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

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

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

となってしまう
本来は

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

とならなければならない

どうやら * は「よくばり」らしくて、途中で > が表われてももっと後ろに > があれば
まだまだいけるだろーとどんどん先へ進んで行ってしまうようだ
それが分かったあと、まぁ正確にタグで区切る必要も無いだろうと考えて
< 記号でsplitしてたんだけど・・・・・
0053おれさま ◆6CTEZS59O00a
垢版 |
2018/09/30(日) 08:15:37.26
<.*?>

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

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

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

これを「最短一致」という
デフォルトは「最長一致」なのだが、最長もこれはこれで使えそうだ
最短一致は正確には→の方向に進んでいく場合の最短一致で
逆方向には働かないので注意
0054おれさま ◆6CTEZS59O00a
垢版 |
2018/09/30(日) 08:17:47.37
>>52を修正
要素番号0 ちんちん</div><p>まんまん
要素番号1 (なし)

↑間違い 正確には↓

要素番号0 div>ちんちん</div> (改行記号が入る) <p>まんまん</div
要素番号1 (なし)
0056おれさま ◆6CTEZS59O00a
垢版 |
2018/09/30(日) 08:24:33.56
おれが今使わせてもらってる誰かが作ったお天気表示ソフトなんだけど
iniファイルをみたら、おれが利用してるヤフー天気のHTMLと同じURLが書いてあった
とすると、このソフトはおれと同じようにHTMLを加工して作っているのでは・・・

もしそうならヤフーがHTMLを改変し、おれのお天気表示ソフトが正確に表示されなくなったタイミングで
このソフトも同じ症状を見せるんではないかと思う
もちろんHTMLの分析の仕方いかんで、そうとも言い切れないだろうけど、観察してみる価値ありだ
0057おれさま ◆6CTEZS59O00a
垢版 |
2018/09/30(日) 08:27:04.70
ちなみにだけど、
<.*?> でタグを表現する方法は不完全らしい
しかし、その不完全さを理解するにはもうちとHTMLやらweb系の知識がいるようなので後回しにしていこう
0058おれさま ◆6CTEZS59O00a
垢版 |
2018/09/30(日) 08:28:56.47
>>54を修正
要素番号0 div>ちんちん</div> (改行記号が入る) <p>まんまん</p
要素番号1 (なし)
0059おれさま ◆6CTEZS59O00a
垢版 |
2018/09/30(日) 08:32:14.87
そういや気温表示がなかった
これ付けておきたいな
特にこれからの季節寒いんで
0060おれさま ◆6CTEZS59O00a
垢版 |
2018/09/30(日) 11:09:23.22
複数ラベルについて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時間ですわ
0061おれさま ◆6CTEZS59O00a
垢版 |
2018/09/30(日) 12:18:48.20
main factory already defined

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

隣のサブフォルダにコピーするとかなんたらこうたらのを選択
0063おれさま ◆6CTEZS59O00a
垢版 |
2018/09/30(日) 13:30:49.27
祝日自体そう多いわけでもないから
内閣府が出してる振替休日込み祝日等のcsvをそのまま使うっていう手もあるな




ん〜
そういえば定期的な実行にthreadとsleep使ってたんだけど
これはあまり良くないとかいうのを読んだ
もう少し基礎力アップさせてから次のソフトに挑んだ方が良いのかもしれない
今のままでもいろいろ作れることは分かったけど、もう少し基礎知識の幅の広さが欲しい
0064おれさま ◆6CTEZS59O00a
垢版 |
2018/09/30(日) 16:02:53.01
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でうまくいくのだ・・・・(と今のところ思っておこう
0065おれさま ◆6CTEZS59O00a
垢版 |
2018/09/30(日) 16:13:25.61
インターフェースはインスタンス化できないだけで
インターフェースの変数は作れるということかな
ActionListener al
みたいのはそういうもんか


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

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

  }
 }
);
みたいなやつ
これもActionListenerをnewしてるからおかしいじゃん!って思うんだけど
ぐぐってみたら、これは、みためはインターフェースActionListenerをnewしてるようで
実はActionListenerを継承した匿名クラスをnewしてるんだそうだ
0066おれさま ◆6CTEZS59O00a
垢版 |
2018/09/30(日) 16:23:42.24
すっきり入門を読んでいる段階では、
オブジェクト指向というものはわかりやすくメンテしやすいコードを書くための技法であって
一歩先へ進みたいなら理解しておいたほうがいいよって程度に思えたんだけど

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

まぁまだ理解仕切れてないし忘れちゃってる部分もあるんで読みなおそっと
0067おれさま ◆6CTEZS59O00a
垢版 |
2018/09/30(日) 16:50:27.99
MainクラスにActionListenerを実装させない方法だと、

btn.addActionListener(new al());
として、これとは別に実際の処理を任せるクラスをつくる
public class al implements ActionListener {
 public void actionPerformed(ActionEvent e) {
 
 }
}
こういうのがどちらかというと基本のコードだから
>>65の匿名クラスのnewというのは、ここでいう al みたいのをnewしてるってことか
0068おれさま ◆6CTEZS59O00a
垢版 |
2018/10/02(火) 11:34:06.14
jarのままだとタスクマネージャやらにファイル名が表示されないから
基本的にはexewrapを使ってexe化している
しかし何度もコマンドプロンプト開いてうだうだ繰り返しやってると煩わしいので
D&Dして処理するできるようバッチファイルを作った

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

久々にバッチファイルについてぐぐってみたんだけど
意外といろいろ出来ちゃうんだということを思い出した
0069おれさま ◆6CTEZS59O00a
垢版 |
2018/10/02(火) 12:00:56.09
パネルの上にもう一枚枠線だけで中身は透明のパネルをかぶせることで
すこしだけおしゃれにしてみた

この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);
0070おれさま ◆6CTEZS59O00a
垢版 |
2018/10/02(火) 12:05:53.56
たぶんLayoutにも関連してくるんだと思う
今のところだけど、

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

としてある
0071おれさま ◆6CTEZS59O00a
垢版 |
2018/10/02(火) 13:07:09.74
フォントの種類っていろいろあるけど今までほとんど気にしたことなかった
デフォルトで表示される日本語フォントがあまりに変なのでメイリオっていうのに変更した
0072おれさま ◆6CTEZS59O00a
垢版 |
2018/10/02(火) 14:19:25.74
すっきり入門読み直してるんだけど
windowsアプリ作ってる時になんどかstatic関連のエラーが出た
なんとなく適当にやったら切り抜けられたんだけど
ちゃんと頭に入れないといけない

いつも忘れるのは

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

ということ。
何度かこれでつまずいたんだけど、そのうちの一つがthread関連の処理をしたとき
threadはまだちゃんと理解できてなくて、それが原因というのもある
threadを使うだけの簡単なプログラムをつくれと言われたら簡単なんだけど
自分がそれまで書いたコードを前提にして、そこにthreadを組み込もうとするといろいろ制約が出てきて難しくなっていくのだ
0073おれさま ◆6CTEZS59O00a
垢版 |
2018/10/02(火) 14:55:27.22
そもそもスレッドは鬼門なのだ
すっきりでも実践編の最後に触れているだけで
入門編しか読んでないおれが立ち入ってはいけない領域だったのだ
しかしスレッドを利用しないとなるとさらに難しいコードを書かなければならなさそうだったので
あえて踏み込まざるを得なかった

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

メインに使うクラスを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クラスのインスタンスを生成するときに
処理系クラスのインスタンス変数を引数として渡すことになる
0074おれさま ◆6CTEZS59O00a
垢版 |
2018/10/02(火) 15:10:03.70
しかし、おれが何もわからないまま参考にしたコードではメインのクラスはこう宣言されていたのだ
先ほど書いたものをもう一度書くが、これだ

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("この辺に処理内容を書く");
 }
}
0075おれさま ◆6CTEZS59O00a
垢版 |
2018/10/02(火) 15:17:30.36
で、結局なんの話だったかというと
そう、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();
  }
 }
}

が、これはエラーが出てしまうのだ
0076おれさま ◆6CTEZS59O00a
垢版 |
2018/10/02(火) 15:30:26.10
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();
  }
 }
}

しかしだ!これでもエラーが出てしまい頭を抱えてしまうだ
0077おれさま ◆6CTEZS59O00a
垢版 |
2018/10/02(火) 15:40:22.85
犯人は 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();
  }
 }
}

しかしだ〜、まだこれでもエラーが出てしまう
0078おれさま ◆6CTEZS59O00a
垢版 |
2018/10/02(火) 15:54:14.10
ようやくここで、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();
  }
 }
}

これでようやく解決したのだ、ちゃんちゃん!
0079おれさま ◆6CTEZS59O00a
垢版 |
2018/10/02(火) 15:58:54.16
こやって書いているとあやふやだったところが見えてくる
実際のコードはずっと長く複雑なので、焦点を絞って小さく書き直すとなかなかいい
解決策はいろいろあるんだろうが、今の知識の範囲内で理解のできる解決策を見つけられるといいのではないかと思っている

間違えて理解しているところはあるだろうが
こうやって書いて残しておけば、そのうち気づくときもくるだろう
0081おれさま ◆6CTEZS59O00a
垢版 |
2018/10/03(水) 13:33:30.22
staticがつくと、インスタンスが全く生成されてないのにアクセスできることになる
そのためインスタンス生成されて始めて使えるようなメンバを呼び出すことはできないし
許してはだめなのだ
だからエラーがでるのだ!
0082おれさま ◆6CTEZS59O00a
垢版 |
2018/10/03(水) 14:18:29.06
ボタン押すと・・・・系

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

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("あ〜ん");
 }
}
0083おれさま ◆6CTEZS59O00a
垢版 |
2018/10/03(水) 14:28:04.79
おれのイメージだと
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全体
リュックの肩紐がインスタンス生成の式

みたいな・・・
0084おれさま ◆6CTEZS59O00a
垢版 |
2018/10/03(水) 14:33:15.80
ボタンを押すと・・・

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



これが基礎の基礎のイメージ
ここがちゃんとできてないとすらすら書けない
0085おれさま ◆6CTEZS59O00a
垢版 |
2018/10/03(水) 14:36:24.58
https://www.javadrive.jp/tutorial/event/index1.html
イベント処理の流れを間単に確認しておきます。

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


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



ボタン押すと、ボタンからActionEentのインスタンス e が自動生成されるイメージ・・・・
0086おれさま ◆6CTEZS59O00a
垢版 |
2018/10/03(水) 14:41:32.69
>>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("あ〜ん");
 }
}
0087おれさま ◆6CTEZS59O00a
垢版 |
2018/10/03(水) 14:58:41.37
>>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("あ〜ん");
 }
}
0088おれさま ◆6CTEZS59O00a
垢版 |
2018/10/03(水) 15:19:45.16
今は覚えちゃったから迷わないけど
ここはよく迷った

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クラスから生成しようとする。そしてこのインスタンスはまた・・・・以下同様

このさまは実際にコードを実行してみるとコンソールでみられる
0089おれさま ◆6CTEZS59O00a
垢版 |
2018/10/03(水) 15:23:39.16
ちなみにおれはSwing Javaと格闘してるのだが
最近よくきいている音楽はSwing Jazz


だから何?????とか言わないで
0090おれさま ◆6CTEZS59O00a
垢版 |
2018/10/03(水) 15:43:14.36
>>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);とするのは理屈としては間違えていないのだが
本来の使われ方からするとおかしいのでじゃばがくるくるぱ〜になってしまうのである
0091おれさま ◆6CTEZS59O00a
垢版 |
2018/10/03(水) 15:54:40.97
あーそういえば思い出した

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

>>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枚開くことになって面白い
そういうプログラム作る時に使えそうだ
0092おれさま ◆6CTEZS59O00a
垢版 |
2018/10/04(木) 10:20:57.63
そして最後に、
>>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);
 }
}
0093おれさま ◆6CTEZS59O00a
垢版 |
2018/10/04(木) 10:28:01.87
  //@+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)
0094おれさま ◆6CTEZS59O00a
垢版 |
2018/10/04(木) 10:51:55.08
この辺を理解するにはある原則的なルールを覚える必要が出てくる

このような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変数にアクセスすることは許されないのだ
0095おれさま ◆6CTEZS59O00a
垢版 |
2018/10/04(木) 10:56:23.17
まぁだからこそ「匿名」クラスという名前がついている

new AA が
クラスAAをnewするというのであれば
AAって名前あるじゃん・・・となる
しかし
new AA が
クラスAAを継承した名無しクラス
または
インターフェースAAを実装した名無しクラス
をnewするという意味だとしたら
まさに匿名っすよね!
0099おれさま ◆6CTEZS59O00a
垢版 |
2018/10/05(金) 12:37:34.40
さて、今日からは

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

について再考する

この処理はすでに作ったソフトで利用してはいるが
理解を深めるために他の処理とは独立した形でとりだして分析すべきだと思っている
先を急いだため、コピペでしのいだ部分もあり、
部分的には理解できていない可能性があるのだ
0100おれさま ◆6CTEZS59O00a
垢版 |
2018/10/05(金) 12:53:55.83
ところで、なぜ右クリからの終了処理が必要になったのかというと
windowsアプリは通常タイトルが表示される枠部分がある
そしてこのタイトルの右の端には最小化・最大化・閉じるボタンがあるのだ
閉じるボタンがあればわざわざ右クリから閉じる機能を作る必要もない

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

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

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

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

今回は1.について分析をしていこうとおもうとる
0101おれさま ◆6CTEZS59O00a
垢版 |
2018/10/05(金) 16:01:38.75
分析大体終了

右クリして閉じる機能は大きく2つに分けて考えるといい
イベント処理が2つあるのでこの2つを分けて考えるのだ

イベント処理というのはつまり >>82-85 と同じ
モナーが肩紐を肩にかけてリュックを背負ってるイメージ
これが2段構えになっている
モナーが背負ったリュックの上に別のモナーが別のリュックを背負ってる感じ

一つ目の処理は
右クリックをして何かが起きるまで

二つ目の処理は
項目がポップアップし、「閉じる」を選択することでフレームが閉じるまで
0102おれさま ◆6CTEZS59O00a
垢版 |
2018/10/05(金) 16:04:25.90
>>83だけどちょい間違えてるな

Aを媒介にして
@のbtnさんがBの処理系全体を背負ってるような感じ
 ↓
@を媒介にして
AのbtnさんがBの処理系全体を背負ってるような感じ
0103おれさま ◆6CTEZS59O00a
垢版 |
2018/10/06(土) 07:51:35.99
最も基礎的なコードを書こうとして逆に迷う

これまでdispose()をプログラム終了のために使ってきたが、Mainとは別のクラスから使おうとするとなかなかうまくいかない
System.exit(0); を使う事で問題を回避できたのだが、原因はなんだったのかなといろいろ考えてる

このサイトでの記載がキーになるのではないかと思っている
http://www2n.biglobe.ne.jp/~fify/shiroutoshikou/java/api/java/awt/Frame.htm

終了処理にはSystem.exit()ではなくdispose()を使っています。
System.exit()はJava仮想マシンの終了を意味しますが、
dispose()はメソッド呼び出し元のウィンドウおよび、
そこから呼び出されているすべてのコンポーネントを解放し、
メモリ資源をOSへと返却します。ここで行いたいのは
Java仮想マシンの終了ではなくFrameを閉じることなので、
dispose()を使うのが作法的にも正解です。

クラスの内部でさらにクラスを定義していることに注意してください。
ここで、先ほどのクラスWinLのようにメソッドwindowClosing()を
オーバーライドしたクラスを用意してフレームを表示するクラスから呼び出そうとしても、
コンパイルエラーとなります。なぜなら、メソッドdispose()は
抽象クラスWindowAdapterおよびその親クラスには実装されていないからです。
メソッドdispose()が実装されているのは、Frameの親クラスであるjava.awt.Windowとなります。
0104おれさま ◆6CTEZS59O00a
垢版 |
2018/10/06(土) 07:56:02.00
やはりよくわからない
が、まぁいいだろう
今回焦点を当てたいのは終了処理ではないのだ
0105おれさま ◆6CTEZS59O00a
垢版 |
2018/10/06(土) 07:57:52.12
さて、気を取り直して、
右クリから終了するコードを書く
これがおれ史上もっとも基本的なコードとして頭にたたき込んでおくものとする

public class Main extends JFrame {

static JPopupMenu pm = new JPopupMenu();//C

Main() {
setSize(100, 100);
setLocationRelativeTo(null);

MyMsListener ml = new MyMsListener();//A
addMouseListener(ml); //@

MyAcListener al = new MyAcListener(); //G
JMenuItem mi = new JMenuItem("閉じる");//E
mi.addActionListener(al); //F
pm.add(mi); //D
}

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

class MyMsListener implements MouseListener { //B
public void mouseClicked(MouseEvent e) {
if(SwingUtilities.isRightMouseButton(e)) {
Main.pm.show(e.getComponent(), e.getX(), e.getY());
}
}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
}
class MyAcListener implements ActionListener { //H
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
0106おれさま ◆6CTEZS59O00a
垢版 |
2018/10/06(土) 08:00:15.68
いや、タブを全角スペースに直すの忘れてたんで再度こぴぺ

右クリから終了するコードを書く
これがおれ史上もっとも基本的なコードとして頭にたたき込んでおくものとする

public class Main extends JFrame {
 
 static JPopupMenu pm = new JPopupMenu();//C
 
 Main() {
  setSize(100, 100);
  setLocationRelativeTo(null);
  
  MyMsListener ml = new MyMsListener();//A
  addMouseListener(ml); //@
  
  MyAcListener al = new MyAcListener(); //G
  JMenuItem mi = new JMenuItem("閉じる");//E
  mi.addActionListener(al); //F
  pm.add(mi); //D
 }
 
 public static void main(String[] args) {
  Main ma = new Main();
  ma.setVisible(true);
 }
}

class MyMsListener implements MouseListener { //B
 public void mouseClicked(MouseEvent e) {
  if(SwingUtilities.isRightMouseButton(e)) {
   Main.pm.show(e.getComponent(), e.getX(), e.getY());
  }  
 }
 public void mousePressed(MouseEvent e) {}
 public void mouseReleased(MouseEvent e) {}
 public void mouseEntered(MouseEvent e) {}
 public void mouseExited(MouseEvent e) {}
}
class MyAcListener implements ActionListener { //H
 public void actionPerformed(ActionEvent e) {
   System.exit(0);
 }
}
0107おれさま ◆6CTEZS59O00a
垢版 |
2018/10/06(土) 08:35:28.74
>>106
おれの感覚では

T @〜Bが右クリから何かを起こすまでの処理
U C〜Hが右クリメニューがポップアップしてから実際のプログラム終了までの処理

というように2つの段階があると捉えている


Tは
@(JFrame).addMouseListenerのモナーが
A肩紐ml宣言を通じて
BリュックであるMouseListenerを実装した実際の処理を背負っている
イメージで捉える

フレーム全体にわたってマウスの動きを感知する機能が加えられる
フレーム上でマウスがクリックされると、その震動 e が肩紐Aをつうじて
リュックにつたわりBの実際の処理へとつながる
このとき e がマウスのどの種類のクリックだったのかを分析して
if 文により、それぞれの処理を個別に指定できる
ここでは e が右クリにより生じたとするなら、pmを特定位置でshowしろと指示する


Uは
CDEpmが何なのを説明し、miまでつながる道筋を示す
Fmi.addActionListenerのモナーが
G肩紐al宣言を通じて
HリュックであるActionListenerを実装した実際の処理を背負っている
イメージで捉える


CDEは一応Uに含まれるようなイメージで捉える
Tでの実際の処理としてpmがshowするのだが
pmを宣言するのがC、pmとはJPopupMenu
つまり右クリしたときにぽよんとあらわれる「あれ」の本体とイメージする
「あれ」(JPopupMenu)は当初は姿形がなく、
ここに項目JMenuItemが加えられることで目視できるようになる
JMenuItemは今回のプログラムでは1個だけで、「閉じる」 の項目を示すために使う
「他地域の天気」などの別の項目を加えたいのであれば複数のJMenuItemを宣言し
これを、目では見えないがぽよんの本体であるpm(JPopupMenu)にaddすることになる

mi(JMenuItem)は宣言時に表示文字列をコンストラクタに渡すことになる
そしてこのmiがTのモナーが背負うリュックのさらに上に立つモナーとなるのだ

このmiは>>82-85のbtnと全く同じ位置づけと考えればよい
Fmi.addActionListener(al);というモナーが
G肩紐al宣言を通じて
Hリュックである実際の処理を背負う構図だ

「閉じる」の項目をクリックしたとたんに震動 e がFモナーの足元で生じ
これがGを通してHに伝わり、最終的に e を受けとったactionPerformedメソッドが
System.exit(0)を実行し、プログラムが終了するのだ
0108おれさま ◆6CTEZS59O00a
垢版 |
2018/10/06(土) 08:48:05.81
このコードの形式を前提とするなら
右クリメニューを増やすごとに
D〜Hを変数名等を変えて書き足すことになる

しかし、これでは面倒ではないか?コードが読みにくくなるのではないか?
という批判に応えるため、クラスを活用したコードを書くのが一般的のようだ
0109おれさま ◆6CTEZS59O00a
垢版 |
2018/10/06(土) 08:50:36.77
ただし、それはもう少し後に回すことにして
>>106を匿名クラスを使って書き直したものを貼ることにする
イベント系の処理は基本的には匿名クラスを使って書くようにしていこうと思っている

public class Main extends JFrame {
 
 JPopupMenu pm = new JPopupMenu(); //C
 
 Main() {
  setSize(100, 100);
  setLocationRelativeTo(null);

  addMouseListener( //@
   new MouseListener() { //A+B
    public void mouseClicked(MouseEvent e) {
     if(SwingUtilities.isRightMouseButton(e)) {
      pm.show(e.getComponent(), e.getX(), e.getY());
     }      
    }
    public void mousePressed(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
   }
  );
  
  JMenuItem mi = new JMenuItem("閉じる"); //E
  mi.addActionListener( //F
   new ActionListener() { //G+H
    public void actionPerformed(ActionEvent e) {
      System.exit(0);
    }
   }
  );
  pm.add(mi); //D
  
 }
 public static void main(String[] args) {
  Main ma = new Main();
  ma.setVisible(true);
 }
}
0110おれさま ◆6CTEZS59O00a
垢版 |
2018/10/06(土) 09:07:46.99
>>107
修正

BリュックであるMouseListenerを実装した実際の処理を背負っている

BリュックであるMouseListenerを実装したクラスMyMsListenerが実際の処理を背負っている


HリュックであるActionListenerを実装した実際の処理を背負っている

HリュックであるActionListenerを実装したクラスMyAcListenerが実際の処理を背負っている
0111おれさま ◆6CTEZS59O00a
垢版 |
2018/10/06(土) 09:16:12.97
さて、先ほど書いた 「クラスを活用したコード」 とは、匿名クラスのことではない
自作のクラスを作成し、自作クラスのインスタンスを複数生成することで
複数の右クリメニューを作って行くという方法である
このタイプの書き方をすることで、右クリメニューの項目が
各インスタンスのnewごとに羅列されるため、見た目わかりやすい

しかし、おれみたいなレベルのプログラマーにとっては匿名クラスで書いた>>109を前提に
右クリメニューを増やしたほうがわかりやすかったりもする
メモリの使い方なんやらでやはり自作クラスを使うべきなんだろうが。

匿名クラスでメニューを増やすなら
D〜Eのブロックをメニューごとに増やすことになる
もちろん変数名などは変えていかねばならぬ
0112おれさま ◆6CTEZS59O00a
垢版 |
2018/10/06(土) 09:30:34.08
例えばこんな感じだ

最終的な処理がより複雑になりコードが長くなった場合
わかりにくいコードになってしまう点は否定できないのだが

public class Main extends JFrame {
 
 JPopupMenu pm = new JPopupMenu(); //C
 
 Main() {
  setSize(100, 100);
  setLocationRelativeTo(null);

  addMouseListener( //@
   new MouseListener() { //A+B
    public void mouseClicked(MouseEvent e) {
     if(SwingUtilities.isRightMouseButton(e)) {
      pm.show(e.getComponent(), e.getX(), e.getY());
     }      
    }
    public void mousePressed(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
   }
  );
  
  JMenuItem mi = new JMenuItem("閉じる"); //E
  mi.addActionListener( //F
   new ActionListener() { //G+H
    public void actionPerformed(ActionEvent e) {
      System.exit(0);
  }});
  pm.add(mi); //D
  
  JMenuItem mi2 = new JMenuItem("サイズを大きくする"); //E
  mi2.addActionListener( //F
   new ActionListener() { //G+H
    public void actionPerformed(ActionEvent e) {
      setSize(300, 300);
  }});
  pm.add(mi2); //D
  
 }
 public static void main(String[] args) {
  Main ma = new Main();
  ma.setVisible(true);
 }
}
0113おれさま ◆6CTEZS59O00a
垢版 |
2018/10/06(土) 09:34:35.47
ちなみに、「サイズを戻す」 というメニューを追加すると
5チャンで書込みがロックされてしまうため項目は2つに留めておいた
繰り返し似た文を書くと駄目なようだ

ロックされた場合は
https://agree.5ch.net/mango/
この板で試行錯誤を繰り返しながら原因把握ができる


コードは繰り返しの文が多くなるので引っかかりやすいかもしれない
0114おれさま ◆6CTEZS59O00a
垢版 |
2018/10/06(土) 09:48:48.02
Javaでつくったwindowアプリの右クリメニューがひどいデザインなのは仕方ないのか?
Swingだとこうなってしまうのか、、、、?
0115おれさま ◆6CTEZS59O00a
垢版 |
2018/10/06(土) 16:00:19.81
右クリから閉じる機能の説明はまだ終わってないのだが
>>100に書いた 「ウィンドウをD&Dで動かす機能」 について先回りしてざっとみている

自分が書いたコードは試行錯誤しながらコピペしまくったせいか
不必要な部分がいくつも見つかった

D&D移動機能については別の機能との関連もあって、頭の中でまったく整理できていない
とくに注目しなければならない「別の機能」とは、
前回閉じた位置で開く機能である

この機能は大まかに説明すれば
ウィンドウを閉じるときにiniファイルに現在座標を記録し
次に開くときにiniファイルから座標を読み込んで、同じ位置に開くというものだ

と、書いたのだが正確にいうとiniファイルに書き込むタイミングはウィンドウを閉じる時ではない
プログラムは予期せぬトラブルによって終了してしまうおそれがある
そこで、ウィンドウ位置が動いた場合、そのたびにiniファイルに場所を記録するのだ
こうすることでトラブル対策になる

そのためD&D機能との関連が大事になるのだ

ちゃんとまとめれば、そう難しいものではないと思うのであせらずやっていこう
すべての機能が整理できたあと、もう一度最初から全部書き直すといいのだが
その気があればやることにしよう
0116おれさま ◆6CTEZS59O00a
垢版 |
2018/10/07(日) 04:33:03.57
>>108
>>111
の修正

「クラスを活用したコード」
は間違いだった
実際に書いてみたところ、クラスではなく、「メソッドを活用したコード」だった
右クリメニューの項目を増やすごとに
文字列とActionListenerのインスタンスをメソッドに引数として渡す
0117おれさま ◆6CTEZS59O00a
垢版 |
2018/10/07(日) 04:42:50.17
実際に書いていくとこういうものになる
>>109をさらに発展させたといえるのだろうか

public class Main extends JFrame {
 
 JPopupMenu pm = new JPopupMenu(); //C
 
 Main() {
  setSize(100, 100);
  setLocationRelativeTo(null);

  addMouseListener( //@
   new MouseListener() { //A+B
    public void mouseClicked(MouseEvent e) {
     if(SwingUtilities.isRightMouseButton(e)) {
      pm.show(e.getComponent(), e.getX(), e.getY());
     }      
    }
    public void mousePressed(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
   }
  );
  addMi("閉じる",
   new ActionListener() {//G+H
    public void actionPerformed(ActionEvent e) {
     System.exit(0);
  }});
  
  addMi("サイズを大きくする",
   new ActionListener() {//G+H
    public void actionPerformed(ActionEvent e) {
     setSize(300, 300);
  }});

 }
 public static void main(String[] args) {
  Main ma = new Main();
  ma.setVisible(true);
 }
 public void addMi(String name, ActionListener al) {
  JMenuItem mi = new JMenuItem(name);//E
  mi.addActionListener(al);//F
  pm.add(mi);//D
 }
}
0118おれさま ◆6CTEZS59O00a
垢版 |
2018/10/07(日) 04:58:55.11
>>117は、@〜Cまではこれまでと同じなのだが、それ以降のD〜Hが違う

まだ目に見えないJPopupMenuに各項目を加え実際の処理につなげていく部分なのだが
そのうち、GActionListener実装クラスのnewとH実際の処理部分だけを項目ごとに書き、
言い換えると、G肩紐とHリュック部分だけを項目ごとに書き、
その他の部分は共通部分としてメソッドにまとめることになる

こうすることで>>112のように項目を増やすごとに変数をあらたに作っていく必要がなくなる

正直言ってこうすることでどれだけのメリットがあるのかは、今のところよく分からない
右クリメニュー機能をつくるために検索した結果、
お手本としたのがこの手のタイプのコードだった
これを理解することを目標に書いてきたので、とりあえず目的達成ということでいいだろう
これから先、右クリメニューのコードを書くときは
これをベースに書いていけるといいなと
0119おれさま ◆6CTEZS59O00a
垢版 |
2018/10/07(日) 05:26:49.45
次に行こう

ウィンドウのD&D移動である
これまで書いてきた処理のほとんどはイベント系の処理だ
D&D移動もイベント系の処理の一つである
パターンがつかめてくると、理解するまでのスピードが速くなってくる

D&D移動の処理も3つのイベントに区分できる

T マウスを押す
U そのままマウスを動かすことでウィンドウがうごく
V マウスを放す

それぞれの処理を引き受けるインターフェースは
T MouseListener
U MouseMotionListener
V MouseListener
ということになる

TとUは同じMouseListenerを使うため、コードはまとめることができるだろう
0120おれさま ◆6CTEZS59O00a
垢版 |
2018/10/07(日) 05:31:13.22
ウィンドウD&D移動

public class Main extends JFrame {
 
 static Point pt;
 
 Main() {
  setSize(100, 100);
  setLocationRelativeTo(null);
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  
  addMouseListener(
   new MouseListener() {
    public void mouseClicked(MouseEvent e) {}
    public void mousePressed(MouseEvent e) {//@
     pt = e.getPoint();
    }
    public void mouseReleased(MouseEvent e) {//B
     pt = null;
    }
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
   }
  );
  addMouseMotionListener(
   new MouseMotionListener() {
    public void mouseDragged(MouseEvent e) {//A
     Point currentPt = e.getLocationOnScreen();
     setLocation(currentPt.x - pt.x, currentPt.y - pt.y);//
    }
    public void mouseMoved(MouseEvent e) {}
   }
  );
 }
 
 public static void main(String[] args) {
  Main ma = new Main();
  ma.setVisible(true);
 }
}
0121おれさま ◆6CTEZS59O00a
垢版 |
2018/10/07(日) 05:58:02.92
一気に匿名クラスを使った最終版を書いたわけだが
基本的にはこれまでとパターンは同じだ

細かい処理が違ってくるだけだ
まずここで使っているPointというクラスが大事だ
簡単にいえばデスクトップ上の(x, y)座標を格納してくれるインスタンスを生成できるクラスなのだ
正確にいうと、デスクトップ上の(x, y)座標は絶対座標というが、
Pointのインスタンスは相対座標も格納できる
今回使われる相対座標は、マウスをウィンドウ内でクリックしたとき、マウスの座標を
ウィンドウの左上端から測った相対座標である

Pointインスタンスに格納された座標をStringで表示するには
Point pt = new Point();
pt = e.getPoint();
を前提とするなら
System.out.prinln(pt.x);
System.out.println(pt.y);
System.out.println(pt);
のどれでもOKだ。一番下のものはtoStringの機能が自動で使われており便利だ

相対座標を取得するメソッドはgetPoint()
絶対座標を取得するメソッドはgetLocationOnScreen()

どちらもActionEvent e つまり「震動」の発生地点の座標を測ることになるので
e.getPoint()
e.getLocationOnScreen
のように e を基準としてコードを書くことになる


T〜Vの処理を細かく見ていく

T→@
マウスを押すことでウィンドウ左上端から測ったマウスの相対位置をptに格納
相対座標はAで使うためにここで取得している

U→A
ドラッグするごとに変化するマウスの位置をcurrentPtに格納していくと同時に
currentPtに応じてウィンドウの位置を設定していく
setLocationにはウィンドウの左上端となる座標を渡さないといけないので
currentPtから相対座標分だけずらした座標を計算してわたすことになる
マウスの座標をそのまま渡してはいけない点に注意しなければならない

V→B
ptにnullを入れる
ちなみにB処理だが、pt = null; をコメント行にしても正常に動いた
pt = null:が必須なのかはよくわからない
少なくとも、ptを他の処理に使い回したい場合にはこうして置いた方がよいのかなと思った
0122おれさま ◆6CTEZS59O00a
垢版 |
2018/10/07(日) 06:19:32.74
yahooから明日のお天気を取得するソフトがらみで
おさらい分析しなければならない最後の部品に取りかかろう

「前回閉じた場所に開き直す」 機能

テキストファイルに座標を書き込む・読み込む
ウィンドウ位置が変ったときにiniファイルに座標をかき込むなど
まだ苦手としている処理が含まれている
0123おれさま ◆6CTEZS59O00a
垢版 |
2018/10/07(日) 07:49:42.28
そのまえに座標の取得について

e からx座標、y座標を取り出す方法なのだが
さきほど使ったのは一旦Pointインスタンスに格納する方法
相対座標に絞って説明するが

Point pt = e.getPoint():
int x = pt.x;
int y = pt.y;

Pointインスタンスを使わないでも
e から直接x座標、y座標を取り出すことは可能だ

int x = e.getX();
int y = e.getY();

これは「右クリから閉じる機能」>>117で使ったものだ
2つの方法を混同して使わないようにしなければならない

ところで、この方法どちらもだが、相対座標を取り出すのに使われるのだが
何を原点(0, 0)とするのかを明確にする必要がある
これについては
「発生元のコンポーネントを基準とする、イベントの相対 x、y 座標値」
と考える
ここでいう発生元とは、e がどこから発生したのか、である

btn.addActionListener 
ならbtnということになるのだろう
btnの左上端を基準に測ってくれるのだろうか(未確認)

this.addMouseListener
this.addMouseMotionListener 
ならthisということになる
このthisだが、>>120では使ってはいないものの
コンストラクタの中にあるaddMouseListenerやaddMouseMotionListener
の前にthisをつけるのが本来の書き方じゃないかと思っている
実際、エラーはでない
thisは「自分自身のクラスのインスタンス」を意味するため、ここでは ma がそれにあたる
MainがJFrameを継承しているから、maはJFrameのインスタンスでもある
つまり
this.addMouseListenerとした場合の e の発生元はthis=ma=JFrame=フレームそのものと考えられる
こうすることで
この場合の e.getX()は
フレーム(ウィンドウ)の左上端を原点とした場合のマウス位置の相対座標をかえすことになる
0124おれさま ◆6CTEZS59O00a
垢版 |
2018/10/07(日) 08:46:22.97
ついでなのだが、右クリ閉じる機能>>117
pm.show(e.getComponent(), e.getX(), e.getY());

showメソッドは、JPopupMenuを表示するためのメソッドである

「イベントを発生させたComponentオブジェクト」内の
(x, y)座標で指定された位置にJPopupMenuを表示する
(x, y)はレファランスで読む限り相対座標でなければならないようだ

e.getComponent() は「イベントを発生させたComponentオブジェクト」を取得
e.getX() は「イベントを発生させたComponentオブジェクト」内での相対座標xを取得
e.getY() は「イベントを発生させたComponentオブジェクト」内での相対座標yを取得

少し脱線するのだが
getComponent()について疑問が残った

ActionEvnetのインスタンスである e についてのメソッドだろうと思って
ActionEventを調べてみたところこのようなメソッドはなかった
どうやら、ComponentEventという別のクラスのメソッドであるようだ
ComponentEventはActionEventによって継承なり実装されてるのかとおもいきや、そうでもない
なぜ e.getComponent() という書き方ができるのか、今の知識では理解できない
これは後回しにしておこう
いずれ理解できるのかもしれない
0125おれさま ◆6CTEZS59O00a
垢版 |
2018/10/07(日) 11:50:34.72
>>124はちょっと勘違いしてた

>>117
pm.show(e.getComponent(), e.getX(), e.getY());
で使っている e はActionEventではなくてMouseEventだった
MouseEventをAPI referenceでみてみると

java.awt.event
クラスMouseEvent

  java.lang.Object
     java.util.EventObject
        java.awt.AWTEvent
           java.awt.event.ComponentEvent ←ここ
              java.awt.event.InputEvent
                 java.awt.event.MouseEvent ←ここ

となっており、MouseEventの親のそのまた親にComponentEventがある
つまり、この繋がりがあるからMouseEventのインスタンス e はComponentEventで
定義されている getComponent()メソッドを利用できるというわけだ

実際にreferenceにもこう書いてある

クラス java.awt.event.ComponentEventから継承されるメソッド
getComponent

な〜んだな〜んだ
そう難しい話ではなかった
0126おれさま ◆6CTEZS59O00a
垢版 |
2018/10/07(日) 12:39:28.20
またまたついでだが
>>117の自作メソッドを使ったパターンについて自分なりのとらえ方というか考え方を書く

自作メソッドの部分
 public void addMi(String name, ActionListener al) {
  JMenuItem mi = new JMenuItem(name);//E
  mi.addActionListener(al);//F
  pm.add(mi);//D
 }
モナーがリュックを背負っている形をつくり
さらにそのモナー全体がJPopupMenuに加わるという
メインの処理は、ここだけで終わっていると考える

そのうえで、addMiを呼び出すこの部分↓はどう捉えるのかというと

  addMi("閉じる",
   new ActionListener() {//G+H
    public void actionPerformed(ActionEvent e) {
     System.exit(0);
  }});

メインの処理の中で、ある変数を利用することで詳細を省いた部分がある
そこを埋めるため、あとからジグソーパズルのピースをはめ込むような処理を担っているとする

欠けていたピースは2つあり、
一つは
本来JMenuItemインスタンス生成時にコンストラクタに
渡すはずの項目名称をnameという変数をつかって空欄状態にしてあった部分
もう一つは
本来addActionListenerの引数として実際の処理を含めた形で匿名クラスのインスタンスを
渡すはずが al という変数を使って空欄状態にしてあった部分

この2カ所に実際のピースをはめたのがaddMiの呼び出し部分と捉えることにする
0127おれさま ◆6CTEZS59O00a
垢版 |
2018/10/07(日) 12:50:20.67
基礎レベルのコードからいくつかの高度化を経てたどり着いた雛形となるコードは
そらで書けるようになんどか繰り返して書くことにする
ただし、インターフェース実装によりオーバーライドが必要なメソッド群については
eclipseのTODOに頼ることにする
import文も同様にeclipseに頼ることにする
それ以外は何も見ずに書けるようにする

Swingは今後どう扱われているかはわからないものの、
今となっては時代遅れな代物に成りはてている
Java自体もそうなりつつあるのかもしれない

しかし、今後どのような言語を学んでいくとしても
Javaに代表されるような主要言語の体系は引き継がれていくと予想される

JavaのSwingを使った時はこういう風に書いたなという明確なイメージが
頭にあるのとないのとでは全く違ってくるのではないか
そこでいくつかの基本パターンについてはしっかりと暗記してしまおうと思っている
0128おれさま ◆6CTEZS59O00a
垢版 |
2018/10/07(日) 15:39:47.30
>>122にとりかかっているんだけど今知ったことがある

https://www.sejuku.net/blog/20794
プログラミング言語のなかでもC++などは、拡張子を「.ini」とした設定ファイルを
読み書きする関数が用意され、それを利用しています。
Javaの場合は、拡張子が「.properties」のプロパティファイルに定数などの
規定値や、ファイルのパスなどをまとめて記載し、読み書きするのが一般的です。



な、なんだって〜
iniファイルってC系の設定ファイルだったのか
Javaではpropertiesを使うとは!

もしかして〜と思って実践編をぺらぺらめくってみたら10章に書いてあった
あれかね、やっぱりこの一冊ちゃんと読んでから分析したほうがいいかな
0129おれさま ◆6CTEZS59O00a
垢版 |
2018/10/08(月) 14:16:47.38
properties便利だわぁ
iniよりずっと難易度下がった

前閉じた場所で開くコードは長くなるんで、今のところはここには書かない
プログラムを大きく分けるとこうなる

T プロパティファイルを読みにいってウィンドウを開く部分
U ウィンドウが動くたびに変数に数値を格納して閉じるときにプロパティファイルに記録する部分

Tについてプロパティファイルを読むためにクラスを自作して
座標と幅・高さに関するフィールドを置く
このクラスはmainメソッドはなく、フィールドに値を突っ込むためのコンストラクタだけ。

Uでプロパティファイルに記録する部分は、Mainクラス内にメソッドを設ける


読み込む時だけクラスをつくって書き込む時はメソッドにしたのは何となく書きやすかったと理由にすぎない
0130おれさま ◆6CTEZS59O00a
垢版 |
2018/10/08(月) 14:22:21.54
もう一つだけ暗記のベースにするためのコード作っておくか

HTMLを取得してタグで分割して配列に格納する

これだけやったらテキストに戻ろう
0131おれさま ◆6CTEZS59O00a
垢版 |
2018/10/09(火) 07:46:04.44
ウェブスクレイピング(英: Web scraping)とは、
ウェブサイトから情報を抽出するコンピュータソフトウェア技術のこと。
ウェブ・クローラーあるいはウェブ・スパイダーとも呼ばれる。
0132おれさま ◆6CTEZS59O00a
垢版 |
2018/10/09(火) 14:39:29.35
ひょんなことからWSH windows shell hostのVBScriptをちょっとだけやってみた
HTML取得したりもできるのかな?と思って調べてみたら
HTMLを専門に扱う目的でプロパティやメソッドが用意されている
これはもしやJavaでもあるのではないかと思って調べてみたら、やっぱりあった

Java ウェブスクレイピング

でぐぐるといろいろ出てくる

「HTMLパース」
HTMLパースとは、HTML文法規則にのっとった文字列を、その文法に基づいて字句解析し、
意味や構造を解釈することをいい、HTMLパースを行うプログラムのことをHTMLパーサといいます 

パースはparse、構文解析
parseIntのparseか

JavaのHTML paserとしては
「Jsoup」 (じぇぃすーぷ)
がいまのところ有力だそうで。
導入方法がいままでみたことがない方法だ
外部ライブラリというのかな

https://qiita.com/Terry3/items/0c1829130111967773bf
eclipseへの導入はここがわかりやすいか?
あとでやってみようか
0134おれさま ◆6CTEZS59O00a
垢版 |
2018/10/09(火) 14:52:15.89
>>133は違うな
これはScalaとかKotlinという別の言語でJsoupを利用しているようだ
Java以外からも利用できるライブラリなんだな
0135おれさま ◆6CTEZS59O00a
垢版 |
2018/10/09(火) 17:12:28.69
FileOutputStream ファイルに書く
FileInputStream ファイルを読む

逆にしてしまいがち
0136おれさま ◆6CTEZS59O00a
垢版 |
2018/10/09(火) 17:29:50.82
スッキリ実践編260ページ
FileReaderやFileWriterで、コンストラクタの引数に文字コードを指定することができると
読み取れるような文章があるんだけど、これできないよね

https://uxmilk.jp/47743
FileWriter クラスは文字コードを指定することができないので、
文字コードを指定するときは、
OutputStreamWriter

FileOutputStream
を使用します。
OutputStreamWriter のオブジェクトを生成するときに、第2引数に文字コードを指定します。
0137おれさま ◆6CTEZS59O00a
垢版 |
2018/10/09(火) 17:32:01.15
File f = new File("sample.txt");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(f), "UTF-8");
BufferedWriter bw = new BufferedWriter(osw);

bw.write("1行目");
bw.newLine();

bw.close();


こういうのを使えば簡単に人が集まるんでしょうね
じゃなくて
こういうのを使えばプロパティファイルの日本語文字化けの問題にも対処できるんかなとか思ったりしたんだけど
0138おれさま ◆6CTEZS59O00a
垢版 |
2018/10/09(火) 18:08:24.09
File f = new File("save.properties");
if (f.exists) {}

みたいな感じでFileクラス使ってきたけど
Path と Files を使っていくことにした

Path p = Paths.get("save.properties");
if (Files.exists(p)) {}

ポイント:
・Pathはインターフェースなのでインスタンスをnewできない
その代りにPaths.get()を使う事でPathインスタンスを取得する
・Filesはインスタンスを生成しないでクラスを直接使ってメソッドにアクセスする

ぶっちゃけFileを使った方がわかりやすいんだが
0139おれさま ◆6CTEZS59O00a
垢版 |
2018/10/09(火) 19:16:12.35
public static final String st = "あああ";

定数であることはfinal修飾子だけで表現できますが、
static修飾子を付けるのがお作法です。static修飾子を付与することで、
インスタンス生成のたびに同じ値をインスタンスにコピーするのを防ぐことができます。


インスタンス生成のたびに同じ値をインスタンスにコピーするのを防ぐことができる
インスタンス生成のたびに同じ値をインスタンスにコピーするのを防ぐことができる

これ大事
0140おれさま ◆6CTEZS59O00a
垢版 |
2018/10/10(水) 02:34:35.36
パブリックスタティックファイナルストリング!すたっ!ああああああああぁぁぁぁぁっぁ!!!!
(変身
0141おれさま ◆6CTEZS59O00a
垢版 |
2018/10/10(水) 09:31:15.40
プロパティファイルの読み書きに関してはみんないろいろ工夫してるんだな
いろんなコードみてきたんだけど、おれの用途だと
技が高度すぎてちょっとここまでしないでもいいかなと思えるものが多い
部分的に参考にしたらよさそうなのはあった

読み込みのクラス作って
コンストラクタでPropertiesをnewしてloadするところまでやる
このクラス内でゲッターみたいなメソッドを作って引数にキー名を指定して
戻り値で値を返すみたいな。

書込みについてはまだ調べてないが
書込みのクラス作ってから
コンストラクタでPropertiesをnewしておいて
セッターみたいなメソッド作って、引数にキー名と値を指定とかかな
値に関しては最終的にはStringにしないといけないんだけど
当初はintだったりStringだったりするわけだから
型によって複数のメソッド作ったりするんかな
0142おれさま ◆6CTEZS59O00a
垢版 |
2018/10/10(水) 09:41:36.02
https://nompor.com/2017/11/26/post-1430/
2018/08/03・・・PropertiesにはReaderやWriterを引数にすることもできます。こちらを利用して文字コードを指定すれば、日本語の表示も可能です。

どこかに同じようなことが書いてあったけど
ちょっとやってみよう
じゃなぜみんなFileReaderやFileWriterを使うんだろうかと思うと
やはりデメリットがあるんだろうな
0143おれさま ◆6CTEZS59O00a
垢版 |
2018/10/10(水) 10:03:14.29
>>141
いやいや、書込みをこの方法で作っちゃうと
インスタンス生成したのはいいがメソッドを使わなければcloseされないという問題が起きるぢゃんか

メソッド単位でFileWriterのnewとclose処理すれば良いんだけど
newというものはそこそこ重い処理だなんてことをどこかで見て以来
こういう連続した処理でそのたびにnewするのはだめなのかなとか思っちゃう
どうなのかね
0144おれさま ◆6CTEZS59O00a
垢版 |
2018/10/10(水) 10:09:22.18
と、ここまで考えて気づいたのは、closeしないまま終わるのは
書込みだけじゃなくて読み込みもだ

参考にしたコードをもう一度見直してみたんだけど
なんと、このコードはFileWriterとかFileReader使ってない
結局closeの問題を避けるためにこういう方法があるのかな
0145おれさま ◆6CTEZS59O00a
垢版 |
2018/10/10(水) 10:20:40.84
ん〜やっぱりわかんないや
お手本のコードもう一度見直したらthrows IOExceptionしてる
読み込みや書込みのクラス内で例外処理も完結してくれないといやだいやだ
0146Mr.名無しさん
垢版 |
2018/10/11(木) 13:09:23.80
お天気表示ソフトが3時間おきに天気取得にでかけるんだけど
これを、何時に起動したとしても、1回目の取得のあとは
0:05
3:05
6:05
みたいに3の倍数の時刻の5分後にとりにいくようにコードを書き直そう
0147おれさま ◆6CTEZS59O00a
垢版 |
2018/10/11(木) 13:11:45.62
CalendarのgetInstanceメソッドは、Calendarオブジェクトを返しますが、
このカレンダ・フィールドは現在の日付と時間に初期化されています。

Calendar rightNow = Calendar.getInstance();

現在日時の取得するのにDateクラスのインスタンス生成に頼る必要はない
0148おれさま ◆6CTEZS59O00a
垢版 |
2018/10/11(木) 14:08:14.05
時刻の引き算は一度Dateをlongに変換する

Date d = new Date();
long l = d.getTime();

で変換終わり

getTime()は
CalendarからDateへの変換でも使うし
Dateからlongへの変換でも使うので混同しないように!

ちなみに
CalendarインスタンスのgetTime()、setTime()はともにDateがらみだが
get()、set()はCalendar内部のフィールドがらみメソッド
0150おれさま ◆6CTEZS59O00a
垢版 |
2018/10/11(木) 15:15:03.74
threadについて

MainクラスはRunnableを実装している
Threadインスタンスとしてthrdを宣言して

mainメソッドで
thrd.start();

public void run() {}
の中で
thrd.sleep(1000);

とするとエラーなしで実行はできるものの注意マークがついていて気になっていた
要はstaticの問題

API referenceをみてみると
static void sleep(long millis)
システム・タイマーとスケジューラが正確であることを前提として、
現在実行中のスレッドを、指定されたミリ秒数の間、スリープ(一時的に実行を停止)させます。

となっていてsleep()メソッドはstaticがついている

しかし、staticの基本として、
static宣言されているフィールドやメソッドには
インスタンス変数名で呼び出しても→thrd.sleep();
クラス名で呼び出しても→Thread.sleep();
どちらでもOKなはず
(スッキリ入門367,368ページ)

なぜクラス名が推奨されるのかはよく分からないが
すくなくともクラス名を使うと注意マークが消えることはわかった
0151おれさま ◆6CTEZS59O00a
垢版 |
2018/10/11(木) 15:28:59.05
おまけだが
static関連で制限される事項として

staticがついているメソッド内でフィールドやメソッドを使う時は
そのフィールドやメソッドはstaticでなければならない

つまり>>150の例で言えば、sleep()にstaticがついているから
sleep()の中でフィールドやメソッドを使う時は・・・・
ということになる

が、sleep()はおれが作ったものじゃないから制限されるといわれても困るわけで
今回の問題とは無関係
0152おれさま ◆6CTEZS59O00a
垢版 |
2018/10/11(木) 15:44:05.19
おれのプログラムだとメインのクラスが

public class Main extends JFrame implements Runnable {}

と宣言されていて、MainにRunnableを実装している
なので、Mainクラスのなかにpublic void run()をオーバーロードする目的で設置することになる

もし1つではなく2つスレッドを作りたい時は
MainにRunnableを実装するのではなく

スレッド用に2つ新しいクラスを作って、これらがRunnableを実装する(またはThreadを継承)
それぞれのクラスの中にpublic void run()をおいて処理内容を書いていくとわかりやすいかな
0154Mr.名無しさん
垢版 |
2018/10/12(金) 04:53:03.08
今どきjavaでGUIって笑
そもそもWindowsアプリなら.NET使えよ

ちなみに俺はプログラミング始めて1年ほどだが、PythonのBeautifulSoupでスクレイピングした株価データをMongoDBに永続化し、javaのspringbootで指定された統計データを公開するWEBアプリをVPS上で運用してるから、そこら辺の質問あったらアドバイスしてやるよ
0155Mr.名無しさん
垢版 |
2018/10/12(金) 04:56:31.10
ちなphp(&laravel)とjavascriptも基本的なことならわかるから質問あったらどーぞ
0156Mr.名無しさん
垢版 |
2018/10/12(金) 05:48:39.33
>>152ってどういうこと?
MainクラスがJFrameを継承してRunnableを実装するなんてあり得ない
設計がおかしすぎる

何を作りたいのか知らんがMVCのよくある設計パターンで、ControllerクラスにRunnableを実装したロジック(model)のインスタンスと、JFrameを継承したインスタンスを生成して、JTextfieldなりにsetすればいいんじゃないのか?

それとsleepがstatic云々言ってるが引数がプリミティブ型なんだから、何の関係もない
ちゃんとリファレンス読んだ?
0157おれさま ◆6CTEZS59O00a
垢版 |
2018/10/12(金) 13:51:28.32
まぁまぁ落ち着いて。
基礎的な動きを確認しながらプログラミング練習してる段階なんでね
これはこうしなければならないみたいなものより
これはこうしても動くし、こうやっても動くみたいな知識が面白いんだよ

javaでGUIってwなんていうけど
メーヴェを作って空を飛ぼうとしてるひとに向かって
空飛ぶならヘリコプターかセスナ使えよ!って言ってるのと同じだよ
ゴールに到達するまでの時間を競うつもりもないし。
プログラミングを仕事にしたらそういう世界になっていくんだろうけど
それってつまんないだろうなと思うんだ
せっかく面白い道具があるのに使い方を縛られるなんてね

>>156
どういうレベルから助言をくれてるのかわからないからどう答えるべきなのか迷うんだけど
まず問題なく動いているということが大事で
今作ったものを土台にいろいろ考えていけるといいなと思ってるよ

https://www.javadrive.jp/tutorial/jframe/index5.html
extends JFrame にかんしてはこれ

>ただし、上記のようにした場合、mainメソッドが含まれるSampleクラスは
>単にmainメソッドが存在するだけのクラスとなってしまいます。その為、
>通常はmainメソッドが含まれるクラスそのものをJFrameクラスの
>サブクラスにする方法が取られます。

このサイトではクラス名はSampleだけど、おれのだとMainのままになってるだけ。
おれはね、これ読んだ瞬間に面白いなぁって思ったんだけど。
自分とこのクラスにextendsして自分とこのmainメソッドで自分のインスタンス生成するとかさ
Swingではこれ普通なの?面白いじゃん
じゃ俺もこれ使おうと思ったんだけどね。
基礎レベルのおれには継承やら実装やらの感覚掴むのに悪くないなって思ってる
ちなみにイベント系のインターフェースも全部Mainに実装させたらMainの行があほみたいに長くなったね
今は匿名クラス使ってるけどね

Runnableも同じようなもんだよ

で、あとsleepか
そもそも起きた問題と何をしたら解決したのかがちゃんとそっちに伝わってるかわからないし
何を問題と捉えて助言をくれているのかもわからないからちょっと難しいよ

もし助言くれるなら、なぜthrd.sleep()だと注意マークがでてThread.sleep()だと出ないのかに
焦点を絞ったもので。引数がどうのこうのの話はそもそもそこが問題の原因ではないだろうと
目星を付けて適当に書いただけで。
問題にしているのはsleepの引数ではなくて、
sleepメソッドがインスタンスから呼び出される場合と
クラスから呼び出される場合の違いなんだ

だれかに何かを伝えるためにここに書いているというよりも
自分が見直した時に参考になる程度にしか書いてないから
いろいろ誤解を与えてるようですまんね

このときはこういう風に考えてたけど、間違ってたなとか、
逆に大事な事忘れてたなとか、あとで見たら面白そうじゃん

>>153
( ^ー゚)b
0158おれさま ◆6CTEZS59O00a
垢版 |
2018/10/12(金) 15:00:32.61
ツールチップで次回取得予定の時刻表示させようとしたけど
右クリメニューとかち合うみたいなんでやめやめ
右クリメニューに表示させるかな
いずれにしてもRun()メソッドがらみなんでちょいめんどくさそう
こんなことやる前に、これまでまとめ上げた内容でもう一度作り直してスッキリさせたほうがいいかもしれん
右クリメニュー関連のコードが迷走してるし
0159おれさま ◆6CTEZS59O00a
垢版 |
2018/10/12(金) 15:04:13.11
あとあれだなぁ
ScheduledExecutorServiceを習得したいね
めんどくさそうだったから、一番簡単な処理方法に逃げてきたんで
0160おれさま ◆6CTEZS59O00a
垢版 |
2018/10/13(土) 05:31:12.81
お天気取得ソフトのエラーがたまに起きるので修正
0時回って5分後に取得しようとすると明日の日付がhtml上にまだ表示されてないようだ
このへん適当にコード書いたんで
日付がないときの分岐処理がなかった
String.containsみたいな処理書くときは忘れないようにしないとな
分岐させないと常にエラーがでるようなものだとすぐに気づくんだけど
たまにしかエラーがでないものだと忘れ去ってしまう

表示されたエラーの内容は半分忘れてしまったんだけど
Stringの配列要素番号として -1 が返されてた
明日の日付が見当たらないと -1 を返してくるようだ
0161おれさま ◆6CTEZS59O00a
垢版 |
2018/10/13(土) 05:59:39.35
いやいや違う

>>160修正
containsは分岐処理でかくものだ
エラーの原因はindexOf()で起きてる
indexOfに渡す引数が見当たらない時にエラーだ
0162おれさま ◆6CTEZS59O00a
垢版 |
2018/10/13(土) 10:54:27.87
ウィンドウのD&D移動で、
MouseListenerの
public void mousePressed(MouseEvent e)での処理なんだけど
いつも間違えるのは、コンポーネントの中での相対座標を取得するコード
JFrameを継承するクラス内だからComponentのメソッドで「も」ある
getX()やgetY()を前置きなしにそのまま使えるんだけど
ComponentのメソッドとしてのgetX()、getY()は相対座標取得のメソッドではない

getX()
コンポーネントの原点の現在のx座標を返します。

なんとなく掴みづらい表現なのだがコンポーネントの左上端の絶対座標を意味してる(と思う)

x = getX(); はダメ。ウィンドウ左上端の絶対座標をとってきてしまう
x = e.getX(); が正解。eを生んだコンポーネントであるJFrameの左上端を原点としたマウスプレス点の座標を取得できる

>>120では、この辺の処理は
pt = e.getPoint();
をつかっており、x と y をばらばらに取得していない
ばらばらに取得するならここで書いたように e.getX()、 e.getY() を使うことになる
0163おれさま ◆6CTEZS59O00a
垢版 |
2018/10/13(土) 15:07:40.61
package privateのクラスをよく使うんだけど
スッキリ入門のどこに書いてあったか探し出せなかったんだけど
やっとみつかったわ
カプセル化のところだ
0165おれさま ◆6CTEZS59O00a
垢版 |
2018/10/14(日) 06:03:39.80
タイトルなしのウィンドウを作り
D&D移動・右クリから閉じる・前回開いた場所で開き直す

こんだけはそらで書けるようにした
いろんな要素が含まれてるから基本覚えるには役に立つ
特にイベント処理は
ActionListener
MouseListener
MouseMotionListener
WindowListener
ComponentListener
が含まれていて練習としては悪くない
Propertyファイルの取り扱いも基礎レベルでしかないけど
しっかり覚えたんで今後に使えそう

またテキストに戻るか
0166おれさま ◆6CTEZS59O00a
垢版 |
2018/10/14(日) 06:12:05.76
Main.class-----------------

public static void Main

class Aaa

class Bbb

---------------------------
これはOK

Xxx.class-------------------

class Aaa

class Bbb

----------------------------
これもOK

クラスはpublicとpackage privateしかない
デフォルトはpackage private
0168おれさま ◆6CTEZS59O00a
垢版 |
2018/10/14(日) 08:41:33.92
iPhoneアプリ作っても実機にいれようとすると年間1万ぐらい払わないといけないと聞いて
作るならandroidアプリだなと思っていたんだけど
よくよく調べてみるとすでに数年前から自分のiPhoneに入れるだけなら無料でいけるようだ
いずれにしてももう少し先の話だ


2. プログラミング言語

アプリを開発する上で最も重要なプログラミング言語。
Androidアプリで主に利用されるのはJavaとC++ですが、
2017年にはオフィシャル言語としてKotlinも追加されました。
iOSアプリは主にobjective-Cが使われますが、
より多くの人がiOSアプリを作れるようにと2014年にSwiftが
オフィシャル言語に追加されています。
0170おれさま ◆6CTEZS59O00a
垢版 |
2018/10/15(月) 12:46:38.43
いいでしょ

Xamarin(「ザマリン」と読みます)は、C#を用いてiOSとAndroidのアプリケーションを
開発するためのライブラリおよび開発環境です。
XamarinはMicrosoftよりVisual Studioの一部として提供されています
0171おれさま ◆6CTEZS59O00a
垢版 |
2018/10/15(月) 12:58:20.37
●iOSアプリ
プログラミング言語 Objective-C Swift
開発環境 Xcode
開発に使用するOS Mac

●Androidアプリ
プログラミング言語 Java
開発環境 Android Studio Eclipse
開発に使用するOS Windows Mac



Xamarin

プログラミング言語 C#
開発環境 Visual Studio(Windows)もしくは Xamarin Studio(Mac)
開発に使用するOS Windows Mac

Windows上では、Visual Studioという非常に優れた開発環境を
利用してiOS/Androidアプリを開発することができます
(注: 詳しくは後述しますがiOSアプリをビルドするには別途Macが必要になります)。




って結局Macいるってことかいな
さすがに無理ですわ
0172おれさま ◆6CTEZS59O00a
垢版 |
2018/10/15(月) 17:05:33.63
abstractクラスを継承したときに、
abstractなメソッドをオーバーライドして確定することを
「実装する」と表現する

これが「実装」という言葉の基本

インターフェースを実装するというのは
インターフェースに含まれるabstractなメソッドをオーバーライドして確定するからこそ
こういう表現が使われる
0173おれさま ◆6CTEZS59O00a
垢版 |
2018/10/15(月) 17:10:34.45
eclipseでかき込んだメソッドやクラスにカーソルを合わせてから
F3を押すとそのメソッドやクラスの宣言が表示される 中身をみられる
F4を押すと階層構造をみることができる
0175おれさま ◆6CTEZS59O00a
垢版 |
2018/10/17(水) 07:55:17.33
オラクルの決定以後、Java周りはざわざわしてて
おれもこの先どうするか考えつつ勉強してる

とりあえず実践編読み終わってからちゃんと決めようとは思ってるが
できたら実践編の次にある2冊を読みたい
Javaそのものの勉強に限らず、サーバやらデータベースやら、
この辺の一般的な知識を頭に入れるいい機会なんじゃないかと思う
他の言語に行くのはいいんだけど、また一からやったら深い所に行くまでにまた時間かかってしまう
言語の勉強だけにいつまでも時間費やせないんで、選択に迷うところだ

すでにJavaScript、C#、pythonの入門本は買ってあるんで
ちょいちょい浮気しながら様子を見ていこうと思ってる
0177おれさま ◆6CTEZS59O00a
垢版 |
2018/10/18(木) 14:47:45.14
ZonedDateTimeは実践編で紹介されていたのか
この辺の新しい日付の処理方法は便利だな

newできないものが多いから注意か

既に作ったプログラムで
DateとThreadを使っているものがあるんだけど
正しく動作しないことがあると書いてある
ふむむ
0181Mr.名無しさん
垢版 |
2018/10/20(土) 03:48:27.50
eclipseでimport文いれるのがめんどくさくなってきた
マウスをクラス名に合わせてポップアップから選択してたんだけど
もっと簡単な方法があるはずだと思ってしらべてみた

まず、* を使って省略して一気にimportすることにした
ウィンドウ→設定→Java→コードスタイル→インポートの編成
.*に必要なインポート数
これが99になってたので1にする

インポートの追加([Ctrl] + [Shift] + [M]) 1個ずつimport
インポートの編成([Ctrl] + [Shift] + [O]) 一気に全部import

これでずっと楽になるはず
0183おれさま ◆6CTEZS59O00a
垢版 |
2018/10/20(土) 13:58:19.34
空白を示す正規表現に \s というものがある
これをこうやって使ってみるとエラーがでる
boolean b = "abc def".contains("\s");

これだとエラーがでない
boolean b = "abc def".contains("\\s");

ここに理由が書いてあった
https://teratail.com/questions/31841


が、\n だと \\n にしないでも動く
理由の解明は後回しにすることにする
とりあえず正規表現で \\ としないと駄目なことがあるということで。
0184Mr.名無しさん
垢版 |
2018/10/20(土) 14:08:51.80
典型的な本読んだだけで理解したつもりになってるタイプだな
入門編読み終わったんならオブジェクト指向で簡単なアプリで作ったら?
DBの代わりにファイルに読み書きするToDoリストやクリックすると月が替わるGUIカレンダーとか
本当に理解してるならこのくらい簡単に作れるはず
それもできないのに正規表現やThreat知っても成長しないぞ
0186おれさま ◆6CTEZS59O00a
垢版 |
2018/10/20(土) 15:52:45.04
インプットとアウトプットは両方大事だね
これはどんな勉強にも言える

入門編読んでから
4つ作って常時起動してるPCでずっと動かしてる
もちろん入門テキストの知識だけでは作れないものなので
いろんなサイト巡って知識かき集めて作ってある

今やってるというか、つい最近までやっていた作業は
最後に作ったプログラムから自分が気に入った機能を実現するコードを抜き出して
雑だったものをもう少ししっかりしたものに組み直す
こんな風にしてお手本コードとしていくつか作っておく
そして、こいつらを何も見ずにざっと書けるようにする
書くたびに所々アレンジを加えていろいろ試して見る
ということをやってた
一つが大体300行程度のコードか

これは結構楽しい
ベースとなるコードは毎日同じなんだけど、理解が深まって悪くない

正規表現はずっと昔からいろんな所で使ってきたんだけど
もちろんプログラミング始める前の話ではある。
覚えようと思ってはいたんだけど、使う機会が年に数回であとはコピペでいけちゃって
なんとなくうやむやにしてて、しっかり頭に入れてなかった
なんというか、正規表現には思い入れがあって、是非自分のものにしたいなぁと。
ちょいちょい毎日のアレンジに組み込んで使っているのだ

数日前からはテキストを読み進めている
アウトプットは楽しいけど、インプットも進めないと知識の幅が広がらない
スカスカな知識でもいいから、こういう事ができるんだということをなんとなく覚えていると
アウトプットとしてソフトを作っているときに選択肢が広がる
0187Mr.名無しさん
垢版 |
2018/10/20(土) 16:11:20.02
具体的にどんなアプリ作ったんだ?
もしかして>>160みたいなの?
0188おれさま ◆6CTEZS59O00a
垢版 |
2018/10/20(土) 16:34:18.61
ちなみにカレンダーはそのうち作ろうと思っている
上のほうですでに書いたんだけど、今デスクトップ上で表示してるカレンダーが
日本の祝日や振替休日を正確に示していないので、代用品が欲しい。
その辺から拾ってこれば早いんだけどそれじゃなんだし。

ところで、プログラムを作ってて思うのは、自作のクラスの
インスタンスを何個も作って活用するという場面はなかなか出くわさないということ。
いや、正確にいうと、そういう場面に無理やり持っていくこともできるんだけど、
無理してる感がすごくて、不自然すぎる

毎日アレンジ練習でプロパティファイルReaderクラスを作って遊んでたりする
カプセル化を施すためにフィールドをprivateにしてsetter、getterを作って
setterにはフィルターかけたりなんかするわけだけど、今までつくったような小規模ソフトだと
ここまでやっても、おいおい無理スンナよ・・・という天の声が聞こえてくる
多様性の練習でabstractクラスやinterfaceをいくつも作るのは面白い
最後にforでまわして結果がでるとすっきりする
が、練習でしかない

その点、カレンダーは日付クラスを作ると大量にインスタンス生成できたりなんかして面白そうだ
月クラスや年クラスなんかも組み込んじゃって多重構造にしちゃったりとかいろいろ想像してる
祝日やらの情報は内閣府のcsvを自動で取り込んで組み込んでもいい
おそらく今の知識で足りるだろう

じゃ、なんで作ってないのかというと、実践編の知識を組み込みたいと思ったからだ
組み込んだほうがよりコード的に面白そうなのがつくれるのであれば、だけど。
今日はコレクションの章を読んだんだけど、この辺も使えそうなら使ってみるつもりだ
日付という集合はキッチリカッチリ仕様が固まっているものなので、
曖昧さが残るデータを取り扱うのに便利そうなコレクションの知識は使えないかもしれないが。

もう一点カレンダーを作るのを遅らせている理由
今の知識だとThreadクラスに定期実行の役割を担わせていくしかない
でもThreadクラスはいろいろと問題があるようだ
既にPCで動かしている4つのソフトはどれもThreadクラスを使っていて
これ以上そういうソフトを増やすことでPCを不安定リスクに晒したくないというのがある。

これについては問題があって、ざっと見る限り実践編では解決する手段が書かれていない
ネットを漁るか別のテキストに手を伸ばすか、という話になる
コピペして流用するのは簡単だ
でも使うならコピペではなく、ちゃんと理解した上で使いたい
代用となるクラスについては上の方でも何度か書いているが
イマイチ自分の理解が浅い部分がある
この辺の理解が深まった頃にカレンダーを作るかもしれない

そう急ぐものではない
0189Mr.名無しさん
垢版 |
2018/10/20(土) 17:54:53.93
俺も入門書読んでた頃、カレンダーアプリ作ったことある

俺はMVCモデルで、viewはSwingで年月変更するボタンと7×6個のJTextFieldを用意して、そこにmodelとなる二次元配列で作った日付をcontrollerではめ込んでいくって設計にした
でも、日付の始まりは月によって違うし祝日は年によって日付が変わるからそこら辺の調整が結構悩んだな
頭で理解するのと、実際にオリジナルのアプリを作るのでは全然違うことを知った

いきなりThreat使ったアプリなんて作れるわけないんだから、まずは簡単な設計でオブジェクト指向に則ったちゃんと機能するアプリを作ってはどうよ?
0190おれさま ◆6CTEZS59O00a
垢版 |
2018/10/20(土) 18:45:27.82
兄さん、それThreatじゃなくてThreadっすよ
何度も間違えてるところからして使ったことないんだろうけど・・・・
おれの作ったアプリは全てThreadクラス利用した定期実行プログラム

兄さん・・・・

おれVBAやってたんだけど
やり始めて数ヶ月後にカレンダーをクラスモジュールとform使って作った
クリックすれば月がどんどん変っていくやつ
日付をクリックすることでその日付が起点となってエクセルの表に入っていく
おれにとってカレンダーを作る事自体はそう難しくないんだよ
VBAみたいなオブジェクト指向でない言語でクラスモジュール使って書く方がよっぽど難しいんだ・・・

てかね、そんな競争みたいのどうでもいいんだ
なんで言語やってると後ろから蹴り飛ばしながらお前のあれが悪いこれが悪いの
言う人多いんだろうか
楽しんでやろうよ?ね?
0191Mr.名無しさん
垢版 |
2018/10/20(土) 20:16:39.60
予測変換使ってたから間違い気づかんかったw

VBAってExcelのマクロを組んだってことでしょ?
そうじゃなくて一からアプリを作ったことあるのかってこと

雑学で本読んでるだけならどうでもいいけど、本気でプログラミングを学びたいなら方向が間違ってるってアドバイスしてるだけ
0193おれさま ◆6CTEZS59O00a
垢版 |
2018/10/21(日) 08:59:11.44
ArrayListのインスタンスが変更されると発生する例外
ConcurrentModificationException

いろいろと書いてみるとたまに出る
iteratorを使って回してると出た
iterator宣言文をちょい上の方に書いてしまうと出るようだ
whileの直前にしたら出ない

どうやらArrayListにaddする前にiteratorをArrayListを対象に宣言してしまうとでるみたいだ
addし終わってからwhileで回す直前にいれるようにしよう
0195おれさま ◆6CTEZS59O00a
垢版 |
2018/10/21(日) 15:19:05.05
実践編はなかなか重いな
重要なコードはそらで書けるようにしていこう
曖昧なままだと先に進んだところでつまずく
とかいいつつ、どれがほんまもんに大事なコードなのかは先に進まないと分からないのだが

一応ArrayListとHashMapの操作法は基本的な部分は頭にいれた
ジェネリスクについてより深くやっていくようなのでちょうどよかった
0198おれさま ◆6CTEZS59O00a
垢版 |
2018/10/22(月) 06:57:09.49
public static final String LS = System.lineSeparator();

改行 定数

今度からこれを使う事にする



旧版
public static final String LS = System.getProperty("line.separator");
0199おれさま ◆6CTEZS59O00a
垢版 |
2018/10/22(月) 10:09:45.11
継承関係
B a t t l e C r e a t u r e
↑            ↑
Character       Monster
↑    ↑       ↑
Hero Wizard     Slime

多様性の話
List<Character> alChar = new ArrayList<Character>();
Character c0 = new Hero("勇者あ");
Character c1 = new Hero("勇者い");
Character c2 = new Hero("勇者う");
Character c3 = new Hero("勇者え");
Character c4 = new Hero("勇者お");
Character c5 = new Wizard("魔法使いa");
Character c6 = new Wizard("魔法使いb");
Character c7 = new Wizard("魔法使いc");
alChar.add(c0);
alChar.add(c1);
alChar.add(c2);
alChar.add(c3);
alChar.add(c4);
alChar.add(c5);
alChar.add(c6);
alChar.add(c7);

List<Monster> alMons = new ArrayList<Monster>();
Monster m0 = new Slime('A');
Monster m1 = new Slime('B');
Monster m2 = new Slime('C');
alMons.add(m0);
alMons.add(m1);
alMons.add(m2);

List<BattleCreature> alBC = new ArrayList<BattleCreature>();
alBC.add(c0);
alBC.add(c1);
alBC.add(c2);
alBC.add(c3);
alBC.add(c4);
alBC.add(c5);
alBC.add(c6);
alBC.add(c7);
alBC.add(m0);
alBC.add(m1);
alBC.add(m2);

for (BattleCreature bc : alBC) {
 System.out.println(bc.getClass());
}

こうやってクラス名を取得したときにBattleCreatureではなく
中身のHero、Wizard、Slimeを表示出来ないかと思って試して見たんだけど成功
0200おれさま ◆6CTEZS59O00a
垢版 |
2018/10/22(月) 10:23:06.11
for (BattleCreature bc : alBC) {
 System.out.println(bc.getClass().isInstance(c0);
}

とすることでBattleCreatureの中身がCharacterかどうかをbooleanで戻す事ができる
c0としてあるが、これはCharacter変数であればなんでもいい
要は、Character変数に代入できるかどうかを判定してくれてる
0201おれさま ◆6CTEZS59O00a
垢版 |
2018/10/22(月) 10:24:50.00
と思ったが違うわ
c0の中身がHeroだから
Heroかどうかしか判定してくれてないな

ん〜失敗
0202おれさま ◆6CTEZS59O00a
垢版 |
2018/10/22(月) 12:36:38.25
どちらか全滅までの自動バトルプログラム完成

魔法使いカンの攻撃!
スライムAに14のダメージを与えた!(186)
スライムCの攻撃!
魔法使いトンは53のダメージをうけた!(0)
魔法使いトンは死んでしまった!
勇者ぽんの攻撃!
スライムBに0のダメージを与えた!(200)
スライムCの攻撃!
勇者ぽんは64のダメージをうけた!(36)
魔法使いコンの攻撃!
スライムBに42のダメージを与えた!(158)
魔法使いカンの攻撃!
スライムBに16のダメージを与えた!(142)
スライムCの攻撃!
魔法使いカンは127のダメージをうけた!(0)
魔法使いカンは死んでしまった!
勇者ぽんの攻撃!
スライムBに140のダメージを与えた!(2)
魔法使いコンの攻撃!
スライムBに22のダメージを与えた!(0)
スライムBを倒した!
スライムAの攻撃!
魔法使いコンは52のダメージをうけた!(0)
魔法使いコンは死んでしまった!
スライムCの攻撃!
勇者ぽんは21のダメージをうけた!(15)
勇者ぽんは逃げ出した!
勇者ぽんたちは、ぜんめつしてしまった!
0205おれさま ◆6CTEZS59O00a
垢版 |
2018/10/23(火) 13:12:01.82
WHSをずっとやってた
簡単なコードおぼえた
フォルダ作ったりファイルコピーしたり。
Javaと比べると簡単
0207おれさま ◆6CTEZS59O00a
垢版 |
2018/10/24(水) 15:52:11.45
今日は復習だけ

WSHのコード2つ
実践編のコード3つ

これだけ

実践編のジェネリクスと列挙型の練習問題、金庫にアイテム出し入れするやつ
最初見たとき一体これはなにやってんだと思ったけど、
いろいろやってたら理解できた

・自作のジェネリクス付きのクラスを使う事でいろんな型のインスタンスをを金庫に入れることができるようにする

・次に、金庫を守るためにカギとなる仕組みを作る
ここで列挙型を利用する
久しぶりのswitchがでてきて復習になった

switch (keytype) {
case LOCK :
 break;
case FINGER :
 break;
}

2つを分離して考えないといけない
0209おれさま ◆6CTEZS59O00a
垢版 |
2018/10/24(水) 16:07:34.72
実践編は各章の練習問題を解けるようにすることを目標とする
解けるというか、覚えて利用出来るようにしておく
これだけだと、テキストに書いてあることの一部しかカバーできない
でも、実践編では、最低限の重要な知識を抑えることに焦点を絞ることにする

toStringのオーバーライドとかクソつまらなさそうなのは切って捨てたいけどどうすっか
この辺は自分で使うイメージが全くわかない
コレクションのところで自然順序とかなんとかでこの辺のオーバーライドがされてないと
ダメだと説教されたんで、大事なんだろうけど

とにかく最後までなんとか読み切る
0210おれさま ◆6CTEZS59O00a
垢版 |
2018/10/24(水) 16:10:44.57
Javaでは型安全、型安全で列挙型やらやってるんだけど
WSHは変数宣言いらないわ全部Variantだわで適当もいいところだ
楽だけど
0211おれさま ◆6CTEZS59O00a
垢版 |
2018/10/27(土) 05:49:23.98
復習復習復習

Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_MONTH, get(Calendar.DAY_OF_MONTH) + 100);

のように書くと、c の日付は +100 される
これと比較したいのはLocalDateTimeクラスを使ったパターン↓

LocalDateTime ldt = LocalDateTime.now();
ldt.plusDays(100);

これだと ldt の日付は +100 されない
plusDays()をCalendarクラスのset()と同じような感覚で書くと間違える

plusDays()は戻り値がLocalDateTimeオブジェクト→オブジェクト変数に格納必要
set()は戻り値がvoid→変数への格納不要

正解は、2行目を
ldt = ldt.plusDays(100);
とすることで100日加算されたオブジェクトに置換える必要がある
0212おれさま ◆6CTEZS59O00a
垢版 |
2018/10/27(土) 05:55:24.37
同じような間違いとして

SimpleDateFormat sdf = new SimpleDateFormat("西暦yyyy年MM月dd日");
System.out.println(sdf.format(c.set(Calendar.DAY_OF_MONTH, get(Calendar.DAY_OF_MONTH) + 100).getTime()));

とするとエラー
原因は set() の戻り値をCalendarオブジェクトと勘違いしている点
もしそうであれば
c.set().getTime()
によってDateオブジェクトを取得できる
しかし
c.set()
はvoidである
よって、これにgetTime()をつなげることはそもそもできない
0213おれさま ◆6CTEZS59O00a
垢版 |
2018/10/27(土) 05:56:40.40
もう何度もやってるからわかってるわいと思ってアレンジして書くといろいろと問題が起きる
細かい部分が分かってないことがアレンジによって露呈する
0214おれさま ◆6CTEZS59O00a
垢版 |
2018/10/27(土) 06:01:38.39
そういえばすっきり入門の最初の方でこういうのを書いていた

String s = new java.util.Scanner(System.in).nextLine();

理屈はいいから覚えろみたいなことが書いてあったんだけど
覚え直した方が逆に楽になりそうだ

Scanner sc = new Scanner();
String s = sc.nextLine();

単純にScannerクラスのインスタンス生成して
nextLine()を呼び出しているだけ
importは別途必要だ
0215おれさま ◆6CTEZS59O00a
垢版 |
2018/10/27(土) 10:20:29.41
ディープクローンが難しかった
テキストと同じ形式なら理解できたんだけど
少し違った形にすると突然難しくなる

ディープクローンの必要性がある変数がprivateで
さらに、コンストラクタの引数になっているような場合

やっと練習用雛形作れたから何度も書いて理解していこうと思う

equalsやhashCodeその他のオーバーライドも組み込んだから
この辺の復習として使う
結局この辺はコレクション関連分野でもあるんで
コレクションの復習にもなる
0216おれさま ◆6CTEZS59O00a
垢版 |
2018/10/28(日) 03:59:48.27
>>183について

\n

\s

この2つはそもそも種類が違う
\n は改行で、\s は空白だから違うのは当たり前とかそういう意味じゃない
属しているグループが全然違う
\n は \t \r などと同じ「エスケープシーケンス」
\s は \w \d などと同じ「あらかじめ定義されている文字クラス」

\n

" " の中にそのまま書いただけで \n という文字そのものではなく、
「改行」として認識される

\s

" " の中に書いたときに 「 \s という文字列として認識」 された場合に
初めて特殊な意味、ここでは「空白」として認識される

もう少し詳しく書く

"\s" と書いてしまうと、\ を特殊な記号として認識してしまう
そのため、これはエスケープシーケンスの一種だな、と誤解してしまう
しかしエスケープシーケンスには \s は存在しないため、エラーとなる

「 \s という文字列として認識」 させるには \ がもつ特殊な機能を消し去って
\ そのままの文字列として認識させる必要がある
そこで、\ の前にもう一つエスケープのための \ をつける
こうすることで、 「 \s という文字列として認識」 してもらえる

つまり、あらかじめ定義された文字列を matches などで使う時は、総じて \\s \\d \\w
のような書き方をしなければならないということになる
0217おれさま ◆6CTEZS59O00a
垢版 |
2018/10/28(日) 04:01:51.70
>>216
修正

つまり、あらかじめ定義された文字列を matches などで使う時は、

つまり、あらかじめ定義された文字クラスを matches などで使う時は、
0218おれさま ◆6CTEZS59O00a
垢版 |
2018/10/28(日) 04:14:51.67
>>183の中に書いてあるURL
ここで質問している人は、おれと同じように、
\n のようなエスケープシーケンスと混同したのだと思う

回答にはエスケープシーケンスとの違いが説明しているものがない
質問した本人は分かったつもりでいるみたいだけど、
問題は解決できてないんじゃないかと思う

スッキリ実践編にもその辺を書いてくれるとよかったな
0219おれさま ◆6CTEZS59O00a
垢版 |
2018/10/28(日) 05:11:57.84
ここで疑問がもう一つ生まれる

\s が 「 \s という文字列として認識」 されたときに初めて 「空白」 と捉えてもらえる
それならば、
\s という文字列とマッチするかどうかを調べたいときはどうすんぢゃい と。

String s1 = "\\s";
System.out.println(s1);
if (s1.matches("\\s")) {
 System.out.println("s1 ok");
}

これではokはでない
s1 は \s と認識されているが
matches("\\s") の \\s は 「空白」 として認識されてしまうためマッチしない
\s と書くとエラーでるし。

今後の課題として残しておこう
0221おれさま ◆6CTEZS59O00a
垢版 |
2018/10/28(日) 05:32:20.22
>>219

String s1 = "\\s";
System.out.println(s1);
if (s1.equals("\\s")) {
 System.out.println("s1 ok");
}

これで一応おk
要は s1 で \s と認識できたわけだから
同じようなレベルで認識してもらえるようなメソッドを使えばよいだけ
そもそもmatchesでは不可能なのかもしれない

containsでもいけた
0222おれさま ◆6CTEZS59O00a
垢版 |
2018/10/28(日) 06:27:50.57
C#関連(本買っただけで何もやってないが)

ビルドの中にコンパイルがある。

コンパイル:
コンピュータが実行するのに適した形式に変えて、実行可能なファイルに変換する。

ビルド:
コンパイル+使っているライブラリに関連づける(リンク)

https://qiita.com/rico/items/9ab8aa110e757a13ef37


Visual Studio が無い Windows 環境で c# コードをコンパイルする
https://qiita.com/asterisk9101/items/4f0e8da6d1e2e9df8e14
0223おれさま ◆6CTEZS59O00a
垢版 |
2018/10/28(日) 06:34:16.89
スクリプト

簡易的なプログラムのこと。スクリプトを記述するための言語をスクリプト言語といい
、機械語への翻訳を必要とせずに実行できる。スクリプト言語は、
アプリケーション開発用の本格的なプログラミング言語に比べ、
用途を限定することで、覚えやすいように簡単な構造になっている。
代表的なスクリプト言語としては、JavaScript、PHP、Perlなどがあり、
特定のアプリケーションの動作の記述、マクロやバッチファイルの作成、
CGIなどの簡単なプログラムに用いられる。
https://kotobank.jp/word/%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88-4871


最近使ってるVBSもスクリプト言語
0225おれさま ◆6CTEZS59O00a
垢版 |
2018/10/28(日) 08:30:31.85
public class Book {
 public boolean equals(Object o) {
  if (o == this) return true;
  if (o == null) return false;
  if (!(o instanceof this)) return false;//←ここダメ
 }
}

A instanceof B

「参照型変数a が bクラス/インターフェース/配列のインスタンスかどうか」
を調べるものなので
Bにインスタンスを持ってきてはダメ

Bに来るのはこの場合だとクラス名のBook

if (!(o instanceof Book)) return false;

が正解
0227Mr.名無しさん
垢版 |
2018/10/29(月) 02:05:19.26
>>219
正規表現で\sという文字列を表すにはエスケープして\\sとなる
だがこれをそのまま引数に渡すとJVMが最初の\を文字エスケープと認識して\sという文字列に変換し、結果的に正規表現の空白文字にマッチするか検証することになる
\\sという文字列を正規表現として渡すには文字エスケープが2つ付けて、\\\\sとする必要がある
0228おれさま ◆6CTEZS59O00a
垢版 |
2018/10/29(月) 11:11:41.30
>>227
なるほどねぇ
言われてみればそうだな

String s = "\\s";
System.out.println(s);

if (s.matches("\\\\s")) {
System.out.println("ok");
}


ちなみにだけど、>>227の前半部分の説明を \n についてすると?
0229おれさま ◆6CTEZS59O00a
垢版 |
2018/10/29(月) 11:13:40.08
ラムダ式とかの6章クリア
練習問題とstream()の基本的な使い方ぐらいだけど、まぁいいか

ぐぐるとラムダ式使ってるコードってたまに出てくるから
参考にしたいときに使える知識かなとは思う
0230おれさま ◆6CTEZS59O00a
垢版 |
2018/10/29(月) 15:29:01.06
ProcessBuilder pb = new ProcessBuilder(
    "c:\\windows\\system32\\notepad.exe", "calcreport.txt");

ProcessBuilder pb = new ProcessBuilder("java", clazz.getName() );

こいつら、上が第7章198ページ、下が同じく第7章217ページ練習問題の答

上が本文内で出てきたときは、まぁこんな感じで外部のexe起動できるんだな
ああそうですか、で終わった

練習問題で下のが出てきて???????????????ですわ
一応練習問題はできるようにするという目標を立てているので、しゃーないから調べてみた

意外と簡単だった

つまりだ、
●CMDでなんかプログラムを起動するときに
>xxx yy zz
みたいに打ちこんでEnterパーン!てやるとする
ちなみにxxxはexeだったりいろいろ

●これをJavaから同じように起動したいと思うなら
ProcessBuilder pb = new ProcessBuilder("xxx", "yy", "zz");
pb.start();

具体的に書くと
●CMD
>notepad /W test.txt
●Java
ProcessBuilder pb = new ProcessBuilder("notepad", "/W", "test.txt");
pb.start();

CMDでnotepadのかわりにnotepad.exeとしてもいいのだが
これはJavaのほうでも同じで "notepad" のかわりに "notepad.exe" としてもよい
ちなみにメモ帳はパスが通ってるからCMDにおけるカレントフォルダがどこであっても
notepad.exeへの完全なパスなしで起動できる

ProcessBuilderの第一引数においても同様に絶対パスを書く必要はない
とにかくCMDでどう書くのかを参考にして書けばいいだけ

よって上に書いた1個目のProcessBuilderの宣言で
ProcessBuilder pb = new ProcessBuilder("notepad.exe", "calcreport.txt");
と書いてもいける

ただし、違いが一つある
CMDだとcalcreport.txtがカレントフォルダになければ新しく作りますか?
とのウィンドウがでる
Javaではcalcreport.txtが存在しないとエラーが生じる

2つ目の
ProcessBuilder pb = new ProcessBuilder("java", clazz.getName() );
も同様
CMDでFQCNを使ってclassファイルを実行する場合に
>java jp.co.aaa.Calc
としてEnterパーン!とするなら
Javaでは
ProcessBuilder pb = new ProcessBuilder("java", "jp.co.aaa.Calc");
pb.start();
と書く
第二引数が clazz.getName() となっているのはFQCNを取得するためだ 👀
Rock54: Caution(BBR-MD5:1341adc37120578f18dba9451e6c8c3b)
0231おれさま ◆6CTEZS59O00a
垢版 |
2018/10/29(月) 16:30:53.48
>>230の2つ目を考えるにあたって注意しなければならないこと

あくまでも ProcessBuilder は「外部」プログラムの実行に使われる
よって、
Javaのクラスファイルを実行するといっても、
外部に存在しているコンパイル済のクラスファイルの実行に使うであって
今現在組んでいるソースコードに存在する他のクラスを指定してもダメ

コードが正常に動くか実験したい時に勘違いしないようにする
0232おれさま ◆6CTEZS59O00a
垢版 |
2018/10/29(月) 16:44:08.02
Eclipseで楽してたらコマンドラインから実行する方法忘れてしまった

例:
Main.class
-----------------------
package aaa;

public class Main {
 public static void main(String[] args) {
  System.out.println("test");
 }
}
-----------------------

(パスを通さないことを前提に説明・カレントフォルダ名はtestとする)
これをコマンドラインから起動するときは
フォルダtestの中にフォルダaaaを作る
その中にMain.classを入れておく
propertiesファイルとか使うなら
フォルダtestに入れておく
CMDでフォルダtestに移ってから
>java aaa.Main
で起動

eclipseのワークスペースからクラスファイルを拾ってくる時は
binフォルダの中をみればいい
ただ、この中にMain.classとは異なる見慣れないものが入ってたりする
Main$1.class
Main$2.class
Main$3.class

eclipseがバックアップ用に用意したものかと思ってフォルダaaaにコピペしなかったらエラー
表示をみるとどうやらこいつらも必要なようだ
この3つもaaaに放り込んだらうまく起動した
0234おれさま ◆6CTEZS59O00a
垢版 |
2018/10/29(月) 16:51:03.00
ここつまんねぇなぁ
覚えても意味なさそうだぁ
とか思っててもいざ練習問題ちゃんと出来るようにしようとすると
派生的にいろんな所の復習することになる
この 「いろんな所」 が結構大事な分野だったりするんで
結局がんばってやったほうがいいんだろうな
0235おれさま ◆6CTEZS59O00a
垢版 |
2018/10/30(火) 10:33:26.15
よし、ProcessBuilderによるclassファイル実行でけた

eclipseの今扱っているプロジェクトのプロジェクトフォルダの直下に
フォルダaaaをおいてこの中にMain.classを入れる

ProcessBuilder pb = new ProcessBuilder("java", "aaa.Main");
pb.start();

で起動確認済
0236おれさま ◆6CTEZS59O00a
垢版 |
2018/10/30(火) 11:14:46.84
>>235の状況下で

Class<?> c = Class.forName("aaa.Main");
System.out.println(c.getName());

はできなかった
ProcessBuilderではいけるのになぜだ

もしかしてと思いながらbinフォルダの中にaaaフォルダをぶちこんだら行けてしまった
手法がどうであれ、ClassクラスもProcessBuilderと同様に外部のクラスファイルに
アクセスできるようだ
0237おれさま ◆6CTEZS59O00a
垢版 |
2018/10/30(火) 12:48:17.63
eclipseでコマンドライン引数を渡して実行する方法

実行の構成→「引数」タブ→プログラムの引数

ここにコマンドライン引数を並べればいいだけ
0238おれさま ◆6CTEZS59O00a
垢版 |
2018/10/30(火) 12:59:51.70
>>236はちと違う感じがする
クラスファイルへのアクセスってのは内部も外部もないのでは。
この辺は学習が進めばハッキリしてくるだろう
0239おれさま ◆6CTEZS59O00a
垢版 |
2018/10/30(火) 13:38:32.43
7章の練習問題は解答が間違えてるようだ
https://teratail.com/questions/153338

問題の指示によると、
文字列配列を引数とするmainメソッドの存在を確認しなければならない
存在する場合のみ、第二引数による条件分岐に入る

にもかかわらず、
@条件分岐に入ってから存在確認処理をしているのが第二引数が I のケース
Aそもそも存在確認を行ってさえいないのが第二引数が E のケース

@の存在確認とは、
getMethod()によって 文字列配列が引数であるmainメソッドを指定している
この条件に当てはまるメソッドがない場合に例外が投げられるようになってる
(throws Exception)
例外はメソッドを呼び出したmainメソッドで処理される
という部分を指している
0240おれさま ◆6CTEZS59O00a
垢版 |
2018/10/30(火) 15:06:42.90
>>239の間違いを正したコードを書いてた

これでいいだろと思って実行してみるんだけど
ProcessBuilder による起動がうまくいかない
起動するクラスのmainメソッドには

System.out.println("eating memory.......");

と書いてあるのだが、これが表示されない
ProcessBuilderによるクラス実行は実験済で間違いないはずなのだが
いろいろやっても上コメントが表示されない

まさかな、と思ってこれを実行するクラスのmainメソッドに追加

JFrame jf = new JFrame();
jf.setSize(100, 100);
jf.setVisible(true);

そしたらなんとフレームが出現するじゃないか
ProcessBuilderによる実行は、「外部プログラム」の実行なので、printlnがあっても
内部的な処理結果を表示するコンソール画面には出ないということか

ちなみに実行するクラスファイルはbinフォルダに置いたままではだめ
プロジェクトのフォルダ直下に置く
ProcessBuilderによる実行は、やはり「外部のプログラム」を動かすものなので
eclipse上、カレントフォルダはプロジェクトのフォルダ直下(この辺は不確実)
0242おれさま ◆6CTEZS59O00a
垢版 |
2018/10/30(火) 15:12:25.80
ちなみにリフレクションによる実行では
ちゃんとコンソールにprintlnの内容が表示される
これが
External Launch と
Internal Launch の違いってことかな
0243おれさま ◆6CTEZS59O00a
垢版 |
2018/10/30(火) 15:46:01.03
>>238の続きなんだけど、リフレクションによる実行は「内部」だね
>>236で、binフォルダにaaaをぶち込むと実行できたのは
まさにbinフォルダが内部的なものだからだ
普通にクラスのソースコードを書いて実行するとbinフォルダにクラスファイルが生成される
つまり、binフォルダにクラスファイルを置くということは、
ソースコードに書いたのと結果的に同じ
外部のクラスファイルを持ってきたという考えはしない方がいい
0244おれさま ◆6CTEZS59O00a
垢版 |
2018/10/31(水) 13:56:32.92
>>239の問題をクリア

@で使っている例外を利用してmainメソッドの存在確認をする方法は
秀逸だと思うので、これはちゃんと利用する
ただし、
launchInternalメソッドの中に書くのではなく
mainメソッドに書く

---------------------------------------------
try {
 m = c.getDeclaredMethod("main", String[].class);
} catch (NoSuchMethodException e) {
 System.out.println("指定されたメソッドが存在しません。");
 System.exit(1);
}
-----------------------------------------------
m は static なクラス変数として宣言したMethodクラスのインスタンス変数
クラス変数としたのは launchInternalメソッドにおいて invoke するのに流用するため

あと、launchExternal メソッドで起動した場合に起動確認のためJFrameを表示させたい
そこでMemoryEaterクラスの main メソッドの中にJFrame表示のコードを入れた
さらにフレームタイトルに launchInternal、 launchExternal どちらから起動されたか
わかるように I か E の文字をいれることにする
そのため、これらのメソッドを起動する際に、I か E の引数を渡すことにする
内部起動か外部起動かによって引数の渡し方が違ってくるところがポイント
-------------------------------------------------------------
public static void launchExternal(Class<?> clazz) throws Exception {
 ProcessBuilder pb = new ProcessBuilder("java", clazz.getName(), "E");
 Process proc = pb.start();
 proc.waitFor();
}
public static void launchInternal(Class<?> clazz) throws Exception {
 String[] args = {"I"};
 m.invoke(null, (Object)args);
}
--------------------------------------------------------------
0245おれさま ◆6CTEZS59O00a
垢版 |
2018/10/31(水) 15:24:10.35
この問題は例外処理の復習になる

●例外インスタンスを自分で投げるケース
throw new IllegalArgumentException("起動方法の指定が不正です");

IllegalArgumentExceptionはメソッドの引数が不正

●例外を伝播させる
public static void launchExternal(Class<?> c) throws Exception { }

throws と複数になってるところがポイント

●例外処理中の e.getMessage() とは
これは e.printStackTrace() を使った場合に表示されるメッセージが冗長なため、
これらのメッセージのうち一部分だけを表示させたいときに使うようだ
具体的には、今取り組んでるコードにおいて、実行対象となるクラスにmainメソッドがない場合

もし e.printStackTrace() なら
-----------------------------
java.lang.NoSuchMethodException: MemoryEater.main([Ljava.lang.String;)
 at java.lang.Class.getMethod(Class.java:1786)
 at Main.main(Main.java:19)
------------------------------

もし System.out.println(e.getMessage()); なら
------------------------------
MemoryEater.main([Ljava.lang.String;)
------------------------------

調べた結果このようになったのだが、疑問に感じたのは実践編7章解答で
catchの中にこのような記述がある

System.out.println(e.getMessage());
e.printStackTrace();

包含関係にあるこの2つを並べることに何の意味があるのか分からない
今のところは自分が調べた結果を信じることにしておこう
e.getMessage()はエラーメッセージを簡潔に書きたいときに使うもの、とする
0246おれさま ◆6CTEZS59O00a
垢版 |
2018/10/31(水) 16:06:25.26
あとこれ

Method m = clazz.getMethod("main", String[].class);

getMethodメソッドの第二引数 String[].class
この class は何なんだ!
調べまくって何となく分かったんだけど、要はこの class は実践編209ページの
Class インスタンスの基本的な取得方法の一つ

Class<?> cinfo = クラス名.class

の class と同じものだということ。
String[].class は文字列型配列に関するClassクラスのインスタンスである

リフレクションと呼ばれる分野について学習してるわけなんだけど
特徴的なのはあるクラスを対象とするとき、
そのクラスを対象とするClass クラスのインスタンスを生成する点

この先はざっくりとした説明になる。

場合によるのだろうが、この分野において、
メソッドに渡す引数の(クラス)型を指定するときも
同様の配慮をしなければならないようだ
つまり、メソッドの仮引数が
int i となっていたら、実引数は
int.class のように表現する場合があるということ

getMethod のレファランスを見てみると

public Method getMethod(String name,
Class<?>... parameterTypes)

Class<?> はまさにClassクラスのインスタンスをここにもってこいという事
0247おれさま ◆6CTEZS59O00a
垢版 |
2018/10/31(水) 16:18:48.94
clazz の宣言文を補足する
例えばこんな風になる

Class<?> clazz = MemoryEater.class;
Method m = clazz.getMethod("main", String[].class);

これは、下のように書いてもよいということになる

Class<?> clazz = MemoryEater.class;
Class<?> stClazz = String[].class;
Method m = clazz.getMethod("main", stClazz);

分析の対象となるクラス(MemoryEater)もClassクラスのインスタンスを生成し
分析の対象となるクラスで使われる引数のクラス型(String[])についても
Classクラスのインスタンスを生成して使いなさい!ということらしい
0248おれさま ◆6CTEZS59O00a
垢版 |
2018/10/31(水) 16:33:22.21
クラス名.class


クラスリテラルとかなんとか
タイプリテラルとか
リテラル記法とか

なにやらかなり特殊な書き方のようだ

今日はこれで終わり
0249おれさま ◆6CTEZS59O00a
垢版 |
2018/11/02(金) 16:05:26.41
自作Classに含まれるメソッドリスト

main
wait
wait
wait
equals
toString
hashCode
getClass
notify
notifyAll

これまで間違えてコードを書いてたみたいで
main以外表示されてなかったんだけど、さっき間違いに気づいて修正
こんなにでてきた
Objectクラスから引き継いだものも表示されるのな
複数のwaitはオーバーロードか
0250Mr.名無しさん
垢版 |
2018/11/03(土) 09:49:29.26
コマンドライン引数によって受けとったclassファイルを
ProcessBuilderによって起動するテストをeclipse上でやろうとすると失敗することが多い
というかclassファイルのソースコードを修正しては起動するみたいなことをしていると起動しなくなったりする
eclipse上ではなくてちゃんとコマンドラインから起動すれば正常に動くので
eclipseの問題なのか
まぁこれ以上ここに時間を費やすのもどうかと思うから追究するのはやめるか
0251おれさま ◆6CTEZS59O00a
垢版 |
2018/11/03(土) 16:42:46.49
今日はずっと前にやってたところの復習してた
せっかく覚えたのに忘れるのもったいないからたまにやらないとね
0252おれさま ◆6CTEZS59O00a
垢版 |
2018/11/04(日) 08:00:49.41
9章269ページあたりを読んでるんだけど
System.out.println() とは結局何なのだろうかと。

System はクラス名で
out はそのフィールドで、型は PrintStream

つまり System クラスでは
PrintStream out;
みたいな宣言があるわけだ
(実際には public final static PrintStream out = null;)

んで、PrintStream クラスのメソッドの一つに
println() がある

out はクラス型をフィールドに用いたもの
すっきり入門340ページの Hero クラスのフィールドとして宣言されている
Sword sword;
と同じようなものか

341ページの下に
hsword.name
というのがあるが、もし Sword クラスの name フィールドが private で
getter が置かれているとしたら
@ h.sword.getName()
となっていたはず

これと
A System.out.println()
は結構似てると考えていいのか

違いは、@では Hero クラスの中で宣言されている sword は static ではないため
アクセスするには Hero クラスのインスタンス h を生成したが
Aでは、System クラスの中で宣言されている out が static 宣言されているため
インスタンス生成が不要だった点
0253おれさま ◆6CTEZS59O00a
垢版 |
2018/11/04(日) 08:04:52.55
こういった構造を、フェイクを使いながら書くと、こんな感じになるのか
これでいいのかな
警告はでてるけど実行可

public class Main {
public static void main(String[] args) {
Systemm.outt.printlnn("aaa");
}
}
class Systemm {
static PrintStreamm outt;
}

class PrintStreamm {
public static void printlnn(String st) {
System.out.println(st);
}
}
0254おれさま ◆6CTEZS59O00a
垢版 |
2018/11/04(日) 08:14:14.18
>>253の PrintStreamm#Printlnn から static を抜いたら警告が消えた
理由はあとで考えることにする

public class Main {
 public static void main(String[] args) {
  Systemm.outt.printlnn("aaa");
 }
}
class Systemm {
 public static PrintStreamm outt;
}

class PrintStreamm {
 public void printlnn(String st) {
  System.out.println(st);
 }
}
0255おれさま ◆6CTEZS59O00a
垢版 |
2018/11/04(日) 09:22:15.30
例えばこのスレを 「2ch.txt」 に全コピペして保存

(例外は投げるとする)
FileReader fr = new FileReader("2ch.txt");
BufferedReader br = new BufferedReader(fr);
String line = br.readLine();
while (line != null) {
 System.out.println(line);
 br.readLine();
}

これだと文字化けしてしまう
そこで文字コードを指定したい

実践編260ページの記述によると、
FileReaderのコンストラクタで文字コード指定ができるかのように思われるが
実際はできない。いや出来るのかもしれないが調べた限りでは分からなかった ぞ

文字コードの指定には
FileInputStream
InputStreamReader
を使う
(この辺はHTML取得の時に使ったコードに似てる
URL、InputStream、InputStreamReader を使った)

FileInputStream fis = new FileInputStream("2ch.txt");
InputStreamReader isr = new InputStreamReader(fis, "SJIS");
BufferedReader br = new BufferedReader(isr);
String line = br.readLine();
while (line != null) {
 System.out.println(line);
 br.readLine();
}

これで文字化け回避できた
SJIS はググってでてきたものを適当にいれたらいけたってだけ
0256おれさま ◆6CTEZS59O00a
垢版 |
2018/11/04(日) 09:34:16.09
TeraPad というテキストエディタを昔から使っているのだが、
下の方に文字コードが表示される
試しにこのスレやgoogleの検索結果のページやらをコピペしてみたり
パソコン内にあるいろんなファイルをTeraPadで開いてみたりしたが
全て SJIS と表示されていた

というか SJIS と指定して開いているからそう表示されるのかもしれないが
少なくとも、TeraPad でみたときに文字化けしていない状態で、SJIS と表示されているなら
SJIS がこの場合の正しい文字コードなんだなと

ちなみにeclipse上で、デフォルト文字コードを取得するこれ
System.out.println(System.getProperty("file.encoding"));
を確認してみると UTF-8 と表示される

この違いが文字化けの原因だ
0257おれさま ◆6CTEZS59O00a
垢版 |
2018/11/04(日) 15:53:55.10
この辺はstream関連のクラスがたくさん出てきて何がなんだか分からなくなる

整理する

-------------------------------基本用語
●文字ストリーム系
Writer、Reader がクラス名に入る
●バイトストリーム系
OutputStream、InputStream がクラス名に入る
--------------------------------

・基本用語の頭に File がつくと
ストリームの終端がファイルであるクラスになる

・基本用語の頭に Buffered がつくと
バッファリングされた出力または入力ストリームをつくるクラスになる

・特殊なものとしてバイトストリームと文字ストリームの橋渡しをするクラス
OutputStreamWriter : 文字をバイトにエンコード
InputStreamReader : バイトを文字にエンコード
どちらも指定された文字セットを用いて変換することになるが
指定がなければシステムのデフォルトの文字セットを用いることになる
この文字セット指定がまさしく >>255でやった "SJIS" である
ここでは文字セットとは文字コードと同義か
0258おれさま ◆6CTEZS59O00a
垢版 |
2018/11/04(日) 16:02:55.25
>>255を再考

FileInputStream fis = new FileInputStream("2ch.txt");//@
InputStreamReader isr = new InputStreamReader(fis, "SJIS");//A
BufferedReader br = new BufferedReader(isr);//B
String line = br.readLine();
while (line != null) {
 System.out.println(line);
 br.readLine();
}

>>257の「基本用語」に注目しながら分析

@一旦バイトストリームによってファイルを読み込んでいく (バイトだからInputStream)
A吸い上げたバイトを文字にエンコードするが、その際文字セットを SJIS に指定 (橋渡し役)
B変換された文字をバッファリングする (文字だからReader)
0259おれさま ◆6CTEZS59O00a
垢版 |
2018/11/04(日) 16:08:17.01
InputStreamReaderのせいで頭が混乱してた
常に文字セットを指定してれば橋渡し変換役だってことが理解できてたんだけど
文字セット指定がないデフォルトでこれまで使ってたんで
役割が頭ん中で明確になってなかった
0260おれさま ◆6CTEZS59O00a
垢版 |
2018/11/04(日) 16:30:14.54
public class Main {
 public static void main(String[] args) {
  FileInputStream fis = null;
  FileOutputStream fos = null;
  BufferedOutputStream bos = null;
  GZIPOutputStream gos = null;
  try {
   fis = new FileInputStream("test.txt");
   fos = new FileOutputStream("test.txt.gz");
   bos = new BufferedOutputStream(fos);
   gos = new GZIPOutputStream(bos);
   int i = fis.read();
   while (i != -1) {
    gos.write(i);
    i = fis.read();
   }
  } catch(IOException e) {
   e.printStackTrace();
  } finally {
   try {
    if (fis != null) fis.close();
    if (gos != null) gos.close();
   } catch(IOException e) {
    
   }
  }
 }
}

実践編9章の練習問題
コマンドライン引数はテストが面倒なので内部指定した
test.txt を読み込んで、同じ内容を test.txt.gz にかき込むんだけど、
書込みの際のフィルタリングとして
バッファリング+圧縮
が指示されている

文字ストリームは一切使わず
バイトストリームのみで処理するため
Reader、Writer がついたクラスは出てきていないのがポイント
0261おれさま ◆6CTEZS59O00a
垢版 |
2018/11/04(日) 16:37:31.85
FileOutputStream

BufferedOutputStream

GZIPOutputStream

の順でフィルタにかけてるんだけど

FileOutputStream

GZIPOutputStream

BufferedOutputStream

でやったらどうなるかテストしてみた
作成されるgzファイルが壊れてた
GZIPOutputStream が最後じゃないとだめみたいだ
0262おれさま ◆6CTEZS59O00a
垢版 |
2018/11/04(日) 16:40:45.04
>>260修正

gos.flush();

を忘れてた
while ブロックの直後に挿入するとする
ふらぁぁぁぁぁぁぁっしゅ!
0263わがはい ◆0BMoNHqNlM
垢版 |
2018/11/04(日) 18:45:21.35
>>261
逆でもいけるやろ
どっちもOutputStreamのサブクラスなんやから
gzip形式で圧縮してるんだから直で開いても見えへんで
解凍するかGZIPInputStream使わんと

public class Main {
public static void main(String[] args) {
try (BufferedInputStream fis = new BufferedInputStream(new FileInputStream("test.txt"));
   BufferedOutputStream gos = new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream("test.txt.gz")));) {
int i;
while ((i = fis.read()) != -1) {
gos.write(i);
}

} catch (IOException e) {
e.printStackTrace();
}

try (BufferedReader gis = new BufferedReader(new InputStreamReader(new GZIPInputStream(new FileInputStream("test.txt.gz"))));) {
String str;
while ((str = gis.readLine()) != null) {
System.out.print(str);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
0264おれさま ◆6CTEZS59O00a
垢版 |
2018/11/05(月) 04:19:58.31
>>263
ほんとだ
たぶんコードをどこかで間違えてたな

しかしわかりにくいので勝手に改変
GZIP→Buffer (test_gos-bos.txt.gz)
Buffer→GZIP (test_bos-gos.txt.gz)
フィルタ順を変えた2つ圧縮ファイルが作られるがどちらも正常

public class Main {
 public static void main(String[] args) {
  try (BufferedInputStream fis = new BufferedInputStream(new FileInputStream("test.txt"));
    BufferedOutputStream bos = new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream("test_gos-bos.txt.gz")));) {
   int i;
   while ((i = fis.read()) != -1) {
   bos.write(i);
   }
  } catch (IOException e) {
   e.printStackTrace();
  }
  
  
  try (BufferedInputStream fis = new BufferedInputStream(new FileInputStream("test.txt"));
    GZIPOutputStream gos = new GZIPOutputStream(new BufferedOutputStream(new FileOutputStream("test_bos-gos.txt.gz")));) {
   int i;
   while ((i = fis.read()) != -1) {
   gos.write(i);
   }
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}
0265おれさま ◆6CTEZS59O00a
垢版 |
2018/11/05(月) 04:22:22.69
自分のコードでも成功

public class Main {
 public static void main(String[] args) {
  FileInputStream fis = null;
  FileOutputStream fos = null;
  BufferedOutputStream bos = null;
  GZIPOutputStream gos = null;
  
  //bos→gosの順
  try {
   fis = new FileInputStream("test.txt");
   fos = new FileOutputStream("test_bos-gos.txt.gz");
   bos = new BufferedOutputStream(fos);
   gos = new GZIPOutputStream(bos);
   int i = fis.read();
   while (i != -1) {
    gos.write(i);
    i = fis.read();
   }
  } catch(IOException e) {
   e.printStackTrace();
  } finally {
   try {
    if (fis != null) fis.close();
    if (gos != null) gos.close();
   } catch(IOException e) {}
  }
  
  //gos→bosの順でもOK
  try {
   fis = new FileInputStream("test.txt");
   fos = new FileOutputStream("test_gos-bos.txt.gz");
   gos = new GZIPOutputStream(fos);
   bos = new BufferedOutputStream(gos);
   
   int i = fis.read();
   while (i != -1) {
    bos.write(i);
    i = fis.read();
   }
  } catch(IOException e) {
   e.printStackTrace();
  } finally {
   try {
    if (fis != null) fis.close();
    if (bos != null) bos.close();
   } catch(IOException e) {}
  }
 }
}
0266おれさま ◆6CTEZS59O00a
垢版 |
2018/11/05(月) 04:28:03.98
fos = new FileOutputStream("test_bos-gos.txt.gz");

fos = new FileOutputStream("test.txt_bos-gos.gz");
と指定すると
中身のファイルが、拡張子なしの
test.txt_bos-gos
になるという事に気づいた
こういう仕様なのか

ちなみに作成された圧縮ファイルが正常化どうかのチェックは
WinRARを使って適当にやってる
0267おれさま ◆6CTEZS59O00a
垢版 |
2018/11/05(月) 04:34:40.49
そして flush() がまた抜けているという件
ふらぁぁぁぁっぁぁぁぁぁっしゅ!!!
0268おれさま ◆6CTEZS59O00a
垢版 |
2018/11/05(月) 04:42:11.26
finally使わないでいい書き方だけど
try () のカッコの中に複数文書いてもいいんだな
おれはこういう風に書きたい

public class Main {
 public static void main(String[] args) {
  try (
   BufferedInputStream fis = new BufferedInputStream(new FileInputStream("test.txt"));
   BufferedOutputStream bos = new BufferedOutputStream(new GZIPOutputStream(new FileOutputStream("test_gos-bos.txt.gz")));
  ) {
   int i;
   while ((i = fis.read()) != -1) {
   bos.write(i);
   }
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}
0269おれさま ◆6CTEZS59O00a
垢版 |
2018/11/05(月) 07:18:55.78
12章のデータベースアクセスを読んでいるのだけど
実践編の次の位置にあるテキストとして
スッキリわかるSQL入門がある
これはJavaのテキストかと思っていたのだが
そういうわけではなさそうだ

「スッキリわかるサーブレット&JSP入門」 はJavaのテキスト

この2冊に踏み込むべきか、迷うところだ
0270おれさま ◆6CTEZS59O00a
垢版 |
2018/11/05(月) 08:08:19.43
ん〜いろいろぐぐってみたがSQL入門は買っておいたほうがよさそうだな
どうせだからサーブレットの方も買うか?
0271おれさま ◆6CTEZS59O00a
垢版 |
2018/11/05(月) 08:26:18.37
それはともあれ、データベースは実践編12章で触ることになるため
DBMSの導入が必要となる

ここでは実践編が勧める HS Database を導入することにする
インストールまでは簡単だ
適当にぐぐれば出てくる
次に・・

実践編335ページ
>以後、この章のプログラムの実行時には、このJARファイルにクラスパス
>(eclipseの場合はビルドパス)を通して実行する必要があります。

eclipseを使っているのでビルドパスとやらを通さなければならない
調べた結果

ビルドパスはプロジェクトごとに通していくことになる
ここでいうJARファイルとは、バージョンごとにファイル名は違うだろうが
おそらくH2 Databaseをインストールしたフォルダにあるこれ
H2\bin\h2-1.4.197.jar
であろうと推測できる

このjarファイルを外部のライブラリとして追加していくことを意味するのだろう

まずプロジェクトのプロパティーを開く
方法はいろいろあるが、パスを通したいプロジェクトをパッケージエクスプローラで選択した状態で
プロジェクト→プロパティー
次に
→「ライブラリー」タブ→外部JARの追加
ここで上記のjarファイルを選択する

こうすることで、パッケージエクスプローラ上で、当該プロジェクトを開いた場合に
「参照ライブラリー」 が追加されており、この中に h2-1.4.197.jar が配置されることになる

不正確なら以後修正していく
0272おれさま ◆6CTEZS59O00a
垢版 |
2018/11/05(月) 08:50:42.49
public class Main {
 public static void main(String[] args) {
  try {
   Class.forName("org.h2.Driver");
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  }
  Connection con = null;
  try {
   con = DriverManager.getConnection("jdbc:h2:G:\\DB\\H2_Database\\test01");
  } catch(SQLException e) {
   e.printStackTrace();
  } finally {
   if (con != null) {
    try {
     con.close();
    } catch(SQLException e) {
     e.printStackTrace();
    }
   }
  }
 }
}


ファイルが作成されたので、これでとりあえずいいのか

Class.forName("org.h2.Driver");
の org.h2 については、パッケージエクスプローラから h2-1.4.197.jar を開くと
直下に同じ名前のパッケージがあるので、これだろう
0273おれさま ◆6CTEZS59O00a
垢版 |
2018/11/05(月) 09:44:33.60
ん〜ん〜
実践編361ページのコード
これおかしくないか?
いろいろとまだ知識が固まってないので自信あるわけではないが

con.close();

の位置
finally ブロックに書かれているのは、どんなときでも必ず実行されなければならないから。
(もちろん if 文で示す通り null の時は除くけど)

しかしだ、この finally ブロックが置かれている位置、catch ブロックの「中」だぞ?
ということは例外が catch されなければ実行されないんじゃないのか?

おかしいのであれば誰かネット上で指摘してるはずだと思って
ぐぐってみたけどヒットしない
おれがおかしいのですか〜
0274おれさま ◆6CTEZS59O00a
垢版 |
2018/11/05(月) 09:49:38.56
public class Main {
 public static void main(String[] args) {
  //finallyが※の内側のケース
  try {
   Class.forName("org.h2.Driver");
  } catch (ClassNotFoundException e) {//※
   System.out.println("@");
   try {
    Class.forName("org.h2.Driver");
   } catch(ClassNotFoundException ee) {
    System.out.println("A");
   } finally {
    System.out.println("finally内側");
   }
  }
  
  //finallyが※の外側のケース
  try {
   Class.forName("org.h2.Driver");
  } catch (ClassNotFoundException e) {//※
   System.out.println("A");
   try {
    Class.forName("org.h2.Driver");
   } catch(ClassNotFoundException ee) {
    System.out.println("B");
   }
  } finally {
   System.out.println("finally外側");
  }
 }
}


結果は 「finally外側」

「finally内側」 が表示されるのは、一つ目の※で存在しないクラスを指定した時
この時例外をキャッチして catch ブロックに入る
そこで初めて finally は実行される

ん〜おかしいよね?
0275おれさま ◆6CTEZS59O00a
垢版 |
2018/11/05(月) 09:56:03.51
いや、話はもう少し複雑なのか?

con が catch 文の中でも使われているから内側、外側両方で finally がいるということか?
つまり上の例で言えば

public class Main {
 public static void main(String[] args) {

  try {
   Class.forName("org.h2.Driver");
  } catch (ClassNotFoundException e) {//※
   System.out.println("@");
   try {
    Class.forName("org.h2.Driver");
   } catch(ClassNotFoundException ee) {
    System.out.println("A");
   } finally {
    System.out.println("finally内側");
   }
  } finally {
   System.out.println("finally外側");
  }
 }
}
0276おれさま ◆6CTEZS59O00a
垢版 |
2018/11/05(月) 10:06:50.64
いやいや、やっぱり違う

内側で使った con は結局、外側の finally で close されるからいいんだ
やっぱ内側の finally は必要ないはずだ

にも関わらず実践編361ページでは内側のみに finally があるのでおかしいなぁ
というのが疑問点
0277おれさま ◆6CTEZS59O00a
垢版 |
2018/11/05(月) 10:11:57.82
ま、とりあえず12章まで読むだけ読んだ
ちょい飛ばしたから、今週は先へは進まずに復習のみでもおkか
0278おれさま ◆6CTEZS59O00a
垢版 |
2018/11/05(月) 15:23:34.40
とか言いながら、斜め読みしながら先へ進むおれ

「リファクタリング」

これな
以前VBAの10,000行ぐらいのプログラム書いたんだけど
おれが組んだもので一番でかいやつ
今も他人によって使われてて、自分でいうのもなんだけど役に立っている

しかし中のコードはひどいもので
その原因の一つは、VBAを一から勉強しながら書いていたから、
勉強初期の頃のコードと、それなりに理解できてきた頃のコードが絡まり合って、それはもう。
もう一つは、計画性がなく気ままに機能を追加してきた結果、ネストの階層がとんでもなく深い

滅多に表層にでないバグを潰したりして、最終的に完成するまでに2年はかかっている

たぶんもう一度組み直せばすっきりとして実行速度もあがると思うのだが
あの苦労をもう一度・・・と思うと。

コードをいじらないでも設定を柔軟に変えられるよう、
各種設定値をワークシート上に記述できるようになってはいるのだが
実は全て正常に動くかは全部チェックしてない
この辺も組み直す過程でチェックできるだろう

今はおれが触れる場所にいるのでなんとかなるのだが
いずれ離れる予定なので、それまでにはなんとかしないといけないのだが。

めんどい
0279わがはい ◆0BMoNHqNlM
垢版 |
2018/11/05(月) 16:54:41.40
初心者あるあるやね
ワイも昔は一つのクラスの中にズラーっと書いて保守性も拡張性も考えとらんかった
といってもプログラミング始めてまだ半年の素人やけども
最近は機能別にクラス分けするようにしとるけど、今度はどう設計するか考えんといかんからこれはこれで大変

>>272
finallyでcloseするとネストが深くなって可読性が落ちるし、し忘れることもあるからauto_closeにしたほうがええで
0280おれさま ◆6CTEZS59O00a
垢版 |
2018/11/06(火) 08:04:51.09
try {
} catch() {
} finally {
 if () {
  try {
  } catch() {
  }
 }
}

これはもうルーチンワークだわ
closeまで書いてから対象となるインスタンス生成してるぐらいだ
try(){} をベースにしようか迷ったけど
めんどくさい方を先に覚えて間違えずに書けるようにしたほうがいい
簡略化が導入されるまでみんな書いてたものだしね
0281おれさま ◆6CTEZS59O00a
垢版 |
2018/11/06(火) 11:08:00.61
スッキリわかるSQL入門 第2版 ドリル222問付き! (スッキリシリーズ)2018/11/30
中山清喬、 飯田理恵子


新しい版がでるそうなのであと3週間ほど待つ事にしよう
0282おれさま ◆6CTEZS59O00a
垢版 |
2018/11/07(水) 10:40:17.29
実践編どくはああああああああああああああああ

寄り道したくなってきたぞ
0284おれさま ◆6CTEZS59O00a
垢版 |
2018/11/07(水) 13:08:47.17
「独学プログラマー」
という本をテキストとして使う

IDLEというPython付属のIDEをテキストでは使っているのだが
PyCharmで普通にpyファイルを新規作成してコード書いて実行した場合と微妙に違うようだ

もしかしてーと思いつつ、左下のほうの「Pythonコンソール」とやらのタブを押してみたら
それっぽいのが出てきたので、コードを打ち込んでみたら正解だ
IDLEをここで使えるようだ
なかなか便利である

ちなみにプロジェクトの削除はPyCharm上でやるのではなく
作成されているプロジェクトフォルダをエクスプローラ上から削除してから
PyCharmを再起動すれば消えている
0285おれさま ◆6CTEZS59O00a
垢版 |
2018/11/07(水) 13:23:25.43
print(3 ** 300)

136891479058588375991326027382088315966463695625337436471480190078368997177499076593800206155688941388250484440597994042813512732765695774566001

プロセスは終了コード 0 で完了しました



おお・・・・
0286おれさま ◆6CTEZS59O00a
垢版 |
2018/11/07(水) 13:25:58.29
こういうでかい数字はjavaだと扱ったことないからわからんのだけど
難しいんではないのか
すごいとおもたぞ
0287おれさま ◆6CTEZS59O00a
垢版 |
2018/11/07(水) 13:32:37.36
この対話シェルとやらは、簡単なチェックのために使うのはよさそうだが
いろいろと学習上誤解を招きそうな機能だな
多言語やってきたおれは、2と打ち込んで実行すると2が表示されることに違和感を感じることができるが
全くの初心者はそれが当たり前だと思っちゃうよな
いや、ある意味学習が捗る部分もあるのだけれども
0288おれさま ◆6CTEZS59O00a
垢版 |
2018/11/07(水) 13:45:46.30
論理演算子はVBAと同じか

and
or
not

if 文は条件はカッコなしで文末にコロン :

ヘッダーとスイート
0289おれさま ◆6CTEZS59O00a
垢版 |
2018/11/07(水) 13:55:16.88
対話シェルじゃなくてpyの方に書いていくことにしているのだが

def ppp(a, b):
 return a + b

print(ppp(2, 5))


こういうの書くと関数のあとは2行は空けろとか言ってくる
Pythonは空行とかタブとか五月蠅いのな
0290おれさま ◆6CTEZS59O00a
垢版 |
2018/11/07(水) 14:13:08.16
うわ、行空けすぎるとおこられるw

あと、関数に渡す引数のデフォルト値設定で

def ppp(n = 1):

ってやったらスペースいれるなって怒られる

def ppp(n=1)

にしろだと
0291おれさま ◆6CTEZS59O00a
垢版 |
2018/11/07(水) 14:51:18.03
なるほどねー
1/3ぐらい読んでみたけど、
Pythonはわかりやすい、悪く言えばいい加減な感じ

今日は終わり!
0292おれさま ◆6CTEZS59O00a
垢版 |
2018/11/08(木) 12:44:03.34
今日はhtmlの基礎
テキストは
「これからWebをはじめる人のHTML&CSS、JavaScriptのきほんのきほん」

ここに書いてあるHTMLやらCSSの簡単なコードをとりあえず
ぱぱぱぱぱぱっと書けるようにしていく

やったことないわけではないんだけど、
JavaScriptやその先のJavaにつなげるために
もう少し記憶を堅いものにしておく
0293Mr.名無しさん
垢版 |
2018/11/08(木) 13:29:57.42
続けていて尊敬。
このままの調子で頑張ってね。
0294おれさま ◆6CTEZS59O00a
垢版 |
2018/11/08(木) 13:59:31.61
ふぁ〜い

HTMLもCSSも、「覚える」ってことをしたことがなかったので新鮮
ぴっちぴちです

今日は用事あるのでここまで
0295わがはい ◆0BMoNHqNlM
垢版 |
2018/11/09(金) 01:13:17.98
>>290
pythonはインデントでスコープを決めるからね
でも文中の空白は問題なかったはずやが

個人的にpythonはあんま好きやないな
科学技術計算や深層学習の分野では強いけどアプリ作るとなるとピンとこん
ワイはjavaでデータベース使ってウェブサイト制作なんかは一通りできるようになったっから、Androidアプリ作るためKotlin勉強しとる
でもワイのノーパソでAndroidStadioのエミュレータ動かすと重すぎて作業できん
新しいPC欲しいで
0296おれさま ◆6CTEZS59O00a
垢版 |
2018/11/10(土) 07:44:23.82
マルチモニタのデスクトップでシコシコ書いてるわ
ブラウザでググりながらが基本なんで
ノーパンは厳しいな
モニタもっとでかいのに取り替えようかとも思ってるぐらいだ

web系のプログラミング始めると
レンタル鯖とか興味湧いてくる
無料もあるけど@500円/月でよさそうなの借りられるし
0297おれさま ◆6CTEZS59O00a
垢版 |
2018/11/11(日) 15:30:45.26
HTML・CSSのテキスト
テキスト通りの流れでVSCodeにカキカキ
しっかり覚えたわけじゃないけど、難易度は低いので
大体なにができるのかざっくり理解出来ていれば
あとはググったりして再現できそう
正直いうとこれつまんねぇのな

HTML/CSSの部分は一通り流したので
JavaScriptの部分をこれまた流し読みをしてみた
Javaで基本やってると大した事ないのな
匿名クラスのような使い方も出てきてるし
JFrameでやってたEvent処理の知識が生きそう
JavaScriptは一時期Javaと近い所にいたようで、似た部分が多くて勉強しやすそうだ
0298おれさま ◆6CTEZS59O00a
垢版 |
2018/11/11(日) 15:39:01.29
Javaの将来性があれなんで、C#の本も買ってある
どちらかに限定しないで両方やればいいじゃんってゆる〜く考えてる
C#はwidowsアプリに強そうなんで、軽く何か作れるレベルまでやってみたい
んでJavaと比べてみたい
0299おれさま ◆6CTEZS59O00a
垢版 |
2018/11/11(日) 16:00:59.79
C#はVSCodeでも開発できるんだけど
この際Visula Studio 2017 Communityを入れる事にしよう

オプションでインスコできるものがいくつかあるんだけど
全部チェック付けたら20GB越えるみたいだ
SSDの容量食いそうだけどまぁいいか
0300おれさま ◆6CTEZS59O00a
垢版 |
2018/11/11(日) 17:32:34.39
「独習C#新版」

ちょいと読んでるんだけど
Javaとやたら似てるな

namespaceというのは初めてだけど
packageみたいなもんかこれ

●Java
System.out.println("hello," + name);
●C#
Console.WriteLine("hello, {0}", name);

プレースホルダー使うところがC系っぽい感じする
Cでもそんなことやってたような(忘れたけど
でもJavaでも位置揃えのために実践編でやったな
0301おれさま ◆6CTEZS59O00a
垢版 |
2018/11/11(日) 17:43:09.38
オブジェクト指向を勉強するのにJavaは適当で
特にスッキリシリーズは初学者にぴったりと聞いたんで使ってたんだけど
その通りだな

このC#のテキストは初学者にとっては厳しいんじゃないか
少なくともスッキリの系統だった教え方と比べると難易度高そう
最初から詰め込みすぎてる

逆に基本がわかってる多言語経験者にはよさそう
0302おれさま ◆6CTEZS59O00a
垢版 |
2018/11/12(月) 12:35:44.40
C#が初心者にとって向いてる点は、
ざっとみた限りではどの参考書もVisualStudio Communityの導入と
使い方を紹介して、これを使って学習を進めてるところだな

スッキリでは統合環境の説明が薄いせいで自分でeclipseの使い方を調べないといけなかった
初心者であっても統合環境がないと、試行錯誤するのに不便すぎる

VisualStudioはビルドすると勝手にexeが実行されてコマンドプロンプトが立ち上がる
プログラミングは最終的な実行ファイルを目にしないとやった感じがしない
そういう点でもいい
windowsユーザーにとってはやはりマイクロソフト製品は親和性が高く感じる
0303おれさま ◆6CTEZS59O00a
垢版 |
2018/11/12(月) 12:51:54.74
C#はJavaとCを足して二で割ったような言語だそうだ

三項演算子とか出てくると、はるか昔にすこしだけCをいじった時の記憶が戻ってくる
Javaっぽいんだけど、Cの話がちょくちょく入ってくる
どちらも多少やったことがあるおれにはぴったりなのかもしれない

独習の3章まで読んだ
全くの初心者ではないんだけど、内容が重めだから復習しないとすぐに知識が抜けそう
スッキリでいえば入門編と実践編が合体してるような感じだ
0304おれさま ◆6CTEZS59O00a
垢版 |
2018/11/13(火) 09:09:18.02
C#はメインメソッドは
Main
と書かないとダメなんだな
Javaみたいな
main
だとダメ

あと、文字列比較では
Javaと違って
==
を使う
0305おれさま ◆6CTEZS59O00a
垢版 |
2018/11/13(火) 11:38:04.43
public static void main(String[] args)
public static void Main(string[] args)

微妙に違うのはやめて欲しいわ 👀
Rock54: Caution(BBR-MD5:1341adc37120578f18dba9451e6c8c3b)
0306おれさま ◆6CTEZS59O00a
垢版 |
2018/11/13(火) 13:39:12.31
独習C#、1/4ぐらい読んだ
読んだとか言っても頭に入ってなかったら意味ないんで
今の5章終わったらもう一度最初から読み直すか
忘れちゃってる部分が多すぎると行き詰まる
0307おれさま ◆6CTEZS59O00a
垢版 |
2018/11/14(水) 13:44:17.37
>>53の最短一致のことも書かれてるな
網羅性が高いな、このテキストは。

しかし文字列操作分野は重い
Javaでも重かったが独習C#はさらに重い
Javaやってなかったら挫折コースまっしぐらだ

コレクションまだやってないのに出てくるし
まさかのラムダ式まで出てくるし
0308おれさま ◆6CTEZS59O00a
垢版 |
2018/11/17(土) 04:19:02.61
ふむむ
VisualStudio で Ctrl+F5 で実行したあと、
コマンドプロンプトを閉じると、フォーカスが出力ウィンドウに移ってしまう
コードエディタに戻ってコードの編集を続けたいのだが
マウスを使って戻すのがめんどくさい

ctrl+tab でコードエディタに戻る事ができる
0309おれさま ◆6CTEZS59O00a
垢版 |
2018/11/17(土) 04:26:04.89
机の上にキーボードおいてカチャカチャやってると深夜だと結構うるさい
タオルを下に置いたら劇的に音が小さくなった
これはいい
0310おれさま ◆6CTEZS59O00a
垢版 |
2018/11/17(土) 04:29:26.94
Javaでファイルやらstream系のクローズを自動化する書き方があったが
C#も同様の方法がある
独習C#では最初からこの方法で教えている

●C#
using () {}

●Java
try () {}
0311おれさま ◆6CTEZS59O00a
垢版 |
2018/11/17(土) 04:40:54.34
using (var writer = new StreamWriter(@"../../data.log")) {}

で2つ上のフォルダにファイル作成

ドット2つ+/ で上のフォルダ
ドット1つ+/ で現在のフォルダ

ファイル操作の練習するわけだけど
exeが作られているフォルダの階層が深いから
exeよりちょい上の方にテスト用のファイルを作る事にする
0312おれさま ◆6CTEZS59O00a
垢版 |
2018/11/17(土) 06:13:38.86
文字コードはほんとやっかいだ

ぐぐるとHTMLではUTF-8を使えと書いてある
これが主流だと。
でもPC上のファイルを開くとSJISしかない
この差は一体なんなんだ
これはJavaでも遭遇した問題だ
ちなみにSJISと判断したのは自分が使っているエディタで開くとそう表示されてるからだ

さらにぐぐってwindowsのメモ帳での文字コードの扱いを調べる
メモ帳では 「名前を付けて保存」 で文字コードを選択して保存ができるようになっている
選択肢にはSJISなどというものはない
ANSIとやらで保存するのがデフォルトのようだ

ANSI
日本語 Windows で ANSI と呼ばれているのは CP932 であり、
これは Shift_JIS が拡張されたもの
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1490895514

SJIS
シフトJISコードは、SJISとも呼び、Microsoft社が決めたコードで
Windows95やMS-DOSやMacなどで使用されています。
http://ash.jp/code/code.htm

ざっくり捉えると、ANSIもSJISもShift-JISということか
ウェブ上ではUTF-8を使えといいつつローカルではShift-JISがデフォルトとは。

でもって、C#でもJavaでもUTF-8が標準的な扱いとなっている
そのためローカルのテキストファイルを実験台として開くと、文字化けの問題が生じる

文字化け回避手段はこんなところか

メモ帳の別名保存によりUTF-8を選択すると
自分の使っているエディタで開いた時にりUTF-8と表示されている
このテキストに日本語を書き込んでから、C#のStreamReaderで開いてみると文字化けしない

もしくは、StreamReaderのインスタンス生成時コンストラクタに
Encording.GetEndording("SJIS")
を渡すと文字化けしない
0313おれさま ◆6CTEZS59O00a
垢版 |
2018/11/17(土) 08:41:48.22
StreamWriter に Encording.GetEndording("UTF-8") を渡して作ったファイルを使ってもおk


その他

https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11160634546
日本語 Windows 9x 系列は、システム内部、DOS プロンプト、
ファイルシステム(FAT16/FAT32)などがほぼ CP932 で統一されていました。

対して、Windows 10/8/8.1/7/Vista/XP/2000 などの
現在主流になっている Windows NT 系列は、ちょっと話が複雑になります。
まず、OS のシステム内部は Unicode UTF-16 に統一されました。
DOS プロンプトは廃されましたが、代わりに搭載されたコマンドプロンプトは、
未だ CP932 を標準で使います(切り替えは可能)。
ファイルシステム(NTFS)も Unicode UTF-16 を使うようになりましたが、
FAT32 は使用可能であり(この場合ファイル名は CP932 になる)、
またファイル内容は CP932 だったり Unicode UTF-8 BOM有りだったり
Unicode UTF-16 だったりします。


https://laboradian.com/char-encoding/
Shift_JIS

Windows の「メモ帳」で何か文章を書いてそのまま保存すると、
文字エンコーディングは「Shift_JIS」になり(厳密には CP932)、
改行コードは「CR + LF」になります。

UTF-8

Unicodeという文字コードを使って、文字を表現する方式の1つです。
現在(2017年)、ウェブサイトの多くは「UTF-8」を使っています。
Shift_JIS では、英語・日本語以外の文字を使うことができませんが、
UTF-8 であれば様々な言語の文字を一緒に使うことができます。
0314おれさま ◆6CTEZS59O00a
垢版 |
2018/11/17(土) 13:15:45.75
× encording
○ encoding

コードの補完機能であるインテリセンス(マイクロソフトの造語か)
頼りっきりになっているとスペル間違えて覚えてたりするんでよくない
eclipseにも補完機能あったけど、わざと手打ちしてた
C#でもそうした方がよさそうだわ
英単語思い出すきっかけにもなるし
0315おれさま ◆6CTEZS59O00a
垢版 |
2018/11/17(土) 13:51:39.20
ファイル操作で、テキストファイルの読み込みやってるんだけど
Javaみたいに

FileReader fr = new FileReader("test.txt", FileMode.Open);
StreamReader sr = new StreamReader(fr);

でもいけるし

StreamReader sr = new StreamReader("test.txt");

でもいけちゃう
Encoding.GetEncoding("SJIS")
はどちらのケースも StreamReader に渡す

C# は、こういう方法もOKだし、ああいう方法もOKだよってのが多いような
0316おれさま ◆6CTEZS59O00a
垢版 |
2018/11/17(土) 13:57:24.77
>>315
間違えた

修正

FileReader fr = new FileReader("test.txt", FileMode.Open);

FileStream fs = new FileStream("test.txt", FileMode.Open);

>>257と同じで、Writer/Reader が入ると文字ストリームかな
FileStream はバイトストリーム
NetworkStream
MemoryStream
もバイトストリーム
0317おれさま ◆6CTEZS59O00a
垢版 |
2018/11/17(土) 14:25:35.29
Console.WriteLineに渡す文字列だけど
変数混じりの場合、Javaと同じような記述方法でもいけるんだな

string st = "あああ";
Console.WriteLine(st + "と叫んだ");

みたいな感じ
こんな風↓しかダメと思ってた

Console.WriteLine(@"{st}と叫んだ");
0319おれさま ◆6CTEZS59O00a
垢版 |
2018/11/17(土) 16:03:30.98
1/3読んだけど
このまま先に進んでもスッカスカな知識になるんで
復習に入るか
覚えないといけない量はスッキリ1冊分ぐらいありそう
0320わがはい ◆0BMoNHqNlM
垢版 |
2018/11/17(土) 22:29:04.87
>>318
そりゃMath.powの戻り値はdouble型やからな
javaだとlong型の最大値を超える計算はBigInteger型使ってnew BigInteger("3").pow(300)で可能やけど、C#でも似た感じでできるんとちゃう?

一見するとPythonの方が便利に思えるけど、どのくらいメモリを食うかわからんちゅうことやから、システム開発なんかには不向きなんやな
0321おれさま ◆6CTEZS59O00a
垢版 |
2018/11/18(日) 08:18:24.19
テキストのちょい先でBigIntegerはやったけどね

そもそも目的というか得意としてる分野がハッキリしてるというのがいい
言語ごとに特徴が明確なら選択しやすい
0322おれさま ◆6CTEZS59O00a
垢版 |
2018/11/18(日) 16:53:55.00
intの範囲ぐらい正確に覚えても罰は当たらないだろう

まいなすにじゅういちおくよんせんななひゃくよんじゅうはちまんさんぜんろっぴゃくよんじゅうはち〜(絶対値1つ小さいプラス値)

-21 4748 3648 +21 4748 3647
0324おれさま ◆6CTEZS59O00a
垢版 |
2018/11/19(月) 11:32:11.19
int i = 128;
Console.WriteLine((sbyte)i);
結果:-128

これの説明で 「残りのビットを反転させる」 なんていう説明が出てくる
この辺を数学的にしっかり学んだ人はなんてことはないんだけど、
そうでないと不思議な感じがする
突然おもちゃを扱うような雑な操作が唐突にあらわれたような印象を受ける

127 (10)
01111111 (2)
127 (sbyte)

128 (10)
10000000 (2)
-128 (sbyte)

8bitで表した2進数の最初のビットは符号を表現するために使われる
これが 1 になったら、つまり10進数で言えば 127 から 128 になった時、
残りのビットを反転させてから、10進数にして 1 を加えてマイナス記号つければ
sbyte にキャストした値になるというものだ

10000000 の最初の 1 を除いた7つの 0 、0000000 を反転させると 1111111 となる
これは10進数でいうと 127 で 1 加えてマイナスを付けると -128

10000000

0000000

1111111

127

-128
0325おれさま ◆6CTEZS59O00a
垢版 |
2018/11/19(月) 11:43:42.11
この気持ち悪い唐突感を取り除くためにぼけぇと考えてたんだけど
これは2進数を持ち出さないでも10進数の範疇で自然なイメージを持てるのではないかと
そういう結論に至った

つまり、10進数で桁が変る瞬間、例えば 99 100 のような場合
上と同じような変遷を書くことができる

100

00
↓ ←ここが「反転」の操作を10進数で表現したもの
99

99

-100

反転とは補数の関係を使った変換なのでこれでいいだろう
数直線で考えたとき、0 から順にたどっていって 100 になった瞬間に、
ぽ〜んと 0 を挟んで真反対の側に飛ばされる感じがわかる
101 を同じように考えると

101

01

98

98

-99

なるほどと
0326おれさま ◆6CTEZS59O00a
垢版 |
2018/11/19(月) 11:52:03.92
2進数というスイッチカチャカチャの世界を、人が常用する10進数に重ねていくこの作業は見事だ
コンピュータが作られていく過程で試行錯誤を重ねてこういうものを作ってきた人たちがいたんだなと
0329おれさま ◆6CTEZS59O00a
垢版 |
2018/11/24(土) 09:48:38.45
まだテキストで勉強してない分野をJavaと同じように書いてどこまでいけるか試してた
コンストラクタ付きのクラス作って、インスタンス化したり。

同じソースファイル内に定義したクラスをインスタンス化する場合であっても
コンストラクタにpublicがついてないとエラーがでるのな
この辺Javaより厳しい
0330おれさま ◆6CTEZS59O00a
垢版 |
2018/11/24(土) 10:05:57.71
Java
文字列の長さを求めるには String.length()
配列の長さを求めるには 配列.length

C#
文字列の長さを求めるには String.Length
配列の長さを求めるには 配列.Length


() がついてりゃメソッドね、で終わるんだけどね

C#だとメンバの1つにプロパティというものがあって
セッターゲッター的な役割を担うようなことが書いてあった
どうやらC#の Length はこれっぽい
https://docs.microsoft.com/ja-jp/dotnet/api/system.string.length?view=netframework-4.7.2#System_String_Length

Javaの配列の length はもっとわかりにくそうなんで放置^^
0331おれさま ◆6CTEZS59O00a
垢版 |
2018/11/24(土) 15:56:56.22
string st1;
string st2;
st2 = st1 + "あああ";//未割り当てのローカル変数'st1'が使用されました。

string st1 = null;
string st2;
st2 = st1 + "あああ";//OK!

string st1;
string st2;
st2 = null + "あああ";//OK!
0332おれさま ◆6CTEZS59O00a
垢版 |
2018/11/24(土) 16:00:09.58
中身がnullだからどうのこうのの話でもないようだ
とにかく初期化されてないものを使うなみたいな?
st2みたいに代入される変数が初期化されてないならまぁいいやとか
0333おれさま ◆6CTEZS59O00a
垢版 |
2018/11/24(土) 16:05:48.92
独習C#80ページのコードを書いていて気づいたわけなんだけど
テキスト上ではstringの初期化として "" を使っている

var st = "";
string st = "";

みたいな感じで。
一応初期化は必ずやれと35ページに書いてある
0334おれさま ◆6CTEZS59O00a
垢版 |
2018/11/24(土) 17:25:13.15
Console.WriteLine(Math.Floor((0.7 + 0.1) * 10));// 7 ダメ
double num2 = (0.7 + 0.1) * 10;
Console.WriteLine(num2.ToString("G16"));// 7.999999999999999

Console.WriteLine(Math.Floor((0.7 + 0.2) * 10));// 9 OK!
double num1 = (0.7 + 0.2) * 10;
Console.WriteLine(num1.ToString("G16"));// 9


浮動小数点数に計算誤差がでちゃう例なんだけど
出る場合と出ない場合を予め区別して把握するのは難しそうだ
0335おれさま ◆6CTEZS59O00a
垢版 |
2018/11/24(土) 18:42:36.15
//正の小数・正の整数を2進数に変換
using System;
using System.Text;
using System.Text.RegularExpressions;

public class Program
{
public static void Main(string[] args)
{
const int Digit = 16;
string input = Console.ReadLine();
Regex rgx = new Regex(@"^([1-9]\d*|0)(.\d+)?$");
double num = 0;
if (rgx.IsMatch(input))
{
num = Double.Parse(input);
var num1 = Math.Floor(num);
var num2 = num - num1;

string num1_byte = Convert.ToString((int)num1, 2);

double a1 = 0;
StringBuilder sb = new StringBuilder();
sb.Append(num1_byte);
sb.Append(".");
for (var i = 0; i < Digit; i++)
{
a1 = num2 * 2;
a1 = Math.Floor(a1);
sb.Append(a1.ToString());
if (a1 >= 0)
{
num2 = num2 * 2 - a1;
}
else
{
num2 = num2 * 2;
}
}
Console.WriteLine(sb.ToString());
}
else
{
Console.WriteLine("適正な数値ではありません");
}


}
}
0336おれさま ◆6CTEZS59O00a
垢版 |
2018/11/24(土) 18:45:05.73
いちいち紙に書いて計算してたけど
あほらしくなって自分で作ってみた
正規表現だけはコピペしてズル

小数部分の桁数は定数で指定
対象となる10進数はキーボードからの入力
0337おれさま ◆6CTEZS59O00a
垢版 |
2018/11/25(日) 07:42:11.25
独習の「同一性(Identity)」=スッキリの「等値(equality)」
→同じオブジェクトを参照、つまり完全一致(==)


独習の「同値性(Equivalence)」=スッキリの「等価(equivalent)」
→オブジェクトが同じ値をもっていれば十分(equals)



この辺業界で統一した用語使って欲しいもんだ
どちらかというと、独習の用語の方が直感的で「スッキリ」してる感じする
0339おれさま ◆6CTEZS59O00a
垢版 |
2018/11/25(日) 08:08:06.13
Equals の s は三単現の s で
SequenceEqual に s がついてないのは配列という複数要素の一致を要求してるからなのかとか
ぼけぇ〜と考えてたが
でもSequence自体は単数だよなとか

まぁいいや
0340おれさま ◆6CTEZS59O00a
垢版 |
2018/11/25(日) 09:16:40.68
bool? b = true;
if (b) {}

というのはダメみたいだ
if 文の条件式は bool でないとだめ
bool? はダメ
0341おれさま ◆6CTEZS59O00a
垢版 |
2018/11/25(日) 09:32:00.02
@
null条件演算子(P.64) 非nullのときだけメンバにアクセス
string unspace = str?.Trim();
A
null合体演算子(P.92) nullの時のデフォルト値を与える
Console.WriteLine(num ?? 100);
B
論理積のショートカット演算(P95) 非nullのときだけメソッドにアクセス
if (str != null && str.StartsWith("http://";) { }


nullを予見したいろんな手法
Bの時に@を使えないか考えてみたんだけど
条件式に
str?.StartsWith() を置いてしまうと、ここが bool? つまりnull許容型の bool と判定されてしまう
if文の条件式に bool? は使えないようなのでエラーが出てしまう
null がきちゃうと判断出来なくなっちゃうから仕方ないのか

Bは大事なんじゃないかと思ってる
VBAのプログラム組んでたときに論理積・論理和系の条件式でよくわからないエラーがでてたのは
これじゃないかと、今思えばだけど。
当時は null を放置しておくと条件式でエラー出ちゃいがちだということを経験からわかってたんで
とりあえず適当な値入れて回避してたんだけど。
0342おれさま ◆6CTEZS59O00a
垢版 |
2018/11/26(月) 03:32:45.42
>>324
>>325
これ>>335でぽちぽちやりながら
このへんをさらに掘り下げてたんだけど
根本的な部分が理解できた

一つ一つの処理であったりルールは理解できるんだけど
なんだかもやもやがついて回る
複数の疑問点が浮かび上がるんだけど、最終的に集約されていくのはこの疑問

Q.「なぜ負の数を表すのにわざわざ補数を使うのか」

言ってることはわかるけど、そもそもなんでこんなことしてんの的な疑問というのは
どこが謎の源泉になっているのか、自分の思考を分析するのがやっかいだ

自分なりにたどり着いた答えがこれ

A.「コンピュータは引き算をしたくないから」

もっというと

A.「スイッチON/OFFの世界だけで計算したいから」

細かく経緯を説明し始めると長くなるんだけど、
ビット演算やらこの辺の分野全てにわたる話なんだと思う
0343おれさま ◆6CTEZS59O00a
垢版 |
2018/11/26(月) 05:20:57.02
補数が関係してくるのはbit演算のうち否定演算

では、
& 論理積
| 論理和
これらはどう使われるのか

まだ学んでいないので想像でしかないんだけど、例えばこんな感じなのか

絵がいくつかあって
A,B,Cと名前を付けるとする
これらの絵は4色の絵の具(赤・青・緑・黒)を使って描かれているのだが
全ての色を使っているわけではない
どの色を使っているかによって場合分けして処理していきたい

このような処理をするときに、ある工夫をしてみる

まず色ごとに特定の2進数を割り当てる(()内は10進数)

int r = 0b0001; //赤(1)
int g = 0b0010; //緑(2)
int b = 0b0100; //青(4)
int w = 0b1000; //白(8)

見て分かるように1をずらしただけのものだ
スイッチのように考える
一番右のスイッチがONのものは赤、みたいな感じ

そして絵A・B・Cについても2進数で表現する
このとき、それぞれの絵がどの色を使っているかによってスイッチON/OFFを切り替える

int artA = 0b0011; //A(3) 緑と赤を使用
int artB = 0b1001; //B(9) 白と赤を使用
int artC = 0b1111; //C(15) 全色使用

前提はここまでで、具体的にこれらをどうつかっていくかを説明(想像)する
例えば、絵Aが赤の絵の具を使っているかどうかによって条件分岐させたいならこうする

if ((artA & r) == 0b0001) { }

絵Aと絵Bで使っている色を全部列挙したいなら

int result = artA | artB;

としてから result について分析すれば分かるだろう
分析方法を想像すると・・・
if ((result & w) == w) { } //白を使っている

みたいな感じか
似たようなことがTCP/IPの本を読んだときも書いてあったような気がする
0344おれさま ◆6CTEZS59O00a
垢版 |
2018/11/26(月) 05:22:35.23
結局、スイッチON/OFFの世界をどうやってうまく利用していくかなんだろうな
すごいもんだ
0345おれさま ◆6CTEZS59O00a
垢版 |
2018/11/26(月) 05:39:25.97
ちなみにだけど

if ((artA & r) == 0b0001) { } ○

if (artA & r == 0b0001) { } ×(エラー)

なので注意
0347おれさま ◆6CTEZS59O00a
垢版 |
2018/11/27(火) 11:51:09.28
public class Program
{
 public static void Main(string[] args)
 {
  for (var i = 0; ; i++)
  {
   int num = new Random(i).Next(1000);
   Console.WriteLine(num);
   if (num == 500)
   {
    break;
   }
  }
 }
}

乱数生成して遊んでた
乱数好き
Randomクラスのコンストラクタに渡す引数は「シード値」といって
これが同じだと生成される乱数は変らない
ここはJavaとは違うよね確か。
まぁそういうわけでシード値を次々に変えていくために
カウンター変数をシード値として流用

練習コードを書くときに乱数を使うとちょっと動きのあるコードを書けるので面白い
0349おれさま ◆6CTEZS59O00a
垢版 |
2018/11/28(水) 10:12:28.84
シード値はJavaでも同じかな
シード値のデフォルトが違うかもしれない
めんどうなんで調べないけど
0350おれさま ◆6CTEZS59O00a
垢版 |
2018/11/28(水) 10:48:40.10
スッキリわかるSQL入門 第2版 ドリル222問付き! (スッキリシリーズ)
中山清喬

ぽちった
0351おれさま ◆6CTEZS59O00a
垢版 |
2018/11/28(水) 21:36:57.44
5章やってたんだけどラムダ式が結構出てくる
先に押さえておきたくて10章に一時的に出張中

この辺はJavaでは薄くしかやってないので
しっかりやらないと理解できない
delegateから始める
0352おれさま ◆6CTEZS59O00a
垢版 |
2018/12/01(土) 07:36:12.73
VBAのちょっとしたのを組まなければならなくなってちょいと中断
さっさと終わらせたい
0355おれさま ◆6CTEZS59O00a
垢版 |
2018/12/01(土) 14:08:34.12
いつもやらかすのは

Range(Cells(i, j), Cells(k, l))

みたいにRangeの指定をCellsを使ってやるケース

このとき、
With ThisWorkbook.Worksheets("なんとか")
で囲ってるなら
Cellsの前にもドットが必要なんだけど、これを忘れる
そしてそれに気づかない
今日もやらかしてしばし作業がとまった
0356おれさま ◆6CTEZS59O00a
垢版 |
2018/12/01(土) 15:23:44.31
C#

Splitクラス

区切り文字はchar型なのでシングルクオーテーションを使わないといけない
string型のダブルクオーテーションを使うとエラー

すぐ忘れる

あと、区切り文字で new[] を使わない時は { } をつかってはダメ
0357おれさま ◆6CTEZS59O00a
垢版 |
2018/12/01(土) 16:55:30.57
正規表現

\d{2,4} ○
\d{2, 4} ×

なんとスペース入れるとダメ
今気づいた
こういうのって実際にコードを打ち込んでみて失敗しないと気づけない
あと、おれはそんな記憶力良くないんで、実際にコード打たないと覚えた気になってて
実際は覚えてないということになる

めんどうだけど、とにかくできる限り全てのコードを打って試していこう
テキストのコードを自分なりに少し変えて試す

いや、これがまためんどくさいのだが、ためになる
0358おれさま ◆6CTEZS59O00a
垢版 |
2018/12/02(日) 08:13:23.33
命令文の中に「:」が入ってくるようなクラスを説明する時に
Console.WriteLineの中に「:」を入れるのはやめて欲しいわ
そうでなくてもできる限り記号を入れないで欲しい
例えば

Console.WriteLine($"位置:{m.Index} 長さ:{m.Length}");

とかいうコード

Console.WriteLine($"位置は{m.Index} 長さは{m.Length}");

でいいだろ
このコードでは「:」は混同の原因になりにくいかもしれないけど
例えば三項演算子とか入ってきたりした場合とか
0359おれさま ◆6CTEZS59O00a
垢版 |
2018/12/02(日) 09:45:34.92
ふぅ 5章の重さは半端ないわぁ
2周目なんだけどしっかりやってるとなかなか進まない
1周目で理解しそびれた部分押さえるのが精一杯
0360おれさま ◆6CTEZS59O00a
垢版 |
2018/12/02(日) 10:03:46.50
せめて9章までやらないと基本分野網羅できない感じする
ここまでやると
コレクション
オブジェクト指向の各分野
を大体押さえることができそう

新版のスッキリSQLも届いたのでちょくちょく目を通していこうかな

GUIアプリをC#でつくるための参考書も買ってあるので
のぞいてみたんだけど、JavaのSwingで作るよりずいぶん簡単そうな感じがする
クラス定義の後ろの方に「:」があるようなコードが書いてあったのだが
これはまだやってない分野だ
自動で作られたコードを隅々まで理解できるようになりたいので
独習の方を先に進めることにする
0361おれさま ◆6CTEZS59O00a
垢版 |
2018/12/03(月) 13:06:46.85
5章2周目クリア
もう一周ぐらいやらないとダメなことは分かっているが
復習はまたあとにして6章に進む
0362おれさま ◆6CTEZS59O00a
垢版 |
2018/12/04(火) 13:59:18.21
Dictionary で使っている Red-Black tree だけど、なるほどなぁ
これは foreach で取り出すとき、できるだけ左側の下の方から探索していくのか
こういうアルゴリズムって面白いな
0363おれさま ◆6CTEZS59O00a
垢版 |
2018/12/04(火) 14:01:24.00
>>358の「:」はインターフェースの実装だったようだ
この辺はJavaと記述が違うからC系から引き継いだものかな
0364おれさま ◆6CTEZS59O00a
垢版 |
2018/12/04(火) 15:12:33.74
コレクションも配列もSortの規則を変えるにはラムダ式を使おう!

var l = new List<int>() { 100, 200 };
l.Sort((x, y) => (-x) - (-y));
Console.WriteLine(string.Join(",", l));

var ary = new[] { 100, 200 };
Array.Sort(ary, (x, y) => (-x) - (-y));
Console.WriteLine(string.Join(",", ary));
0367おれさま ◆6CTEZS59O00a
垢版 |
2018/12/07(金) 05:06:13.54
すっきりとちがって独習はたまに誤解を招きそうな表現があるんで気をつけないといけない
おまえらぐらいだとこの程度の説明でわかるだろ?あ?
みたいなのを感じる
が、おれは残念ながら分からない
この説明端折りすぎてんなと思ったらコードいろいろ書いて確認してる
0368おれさま ◆6CTEZS59O00a
垢版 |
2018/12/07(金) 08:57:32.42
C#ではインスタンス経由でstaticメンバにアクセスできないのか
Javaだとスッキリ入門で複数の勇者インスタンスが、共有のお金にアクセスするために
static int maney を定義していたが、ああいうのはだめなのか

独習278ページ
「クラスメソッドはオブジェクト経由では呼び出さない」
0369おれさま ◆6CTEZS59O00a
垢版 |
2018/12/07(金) 10:20:09.17
Mathクラスがなぜ静的クラスなのかを説明している文だけど
関連した機能を一つのクラスにまとめることでわかりやすいから、
みたいな説明がされている

これって説明になってないと思う

そうじゃなくて、このような数学的な処理ってのは
引数を渡して即座に処理をして結果を返せば足りるんで
いちいちデータをフィールドに格納しておく必要はないから
ってのが最大の理由じゃないの

そもそもインスタンス化の最大の利点はインスタンスごとに
異なるフィールド値を格納しておくことができる点でしょ

そこを説明してないのってちょっとあれだと思うんだけどどうなんだろうか
ちがうんかね
独習287ページ
0370おれさま ◆6CTEZS59O00a
垢版 |
2018/12/08(土) 03:39:21.77
値型の値渡し
参照型の値渡し
値型の参照渡し
参照型の参照渡し

今読んでてちょい混乱したけどもうおk
「値渡しはコピー」で
「参照渡しはこれをみてね」
みたいな理解でいけた

これCでもやったような記憶があるがデジャブだろうか

面倒だがひとつひとつテストコードを自分で書いて確かめてみようか
0371おれさま ◆6CTEZS59O00a
垢版 |
2018/12/08(土) 11:56:46.33
自作のJavaプログラムだけど、ちょっと前から動かなくなってた
どうやらJDKのパージョンアップにともなって仮想マシンにアクセスできなくなっていた
ユーザー側の問題になるんだけど、バージョンアップ程度で環境変数やらいじらせるのっていまいちだな
やっぱwindowsアプリつくるならC系なのかね
0372おれさま ◆6CTEZS59O00a
垢版 |
2018/12/09(日) 07:36:37.58
素数かどうか調べるプログラムに感心した

平方根となる小数を切り捨てて整数にする
この整数の値になるまで2から順に除算をして
余りが0になるものがあるか調べる
ヒットする場合は素数ではない

var prime = true;
for (var i = 2; i <= Math.Floor(Math.Sqrt(num)); i++)
{
 if (num % i == 0)
 {
  prime = false;
  break;
 }
}

中学校の数学で必死こいてやってた作業と全く同じだ
「真ん中」まで調べる的な
0373おれさま ◆6CTEZS59O00a
垢版 |
2018/12/09(日) 07:49:41.09
IEnumerable<>を戻り値として使うイテレーター構文は
foreachを簡単に使えるようにするために利用される
(foreachを使えるようにIEnumerableインターフェースを実装するのは大変なので)

ポイントは
yield return (と、yield break)
0374おれさま ◆6CTEZS59O00a
垢版 |
2018/12/09(日) 15:59:29.32
独習318ページの3.@の解答
readonlyと書いてあるけどprivateだよなこれ
いちいちここに書いてないけど誤植がちらほらある
誤植だと思い違いしてるケースも考えられるので実際困る
0376おれさま ◆6CTEZS59O00a
垢版 |
2018/12/11(火) 14:39:54.48
インデクサーの説明わかりにくいなあ
インスタンス名[index] でインスタンスを利用したいときに使うみたいな感じか
フィールドが配列の時に使うとうまい具合に組み合わさって利用価値があるみたいな
0377おれさま ◆6CTEZS59O00a
垢版 |
2018/12/11(火) 15:00:20.81
インスタンス名[ ] の形式で利用したいなら自由に使えるようなものなので
例えば[ ]の中が要素番号的なものでなくても使えると。

class Test
{
 public string this[string st]
 {
  get { return st; }
 }

}
class Program
{
 public static void Main(string[] args)
 {
  var t = new Test();
  Console.WriteLine(t["aaa"]);//結果「aaa」
 }
}
0378おれさま ◆6CTEZS59O00a
垢版 |
2018/12/11(火) 15:02:25.81
で、フィールドが配列の時に、インデクサーを組み合わせて使うと
真価を発揮できると(まるで真価を発揮できてない例だが・・・・

class Test
{
 string[] ary = new string[3];
 public string this[int index]
 {
  set { ary[index] = value; }
  get { return ary[index]; }
 }

}
class Program
{
 public static void Main(string[] args)
 {
  var t = new Test();
  t[0] = "aaa";
  Console.WriteLine(t[0]);//結果「aaa」
 }
}
0379おれさま ◆6CTEZS59O00a
垢版 |
2018/12/11(火) 15:31:09.84
this[string st]
this[int index]
の部分が大事で、こういう使い方をすると便利だなと思うような場面で使えば良いのかな
特にインスタンスを配列ライクに使いたい場合
インスタンスをforで回しながら何かをインスタンス内のどこかに代入していきたいとか
0380おれさま ◆6CTEZS59O00a
垢版 |
2018/12/13(木) 14:28:36.18
忙しくなってきて時間裂けなくなってきたけど
少しずつでもいいんでやっていこうと思う
0381わがはい ◆0BMoNHqNlM
垢版 |
2018/12/14(金) 21:36:14.76
マッマに新しいPC買ってもらっただで
今までは簡単なアプリをGooglePlayにリリースしてきたけど、ようやく本格的なアプリが作れそうや

あとは今運営してる比較サイトもAjaxで非同期にデータベースとアクセスできるようにしたい
Googleが提供してるFireBase使えば、サーバーサイドの開発する必要すらないみたいやな
便利な時代になったで
0382おれさま ◆6CTEZS59O00a
垢版 |
2018/12/15(土) 08:52:59.06
ぐぐるさんは優秀なapi無料で公開してくれてるからありがたいんだけど
セキュリティ固めてる環境からアクセスするようコードに仕込んでると
そのうち担当者から怒られそうなのがネック
0383おれさま ◆6CTEZS59O00a
垢版 |
2018/12/16(日) 13:50:25.94
ふぅ 8章まで終わった
覚えてるのかと言われたらスッカスカだが一応理解はした
スッカスカで先に進むと理解できなくなりそうだが
ここは敢えて進むのだ
0384おれさま ◆6CTEZS59O00a
垢版 |
2018/12/17(月) 10:25:03.37
>>343は列挙型で使うようだ
「<<」演算子を使うと、色ごとに2進数を割り当てる時に、
1をズラしたものを簡単に定義できる

int r = 1;     //0b0001 赤(1)
int g = 1 << 1; //0b0010 緑(2)
int b = 1 << 2; //0b0100 青(4)
int w = 1 << 3; //0b1000 白(8)

こんな風に
0385おれさま ◆6CTEZS59O00a
垢版 |
2018/12/18(火) 12:39:07.59
ちょいGUIに寄り道する
入門本買ってあるので簡単なものを作れるようにしていく
Javaの時と同じ流れでやっていく
0386おれさま ◆6CTEZS59O00a
垢版 |
2018/12/18(火) 12:50:19.99
slnファイルをクリックするとそのソリューションがVisual Studioで立ち上がる

ふむふむ
0387おれさま ◆6CTEZS59O00a
垢版 |
2018/12/18(火) 13:20:24.31
違う本読むとまたそれはそれで勉強になるわぁ
Visual Studioの使い方適当にやってたけどいろいろと説明してくれててありがたい

オブジェクト指向がどういう流れで生まれてきたのかとか、
この辺は著者によっていろんな説明してくるけど、この本の説明は頭にすっと入る
データベースの誕生に関連させてオブジェクト指向の誕生を説くあたり

別のプログラムを組む時に、他のプログラムから一部借用してきたりとか、そういう再利用のしやすさ
0388おれさま ◆6CTEZS59O00a
垢版 |
2018/12/18(火) 13:39:17.87
ふーむ
これはVBEのフォーム組むのとすごーく似てるね
VBAのプロパティってC#のプロパティと同じものなのか
オブジェクト指向のインスタンスやプロパティ、メソッドをコードからじゃなくて
VisualStudioのGUIを使って説明するとか斬新だわ

あと、デザイン画面でぽんぽんとコントロールを貼り付けていくと
勝手にコードが背後で生成されていくわけなんだけど
このコードも理解したいな
JavaでSwingで試してた時は全部自分で書いてたわけで
C#では相当楽できるんだが、仕組みは分かっておきたい
パーシャルクラスとかさっき勉強したばかりのを使ってて復習にもよさそう
0389おれさま ◆6CTEZS59O00a
垢版 |
2018/12/18(火) 13:54:22.10
Program.csがMainメソッドを持つ主か
ここからスレッドを走らせ
編集対象となっているForm1.csのForm1クラスのインスタンス生成
Form1クラスのコンストラクタがInitializeComponentメソッドを呼ぶ
これはデザイン用に用意されているForm1.Designer.csにあるメソッドで
ちょうど、Swingでコンストラクタの最初の方に書いていたようなコントロールの配置とかが書いてある
各コントロールの実際の動きはForm1にメソッドとして記述していくわけか
Javaでのイベント系の処理とどの程度類似してるか
そっくりというわけではなさそうだ
0390おれさま ◆6CTEZS59O00a
垢版 |
2018/12/18(火) 15:28:42.09
この辺を理解するには独習の最後の最後を読んだほうが良さそうだ
いろいろ調べてみたんだけど、マルチキャストデリゲートなのかな
それだけでは説明できない要素が加わっているようなので、これを理解するには
独習の最後、ほんとに最後なんだよなこれ、ここを読むほうがよさそう

で、明日読もう
今日は終わり
0391おれさま ◆6CTEZS59O00a
垢版 |
2018/12/20(木) 21:18:18.08
public delegate void MyEventHandler(object sender, EventArgs e);

class Program
{
 public event MyEventHandler myEvent;

 public void handler(object o, EventArgs e)
 {
  Console.WriteLine("handler called");
 }

 public static void Main(string[] args)
 {
  Program target = new Program();
  target.myEvent += target.handler;//+= new MyEventHandler(target.handler)も可

  target.myEvent(target, EventArgs.Empty);
 }
}

eventを使った簡単な例

new使ってデリゲートに代入する方法を忘れてた
ネットで調べるとこの書き方を使ってるものが多かったので何だこりゃと思ったんだけど
よくよく独習読み直したら最初の方に書いてあった

target.myEvent(target, EventArgs.Empty); に相当するコードは
windowsアプリでボタンとかをデザイン画面で作った時に自動生成されるコードには見当たらない
ボタンを押したときに内部的にこのコードと同じ機能が働くことで
デリゲートに代入されているメソッドが実行されるという流れなのか

object o
EventArgs e
この2つの引数もわかりにくい
oはイベントの呼び出し元のインスタンスを意味するみたいだ
EventArgsはまだよく分からない
0392おれさま ◆6CTEZS59O00a
垢版 |
2018/12/20(木) 21:29:42.81
o は 「イベントを発生させたオブジェクト」

と書いた方がよかった

EventArgs e は 「ハンドラに渡す引数」
上の例だと渡すべき引数がないのでEventArgsクラスのEmptyプロパティがついている

ここ↓を参考にしてるんだけど、おれにとっては一番わかりやすい
http://www.atmarkit.co.jp/fdotnet/csharp_abc/csharp_abc_013/csharp_abc01.html
EventArgs eについてもここ↓
http://www.atmarkit.co.jp/fdotnet/csharp_abc/csharp_abc_013/csharp_abc02.html
で理解出来そうだ
0393おれさま ◆6CTEZS59O00a
垢版 |
2018/12/20(木) 22:02:43.05
なんとなくだけど、分かった気がする
ハンドラ、つまり、実際に実行されるメソッドなんだけど、これに情報を渡したい時がある
このとき、場合によってどういう情報を渡したいのかは様々なので、
自分でクラスを作ってそこに情報を記録してわたせということか。
その際、EventArgsクラスを継承してクラスを作る事になる

その例となるコードが上に上げたURL2個目に書いてある

では、これがwindowsアプリを作った時に自動生成されるコードにどういう形で反映されているかだ

e に何を情報として詰め込んで渡しているかは、自動生成されたコードには書かれていない
これはボタンとかのAPIが内部的にやってるようだ

ここでよくよく考えてみると、JavaのSwingでも同じような e が出てきた
例えば>>109
右クリしたときのmouseClickedメソッドはMouseEvent eを引数として受けとるわけだけど
この e を使って、showメソッドに e.getComponent(), e.getX(), e.getY() という引数をわたしている
この getComponent(), getX(), getY() こそが内部的に e に格納されいる情報というわけか
まぁここでは情報というかメソッドではあるんだけど、e について用意されたものなわけだ

同じ事をC#でやろうとしても、ちょっと勝手が違う
0394おれさま ◆6CTEZS59O00a
垢版 |
2018/12/20(木) 22:13:25.62
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 9);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(51, 12);
this.label1.TabIndex = 0;
this.label1.Text = "こんにちは";
this.label1.DoubleClick += new System.EventHandler(this.label1_DoubleClick);


private void label1_DoubleClick(object sender, EventArgs e)
{
 label1.Text = "ダブルクリックされました";
 MessageBox.Show(sender.ToString() + "\n" + e.ToString());//@
}


これは、「こんにちは」と書かれたラベルをデザイン画面で作った時に自動生成されたコード
ラベルをダブルクリックしたときに「ダブルクリックされました」とラベルの表示が変るようにしてある

ここに、今問題としている引数2つ、senderとeの内容をToString()で表示させる一行を加えた@
@の結果はこう↓
System.Windows.Forms.Label, Text: ダブルクリックされました
System.Windows.Forms.MouseEventArgs
0395おれさま ◆6CTEZS59O00a
垢版 |
2018/12/20(木) 22:24:51.24
Javaでは e と打ったあと、自動補完システムが e について使えるフィールドやメソッドを
示してくれた
C#でもインテリセンスが示してくれるんだけど、
Objectクラスのメンバのようなものしか表示されていないようだ
そこで、この一行を@の代りに使ってみる

MessageBox.Show(sender.ToString() + "\n" + ((MouseEventArgs)e).Clicks);

これは、((MouseEventArgs)e). まで書いたときに、インテリセンスが羅列した候補からClicksを選んだ場合だ
このようにMouseEventArgsでキャストすることで、Javaと同じように e の実際のメンバが表示できた
要は、基底クラスのEventArgsのままだとメンバが表示されないので
派生クラスのMouseEventArgsにキャストし直したというわけだ
e がどのクラスなのかは、>>394でやったようにToString()を使って知ることができる

ちなみに、結果は

System.Windows.Forms.Label, Text: ダブルクリックされました

2

とでる
e から、クリックの回数である 2 という情報を引き出せたことになる

一応満足した
0396おれさま ◆6CTEZS59O00a
垢版 |
2018/12/21(金) 02:45:55.79
((MouseEventArgs)e).X
((MouseEventArgs)e).Y
相対座標もこれで取得できる
ラベルの左上が原点かな?たぶん

C#はこの辺の理解全くなしでGUIアプリを組めるという点では楽だな
その反面理解なしに進んでしまうから、そのうち壁にぶつかりそうだけど

これまでコンソールアプリだとVisualStudioの画面に、
windowsアプリだとMessageBox.Show()でメッセージボックスに
文字情報を出力してきたけど
これからはフォーム上に作ったテキストボックスに出力する方がよさそうだ
こぴぺもできるしね

ここにコード貼るときにタブというかスペースを加工しないと
うまくインデントを表現できなかったので、正規表現使えるエディタで置換してた
ただ、ちょっと使いづらい
そこで、この加工をする専用のwindowsアプリを自分で作ってみようかなとか思ってる
簡単そうだし役に立ちそう
0397おれさま ◆6CTEZS59O00a
垢版 |
2018/12/21(金) 14:46:10.20
でけた〜
初のC#アプリ
やっぱりC#は簡単に作れるなぁ

正規表現でちょっと迷ったところがあったけど
サブマッチパターンに名前を付けて処理することで解決した
0398おれさま ◆6CTEZS59O00a
垢版 |
2018/12/21(金) 15:23:30.36
private void button1_Click(object sender, EventArgs e)
{
 string textBox1Value = textBox1.Text;
 var rgx = new Regex(@"(?<wideSpaces>^( )*)(( ){4})", RegexOptions.Multiline);

 while (rgx.IsMatch(textBox1Value))
 {
  textBox1Value = rgx.Replace(textBox1Value, "${wideSpaces} ");
 }

 textBox2.Text = textBox1Value;
}

目的は、
マルチラインのtextBox1に表示されているコードの全てのインデント(半角スペース4個)を
全角スペース1個に置換し、結果をtextBox2に表示させること

方法はいろいろあると思うけど、こういう流れでやった

マルチラインモードの正規表現で文字列先頭にある半角スペース4個セットを検索して、
これを全角スペース1個に置換。
半角スペース4個セットは複数並んでいる場合もあるため、一度では処理できない

そこで、whileで半角スペース4個セットがなくなるまで回す方向で考える。

正規表現に少し手を加える
文字列先頭にある「0個以上の全角スペースと、これに続く半角スペース4個セット」を検索し
これを置換する。0個以上の全角スペースとは、置換済のインデントを意味する
どのように置換するかだが、
0個以上の全角スペースはそのままで、半角スペース4個だけを全角スペース1個へ置換する
0個以上の全角スペースはそのまま残すため、
この部分を丸括弧でくくってサブマッチパターンとし、wideSpacesと名前を付ける

(?<wideSpaces>^( )*)

そして、置換後文字列にwideSpacesを利用する

最初はsplitして一行ごとに処理していたけど、せっかくだからマルチラインモードとかの
復習も兼ねて、てんこ盛りでやってみた
文字列の途中に半角スペース4個がないと仮定するならもっと簡単なのだが
そこはこだわってちゃんと作ってみた
貼ってあるコードは、もちろん作ったばかりのアプリで置換作業をしたもの。
0399おれさま ◆6CTEZS59O00a
垢版 |
2018/12/22(土) 15:28:42.73
windowsアプリの入門本使っていくつか作ってるんだけど簡単に作れるわ
今の知識だけでもいろんなもの作れそう
Javaでも外部ライブラリやら導入すればもっと簡単にできたのかもしれないけど
VisualStudioだと追加導入の手間いらずでこれだけ作れるのはすごい
今ちょうど>>119-121に相当するコードを書いていたのだけど、ずっと簡単にかける
前回閉じた場所で開く機能も試しにやってみたいがどうすっか
0400おれさま ◆6CTEZS59O00a
垢版 |
2018/12/22(土) 17:44:48.34
閉じたときの場所をlocation.logに記録して
開いた時にlocation.logから座標を読み取って再現するという
Javaでもやった例のパターンなんだけど

開いた時にロードする時、当然コンストラクタに記述するんだろと思いきや
windowsアプリだとイベントとして記述するみたいだ
これも斬新だな
0401おれさま ◆6CTEZS59O00a
垢版 |
2018/12/22(土) 17:54:18.81
private void Form1_Load(object sender, EventArgs e)
{
 string str = null;
 int x = 0;
 int y = 0;
 
 if (File.Exists(Path))
 {
  using (sr = new StreamReader(Path))
  {
   str = sr.ReadToEnd();
  }
  var rgxX = new Regex(@"(^x=)([0-9]+)", RegexOptions.Multiline);
  var strX = rgxX.Match(str).Groups[2].Value;
  var rgxY = new Regex(@"(^y=)([0-9]+)", RegexOptions.Multiline);
  var strY = rgxY.Match(str).Groups[2].Value;
  if (int.TryParse(strX, out x) && int.TryParse(strY, out y))
  {
   this.Left = x;
   this.Top = y;
  }
  else { SetCenter(); }
 }
 else { SetCenter(); }

 void SetCenter()
 {
  this.Left = (Screen.PrimaryScreen.Bounds.Width - this.Width) / 2;
  this.Top = (Screen.PrimaryScreen.Bounds.Height - this.Height) / 2;
 }
}

座標をロードするハンドラ
Pathはクラス定数としてlocation.txtが定義されてる
location.txtにはフォームを閉じる際、
x=100
y=150
のような形式で座標が登録されるようになっているので、
ロードハンドラではこれを読み込むことになる
正規表現はお気に入りのサブマッチパターンを使った
TryParseでx,y座標ともにintへの変換が成功した場合のみフォーム表示の座標として利用
失敗したときは内部メソッドのSetCenterを呼び出してモニタ中央に表示させる
0402おれさま ◆6CTEZS59O00a
垢版 |
2018/12/22(土) 18:11:47.95
フォームを開く時にモニタ中央に表示させるコードとしてこういうものがある

this.StartPosition = FormStartPosition.CenterScreen;

これを使うのであれば、コンストラクタに書く必要がある
上のロード用のイベントハンドラはどうやらフォームが表示されたあとに動いているようだ
ハンドラにStartPositionを書いてしまっても今更ということになってしまう
そのため、SetCenterメソッドでは、
すでに表示されているフォームの位置を変更するという形をとっている
0403おれさま ◆6CTEZS59O00a
垢版 |
2018/12/23(日) 02:47:39.01
例えばカレンダーをつくるとして、日付を表示するパネルが42枚並んでるとする
このとき各日付パネルをクリックすることで何らかのアクションを起こしたい時
Form1クラスに42個のイベントハンドラを並べるのはどうなんだと思い調べてみた

https://dobon.net/vb/dotnet/control/buttonarray.html

配列を利用することになるんだけど
いくつかの方法があるようだ
0404おれさま ◆6CTEZS59O00a
垢版 |
2018/12/23(日) 03:24:19.38
uint x;
Console.WriteLine(uint.TryParse("-10", out x));


結果はfalse
これを利用することで、モニタの表示画面からはみ出した座標が記録されていた場合
次に開く時はモニタ中央に開けるかやってみた


string str = null;
uint x = 0;
uint y = 0;

if (File.Exists(Path))
{
 using (sr = new StreamReader(Path))
 {
  str = sr.ReadToEnd();
 }
 var rgxX = new Regex(@"(^x=)([0-9]+)", RegexOptions.Multiline);
 var strX = rgxX.Match(str).Groups[2].Value;
 var rgxY = new Regex(@"(^y=)([0-9]+)", RegexOptions.Multiline);
 var strY = rgxY.Match(str).Groups[2].Value;
 if (uint.TryParse(strX, out x) && uint.TryParse(strY, out y))
 {
  this.Left = (int)x;
  this.Top = (int)y;
 }
 else { SetCenter(); }
}
else { SetCenter(); }

void SetCenter()
{
 // this.StartPosition = FormStartPosition.CenterScreen;はForm_Loadイベントハンドラでは機能しない
 this.Left = (Screen.PrimaryScreen.Bounds.Width - this.Width) / 2;
 this.Top = (Screen.PrimaryScreen.Bounds.Height - this.Height) / 2;
}


一応いけるんだけどサブモニタ上ではうまく機能しないようだ
マイナスのy座標が記録されている場合でも、そのままの座標で開いてしまう
メインモニタ上では機能するので、とりあえずいいか
0405おれさま ◆6CTEZS59O00a
垢版 |
2018/12/23(日) 04:52:11.42
あーちょいまてよ
正規表現にマイナスが含まれてないな
この辺でおかしくなってそうだ
今いそがしいからあとから触ってみよう
0406おれさま ◆6CTEZS59O00a
垢版 |
2018/12/23(日) 05:07:48.63
>>404の正規表現部分だけを修正
var rgxX = new Regex(@"(^x=)(-?[0-9]+)", RegexOptions.Multiline);
var strX = rgxX.Match(str).Groups[2].Value;
var rgxY = new Regex(@"(^y=)(-?[0-9]+)", RegexOptions.Multiline);
var strY = rgxY.Match(str).Groups[2].Value;


これでサブモニタでマイナス側に飛び出しても大丈夫

可能性として、下とか左に飛び出す場合もあるわけで
そういう場合には対応できていない
そう難しいわけではなさそうだけど
0408おれさま ◆6CTEZS59O00a
垢版 |
2018/12/23(日) 09:43:36.30
>>404をさらにアプデ
private void Form1_Load(object sender, EventArgs e)
{
 string str = null;
 int x = 0;
 int y = 0;

 if (File.Exists(Path))
 {
  using (sr = new StreamReader(Path))
  {
   str = sr.ReadToEnd();
  }
  var rgxX = new Regex(@"(^x=)(-?[0-9]+)", RegexOptions.Multiline);
  var strX = rgxX.Match(str).Groups[2].Value;
  var rgxY = new Regex(@"(^y=)(-?[0-9]+)", RegexOptions.Multiline);
  var strY = rgxY.Match(str).Groups[2].Value;
  if (int.TryParse(strX, out x) && int.TryParse(strY, out y))
  {
   this.Left = x;
   this.Top = y;
  }
  else { SetCenter(); }
 }
 else { SetCenter(); }

 var scr = Screen.GetBounds(this);
 const double RemainLimit = 0.6;
 bool result = true;
 result &= (scr.X + scr.Width - this.Left > this.Width * RemainLimit);
 result &= (this.Left + this.Width - scr.X > this.Width * RemainLimit);
 result &= (scr.Y + scr.Height - this.Top > this.Height * RemainLimit);
 result &= (this.Top + this.Height - scr.Y > this.Height * RemainLimit);
 if (!result) { SetCenter(); }

 void SetCenter()
 {
  this.Left = (Screen.PrimaryScreen.Bounds.Width - this.Width) / 2;
  this.Top = (Screen.PrimaryScreen.Bounds.Height - this.Height) / 2;
 }
}
0409おれさま ◆6CTEZS59O00a
垢版 |
2018/12/23(日) 09:45:41.05
>>408
uintは座標がマイナスの場合しか使えないロジックなのでやめやめ

こんな風にした
保存してある座標をそのまま使って一旦フォームを表示させる
もちろんlocation.txtがないとか、数値が想定通りに記録されてない場合はメインモニタ中央へ表示

その上で、フォームがモニタ画面から飛び出し「すぎてる」場合はメインモニタ中央へ移動
RemainLimit = 0.6はフォームの幅・高さの6割がモニタ画面に映っているならOK
それを下回ったらメインモニタ中央へ表示、という定数
これで上下左右・メインモニタ/サブモニタ関係なしにオールマイティにはみ出し補正可

resultのロジックだけど
result = result && (〜〜〜);
でやってたんだけど、もしかしてとおもって
result &= (〜〜〜);
にしたら行けたんでこれにした
要は if を並べて階層深くしたり、条件式が長くなるのが嫌だっただけなんだけど

これはクラスにまとめてこれから作っていくアプリにも使っていこうかなぁ〜
0410おれさま ◆6CTEZS59O00a
垢版 |
2018/12/23(日) 09:56:37.15
フォームを一旦表示させてから問題あるなら移動させるという2段階の方法を採った理由は
一度に所定の位置へ置こうとすると、scr.X とかがうまく取得できなかったから
0411おれさま ◆6CTEZS59O00a
垢版 |
2018/12/23(日) 10:00:56.74
どうでもいいような部品なんだけど
うまくいったんで満足である

独習はまだしっかり頭にはいってないところがたくさんあるけど
辞書的に使うのにも適してる

今のGUIの入門本しばらくやってから、独習の残り1割ぐらいだけど
まだ読んでない部分読むか
復習も何度かしないといけないな
0412おれさま ◆6CTEZS59O00a
垢版 |
2018/12/24(月) 11:13:08.50
>>403で書いた複数コントロールを束ねる処理についてなんだけど、
今やってる入門本でも紹介されていた

複数のボタンをひとつのハンドラでコントロールする方法を使う
デザイン画面で複数ボタンを選択してから
右下プロパティウィンドウ→イベントタブ→Clickの項目にハンドラ名を入力してEnter
で、Form1に選択した複数ボタンに一括対応するハンドラが自動生成

ここでひとつ問題がある
Form1のこのハンドラを見ただけでは
このハンドラがどのコントロールに対応してるかがわからない
覚えてりゃいいんだけど、またはコメント書いておけばいいとかいう話ではあるんだけど
やはりちゃんとコード上で確認できるべき

そこで、確認方法
左上ソリューションエクスプローラウィンドウ→Form1をクリックして展開
→Form1.Disigner.csをダブルクリックして開く
コード上に
「Windows フォーム デザイナーで生成されたコード」
というregionがあるので左端+をクリックして展開
この中にbutton2に対応する部分がある

//
// button2
//
this.button2.Location = new System.Drawing.Point(13, 13);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(125, 100);
this.button2.TabIndex = 0;
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.buttons_Click);//←ここ

複数ボタン対応ハンドラの名前は「buttons_Click」としたのだが、
button2.Clickにbuttons_Clickハンドラが登録されている
ここからbutton2.Clickがbuttons_Clickメソッドによりコントロールされることがわかる
同じようにbutton3, button4, button5 ・・・・といったbuttons_Clickハンドラにより
コントロールされるボタンのコードにも、buttns_Clickが登録されているのがわかる
0413おれさま ◆6CTEZS59O00a
垢版 |
2018/12/24(月) 11:20:44.17
複数コントロールを一括してひとつのハンドラにまとめるには
対象となるコントロールをぽちぽちとctrl+左クリすることで選択していくわけだけど
こういう方法によると、対象外のオブジェクトを間違えて選択してしまうことがある

実際に自分がやった間違いとしてこれ↓

//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.button10);
this.splitContainer1.Panel2.Controls.Add(this.button7);
this.splitContainer1.Panel2.Controls.Add(this.button4);
this.splitContainer1.Panel2.Controls.Add(this.button9);
this.splitContainer1.Panel2.Controls.Add(this.button6);
this.splitContainer1.Panel2.Controls.Add(this.button3);
this.splitContainer1.Panel2.Controls.Add(this.button8);
this.splitContainer1.Panel2.Controls.Add(this.button5);
this.splitContainer1.Panel2.Controls.Add(this.button2);
this.splitContainer1.Panel2.Click += new System.EventHandler(this.buttons_Click);//←ここ
this.splitContainer1.Size = new System.Drawing.Size(412, 396);
this.splitContainer1.SplitterDistance = 54;
this.splitContainer1.TabIndex = 0;

ボタンの背景にあるパネルを間違えてクリックしてしまい
パネルがbuttons_Clickハンドラの支配下に置かれてしまっている
このままだとボタンではなく背景のパネルをクリックしただけで
buttons_Clickハンドラに記述されている処理が実行されてしまう

パネルが選択されたかどうかは、デザイン画面上は非常にわかりにくく間違いを招きやすい
選択されたオブジェクトが羅列されているウィンドウは見当たらない
注意深くやっていくしかないというところか
0415おれさま ◆6CTEZS59O00a
垢版 |
2018/12/24(月) 11:30:14.22
ところで、>>413のようにミスしてしまった場合の対応なのだが、
実際、どのオブジェクトがどのハンドラの支配下にあるのかは>>412でわかるように
「隠された」コードを見るしかない

しかも、この部分にはこんなコメントが記述されている

/// <summary>
/// デザイナー サポートに必要なメソッドです。このメソッドの内容を
/// コード エディターで変更しないでください。
/// </summary>

>>413の「//←ここ」の行を削除すればいいんだろうなということは
今まで貯めた知識で分かってはいるんだけど、本当にいいんだろうかと。
別の方法により、「自動的に」削除させる方法があるんだろうか

まぁよくわからないので、マイクロソフトさんに逆らって勝手にコードを削ることにする

この辺の知識なしでVisualStudioをさわる人はどう処理をしているのか
もう一度対象オブジェクトを全て削除してから自動生成し直しているのかな

なんだかんだこだわって理解しようとしてると、そのうち役に立つもんだ
0416おれさま ◆6CTEZS59O00a
垢版 |
2018/12/24(月) 12:20:33.91
>>412のこれだけど

this.button2.Click += new System.EventHandler(this.buttons_Click);

this.button2.Click += new EventHandler(this.buttons_Click);
だとエラーがでる
コードが記述されているのはForm1のパーシャルクラスなんだけど
Form1.csにはusing System;が記述されているから省略してもいいんじゃないかと思ったのだが
パーシャルクラスであってもファイルが違うなら、冒頭にusing System;入れないと
省略できないようだ

実際にusing記述したら省略してもいけた
ここは基本的にユーザーがいじらない前提でコードが自動生成される場所なので
usingでの省略は逆に足手まといになるのかな
0417おれさま ◆6CTEZS59O00a
垢版 |
2018/12/24(月) 12:44:16.76
イベントドリブンモデルについて再考

>>391なんだけど、こう書き直してもいい

public delegate void MyEventHandler(object sender, EventArgs e);

class Program
{
public event MyEventHandler myEvent = (sender, e) => { }; //←ここ注目

public void handler(object o, EventArgs e)
{
Console.WriteLine("handler called");
}

public static void Main(string[] args)
{
Program target = new Program();
target.myEvent += target.handler;//+= new MyEventHandler(target.handler)も可

target.myEvent(target, EventArgs.Empty);
}
}

独習567ページのコードに含まれているこれ、
public event KeyCommandEventHandler KeyCommand = v => { };
の理解のために比較対象としてあげてみた
独習の方の
v => { }
は空のメソッドを意味する。
= v => { }
により空のメソッドを初期値としてKeyCommandに代入していることになる
そもそもデリゲート型変数であるKeyCommandにはメソッドが入る
int型変数の初期値として 0 を入れることがあるように
デリゲート型変数にラムダ式を使って空メソッドを初期値として代入しているわけだ。
もちろん初期値を代入することは必須ではないので
public event KeyCommandEventHandler KeyCommand;
と書いてもエラーはでない(はずだ!)
同様に、初期値を設定しない>>391のようなコードも問題なく動く(これは確認済)

上で書きなおしたコードは
(sender, e) => { }
を初期値としてデリゲート型変数myEventに代入している
ラムダ式で表したメソッドだ
デリゲートは引数2つと戻り値voidなので、これに対応した形になっている
0418おれさま ◆6CTEZS59O00a
垢版 |
2018/12/24(月) 12:54:49.55
>>417修正
イベントドリブンモデルにおいては、もちろん通常のデリゲートでも同じような事が
言えるのかもしれんが、
いや、もっというと初期値というもの全般について言えることなんだけど

変数に中身が入ってない状態で呼び出されてしまった場合に備えて
やはり空のメソッドでも入れておくべきだ

初期値についてはいろいろルールがあったはずだが忘れたw
調べるのが面倒なのでおいおいということにしよう
クラス変数とローカル変数でも変ってきたはず

とりあえずこれだけは確認した。下のコードはエラーがでる
初期値代入なしで、中身となるメソッドも入れずに実行した場合

public delegate void MyEventHandler(object sender, EventArgs e);

class Program
{
 public event MyEventHandler myEvent;

 public void handler(object o, EventArgs e)
 {
  Console.WriteLine("handler called");
 }

 public static void Main(string[] args)
 {
  Program target = new Program();

  target.myEvent(target, EventArgs.Empty);
 }
}
0419おれさま ◆6CTEZS59O00a
垢版 |
2018/12/24(月) 13:08:21.72
VisualStudioでは、ボタンクリックなどで使われるデリゲート型変数の初期値は
どうなっているのか調べてみた

>>412に従って表示されたbutton2.ClickのClickにカーソルを合わせて右クリ
→定義へ移動

public event EventHandler Click;

初期値となる空メソッドは代入されていないように見える

public event EventHandler Click = (sender, e) => { };

こう書き加えてやろうと思ったがもちろん勝手には書き込めないようだ
中身となるメソッド(ハンドラ)が自動生成されて、自動で代入されていくので
初期値がないことによって生じる問題は基本的には起きないと想定した結果か
0420おれさま ◆6CTEZS59O00a
垢版 |
2018/12/24(月) 13:12:10.10
忘れてた
>>418で、
初期値設定した上で、中身のメソッドを入れなかった場合はエラーなし
何も表示されずに終了

public delegate void MyEventHandler(object sender, EventArgs e);

class Program
{
 public event MyEventHandler myEvent = (sender, e) => { }; //初期値代入

 public void handler(object o, EventArgs e)
 {
  Console.WriteLine("handler called");
 }

 public static void Main(string[] args)
 {
  Program target = new Program();
                         //中身メソッド代入しない
  target.myEvent(target, EventArgs.Empty);
 }
}
0421おれさま ◆6CTEZS59O00a
垢版 |
2018/12/24(月) 14:13:10.09
private void buttons_Click(object sender, EventArgs e)
{
 if (((Button)sender).Text == "あたり")
 {
  MessageBox.Show("あたり!");
 }
}

イベントハンドラの第一引数の具体的な使い方

>>395-396では第二引数 e をやったけど
今回は第一引数のsenderについて

使い方は e と同じで、object型になっているので派生クラスにキャストすることで
senderに格納されてるデータを引き出せる
派生クラスの正確な名称は
MessageBox.Show(sender.GetType().ToString());
を一旦置いてみることで取得できる
この場合
System.Windows.Forms.Button
と表示されるので「Button」が派生クラスだと分かる

Javaだとこの辺のデータも e に格納されていたと思う
>>109の e.getComponent() がそれか
0422おれさま ◆6CTEZS59O00a
垢版 |
2018/12/24(月) 14:15:36.97
派生クラスの名前は
Form1.Designer.csを見ても分かる

this.button2 = new System.Windows.Forms.Button();

ボタンには Buttonクラスのインスタンスが代入されている
0424おれさま ◆6CTEZS59O00a
垢版 |
2018/12/27(木) 15:11:07.59
フォームの大きさを変えたときにボタンとかテキストボックスが自分の思う通りに
追随してサイズを変えたり、または固定されたり・・・といったことをやってた

SplitContainer→FixedPanel, IsSplitterFixed
TableLayoutPanel

などなど・・・
なれないと思った通りにするのに時間かかる
0425おれさま ◆6CTEZS59O00a
垢版 |
2018/12/27(木) 15:52:12.98
イベントハンドラの中で、Form1の座標を取得したいとき、
イベントハンドラに渡されるsenderの実体がForm1の時は問題ない
((Form1)sender).Left
((Form1)sender).Top

senderの実体がButtonの時は同じようにやってもエラーが出る
ButtonなのにForm1型にキャストしようとするからだ
この場合はこうする
((Button)sender).FindForm().Left
((Button)sender).FindForm().Top
Buttonが位置するFormを取得するメソッドFindFormを使えばいい
0426おれさま ◆6CTEZS59O00a
垢版 |
2018/12/27(木) 15:54:53.70
自分で気に入ったアイコンをexeファイルやフォームに表示できるようになった!
0427おれさま ◆6CTEZS59O00a
垢版 |
2018/12/29(土) 10:56:50.05
TableLayoutPanel内にコントロールを並べてるのを忘れてると
これらコントロールのサイズを変更しようとしたときに動かなくて
あれれれれ
と思う事があるので注意

TableLayoutPanelで1行2列の2セルにそれぞれテキストボックスを置いていたんだけど
2つのテキストボックスの間にSplitterを挟むことでテキストボックスの幅を
ユーザーが自由に変更出来る仕組みにしようとした
上の記述はこの時遭遇したトラブル
TableLayoutPanelのセル内でもコントロール配置場所は、該当するコントロールの
Anchor,Dockプロパティによって影響を受ける

そもそもの話になるが、Splitterを使う場合はTableLayoutPanelは使わないので排除する
0428おれさま ◆6CTEZS59O00a
垢版 |
2018/12/29(土) 11:13:58.29
Splitterを使う時はこれと接するコントロールのDockプロパティの使い方に注意
>>427のように、2つのtextboxを横に2つ並べて、その間にSplitterを置く場合、

1つ目の左側に置くtextboxのDockプロパティはLeft
Splitterは自動的にLeftに設定され
2つ目の右側に置くtextboxのDockプロパティはFill ←ここ大事

右側をFillにしないと実行時にSplitterにカーソルを合わせてもカーソル表示が変らないし
幅を変えることもできなかった
0429おれさま ◆6CTEZS59O00a
垢版 |
2018/12/29(土) 16:37:34.90
入門本にgmailチェッカーが載ってたので作ってみたんだけど
テスト用にあらためてgmailアカウント新規でとろうと思ったら電話番号要求してくんのな
でもってSMSとかで確認するとか
あほらしくなって昔取得したアカウント引っ張り出してきて使うことにした
でも結局gmail側のセキュリティ機能が働いてちゃちなアプリではアクセスできないことがわかったので終了
0430おれさま ◆6CTEZS59O00a
垢版 |
2018/12/29(土) 16:55:07.37
ツイッター投稿アプリも載ってたので作ろうと思ったのだが
ツイッター側からアプリ作成に必要なAPIキーをもらうために
開発者用アカウントをつくらねばならない
これまた電話番号登録しろと出る
これもいやなのでパスでーす
0431おれさま ◆6CTEZS59O00a
垢版 |
2018/12/29(土) 17:25:48.41
>>415について
プロパティウィンドウでイベントを表示させると、
登録済のイベントがあれば右側にハンドラの名前が表示される
これを右クリ→リセットすればForm1.Designer.csからも該当コードが自動的に削除されるようだ
0432おれさま ◆6CTEZS59O00a
垢版 |
2018/12/29(土) 17:30:12.88
1.
VisualStudio自体を複数開くことができる
ソリューションはslnファイルから直接ひらくことができるが
複数のslnファイルを順々にクリックしていけばどんどん新しいVisualStudioのウィンドウが開いていく
デザイン画面で、複数の設定がめんどくさそうなコントロールを選択してctrl+c
別のVisualStudioのデザイン画面でctrl+vをすればこぴぺもできる

2.
全然別の話だが、clickイベントとmouseClickイベントの違い
mouseClickはそのまんまだけど、clickイベントは、例えば
ボタンにフォーカスがある時にキーボードでEnterを押すことでもイベント発生可能
0433おれさま ◆6CTEZS59O00a
垢版 |
2018/12/30(日) 04:19:55.99
グラフィックについて

ざっとみたところ理解しないといけないクラスとして

1.Graphics
2.Image
3.Bitmap

入門本では説明が簡略化しすぎてるので、自分で調べないとダメだ
0434おれさま ◆6CTEZS59O00a
垢版 |
2018/12/30(日) 07:14:59.98
グラフィック関係については一体どこから手を付ければいいのか難しいところだ
そもそも外部から持ってきた画像を表示する方法を明確にしていかないといけなさそうだ
つまりリソースの管理をVisualStudioでどうやっているのかについてだ

画像をフォームに表示する方法として、入門本で初めてやったのはこれだ

PictureBoxというコントロールをフォーム上に置く
フォーカスを当てると右上に表示される三角形から「イメージの選択」
次にローカルリソース→インポートにより外部の画像ファイルを選択して取り込むという流れになる

ここで疑問が出てくる
このインポートされた画像は一体どこに保存されているのだろうか
もちろん作成されたexeの中に入っているのは分かっているのだが
その前段階として該当するソリューションフォルダの中のどこかに
画像ファイルが取り込まれていると考えるのが妥当だろう
しかし探しても、画像ファイル自体は見つからないし、
コードをみても画像ファイルの拡張子からして見当たらない

ここでいろいろ検索してみたところ、どうやら取り込まれた画像ファイルは
拡張子「resx」の「XMLリソースファイル」とやらに格納されているようだ
実際にウィンドウ右上のソリューションエクスプローラーのForm1.csを展開するとForm1.resxがある
これをダブルクリックすると、この中に先ほどインポートした画像が入っているのを確認できる
resxには画像だけではなく、音声や文字列を格納することもできるそうだ
resxを利用しない方法もあるようだが、とりあえず利用する流れでやっていくことにしよう

インポートした画像をForm1.resxの中で選択すると、
pictureBox1.Imageという名前が付けられていることが分かる
画像ファイルとしての拡張子が消えている点に注意しなければならない
pictureBox1.Imageをコードの中から探すと、Form1.Designer.csの中に見つかる

System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
this.pictureBox1 = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// pictureBox1
//
this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
this.pictureBox1.Location = new System.Drawing.Point(0, 0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(412, 450);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;

usingを使っていないと長ったらしく非常にわかりにくい
0435おれさま ◆6CTEZS59O00a
垢版 |
2018/12/30(日) 07:25:31.53
と、ここまで書いて気づいたのだが、
入門本で初めてフォームに画像を表示した方法はこの方法ではなかったようだ
具体的にはこうやった

ソリューションエクスプローラのプロジェクト名を右クリック→プロパティ
→左側ペインからリソース選択
中央に表示される白いスペースに外部の画像ファイルをDDして放り込む
すると、>>434でもやったが、pictureBoxの右上三角マーク→イメージの選択
  (ここでローカルリソースから外部画像ファイルを選ぶのが>>434の方法だ)
→プロジェクトリソースファイルを選択することで
この中から表示する画像ファイルを選択することができる

この方法によればソリューションフォルダの中に画像ファイルがそのままの形で保存されている
プロジェクト名のフォルダの直下にResourcesフォルダが作られており、この中に保存されている

この方法によるリソースの管理は単純なので>>434の方法より理解しやすいが
せっかくなので>>434の方法についても調べてみることにする (結局分からないかもしれないが
0436おれさま ◆6CTEZS59O00a
垢版 |
2018/12/30(日) 08:04:38.15
>>435の方法についていくつか気づいた点

ソリューションエクスプローラのプロジェクト名を右クリック→プロパティ
→左側ペインからリソース選択

ここで開いているウィンドウだが、>>435で、「白いスペース」と書いたが、実際には
デフォルトでは文字列をリソースとして格納するウィンドウが開いており、白いスペースはない
ここに画像ファイルを放り込めば自動的にイメージ対応のウィンドウに切り替わる
対応するリソースの種類に合わせて手動でウィンドウを切り替えるには、ウィンドウのすぐ上の
項目の一番左側、デフォルトだと「文字列」となっているが、右の逆三角形のマークから
イメージ、アイコン、オーディオなどの選択ができる
白いスペースが表示されるのはイメージの対応ウィンドウとなったときだ

もう一点。
>>435の方法を採った場合に、画像ファイルをpictureBoxに置きたい場合
つまり、一旦リソースとして取り込んだ画像ファイルを実際にコードの中で呼び出して使いたい場合だが
デザイン画面のpictureBoxにフォーカスしたときの右上三角マークからイメージ選択する場合は
対応コードはForm1.Designer.csに自動生成されることになる
そうではなく、自分でハンドラなどから呼び出したい場合はこうする

pictureBox1.ImageLocation = @"C:\Image\aaa.jpg";

ImageLocationプロパティに、画像ファイルをフルパスで指定すればよい
Imageプロパティを使っても指定は可能なようだ
前述のForm1.Designer.csに自動生成されるコードもImageプロパティを使用しているようだ↓

this.pictureBox1.Image = global::TestProject.Properties.Resources.aaa;
//(TestProjectはプロジェクト名)

「global::」はグローバル名前空間のエイリアス、独習393ページで一応学習済
この場合なくても動いた

上の一行をusingを使うことで

using TestProject.Properties;

this.pictureBox1.Image = Resources.aaa;

こう書いてもいけた
0437おれさま ◆6CTEZS59O00a
垢版 |
2018/12/30(日) 09:18:22.07
>>434のコードを分析

再度書き直すと、この方法は画像ファイルをForm1.resxというXMLリソースファイルに格納し
ここから画像ファイルを呼び出してpictureBoxに表示させるというものだ

>>434の最後に貼ってあるコードは、アプリを開いた時に該当する画像が表示されるよう
Form1.Designer.csに記述されたものだ。
このコードはコンストラクタを通じてアプリ起動時に読み込まれる
このコードのうち、大事なのは↓の2行

System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));

this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));

これらをusingを使ったとして、部分的に省略すると

ComponentResourceManager resources = new ComponentResourceManager(typeof(Form1));//@
this.pictureBox1.Image = ((Image)(resources.GetObject("pictureBox1.Image")));//A

となる。
この2行は、そのままボタンクリックのハンドラに移しても機能する
(↓では変数resourcesはrsに変更)

private void button1_Click(object sender, EventArgs e)
{
 var rs = new ComponentResourceManager(typeof(Form1));//@
 this.pictureBox1.Image = ((Image)(rs.GetObject("pictureBox1.Image")));//A
}

@についてだが、わからん、なにやらよくわからん
コンストラクタの引数typeof(Form1)はForm1という型に対するTypeオブジェクトだ

「指定した ComponentResourceManager の情報に基づいて、
サテライト アセンブリでリソースを検索する Type を作成します。」
https://docs.microsoft.com/ja-jp/dotnet/api/system.componentmodel.componentresourcemanager?view=netframework-4.7.2

ということらしいんだけど、わからん
ま、とりあえずForm1.resxを探し出すためのものと理解しておこう

Aについてだが、GetObjectは例えば画像以外にも音声などもresxから取得することになるため
戻り値の型はオールマイティーなobjectとなっている
ただし、ここで取得しているのは画像なのでImage型にキャストしている
0438おれさま ◆6CTEZS59O00a
垢版 |
2018/12/30(日) 09:28:54.37
ちょいとまとめると

外部にある画像をリソースとして使うには大きくわけて2つの方法を学んだ

@resxファイルに格納する方法>>434
AResourcesフォルダに格納する方法>>435

そして、どちらにも言える事だが、
アプリ起動時に表示させる場合はForm1.Designer.csに
そのためのコードが自動生成されていることになる
起動後にボタンをクリックするなどによって画像を表示させたいときは
ハンドラ内に自分で記述することになる
ただし、コードの内容は自動生成であろうが自分で記述したものであろうが、
基本的に差異はない
0439おれさま ◆6CTEZS59O00a
垢版 |
2018/12/30(日) 09:41:43.25
https://ja.wikipedia.org/wiki/%E3%83%93%E3%83%83%E3%83%88%E3%83%9E%E3%83%83%E3%83%97%E7%94%BB%E5%83%8F

●ビットマップ画像
ビットマップ画像(ビットマップがぞう、bitmap image / bitmap graphics)とは、
コンピュータグラフィックスにおける画像の表現形式で、ピクセル(画素)を用いたもの。
画像をドットマトリクス状のピクセル群として捉え、
RGB等の表色系に基づいたピクセルの色・濃度の値の配列情報として取り扱う。

●ベクタ画像
これに対し、幾何図形を作成するための情報を数値や式として表現したものをベクタ画像と呼ぶ。
0441おれさま ◆6CTEZS59O00a
垢版 |
2018/12/30(日) 09:55:42.70
@
継承 Object→MarshalByRefObject→Image→Bitmap

A
http://koshinran.hateblo.jp/entry/2017/06/30/223423
●System.Drawing.Image
ベクタ画像、ビットマップ画像問わず、画像を扱う為のクラス。
png、jpg、gif 等、さまざまな画像形式ファイルを読み書きできる。

●System.Drawing.Bitmap
ビットマップ 画像を扱う為のクラス。
System.Windows.Forms はビットマップベースの GUI 環境なので、
System.Windows.Forms を使った GUI プログラミングでは
Bitmap クラスをよく使用する。
だが、ビットマップに対する図形の描画などは
Graphics クラスを介して行う。


わかりやすいっす
ここでGraphicsが出てくるのですね
0442おれさま ◆6CTEZS59O00a
垢版 |
2018/12/30(日) 10:03:56.26
>>441の@から分かるようにBitmapはImageの派生クラスでビットマップ画像に特化したクラスということになる
じゃ>>437のこれ↓を

private void button1_Click(object sender, EventArgs e)
{
 var rs = new ComponentResourceManager(typeof(Form1));
 this.pictureBox1.Image = ((Image)(rs.GetObject("pictureBox1.Image")));
}

こう↓書き換えたら・・・(キャスト先の型をImageからBitmapに変更)

private void button1_Click(object sender, EventArgs e)
{
 var rs = new ComponentResourceManager(typeof(Form1));
 this.pictureBox1.Image = ((Bitmap)(rs.GetObject("pictureBox1.Image")));
}

いけた!
0443おれさま ◆6CTEZS59O00a
垢版 |
2018/12/30(日) 10:07:22.08
今気づいたんだけど、pictureBoxに画像を設定したりごちょごちょやってると
いつの間にかForm1.resxにあった画像が消えてるというかResourcesフォルダに移ってる・・・?
何らかの連動性があるようだ
この辺については後回しにしていこうとは思うが
こういう現象から導き出される答えは、できるだけResourcesの方を使った方が今のところは安全だということなのかもしれない
0445おれさま ◆6CTEZS59O00a
垢版 |
2018/12/30(日) 10:25:59.81
>>444の3通りについてはちゃんとやろうと思う
特に入門本は3つ目の方法でGraphicsを取得しているんだけど
入門本ではImageではなくBitmapを使っている
この辺の違いも明確にしていきたい

ちなみにImageは抽象クラスなのでnewできないが
Bitmapは抽象クラスではないのでnewできる
0446おれさま ◆6CTEZS59O00a
垢版 |
2018/12/30(日) 16:58:24.29
入門本で玉が跳ね返りながら動くコードを学んだので
高速で跳ね返って動く玉をクリックして捕まえるゲームを作った
クリックのアタリ判定はクリック座標と玉の中心座標の距離を求めてこれが玉の半径以内ならアタリ

イライラするだけのゲームになった
0447おれさま ◆6CTEZS59O00a
垢版 |
2018/12/31(月) 04:59:58.32
JavaでグローバルIPアドレスを毎日記録するアプリを作って
これをタスクスケジューラに登録してあるんだけど、何日か経つと勝手に無効化してしまう
これは一体何が原因なのか
いろいろ調べてみたんだがイマイチわからない
とりあえず正常に動いているタスクの設定を真似して設定を見直してみた
これで動くといいのだが

自分で作ったJavaのプログラムが常時起動しているせいで
タスク実行時にすでに実行中だと判断されてしまっているとか・・・?
0448おれさま ◆6CTEZS59O00a
垢版 |
2018/12/31(月) 05:01:11.97
JavaでグローバルIPアドレスを記録するアプリをつくって
これを毎日起動するようにタスクスケジューラに登録してあるんだけど*
0449おれさま ◆6CTEZS59O00a
垢版 |
2019/01/01(火) 15:31:46.59
使っているwindowsアプリの入門本は
「作って覚えるVisualC#2017」
なんだけど、VisualStudioの基本操作が紹介されてるという点
どういう流れでアプリをつくっていくのかが分かるという点
この辺がいい
学習の通過点としてこういうテキストは必要だと思う

ただ、このテキスト通りに作っていくと次第に分かっていくんだけど
背後で自動生成されている膨大な量のコードがあるという事
結局これが理解できてないと応用が利かなくなるという点に気づかされる
もちろん俺はまだ一部しか理解できない、というか一部しか見てない
「プログラミング経験ゼロでもしっかりわかる」と銘を打っているんだけど
さすがにこれは言い過ぎ感が否定できない

アマゾンのレビューをみると、誤植を指摘している人がいる
正確にどのページのどの部分かと指摘してるわけではないのだが、
大文字と小文字を間違えてるとかうんぬん
おれはまだ全て読み終えたわけではないが、
ここのことを言っているのではないかと思い当たる部分に出くわした

結論から言うと、誤植ではないと思う

あるフォーム@のボタンを押すことで別のフォームAを一時的に立ち上げるという機能を考える
Aは利用後すぐに閉じられるが、必要な時に何度も立ち上げることになる

このときにAで使うデータを@で作って置いて、
Aを立ち上げるたびに引数を使って渡していきたい
ここで、Aを立ち上げるとは、コード上ではインスタンスを生成することになる
Aクラスのコンストラクタに引数を渡してAインスタンスを生成するのだ
ここで引数がintやstringなら簡単なのだが、
引数自体も自作クラス(CategoryDataSet)のインスタンスなのだ
@の側で引数となるインスタンス内にデータを入れてから、インスタンスごとAに渡す流れなのだ
こうなると

1.@の側で生成する実引数となるインスタンス(categoryDataSet1)
2.Aのコンストラクタでの仮引数(dsCategory)

という2つの変数が登場する
これだけでも初心者は混乱する
さらにだ、Aの側ではdsCategoryとは別に、同じ型の空の変数を用意して、これと
dsCategoryをMergeするという手法を使っている(401ページList2)
この変数が

3.Aの側で用意してある変数(categoryDataSet)

つまりだ、

クラス名CategoryDataSet
@の変数categoryDataSet1
Aの変数categoryDataSet

この3つがごっちゃごちゃになって、別々のものだと理解できず、その結果、
誤植だろこれ!となったのではないかと思う
独習なみにしっかりとした説明があればいいんだけど、背後に生成されるコードについては
ほとんど説明はなく、変数categoryDataSetに至っては、俺の見落としがなければなんだけど、
テキスト内に唐突に出現しているのだ
この変数は、背後で自動生成されているFormItem.Designer.cs内の
InitializeComponentメソッドでnewされているのだが、そんなことに触れようものなら
パンドラの箱をあけるようなもので収拾が付かなくなる
仕方なかったのだろう・・・・・
0450おれさま ◆6CTEZS59O00a
垢版 |
2019/01/03(木) 23:39:00.92
DataGridViewとDataSet、DataTableの関連についていろいろ調べてた
一体どれがどういう目的で使われているのかとか
なんとなく分かった
0451おれさま ◆6CTEZS59O00a
垢版 |
2019/01/05(土) 07:59:18.20
引き続き入門本(作って覚えるVisual C#)を読んでるんだけど
DataTableに格納されたデータを取得してこれをcsvファイルに書き込むという場面で
こういうコードがテキスト内に書かれている

foreach (MoneyDataSet.moneyDataTableRow drMoney in moneyDataSet.moneyDataTable)

唐突になにやら面妖なコードが出現
foreachに続く丸括弧内のコードなのだが
普通ここに書くコードの内容を考えると、こう推測できる

@「moneyDataSet.moneyDataTable」 というコレクション(or配列)があって、
A「MoneyDataSet.moneyDataTableRow」 という型の要素が入っている

DataSetはエクセルでいうブック
DataTableはエクセルでいうワークシート
ということらしいので、ワークシートの中の行をコレクションの要素をして扱っているようなイメージか

これぐらいで納得できればいいのだが、じゃ実際にこういう機能、
つまりDataTable内に格納されたデータを取り出す場合に
具体的にどういうコードを書けばいいのかを考えると、この程度の理解では書けないのではないかと思う

そこで、ひとまず@、Aは一体何なのかを実際のコードから読み取ってみよう、と思ったわけだ
0452おれさま ◆6CTEZS59O00a
垢版 |
2019/01/05(土) 08:45:37.51
が、見事に打ち砕かれた

@「moneyDataSet.moneyDataTable」
moneyDataTableがコレクションまたは配列ということであれば、どこかでそういった宣言が
なされているはずだと考えた。もちろん自分でそういったコードを書いた覚えはないので
自動生成されているコードがあるのだろう
そこで、moneyDataTableにカーソルを合わせ右クリ→定義へ移動
するとMoneyDataSetDesigner.cs(これをデザイナと言うそうだ)内に移動する
MoneyDataSetクラスのプロパティとしてmoneyDataTableが定義されているようだ

public moneyDataTableDataTable moneyDataTable {
 get {
  return this.tablemoneyDataTable;
 }
}

これによるとmoneyDataTableを取得すると同じクラス内の変数tablemoneyDataTableが
かえされると・・・もうここでギブアップしたくなるが先に進む
つまり、moneyDataTableはtablemoneyDataTableのゲッターのようなもんで
moneyDataTableの正体はtablemoneyDataTableという認識でいいのか
いや、ゲッターならスペルは同じにして頭文字の大文字小文字変えるだけにしてくれとか
そういうのはなしなんだろうな・・・

取り合えずそういうことみたいなんで、tablemoneyDataTableを同様に右クリ→定義へ移動
すると同じクラス内のここに移動する

private moneyDataTableDataTable tablemoneyDataTable;

「moneyDataTableDataTable」というクラスの変数として宣言されている
この辺のクラス名や変数名をみてると頭が痛くなってくる
moneyDataTableDataTableを右クリ→定義へ移動

public partial class moneyDataTableDataTable : global::System.Data.TypedTableBase<moneyDataTableRow>

ふぅ・・・もうやめたほうがいいのか・・・
これはよくみると同じMoneyDataSetクラスの内部に設けられたインナークラスのようだ
TypedTableBaseクラスを継承している
わからん!
が、このクラスの中をずっと見ていくと、これか・・・と思い当たるメソッドを発見

public moneyDataTableRow this[int index] {
 get {
  return ((moneyDataTableRow)(this.Rows[index]));
 }
}

独習を復習し直さないとこれは理解できない
インデクサーを使っているんだよねこれ
独習441ページのコードと類似点が多い
この辺からコレクション的な何かを「感じる」

これぐらいにしておこうか・・・
俺の実力だとこれ以上やっても理解するまでにメリット以上の時間がかかりそうだ
それより独習をちゃんと復習してもう少しコードを読解する能力を身につけた方がよさそう
0453おれさま ◆6CTEZS59O00a
垢版 |
2019/01/05(土) 08:58:22.63
https://ohke.hateblo.jp/entry/2016/12/03/231909
>・DataSet、DataTable、DataColumn、DataRowを継承したクラスを使う
>・プロパティを介してDataTable、DataColumn、DataRowの値へアクセスできる


デザイナを使った、つまり自動生成されたコードの特徴だそうだ
継承とプロパティを介したアクセス
知識ある人には便利なんだろうが、おれにとってはこの2つが理解を拒む壁となってそびえ立つ

DataSet関連のコードはデザイナを使わなくても組めるので
分からなかったら自分で一から書いていった方が良いのかもしれない
そう思って基礎的なコードをいくつか書いてDataGridViewで表示させてみた

この辺はこれぐらいでいいかと思う
続けていけばそのうち分かることもあるだろう
0454おれさま ◆6CTEZS59O00a
垢版 |
2019/01/05(土) 09:17:42.37
>>452の最後のコードはメソッドではなく、まさにインデクサーそのものか

(再掲)
public moneyDataTableRow this[int index] {
 get {
  return ((moneyDataTableRow)(this.Rows[index]));
 }
}

今、独習のインデクサーのところを見直しているんだけど、
インデクサーはぶっちゃけて言えばインスタンスの配列化をするための技法
つまり、moneyDataTableDataTableクラスのインスタンスを配列化しているといえる
そして、moneyDataTableDataTableクラスのインスタンスがtablemoneyDataTable
で、こいつをそのまま戻り値として返しているのがmoneyDataTableプロパティ

>>451 @「moneyDataSet.moneyDataTable」は
MoneyDataSetクラスのインスタンスmoneyDataSetのプロパティmoneyDataTableであり
これにより上に書いたような流れで、最終的には
moneyDataTableDataTableクラスの配列化されたインスタンスを意味することになる
この配列の要素となっているのが
((moneyDataTableRow)(this.Rows[index]))
であり
簡単にいえば
Rows[ ] の要素となるのだろう
Rowsにカーソルを合わせると

DataTable.Rows このテーブルに属している行のコレクションを取得します

と出てくる。継承元となっているDataTableがここででてくるわけだ
そしてついに、コレクションという言葉にたどり着いた
道が険しく長すぎる

これでいいだろと言いつつ、調べた結果なんとなく分かった気がしてきた

(配列配列といっているが実際にはインデクサーによる配列的ななにかで実際に配列と行って良いのかは知らない)
0455おれさま ◆6CTEZS59O00a
垢版 |
2019/01/05(土) 09:21:13.98
独習読んでると、いや、こんなの使わないだろ〜
少なくとも自分では使わないよ、とか思うところが結構あるんだけど
デザイナ使った場合、デザイナで自動生成されたコードから
何かを取得して自分のコードで使いたいと思った時、
つまり上に書いたような場合なんだけど、
こういうときに自動生成されたコードが理解できてないと全くコードを書けない

とするとやはり独習レベルの知識は頭に入れておかないとダメなんだろう

道は長いぞ!
0456おれさま ◆6CTEZS59O00a
垢版 |
2019/01/07(月) 04:08:33.66
テキストボックスをデザイナでForm1上に置くことにより自動生成されるコード
テキストボックスのNameプロパティをmyTextBoxとした
特に大事なのはmyTextBoxがTextBoxクラスのインスタンス変数名として「も」利用されているという点。


private System.Windows.Forms.TextBox myTextBox;
//↑Nameへの代入値がそのままインスタンス変数名としても使われる

//
// myTextBox
//
this.myTextBox.Location = new System.Drawing.Point(13, 13);
this.myTextBox.Name = "myTextBox";
this.myTextBox.Size = new System.Drawing.Size(100, 19);
this.myTextBox.TabIndex = 0;

//
// Form1
//
this.Controls.Add(this.myTextBox);
0457おれさま ◆6CTEZS59O00a
垢版 |
2019/01/07(月) 04:55:58.12
StreamReaderを使う時、一行ずつ読み込むとして
whileの繰り返し条件として使う部分

StreamReader sr = new StreamReader(path);

@while (sr.EndOfStream) { }
Awhile (sr.Peek() >= 0) { }
Bwhile (sr.ReadeLine != null) { }

@、Aは正解
Aは少し古い方法で次に読み込む文字のint型整数値(Char型の中身)を返す
読み込む文字がないと「-1」を返すので、0 以上で有る限り、という条件にする
@のEndOfStreamがプロパティであるのに対してPeekはメソッドなので丸括弧忘れないこと

Bはダメ
読み込む行がないとReadLineがnullを返す事を利用しようとしたものだが、これはダメ。
理由は、ReadLineは単純にチェックのために使いたかったのだが、
実際にここで使ってしまうと、読み込み済として一行進めてしまい、
whileブロックの中で読もうと思っていた行を先取りしてしまう
エラーが出るわけではないが使えない
別途変数を用意して使う方法も考えられるが、そこまでしなくても@、Aがあるので・・・
0458おれさま ◆6CTEZS59O00a
垢版 |
2019/01/07(月) 06:08:43.25
>>451
@「moneyDataSet.moneyDataTable」関連のコードの位置

【moneyDataSet】はForm1.Designer.csで宣言されるインスタンス
private MoneyDataSet moneyDataSet;
 ↓
【moneyDataTable】はMoneyDataSet.Designer.cs(以下同じ)、MoneyDataSetクラスのプロパティ
public moneyDataTableDataTable moneyDataTable {
 get {
  return this.tablemoneyDataTable;
 }
}
 ↓
【tablemoneyDataTable】MoneyDataSetクラスのフィールド
private moneyDataTableDataTable tablemoneyDataTable;
 ↓
【moneyDataTableDataTable】MoneyDataSetクラスのインナークラス
public partial class moneyDataTableDataTable : global::System.Data.TypedTableBase<moneyDataTableRow> { }

↑のインデクサー↓
public moneyDataTableRow this[int index] {
 get {
  return ((moneyDataTableRow)(this.Rows[index]));
 }
}


A「MoneyDataSet.moneyDataTableRow」関連のコードの位置

【MoneyDataSet】MoneyDataSet.Designer.csの中のクラス
public partial class MoneyDataSet : global::System.Data.DataSet { }

【moneyDataTableRow】↑のインナークラス
public partial class moneyDataTableRow : global::System.Data.DataRow { }
0460おれさま ◆6CTEZS59O00a
垢版 |
2019/01/11(金) 16:59:28.83
頼まれたんでVBAやってるんだけど
VBAでも普通に正規表現使えたのか
知らなかったわ
IEがらみのライブラリかなんか使うみたいだけど

C#で正規表現結構やったんで役に立った
0461おれさま ◆6CTEZS59O00a
垢版 |
2019/01/13(日) 11:49:51.37
VBAに没頭

自分が作ったものじゃないんだけど、あるwebアプリがある
現在ブラウザに表示してる特定のデータをCSVで吐き出す機能を持っている
このCSVからデータをエクセルに取り込んで加工するということをやってる

ただ、
大したデータ量ではないのに、CSVを作らせるのに1分ぐらいかかったりして結構とろい
ローカルで作成するんじゃなくて、鯖に作らせているようだ

そこで、IEによってローカルに取込み済のHTMLを横取りして加工できないかと。
つまり、HTMLスクレイピングをVBAでできないかと思って
ボトルネックになりそうな部分をちょっと触ってみたんだけど、
意外といけそうなんだよなぁ

とりあえず、CSVを使うバージョンを作ってから
暇な時にHTMLスクレイピングやってみようかな
0462おれさま ◆6CTEZS59O00a
垢版 |
2019/01/13(日) 12:02:45.85
メソッドたくさん作ってからどれ使うかあとから決めると頭が整理できていいな

以前はひとつのメソッドを作り込んでたんっだけど
これをやってしまうと、別のメソッドとして切り出した方が
いい機能まで突っ込んでしまって融通が利かなくなる

ちょっとした機能でもどんどん独立させて作る
同じ機能でも少し違うやつが考えられるなら、全部作ってみる
作ってからどれ使うか選びながら組み立てていく

あと、Functionを作ったら、すぐ下にテストのためのメソッドを作っておくと何かと便利
0463おれさま ◆6CTEZS59O00a
垢版 |
2019/01/13(日) 17:59:48.65
あと、複雑なロジックは紙にシャーペンで書く
絵や図を書き加えながら、コードを書いていく
消しゴムも必須

やっぱ深く考えるにはアナログが一番いい
0464おれさま ◆6CTEZS59O00a
垢版 |
2019/01/14(月) 09:22:32.85
HTMLスクレイピングというかウェブスクレイピングをVBAでやってるんだけど
Dictionaryないかなと思って調べたら、一応使えるようだ

しかし、使ってみたら、ソートの機能すらない
仕方ないので自分で書いてたんだけど、どうもうまく動かない
この原因探しが大変だった

結論から言えば、forのカウンタの部分で最大値を指定するわけだけど
ここに同じforブロックのなかで変化してしまう変数を使ってしまっていた
繰り返し処理の途中で予期せず最大値が変化してしまい、エラーに繋がっていたのだ

VBAのDictionaryで使うソートの機能をネットで調べると、いろいろと洗練されたコードが出てくる
こぴぺの誘惑にかられたのだが、無骨なコードになってしまうとは言えども
この程度自分で書けないのも悔しくて、、あー疲れた
0465おれさま ◆6CTEZS59O00a
垢版 |
2019/01/15(火) 11:25:40.95
列挙体初めて実戦で使ってみた
これ便利だな
要はbool系は2つしか選択肢ないけど
これをいくつも増やした感じか
switchというかvbaだとselectなんだけど
これにも列挙体使えるし
0468おれさま ◆6CTEZS59O00a
垢版 |
2019/01/19(土) 11:43:13.06
ふぅ大体終わったぜ・・・・

今回のVBAプログラムは処理が重くて表示が固まるのが特徴のひとつだった
これをどうやって軽くしていくかが課題
もっと速くなると思うけど、一応固まらないようにはなった
0472おれさま ◆6CTEZS59O00a
垢版 |
2019/01/25(金) 13:22:28.16
プログラミングばかりやってたらアジアカップ見るの忘れてたわ
次の試合から録画する
このタイミングで決勝が日韓戦だと妙な盛り上がりを見せそうだ!
0473Mr.名無しさん
垢版 |
2019/01/26(土) 09:39:32.20
凄くがんばってるなぁ・・・頭の下がる思いでみてる。
0474おれさま ◆6CTEZS59O00a
垢版 |
2019/01/27(日) 08:02:39.25
独習最初から読み直してる
コードかきかきしながら
おれぐらいすぐ忘れる人間はこうでもしないとな


>>473
ぐへへへへへ
0475おれさま ◆6CTEZS59O00a
垢版 |
2019/01/27(日) 08:15:41.43
これからはクラスを作ったらドキュメンテーションコメントを使っていくことにする
///
これ
0477おれさま ◆6CTEZS59O00a
垢版 |
2019/02/01(金) 04:20:20.08
いままでちゃんと覚えてこなかった基本的な事を読み返しながら覚えるようにしてる
例えば値型のサフィックスとか表になって紹介されてるようなやつ
0480おれさま ◆6CTEZS59O00a
垢版 |
2019/02/03(日) 13:02:06.71
if とか switch とかすごく基本的なもの復習した
基本とかいいつつ独習は細かい論点も触れるので忘れてるところもあった
0483おれさま ◆6CTEZS59O00a
垢版 |
2019/02/07(木) 14:19:32.31
いろんなもの作れるようになってきた
IEコントロールおもろいな
VBAだけど
0484おれさま ◆6CTEZS59O00a
垢版 |
2019/02/09(土) 13:15:51.03
今日もずっとVBAいじってた
リンククリックしてウィンドウを閉じたり開いたりしてると
いろいろエラーが出てくるんだよね
再現性の高いエラーならいんだけど、ネットと関わるエラーはそうじゃないものが多くてやっかい
とりあえずはエラーがでないようなのを作ってみたんだけど
時間を置いて何度も繰り返さないと確信もてない
なぜか時間を置いてからもう一度やるとエラーがおきてたんでその辺気をつけないといけない
0485おれさま ◆6CTEZS59O00a
垢版 |
2019/02/10(日) 10:33:42.86
新しいウィンドウをIEで開いた時なんかに
開ききる前にIEを捉えようとするとエラーが出る
見た目開いたように見えても読み込みが不十分だったりすることがあるから
IEを掌握する処理をループで回すのがキモとなるようだ
0486おれさま ◆6CTEZS59O00a
垢版 |
2019/02/12(火) 03:53:47.73
CStr と Str の違い

Str()は、符号の1桁分が必ず確保されていて、
数値が正の時の戻り値の頭にはスペース(空白)が入ります。
Cstr()は、プラスのときにスペースは入りません。




これな・・・・これなんだよ
やっと原因見つけたわ
0487おれさま ◆6CTEZS59O00a
垢版 |
2019/02/12(火) 07:19:11.13
windows10だとIE使えないと思ってたんだけど
機能追加でInternet Explorer11が使えるのか
知らなかったわ
ウェブアプリでIE使ってる場合はそのまま移行できるってことかな
その辺勉強してないからわからんが
0489おれさま ◆6CTEZS59O00a
垢版 |
2019/02/13(水) 09:38:09.55
最近VBAでプログラミングするときは
public宣言をできるだけ避けるようにしてる
Subプロシージャはメインとなるひとつだけにして
あとはFunctionを使う
戻り値が欲しいときFunctionの戻り値を使えば良いんだけど
使い勝手が悪いときは、Subプロシージャ内で変数宣言してから
これを参照渡しすることにしてる
昔は大量のPublic宣言された変数があって見通しが悪かったんだけど
この方法に変えてからマシになった感じがする
こういうやり方が正しいかどうかは知らないんだけど
0491おれさま ◆6CTEZS59O00a
垢版 |
2019/02/13(水) 15:35:29.43
windowsのタイムスケジューラってなにが原因かよくわからんけど
いつのまにか無効になってて一日一回設定してあるプログラム起動が
実行しないようになっちゃうのな
設定変えていろいろやってるんだけど、もういっそのことC#で常時起動の何か作って
そこから実行するようにしようかな
常時起動のJavaプログラムもあるからそこからやってもいいんだけどせっかくだし
0494おれさま ◆6CTEZS59O00a
垢版 |
2019/02/19(火) 07:47:07.77
忙しくてなかなか再開できないわい
また秋ぐらいから再開しようかなぁ
その頃になれば時間ができるだろうから
0495おれさま ◆6CTEZS59O00a
垢版 |
2019/02/20(水) 12:04:39.66
VBA漬け
エラー処理までちゃんと作らないと気が済まなくて
暇な時間がVBAに吸い取られていくのだ
0496おれさま ◆6CTEZS59O00a
垢版 |
2019/02/21(木) 07:32:35.55
今期は正規表現が使えるようになったのが大きな収穫だった
C#の独習で覚えたんだけどVBAでも使えるんで大活躍
今日はVBAの入力フォームを作らなくてはならぬ
0498おれさま ◆6CTEZS59O00a
垢版 |
2019/02/23(土) 10:52:15.17
入力フォームのテキストボックスに特殊なデータを貼り付けたいとおもって
SendKeysってのが使ってみたんだけど、今のところうまくテキストボックスに入れることができない
が、その代りに、VBEのコードのカーソルが当たったところに指定した文字列が入力されてるのに気づいた
コードを操作出来ちゃうことになるんだけどどゆことよw
0499おれさま ◆6CTEZS59O00a
垢版 |
2019/02/23(土) 16:53:44.47
正規表現を使えるようになったとか書いたけど
よくやってしまううっかりミスに気づいた
しかも自分ではそう簡単に間違いだと気づけないやっかいなやつ
アホみたいなミスなんだけど
"\d"
"\D"

"{\d}"
"{\D}"
と書いてしまう
これまでにも何度もやってて、気づけなくて結局他の表現方法使ってたんじゃないかと思う
ほんとにアホみたいなんだけどなぜか自分では気づけなかった
今回相当時間かけて悩んでようやく気づいたw
たぶんだけど、
"\s"
"\S"
とかでも同じような事をやってたと思う
まじで注意
0501おれさま ◆6CTEZS59O00a
垢版 |
2019/02/25(月) 13:22:49.67
今作ってる入力用フォームでエンターキー押したときにあるテキストボックスから別のコントロールに
フォーカスが移るのを阻止したいと思っていた
別のコントロール全てにTabStop=Falseを設定すれば実現できるんだけど
それだと別の問題が生じるので、できたら他の方法をとりたかった
そこで、
対象となっているテキストボックスに

MulitiLine = True
EnterKeyBehavior = True

を設定することで解決
このテキストボックスは一時的に入力を受け付けるだけの特別なものなので
表示される内容は問題にならないのでこれでOK
ちなみに、EnterKeyBehaviorプロパティはTextBox内でエンターキーを押した時に
改行する機能を持たせるもの。(デフォルトだとTextBox内での改行はctrl+Enter)
0502おれさま ◆6CTEZS59O00a
垢版 |
2019/02/25(月) 13:32:22.26
KeyDownのプロシージャを作って、

If KeyCode = vbKeyReturn Then 〜

を記述することでエンターキーの無効化を試みたんだけどこれは失敗だった
Ifブロック自体は働くんだけど、おそらくそのあとに、フォーカスが移る機能が働いてしまうみたいだ
フォーカスが移ったあとに戻す方法もやってみたけど、これは成功した
しかし、フォーカスが移った先のコントロールに影響が波及するのでこれも避けたかった
よって>>501の方法がベスト
0503おれさま ◆6CTEZS59O00a
垢版 |
2019/02/25(月) 13:34:33.86
上とは関係ないけど
別のところで使えるかもしれないプロパティを見つけたので書いておく



TakeFocusOnClickプロパティ

コントロールがクリックされたときにフォーカスを取得するかどうかを指定します。

True ボタンはクリックされた場合にフォーカスを取得します (既定)。
False ボタンはクリックされた場合にフォーカスを取得しません。
0504おれさま ◆6CTEZS59O00a
垢版 |
2019/02/25(月) 16:32:38.86
以前つくったものについて高速化を図ろうと思っている
そのうちだけど。

グローバル変数が多い糞仕様を直したいんだけど
ここをいじるとグローバルが故に影響の大きさが怖い
グローバル変数をさわるとしたら、もう一度全部一から作り直す気持でかからないといけない

今のところは、ネストの深い場所で、ワークシート関数へ置換えができないかを考えている
特に、遅くなりがちなセルの値を取得するようなもの
具体的にはforで回しながらIfで一致を試みるようなコードに
Find関数やCountIf関数を使えないか模索したい
0505おれさま ◆6CTEZS59O00a
垢版 |
2019/02/26(火) 11:19:05.14
二点

・TextBox1_Changeは、テキストボックスに、他のボタンやプログラムを使って
今表示されているものと同じ内容を表示させた場合には働かない
当たり前といえば当たり前だけど、文字列の再入力全てに反応するのではなく
文字列の内容が変化したかどうか、そこに反応する


・Val は文字列を数値に変換する
Valueの略か?
0506おれさま ◆6CTEZS59O00a
垢版 |
2019/02/27(水) 17:03:30.22
TextBoxとかのKeyDownイベントで
Ctrl + c とかを判別する時、

If Shift = 2 and KeyCode = vbKeyC とするのが正解
If KeyCode = vbKeyC and Shift = 2 とするのは不正解

下のコードだとCtrlを押した時点ではCを押していないため
Cを押す前にifブロックをそのまま抜けてしまう

ちょい時間なくて未確認だけどたぶんこうかなと思っている
0508おれさま ◆6CTEZS59O00a
垢版 |
2019/03/01(金) 14:31:10.74
ただしだ、

上に書いた例だと
Ctrl+c の話なんだけど
c だけを押した時も別の機能を持たせたいとする

このときに

If KeyCode = vbKeyC Then
(処理)
ElseIf Shift = 2 And KeyCode = vbKeyC Then
(処理)
End If

とするとctrl+cが働かない

If Shift = 2 And KeyCode = vbKeyC Then
(処理)
ElseIf KeyCode = vbKeyC Then
(処理)
End If

だとうまくいくようだ
0509おれさま ◆6CTEZS59O00a
垢版 |
2019/03/01(金) 14:35:47.47
あと、今まで知らなかったことを知った
なんでこんなことを知らなかったんだろうと今更ながら衝撃を受けた

VBAで書いたFunctionプロシージャを
ワークシート関数として使う事ができる

これは知らなかった
たぶんVBAやってる人は当たり前に知ってることなんだろうけど
独学でやっていたせいかこんな大事な事を知らなかった

ワークシート関数をVBAのコードで使うと便利だし高速化に繋がることは知っているんだけど
逆があるとは!

ワークシート関数の優れたところは、簡単な記述でリアルタイムにセルに
値を反映させることができる点。
これを使えば、今まで躊躇してきた問題も解決できそうだ
0513おれさま ◆6CTEZS59O00a
垢版 |
2019/03/08(金) 07:53:14.19
VBAのクラスモジュールはほとんど使ったことなかったんだけど
ネットでざっと読んでみるとJavaやC#のクラスと同じような仕組みだとわかる
どちらかというとC#か
以前数回使ったことあるんだけど、あまりよく分からないまま使ってた
オブジェクト指向の言語勉強してからもう一度学び直すと、なるほどなって思える
そこでVBAのもう少し高度な参考書をぽちってみた


入門レベルでは決して足りない実務に必須のスキルとは ExcelVBA 実戦のための技術
単行本 ? 2018/5/24
沢内 晴彦 (著)


今まで作ってきたものを見直すために使えるかもしれない
0514おれさま ◆6CTEZS59O00a
垢版 |
2019/03/09(土) 03:28:40.70
昔作ったVBAのコードを数時間いじって高速化を試みてみたんだけどことごとく失敗に終わった
高速化とか考えずにとりあえず作ってみたっていうコードが一番速かったという結末

コードの5カ所ぐらいで時間計測してみたら、処理が遅くなっている場所を読み違えていたようだ
ただ、主因となっているところは複雑なコードではなく、改善の余地があまりない
難しいもんだ
0515おれさま ◆6CTEZS59O00a
垢版 |
2019/03/09(土) 07:49:20.40
うぉ・・・高速化成功した・・・
所要時間が1/5に短縮!

5000個ぐらいのセルの値をクリアするコードなんだけど
クリアしちゃだめなセルもある
セルの値が、10パターンぐらいの文字列のどれかに当てはまるなら、そのセルはクリアしちゃダメ
んで、
たぶん一致不一致の判定で時間かかっているんだろうと思って
Likeとアスタリスク使う方法、正規表現使う方法、10パターンの文字列を配列に格納したり
コレクションに格納したり・・・
いろいろやってみたんだけど大差なし
どうやら、実際に消し込む作業に時間がかかっているということが判明

Cells(i, j).Value = "" や Cells(i, j).Clear より
Cells(i, j).ClearContets の方が速いということはわかったんだけど
それ以上の方法が見当たらなかった

で、いろいろググってたんだけど、解決方法は以下の通り

10パターンの文字列は配列だろうがコレクションだろうが大差ないから適当になんかに入れておく
一旦5000個のセル値を配列CellsDataに格納する方向で進むんだけど、
CellsDataの値をひとつずつ10パターンに当てはまるか判定して
当てはまる時だけセル値をCellsDataに入れていく
当てはまらない時は入れないから、そのセルに対応するCellsDataの要素には何も入らないことになる

こうすることで、CellsDataの中身は、必要なセル値を消去した後の表と同じ内容となる

そして、この消去用配列CellsDataを使って、一気に書き込んでいく

Range(Cells(), Cells()) = CellsData

これ↑が突破口だった
よく考えるとこれまで何度か読んだことがある話だったんだけど、思いつかなかった
大量のデータ消去には消去用配列をRangeに一括書き込みすることで高速化が図られるのだ!

これは何も消去だけに限った話ではないのかもしれないんだけど、
単なるデータのセルへの書込みで目立って遅くなったことはない
とするとやはり消去時に特に効果が出る手法なのかもしれない
0517おれさま ◆6CTEZS59O00a
垢版 |
2019/03/10(日) 12:53:50.55
新しく買ってきた本ちょっと読んだけど知らなかったこと多い

Dim i, j as integer
とかいまだにやってる人がいるが・・・・

と書いてあったのだが、はい、わたくしです
知らなかったわぁ
これ i がVariant型になっちゃうそうだ
たぶん勉強始めた頃にこう書いてあったサイトを真似しちゃったんだと思う
こう書いてあるサイトや参考書が結構あるから勘違いしてるひとが多いそうだ
正確には

Dim i As Integer, j As Integer

カウンターぐらいじゃそう問題は起きないかもしれないけど
他の型の変数も同じように定義してきたから
これが原因でわけわかんなくなったエラーもあっただろうな
0518おれさま ◆6CTEZS59O00a
垢版 |
2019/03/10(日) 12:58:34.73
>>515の続きだけど、ワークシートからのデータ取得も
一旦Range型変数に一括取得してから
Rangeから配列に一括代入
そのあと、必要な操作をしたほうがよさそう

今までは必要なデータのみを for や If とかを使って
ワークシートから抽出して配列に代入してた
0519おれさま ◆6CTEZS59O00a
垢版 |
2019/03/10(日) 13:01:14.61
ちょいおかしいか
とにかく不要部分も含めて配列に一括取得してから操作したほうが速いかもって話だ
0520おれさま ◆6CTEZS59O00a
垢版 |
2019/03/12(火) 12:02:34.37
列挙体便利すぎ
可読性が全然違うわ
セルに書き込んだ設定値を拾って配列に入れて使ってたんだけど

Ary1(1, 1) = Ary2(1, 2) & StrConv(Ary2(1, 1), vbWide)

みたいな書き方してたから、わけわからんコードになってた
今時間見つけては、過去に作ったでかいプログラムを作り直してる
作り直す上での課題はたくさんあって書き切れないんだけど
この前買った本をもう少し読んでから本格的に取りかかった方がよさそうなんだよな
とか言いながらコードどんどん書いちゃってるけど

列挙体はネストができるともっとよかった
0523おれさま ◆6CTEZS59O00a
垢版 |
2019/03/17(日) 07:51:08.57
vbaでクラスモジュールを使う必要性はない、あっても限定的だ
とも言われている
でも、ざっと勉強した感じでは、コードの可読性やメンテナンスのしやすさを考えるとそうとも言えないという印象を持った

一度しっかり使えるようにしておきたいので
実用的なお手本コードを何度か書いてものにしようと思う

参考書にはColectionやDictionaryと組み合わせた処理が書いてあるので
これをちゃんと理解して使えるようにしたい
0525おれさま ◆6CTEZS59O00a
垢版 |
2019/03/17(日) 10:24:32.81
https://qiita.com/pregum/items/071f72969d72d90cf826

ここにもCollectionとDictionaryを組み合わせるコードが載っている
使い方は参考書に載っているものとは違うんだけど、
基本的に大事な事は
DictionaryはExistsメソッドによる検索機能が優れているので
検索機能を強化するために使っているという点

CollectionとDictionaryは似ているので
何のために使い分けているのか把握しておかないといけない
じゃCollectionの利点はというと
Dictionaryと違ってItemのみの登録ができるという点なのか
なので、一次元配列を使おうかという場面でCollectionはいい対抗馬になる

ここに検索機能をつけたい場合は
何かを媒介としてDictionaryとつなげる


ここも参考にした
http://blog.livedoor.jp/minus_alpha/archives/4233055.html
0526おれさま ◆6CTEZS59O00a
垢版 |
2019/03/17(日) 10:29:47.92
ええっと、>>525の何かっていうのは、Collectionのインデックス番号だな

Dictionaryにはこのインデックス番号をItemとし、Keyを検索ワードとして登録していくわけだ
IndexNum = myDic.Exists(検索ワード)
とすると検索ワードに対応するインデックス番号を取得できるので、
こいつを使って、Collectionの要素を参照していく
myCol.Item(IndexNum)
とかいう感じで
0527おれさま ◆6CTEZS59O00a
垢版 |
2019/03/19(火) 08:27:16.59
プログラムの組み直し終わったわ
以前の1/4ぐらいの時間で終了
まぁ以前のコードも参考にしてるから当然なんだけど
改変部分も結構ある
以前より使い勝手がよくなったと思うし処理速度は1/10ぐらいになっている

Dictionaryを組み込んでないのが心残りだわ
やっちゃおうかな・・・メインの部品に組み込んでいくから影響範囲が大きいんだよな
0529おれさま ◆6CTEZS59O00a
垢版 |
2019/03/19(火) 10:46:19.01
構造体がデータを格納する機能だけであるのに対して
クラスモジュールはメソッドがついてくるから、その辺まで拡充した役割が必要な時は
クラスモジュールに軍配があがるのかなぁ
あと、セッターで適正値に直したり排除したりできるし
やっぱ複雑なものはクラスモジュールに任せると可読性あがりそう
今回のプログラムも結局クラスモジュールは中心的な処理の中には入れなかったし
これも心残りだわ
0530おれさま ◆6CTEZS59O00a
垢版 |
2019/03/19(火) 10:48:31.52
Dictionary は Exists を目当てに使うのが正解なのもしれない
これ便利
だけど、Key が対象となるわけなので、同じものが重複するようなデータには使えないな
それがネックか
0532おれさま ◆6CTEZS59O00a
垢版 |
2019/03/23(土) 11:40:42.74
ふぅぅぅぅぅ
やっとわかったぜ・・・

ユーザーフォーム上に動的配置したコントロール間で相互にアクセスする方法

もし静的配置であれば簡単で
例えば
TextBox2のクリックイベントプロシージャ内で
MsgBox UserForm1.TextBox1.Value
と書けばいいだけ

動的配置した場合はこういう風にはアクセスできない
今までも動的配置によるコントロール配置はやってきてるんだけど
相互アクセスはやったことがなかった

クラスモジュールにイベントプロシージャを置く事になるんだけど
この中で
動的配置されたテキストボックスのコントロール名を使ってアクセスするというのが解答のようだ

つまり、ユーザーフォームで動的配置したときに、アクセスしやすいように
Nameプロパティで名前をつけておく。
例えばTargetTextとしよう
その上で、クラスモジュールで

Dim tempTextBox as Control
Set tempTextBox = UserForm1.Controls("TargetText")

とすれば
MsgBox tempTextBox.Value

でアクセス可能



疲れたああああああああああああああああああああああああああああああああああああああ
0533おれさま ◆6CTEZS59O00a
垢版 |
2019/03/23(土) 15:32:11.89
ユーザーフォーム上のコントロール動的配置についてもう少し理解を深めるために
単純なプログラムを作ってテストを重ねてみた
ぐぐっても出てこない部分は想像に頼ってるんだけど、大体理解出来たと思う

たまにこういう事をやらないと無駄なコードを書くことになる
今回は今まで書いてたコードの間違いというか、無駄な部分をいくつか見つけたのが収穫だった
0534おれさま ◆6CTEZS59O00a
垢版 |
2019/03/24(日) 09:27:53.73
よし、機能的には大体やりたいこと全部できた
あとはエラーが出ないか現場でチェックだな
一仕事終わった
0538おれさま ◆6CTEZS59O00a
垢版 |
2019/03/30(土) 08:49:18.17
VBAでエラー処理をSubプロシージャごとに書いていく作業が刺身にタンポポ乗っける作業と同じぐらい苦痛
これC#で自動化するプログラム書いちゃおうかな
単なる文字列操作だからできるよな
ここ数ヶ月やってなかったんで忘れてしまったが、C#の課題としておくか
0539おれさま ◆6CTEZS59O00a
垢版 |
2019/03/31(日) 08:55:24.58
>>537を参考に罫線をコピーするコードを書いてみたんだけど死ぬほど遅い

やっぱりCopyメソッド使った方がよさそうだ
0543おれさま ◆6CTEZS59O00a
垢版 |
2019/04/08(月) 12:16:38.61
C#の参考書少しずつ読んでるんだけどVBAとダブる部分は
VBAだとどうなのかをメモしてる
この辺ちゃんとやっておかないと記憶があやふやになる
0544おれさま ◆6CTEZS59O00a
垢版 |
2019/04/10(水) 15:57:46.05
VBAとしっかり比較しながらやると勉強になる
C#の知識が増えるころにはVBA忘れる現象に少しは歯止めがかかりそう
というか比較しながらやると知識の固定にも役に立ちそうだわ
除算系の算術演算子とか基本的なのも忘れるからなぁ

独習読み込むのと同時に
C#でちょっとしたウィンドウズアプリ作ってる
URLをテキストボックスに入れてボタン押すと
サーバーにアップロードしてあるZipをダウンロードして解凍して
日付で名前をつけたフォルダに入れるってやつ
こういうのってエラー処理やら利便性無視すれば簡単にできるんだけど
いろいろ考えちゃうと難しくなる
適当なところで見切りつけて終わる予定だけど。
ググって出てくるコードみると、イベントにマルチキャストデリゲートだったか
そんなの使ってたりするんで理解しようとすると大変だ

GUI関連をきちんと理解するのに役に立つ本があるといいな
0545おれさま ◆6CTEZS59O00a
垢版 |
2019/04/11(木) 15:42:43.04
今日の学習は終わり!
4章の途中まで復習した
switch-case文、
VBAだとSelect Case-Case文
これがたまに混同する
If文の条件式みたいにC#だと丸括弧を使うので注意だな
すぐ忘れる
0547おれさま ◆6CTEZS59O00a
垢版 |
2019/04/14(日) 07:40:29.88
ローカル変数の整数型、初期化しないと
VBAのIntegerだとゼロ
C#のintだとコンパイルエラー

フィールドだとC#はゼロ埋めのようだ
配列も同様

この辺VBAの方が易しい
0549おれさま ◆6CTEZS59O00a
垢版 |
2019/04/16(火) 14:35:25.16
delegateをごちゃごちゃいじってる
簡単なプログラムを何個も作ってテストしてる
いろいろ分かってきたわい
0550おれさま ◆6CTEZS59O00a
垢版 |
2019/04/18(木) 14:13:49.97
ラムダ式をごちゃごちゃいじってる
独習のラムダ式の説明はいまいちだな
理解はできたんだけど、これじゃ挫折する人いると思う
デリゲートを用いる最も簡単な例、つまり、メソッドの引数としてメソッドを引き渡すケースではなく
メソッドを変数に代入して使うだけの簡単なケースを
ラムダ式の紹介の一番最初に出してくれないと。
おそらく紙面を節約しないといけない都合でこうなったんだろうけど
0551おれさま ◆6CTEZS59O00a
垢版 |
2019/04/18(木) 15:10:18.74
配列とかコレクションとかで、全ての要素を順に操作する目的で
ラムダ式が多用されるのな
これ便利だわ

ちなみに独習の標準ライブラリの章で配列にAnyメソッドを使ってる場面があるんだけど
これはListでも使えて、たぶんListにあるExistsメソッドと機能は同じだ
Anyはusing System.Linqが必要

この辺の知識はForの代用として使えるから、すっきりとしたコードをかけるようになれそう
0553おれさま ◆6CTEZS59O00a
垢版 |
2019/04/20(土) 04:30:11.10
ラムダ式の構文でこんなのが独習に書いてある

TResult Func<T, TResult>(T arg)

こういうのをこれまで半ば無視しつつも、時に参考にしてきた
厳密な使い方を理解したいなら、この「構文」とやらをちゃんと理解しておいたほうがいいんだろうなとは思ってる

この構文の形式に近いものがコードに現れてくるのは
ラムダ式で表現されたメソッドを受けとるメソッドの定義部分
例えば
void DoMethod(Func<int, string> output) { Console.WriteLine(output(10)) }
みたいな。

TResult Func<T, TResult>(T arg) において、

<T, TResult> は、T型を引数とし、TResult型を戻り値とする、の意味。ジェネリックだ
頭のTResultは、TResult型の戻り値をおけ、の意味
(T arg)は、T型の引数argをおけ、の意味

argは、argument 引数 の意味
引数というのはparameterじゃなかったっけと思って調べてみたんだけど

argument 実引数
parameter 仮引数

みたいな違いがあるという記述があるという一方
それほど厳密な定義でもないという話も。

エントリーポイントのメインメソッドの引数、つまりコマンドライン引数でも
args として複数の引数を示している
argとかargsが構文に書かれていたら、実際にここに引数を書けということだと理解すれば足りるということだな
少し違和感を感じるのは、なぜ引数だけargという記述を用いて、
戻り値の方はTResultという型しか書いてないのかという点だけど、
まぁこれはよく考えたら、例えば仮引数に変数を使うけど、
戻り値にあらためて変数を使う事はないし、戻り値はメソッド名を書くことで取得できるわけで
そういう意味では、引数にargの記述があり、戻り値にはこういう記述がないのは当たり前か
戻り値を
0554おれさま ◆6CTEZS59O00a
垢版 |
2019/04/20(土) 04:43:07.46
そう考えると、こう書くのが正確なのか

TResult Func<T, TResult>(T arg) において、

Func<T, TResult> は、Func<>の<>の中に2つの型を書けということを示す。そして、
(T arg)の記述により、一つ目のTが引数の型として使われることを説明
構文の冒頭に記述されるTResultの記述により、2つ目のTResultが戻り値の型として使われることを説明

みたいな感じか
まずFunc<T, TResult>という風に書け
そして、TおよびTResultが何なのかを説明するために
TResult Func<T, TResult>(T arg)
というようにFunc<T, TResult>の前後に追加して記述されていると。

順番を意識したほうがよさそうだ
0555おれさま ◆6CTEZS59O00a
垢版 |
2019/04/20(土) 18:13:08.77
LINQで分からないところがあって、ずっと考えてた
やっと分かった(気がする)んで今日はこれで終わろう
もう少しちゃんと説明が書いてあるといいんだけど、難しかったんだろうな
ぐぐってもなかなかヒットしないしね
0556おれさま ◆6CTEZS59O00a
垢版 |
2019/04/21(日) 09:03:25.23
LINQを使う前に、IEnumerable<T>の理解はしておかなきゃね
ということでその辺の復習してる
0557おれさま ◆6CTEZS59O00a
垢版 |
2019/04/21(日) 09:13:37.09
独習に例示してあるコードは実践的にしたいためか
学習するには要点がぼけてしまってるものがある
なので、自分でぱっとみてポイントが分かるようなコードに書き直して
ちっこくプリントアウトして独習に貼り付けるというアナログなことをしている
なんだかんだいって勉強は紙の方がいいんだよなぁ
検索ができないという点をのぞけばだけどさ

リアル本と電子書籍のハイブリッドなナニカができるといいな
見てくれはリアル本なんだけど、一ページ一ページが電子的な処理が施されていて
印刷内容だけでなくメモった内容も表紙に内蔵されたストレージに保存される
これを使って検索も容易に出来るとか
俺しか需要がないか
0558おれさま ◆6CTEZS59O00a
垢版 |
2019/04/22(月) 14:28:31.25
頭の中で、抽象クラスというものの存在意義と
ポリモーフィズムがしっかりと関連づけられていなかった
ここがちゃんと結びついてるといろんなルールもすんなり頭に入ってくる (ような気がする
0560おれさま ◆6CTEZS59O00a
垢版 |
2019/04/27(土) 16:54:28.86
あるクラスのプロパティAやメソッドAが、別のクラスBのオブジェクトを返す場合
AとBの名前が同じなことが多いのかな
これまで適当に捉えてたから気づかなかったんだけど、正確に捉えて置いた方がよさそうだ

例えば、
正規表現で、RegexクラスのメソッドMatchがMatchクラスのオブジェクトを返すから
Matchメソッドの構文は

Public Match Match(string input [, int beginning [, int length]])

とMatchが2つ連なっている
で、戻り値として得たMatchオブジェクトというかインスタンスのメンバを使っていろいろと
詳細データを引き出すことになる
なので、最低限この2つのMatchが別物だと認識することは必要
0561おれさま ◆6CTEZS59O00a
垢版 |
2019/04/27(土) 17:41:40.08
正規表現で
サブマッチ文字列を取り出しすとする

foreach (Group item in m.Groups)
{
Console.WriteLine(item.Value);
}

みたいにするんだけど、このとき、Groupをvarにすると
Valueプロパティが使えなくなる

foreach (var item in m.Groups)
{
Console.WriteLine(item);
}

ならいける
ん〜なんでだろと思って調べてみたんだけど、varを使うとitemにobject型が入るみたいだ
そのため、Group型であれば使えたはずのメンバーが使えなくなる
単純に表示させるだけなら別に問題ないんだけど。

ここで大事なのはvarを使っても具体的な型を使っても同じだと思っていたけど
そうではないケースがあるということだ
上の例だとGroupを使った時はvarを使った時と比べると、6個も追加のプロパティが使えるようになる
複雑な操作を必要とする場合、影響大きいかも
0562おれさま ◆6CTEZS59O00a
垢版 |
2019/04/27(土) 18:39:44.47
正規表現おもろいなぁと思って
正規表現の聖書と言われているオライリーの「詳説 正規表現」をアマゾンでみたら

\5,184
https://www.amazon.co.jp/dp/4873113598/

ふぇ・・?正規表現だけで5せんえんですか!
しかしそのうち買ってしまう予感がする・・・・
0563おれさま ◆6CTEZS59O00a
垢版 |
2019/04/28(日) 12:57:04.01
public static void Main(string[] args) {
 Console.WriteLine("aaa");
}

みたいなJavaでやってたカッコの付け方に変更できるようだ
Visual Studioの
ツール→オプション→テキストエディタ→C#→書式設定

「始め中カッコ」
という名称があるようだ

変更しようか迷うところだ
0564おれさま ◆6CTEZS59O00a
垢版 |
2019/04/28(日) 13:07:30.18
DateTimeの復習してて令和を含んだ文字列をParseできないか試したけどだめだった
VisualStudioをアプデしたらいけるかなと思ってやってみたら、
これ数ギガ分、つまりファイル全部アプデすんのな
DL待ちで使えなくなってしまった
0565おれさま ◆6CTEZS59O00a
垢版 |
2019/04/29(月) 07:20:46.95
windowsアプデのKB4493453を手動でいれたら、令和認識するようになったわ

var str = "令和1年5月1日";
var d = DateTime.Parse(str);
Console.WriteLine(d);

結果:
2019/05/01(日) 0:00:00
0566おれさま ◆6CTEZS59O00a
垢版 |
2019/04/29(月) 11:57:46.59
IFormatProviderとかいうのがいろんな構文に引数の型として出てくる
引数の型として指定されているにもかかわらず、実際のコードをみると
「IFormatProvider」という文字はどこにも書かれていない
見て見ぬフリしてたがちゃんと調べてみた

通常はIFormatProviderを実装したクラスであるCultureInfoクラスを利用するようだ
日本独自の表現をしなければならないような場合に使うようだ
例えば日付情報なんか
「2019年」というだけで「年」という日本語を使うので、正確に言えばこういうものを表示する場合だって含まれる

IFormatProvider provider
のようにメソッドの引数として指定されている場合、実際のコードではこう書く
・new CultureInfo("ja-JP")
・CultureInfo.CurrentCulture
・CultureInfo.GetCultureInfo("ja-JP")
のどれでも結果は同じだった
要はIFormatProviderを実装するCultureInfoクラスを使って
日本だってことが伝わればいいようだ
0567おれさま ◆6CTEZS59O00a
垢版 |
2019/04/29(月) 12:12:28.99
var dt = DateTime.Now.AddDays(2);
var ci = new CultureInfo("ja-JP");
ci.DateTimeFormat.Calendar = new JapaneseCalendar();
Console.WriteLine(dt.ToString("f", ci));

結果:
令和元年5月1日 12:03



おぉ・・・でたでた

ci.DateTimeFormat.Calendar = new JapaneseCalendar();
が大事
DateTimeFormatプロパティは戻り値がDateTimeFormatInfoオブジェクト
つまりCultureInfoクラスは、DateTimeFormatInfoオブジェクトをフィールドとしてデータ保持していることになる
そんでもってDateTimeFormatInfoクラスはCalendarプロパティを持っている
CalendarプロパティはCalendar型のフィールドに繋がっている
ここにJapaneseCalendarオブジェクトを代入する

継承Object→Calendar→JapaneseCalendar

だから代入可ということか
0568おれさま ◆6CTEZS59O00a
垢版 |
2019/05/01(水) 13:30:45.23
おっしゃ
実際に役立つアプリができた
ランチャー的なものなんだけど練習にはちょうどいいし
自分で使う分には相当便利で満足
令和の初日に完成か
0569おれさま ◆6CTEZS59O00a
垢版 |
2019/05/02(木) 16:24:00.66
もう1個作った
Javaで作ったやつをC#で作り直したんだけどずっと簡単だった
VSの恩恵を受けてるだけなんだけど。
夏時間も反映する海外の時間も表示する時計なんだけど
ついでにこいつをタイムスケジューラ代わりに使っていこうと思う
Windowsのタイムスケジューラはなぜかそのうち機能停止するので役に立たない
0570おれさま ◆6CTEZS59O00a
垢版 |
2019/05/03(金) 00:47:31.36
webスクレイピングまで行かなくてもhtmlもらってくる処理をしたりするときのお手本コードを
調べてるとasync awaitをつかったものがでてくる
この辺は独習で飛ばしてしまったのでやり直すことにしよう
0571おれさま ◆6CTEZS59O00a
垢版 |
2019/05/03(金) 10:56:11.45
async awaitのところ、独習の説明だと分かったのか分かってないのか分からないという
経験から言えば、これはちゃんと理解できてないなという程度

もう一冊買ってある参考書を読むことにする
0572おれさま ◆6CTEZS59O00a
垢版 |
2019/05/03(金) 13:10:12.97
実戦で役立つ C#プログラミングのイディオム/定石&パターン

を読んでるんだけど、わかりやすいわぁ
独習は基本的な所を網羅してる点でいいんだけど、少し難しい所に入ると
紙面節約のためか学習の順序ってのをすっとばして説明するから困る

独習もう一度しっかり読んでから実戦を読もうと思ってたけど、
こっちも読み進めていった方が効率あがりそうだ
0573おれさま ◆6CTEZS59O00a
垢版 |
2019/05/03(金) 15:20:05.79
Javaで作った定期的なグローバルIPアドレス記録を時計アプリに組み込んだ
ローカルIPアドレスもついでに記録するようにしたんだけど、これが案外手間取った

あとTimerのインターバルが100mm秒だとなかなか気づけなかった
1秒だと思い込んでた

タイムスケジューラ的な使い方がうまくいくなら
これからはこいつがwindowsのタイムスケジューラのかわりとして利用できることになるわけだ

今回は基本的な非同期処理も取り入れていろいろ勉強になった
0574おれさま ◆6CTEZS59O00a
垢版 |
2019/05/05(日) 10:54:49.01
タスクスケジューラに登録してたのものをすべて時計アプリから実行するようにした
バッチファイルもいけるかなと思っていろいろ調べてやっと問題なく起動できるようになったんだけど
よくよく考えてみたら、exeにコマンドライン引数を渡すためのバッチファイルだった
つまり、普通にexeを時計アプリから引数付きで起動すればいいだけの話だった

もっと言えばそのexeも自分がプログラミングができないから、ネット上から誰かの作ったフリーソフトをダウンロードしたもので、すでにある程度自分でやれるんだから、自作すればいいだけの話なのだが。

少しずつ自作のプログラムに置換えていこうと思う
0575おれさま ◆6CTEZS59O00a
垢版 |
2019/05/05(日) 14:37:42.91
エスケープシーケンス関連の理解が不正確
もっと厳密に理解することにする
なんとなく適当にやってるとできちゃうからよくない
0576おれさま ◆6CTEZS59O00a
垢版 |
2019/05/05(日) 15:30:50.95
Console.WriteLine("aa\naa");//aa[改行]aa
Console.WriteLine("aa\\naa");//aa\naa
Console.WriteLine(@"aa\naa");//aa\naa
Console.WriteLine("aa\daa");//エラー
Console.WriteLine("aa\\daa");//aa\daa
Console.WriteLine(@"aa\daa");//aa\daa

Console.WriteLine((new Regex("aa\naa").IsMatch("aa\naa")));//true(これは特殊な例か)
Console.WriteLine((new Regex("aa\\naa").IsMatch("aa\naa")));//true
Console.WriteLine((new Regex(@"aa\naa").IsMatch("aa\naa")));//true
Console.WriteLine((new Regex("aa\daa").IsMatch("aa1aa")));//エラー
Console.WriteLine((new Regex("aa\\daa").IsMatch("aa1aa")));//true
Console.WriteLine((new Regex(@"aa\daa").IsMatch("aa1aa")));//true

んー正規表現のパターンの中でエスケープシーケンスを用いる場合
基本的には逐語的な表現をしないといけないと思うんだけど、
\nのようにそうでないものもある
上の単純なConsole.WriteLineでの出力で\nについてエラーがでないことと関連するんだろうなぁとは思うんだけど、まぁそういうことなんだろうな
0577おれさま ◆6CTEZS59O00a
垢版 |
2019/05/05(日) 16:56:26.81
非同期処理async-awaitはC#7.1以降、Mainメソッドでも使えるようになった

しかし、デフォルト設定だと
「最新のメジャーバージョン」を適用することになっているためC# 7.0までしか使えない
そこで、プロジェクトのプロパティ→ビルド→詳細設定から7.1以降を選ぶ


もう一つ

DateTime型は算術演算子を使った比較ができるんだけど
DateTime.Nowを使って取得した現在時と、new DateTime()で取得した固定時間を比較して
イコールになったタイミングで何かをするみたいなことをしようとしてもなぜか一致しない

これは、DateTime型がミリ秒まで格納してるから。
Nowの方はミリ秒が半端なのに対して固定時間はゼロなので、大抵一致しない
そこでミリ秒部分を無視できるように、ToString()でミリ秒がないような文字列に変換して比較するといい


ちなみに、この実験をするときに、VBAでつかったSleepみたいなメソッドがあるといいなと思ったんだけど、
非同期処理をするTask.Delay(1000)を使った方がよいということだ。
これを繰り返し処理と合わせて、1秒おきに処理させて一致させると。
んで、Task.Delayをメインメソッドで使えたら楽できると思って、・・・・最初の話につながる
0578おれさま ◆6CTEZS59O00a
垢版 |
2019/05/05(日) 17:06:54.65
時計アプリでTimerを使ったんだけど
whileとTask.Delayを組み合わせる方法とどちらがいいんだろうか

そういやTimer使った時、非同期処理なんて考えても行かなかったんだけど
https://qiita.com/kenji-yokoi/items/3115dbf876e6ed30ba50
こんな感じにやったほうがいいわけか

結局どちらの方法を使っても非同期処理をうまくやればいいってことかな
0580おれさま ◆6CTEZS59O00a
垢版 |
2019/05/06(月) 13:27:13.36
引き続いてasync-awaitやってるんだけど
自分で適当に練習コード書こうとするといろいろ気づく

Mainメソッドでasyncを使う時
public static async Task Main(string[] args)
みたいにTaskを戻り値の型としないといけない
これをvoidとするとエラー

これは理解できる

C#7.1以前は別にasyncのメソッドを作ってたわけだ
static async Task RunAsync()
みたいなの。
これをMainとかから呼び出す形で使ってたわけだけど
そのままMainに組み込めるようになったということなので
Mainの戻り値がTaskになるのはごく普通

そもそもここをTaskとするのは、そのメソッドを呼び出したメソッドに非同期処理の状況などを
通知するためなんだけど、Mainを呼び出すメソッドに通知するって話になる
ん・・・?ってなるけどここはまぁいいとする

問題は、GUIアプリでつかうイベントハンドラを非同期にした場合
private async void button1_click()
これはなんでvoidなんだ?って話

これがおかしいのかこれは普通でほかがおかしいのか、その辺を突き止めるのがやっかいだったけど
結論としては、イベントハンドラの方が特別で例外的な仕様になっているようだ
ここでvoid Taskとするとエラーがでる
そもそもイベントハンドラを呼び出すのはコードではなくてユーザだから
Taskで通知を返しても意味ないじゃんとかいうことらしい

なるほどね
0581おれさま ◆6CTEZS59O00a
垢版 |
2019/05/06(月) 13:51:12.44
//@
public static async Task Main(string[] args)
{
 await Task.Run(() => DoSomething());
}
//戻り値のない同期メソッド
static void DoSomething()
{
 var str = "aaabccc";
 var result = str.Split('b');
 Console.WriteLine(string.Join(".", result));
}

//A
public static async Task Main(string[] args)
{
 var str = await Task.Run(() => DoSomething());
 Console.WriteLine(str);
}
//戻り値のある同期メソッド
static string DoSomething()
{
 var str = "aaabccc";
 var result = str.Split('b');
 return string.Join(".", result);
}

//B
public static async Task Main(string[] args)
{
 await DoSomethingAsync();
}
//戻り値のない非同期メソッド
static async Task DoSomethingAsync()
{
 await Task.Delay(2000);
}

//C
public static async Task Main(string[] args)
{
 var str = await DoSomethingAsync();
 Console.WriteLine(str);
}
//戻り値のある非同期メソッド
static async Task<string> DoSomethingAsync()
{
 await Task.Delay(2000);
 return "aaa";
}
0582おれさま ◆6CTEZS59O00a
垢版 |
2019/05/06(月) 14:35:50.64
非同期Mainではwaitは使わないでいいってことかな
呼び出し元でwaitを使うわけだけど
そもそも呼び出し元がないような形になっているのでwaitを使いようがない
0583おれさま ◆6CTEZS59O00a
垢版 |
2019/05/06(月) 15:03:41.51
https://www.kekyo.net/2016/12/06/6186
ここにすごく大事な事が書いてあるような気がする

自分なりにまとめると、
非同期Mainでwaitを使わないでよいのと同じような理由で
GUIアプリのイベントハンドラでもwaitを使わなくてもよい、というようなことになるのかな

使っちゃうと「デッドロック」とやらを引き起こしてしまうそうな

waitをつかわなくちゃだめな例としてはコンソールアプリで非同期メインを使ってないケース
メインメソッドから非同期メソッドを呼び出す
すると、呼び出し先の非同期メソッドではawaitで当該非同期処理の終了を待機することになる
その間にメイン「スレッド」はメインメソッドを抜けてしまってプログラムが終了してしまうことになる
つまり、非同期メソッドの終了を待たずしてプログラム全体が終わってしまうことになる
これは呼び出し元がメインメソッドだからこそ起きるとも言える

@非同期メインでwaitを使う必要がない理由
非同期メインではメインメソッドの中で「await」(waitではなく)を使う事になる
これによってawaitに続く非同期処理が終了するまでメインスレッド自体が待機することになる
これによってメインスレッドが勝手に終了してプログラムが終わってしまうなんてことはないということだ
コンソールアプリで非同期メインを使わないケースでは「await」が置かれているのはメインメソッドではなく、メインメソッドから呼び出される非同期メソッドの中であるという点に注目すれば違いが分かる
この場合は、非同期メソッドの流れがそこでawait(待機)状態になるわけだ
非同期メインではメインメソッド内にawaitが置かれるためメインメソッドの流れがそこでawait(待機)状態になる

A
0584おれさま ◆6CTEZS59O00a
垢版 |
2019/05/06(月) 15:10:11.18
AGUIアプリのイベントハンドラでwaitを使っちゃだめな理由
イメージ的な説明なんだけど、
コンソールアプリで非同期メインを使っているときのメインメソッドと
GUIアプリの非同期イベントハンドラは同じような位置づけになるんじゃないかと。
つまり、
非同期のイベントハンドラ内でawaitを使う事になるので、そこで非同期処理が終わるまで待機してもらえるためwaitの必要がない
これは@とまったく同じこと


いまんところはこういう理解をしている
そのうち変るかもしれないが
0585おれさま ◆6CTEZS59O00a
垢版 |
2019/05/07(火) 18:03:21.34
FileInfoとかDirectoryInfo使う時のパス指定で

「 . 」カレントディレクトリ
「 .. 」一つ上のディレクトリ

が使えるんだけど、一般的ではないのか独習にも書いてない
FileInfoのコンストラクタに渡す引数なんだけど

" data.txt "
" . / data.txt "
" . \data.txt "

この3つはどれを渡してもカレントディレクトリのdata.txtの意味になる
(5ch上では判別しにくいので半角スペースをいれてある)
/ と \ が同じ意味で使えるっていうのは・・・・

さらに

" .. /data.txt "
" .. \data.txt "

この2つはどちらも一つ上のディレクトリのdata.txtを意味する

まさかと思ってやってみたんだけど、
これまで出てきたパス指定なんだけど、¥のかわりに/を使っても大丈夫だった
なら逐語的表現を指定する@を使う必要がなくなるのか
なんで独習には書いてないんだろうか

思い出してきたんだけど、スラッシュをフォルダの区切りとして使うのはもともとUNIXでの書き方か
http://www.tohoho-web.com/ex/draft/path.htm
windowsだとバックスラッシュを使うのが基本
HTMLだと/が使える
この辺は混在してるわけか
0586おれさま ◆6CTEZS59O00a
垢版 |
2019/05/09(木) 14:23:31.97
地道に独習の復習

やってて思うんだけど、簡単なコードの使い方ぐらいは調べなくても
さっさと書けるようにしないと、難しいコードの使い方を覚えようとしたときに行き詰まるんだよな
記憶力がいまいちだからしっかり覚えるために工夫していかないといけないなと思ってる
0587おれさま ◆6CTEZS59O00a
垢版 |
2019/05/10(金) 17:47:09.29
VBAのプログラム作ってた
windows API呼び出すものなんだけど
DoEventsを使わないとうまく行かないということにやっと気づいた
うまく作れた
0588おれさま ◆6CTEZS59O00a
垢版 |
2019/05/11(土) 11:20:02.43
VBAのプログラム作ってて思うんだけど
windowsAPIを使いこなすための基本知識が欲しい
なんだかんだこぴぺで足りてしまうんでちゃんと勉強してこなかった
何かいい本ないかと思ってアマゾンで検索して
よさそうなのポチろうとしたら、すでに購入済だって表示されててワロタ
今その本発掘してきた
0589おれさま ◆6CTEZS59O00a
垢版 |
2019/05/11(土) 14:12:48.22
これはVBAだけじゃなくて他の言語もやってないと難しいな
ずっと前に少しだけ読んで結局途中で挫折したの思い出した
今読むとそこそこ理解できる
C言語の知識も使うようだ
ずっと昔に少しだけやったけど忘れてしまっている
0590おれさま ◆6CTEZS59O00a
垢版 |
2019/05/12(日) 08:42:43.67
VBAで引数にカッコつけるかどうかの話は大事なんだけど結構忘れる
細かい仕様を理解してないとどうしてこのバグがおきてるのか理解できない
ここはちゃんと押さえないといけないんだが・・・

括弧()はどんなときに使うの?
http://officetanaka.net/excel/vba/beginner/07.htm

もう一つこれ

VBA 関数に引数を渡す
https://www.tipsfound.com/vba/02002

ここの「ByVal と ByRef の違い」の「注意点」ところ
もう一度読んでおかないといけない
これたぶん知らなかったと思う

「これは引数に括弧 () を付けると、強制的に ByVal (値渡し) にする仕様のためです。」

callをつけない場合にバラエティに富んだ動きをするみたい
いままで経験的にcallをつけた方がエラーが起きにくいと思っていたのは
この辺の仕様を理解出来てなかったからだな
0591おれさま ◆6CTEZS59O00a
垢版 |
2019/05/12(日) 09:15:32.83
http://officetanaka.net/excel/vba/statement/Call.htm
myFunctionが引数を受け取り値を返すユーザー定義関数だった場合の書式は、
次のとおりです。

myFunction 123 正常
myFunction(123) エラー
Call myFunction 123 エラー
Call myFunction(123) 正常
rc = myFunction 123 エラー
rc = myFunction(123) 正常
rc = Call myFunction 123 エラー
rc = Call myFunction(123) エラー

こう書いてあるんだけど、2番目のこれ

myFunction(123) エラー

実際にVBEで書くとこんな感じに半角スペースが自動的に挿入されて表示される

myFunction (123)

でもって、エラーなしで通ってしまう
myFunctionの中身次第で通らないこともあるのかもしれないんだけど、解釈としてはこう

myFunction 123 '戻り値を利用しないからカッコをつけないパターン
myFunction(123) '戻り値を利用しないからカッコをつけるとエラー(しかし実際にはこう書くことはできない)
myFunction (123) '戻り値を利用しないからカッコをつけると本来エラーなのだが、半角スペースが自動ではいることで、このカッコは別の意味を持つ。つまりこのカッコはByValを強制するカッコとなる。
0592おれさま ◆6CTEZS59O00a
垢版 |
2019/05/12(日) 15:55:25.36
Win32APIの知識はVBAだけじゃなくて他でもそのうち役に立つかもしれない
と思ってやってるんだけど、それより
C言語が絡んできたのが面白い
まさかVBAやっててC言語の知識を使うとは思わなかった

ある言語から他言語を使うようなパターンは今まで一度もやったことがなかったから
そういう意味でも面白い

固定長のnull埋めされた文字列を定義して渡したあと
戻ってきた文字列からnullを抜いた残りを取り出すとか
0593おれさま ◆6CTEZS59O00a
垢版 |
2019/05/14(火) 13:39:18.82
またVBAのプログラム作ってた
正規表現盛りだくさんやつ
やっぱ正規表現の本買っちゃおうかなぁ
これ使えるわ
0594おれさま ◆6CTEZS59O00a
垢版 |
2019/05/16(木) 07:54:49.59
あーまたVBAにはまってきた
C#と文法がぐちゃぐちゃになって次第にVBA勢に脳内が支配されて・・・・
うがああああああああ

functionの作り方で、配列とかを引数としてfunctionに渡して適切な値を入れてもらう
んで戻り値をbooleanにして成否を伝えるっていう
Win32APIの勉強しててこのパターンがよく出てきたんで真似てみたんだけど悪くない
0595おれさま ◆6CTEZS59O00a
垢版 |
2019/05/18(土) 09:02:34.44
たくさんプログラム作ってると、以前作ったもののメンテナンスしないと
いけない場面によく出くわすんだけど
共通した処理を関数に切り出したり、共通した値を定数として宣言したりするのってほんと大事だ
昔つくったのはこの辺ができてないから、少しいじるだけでも大変
いろんな所に同じものが散らばってるから全部直さないといけない
メンテナンスまでやると大事さがわかってくるなぁ
0596おれさま ◆6CTEZS59O00a
垢版 |
2019/05/20(月) 14:36:34.46
VBAのプログラムを3つ同時に作ってる

一つは昔作ったやつで、これまでは使われてなかった
でも使う事になったんで見直したらいろいろいじりたくなってきた
マジックナンバーが多すぎるし共通部分の洗い出しが全然できてない
これじゃメンテナンスに苦しむのは目に見えてる
今後変更されそうな部分は簡単に取っ替えられるようにしておかないとね
ほんとはもっと大きくいじってもよさそうなんだけどキリがない

10個ぐらいのデータを並べて1セットとして
このセットを1ページに複数行複数列タイルを貼るかのように
並べていくパターン

この処理が3つのシートそれぞれにあって、それぞれ別個のコードを書いてた
セットの中身も違うし、並べるタイルの数も違うんだけど
これを一般化して関数として作り直した

数列の一般項を求めるのがポイント
関数に渡す引数が多いので構造体を使って一気に引き渡すと同時に
構造体によるインテリセンスによって間違いを減らす

これによって、タイルの中身が変更されたときにもすぐに対応できるし
タイルの並べ方が変更されても与える定数を変更することで簡単に対応できる

ちなみにこれまでのコードでは、
タイルを並べるような概念はなくて、項目のひとつひとつを適切な場所に個別に配置していくパターン
セットの並べ方が変ると、10項目ひとつひとつについて修正が必要になっていた
コードの見通しも悪かった
0597おれさま ◆6CTEZS59O00a
垢版 |
2019/05/21(火) 14:34:27.01
オライリーの詳説正規表現買っちまったぜ・・・・正規表現だけで5せんえんとか・・・
0598おれさま ◆6CTEZS59O00a
垢版 |
2019/05/22(水) 12:35:15.08
VBAのコード書いてると
配列は全部要素番号1からの方が処理しやすくて統一してるんだけど
ほかの言語やるとゼロからだし、VBAだってsplitが返す配列はゼロから始まるし
やぱ配列はゼロからに統一したほうがいいのかなって最近考えてる
どの言語やるにしても必ずゼロから始まると意識して気をつけてれば慣れるものかもしれないし
0602おれさま ◆6CTEZS59O00a
垢版 |
2019/05/30(木) 15:31:53.35
今日はいろいろテクを学んだ
配列関連だから今後使えると思う

Rangeで列や行を一括取得したときに作られてしまう二次元配列を
1次元配列にする方法

とか

あとListBoxにアイテム追加するのにAddItem使ってたけど
これ表示がバグることがあるんで、Rangeや配列から一括代入したほうがよさそう
バグらなくなったんでたぶんこうしたほうがいいんだと思った
0603おれさま ◆6CTEZS59O00a
垢版 |
2019/06/01(土) 08:48:18.36
ん〜まだまだ完成しないな
少しずつやっていくしかない
大分進んで、構造的なものも明確になってきたんで
あとは間違いないように組んでいくだけだ
0605Mr.名無しさん
垢版 |
2019/06/04(火) 11:20:36.28
難しいけど上げとくね
0607おれさま ◆6CTEZS59O00a
垢版 |
2019/06/05(水) 16:00:24.08
俺が以前作った使えなさそうなプログラムが知らない所で意外な活躍をしてた
役にたつことはあまりなさそうなものでも
使う人が用途を見つけた途端にとんでもないものに化けるから面白い
がちがちに固めずふんわり系のインフラ的ソフトは特にね
0609おれさま ◆6CTEZS59O00a
垢版 |
2019/06/09(日) 09:20:06.69
ん〜大体これでいいかな
つけた方がいい機能は全部つけた
やっぱ入力フォームは鬼門だなぁ
各コントロールが複雑に入り組んでて制御が大変だ
特にListBoxがらみ

でもこれで大きなバグは潰したと思うから
これ以上でないことを祈るばかり・・・・
0610わがはい ◆0BMoNHqNlM
垢版 |
2019/06/11(火) 04:19:34.88
まだそんなことしてたんか

ワイのwebアプリはMongoDBからAjaxでデータ抽出してクライアントサイドでD3js使って視覚化できるようになったからひとまず完成かな
AdSense貼って月二万弱くらいの収益は得られるようになったで

次はサーバサイドでTensorFlowの処理結果をブラウザでインタラクティブに操作できるアプリ作れないか考えてる
深層学習を一から勉強せんとあかんから完成はだいぶ先やな
0612おれさま ◆6CTEZS59O00a
垢版 |
2019/06/14(金) 09:53:41.47
とりあえず引き渡してきた
まだバグ見つかるかもしれないけど
ほぼ大丈夫だろー
0613おれさま ◆6CTEZS59O00a
垢版 |
2019/06/14(金) 15:37:39.28
こういう風に変えたいなって思った時に
すんなり変える事ができるようになってきた
新機能を追加する場合も昔と比べたらずっと楽

最初から変更に備えたコードを書いているというのもあるし
いろんな技術も身についてきた感もある

VBAに関して言えば、できる限り設定値を外に出して
コード外で変更に対処できるようにもしてるから
小さな変更はかなり楽
0614おれさま ◆6CTEZS59O00a
垢版 |
2019/06/15(土) 13:00:35.00
VBAのDictionaryだけど
とりだすときの順番は先入先出で保証されてるみたいだな
保証されてないとか書いてあるサイトもあったけど
大丈夫みたいだ
0616わがはい ◆0BMoNHqNlM
垢版 |
2019/06/15(土) 23:27:36.95
知らなかったのかよw
dictionaryは連想配列なんだからやり方次第でスタックとしてもキューとしても使えるやろ

プログラミングは自分の頭と手を使って作らないと身につかんで

ワイもオライリーJavascriptの分厚い本読んで模写したりしたが、自分でアプリ開発するまで依存性の注入とかmvcモデルとかイマイチ本質を理解できんかったな
0617おれさま ◆6CTEZS59O00a
垢版 |
2019/06/16(日) 03:12:42.17
最後に一度だけレスしておくけどさ、
順番保証ってのは当然foreachで回した場合の話でしょ
順序の保証の話は基本書ちゃんと読んでいればforeachとのからみで
幾度となく説明されてるはず
Javaなら拡張For文だっけ?
それぐらい感づいて欲しい
まともに勉強していれば分かったはず

当然Stack Queueの話ではない
後入れ後出しとか先入先出の話は
そもそも配列のように順序保証されたList系のコレクションの特徴
仮に連想配列でそういった使い方をするとしてもそれはキーの自由度を犠牲にした上でのことでしょ

連装配列ってのは基本的には順序保証はされていないと考える
もともとKeyを媒介にしてデータをとりだすことを想定したものだから。
C#で言えばDictionaryが連想配列
これに順序保証の機能が追加されたものとしてSortedDictionaryが用意されている
基本的には、「連装配列は順序は保証されていない」と考えるべき
これは、「基本的」学習事項

Javaでも連想配列の基本となるのがHashMapだが、順序保証されていない
HashMapの順序保証のことを説明するのに、StackとかQueueの話は出てくる余地はない

VBAのDictionaryについて順序保証されていないと想定するのはごく自然な流れで
順序保証されていることが特殊であると考えるべき

たぶんな、金目当てに新しいものにどんどん飛びついているから
基本的な部分が抜けちゃってると思うわ
「プログラミングは自分の頭と手を使って作らないと身につかんで」
0619おれさま ◆6CTEZS59O00a
垢版 |
2019/06/16(日) 06:09:35.21
とりあえず組みおえたVBAプログラムだけど
機能の一つを使えるようにするのに障害があるってことで
急きょ代替案を選択することになった
ちゃっちゃと組み直すか
0620わがはい ◆0BMoNHqNlM
垢版 |
2019/06/16(日) 08:48:52.54
順序が保証されるかどうかなんて勉強始めて1か月目で確認することやんw

それを知らなくて今までどんなプログラム書いてきたん?
0621おれさま ◆6CTEZS59O00a
垢版 |
2019/06/16(日) 09:24:12.01
大体こんなもんか

いくつかの関数でListBoxやら他のコントロールを引数として受けとっているんだけど
これってインテリセンスが働かないからイマイチなんだよなぁ
プロパティ覚えりゃいいんだけどキーボード叩くのが面倒

今組んでるのが安定運用されるようになればしばらくはVBAから離れられそう
これまでいくつかのファイルに分離されていたものを統合したもので
処理上の様々なパラメータもシート上に出して利用者が設定できるようにした
いろんな意味で使う人にとっては便利になるんだけど、コードは複雑化する
バグも出やすいので慎重になってる
シビアな場所で使うようなんで間違いがないといいんだが。
0622わがはい ◆0BMoNHqNlM
垢版 |
2019/06/16(日) 09:51:16.17
ちょっとした便利ツールみたいなもんか
JavaやC#学んでるなら何か作って公開してみたら?
あんま個人開発向きの言語やないけど

ワイもJava勉強したが、結局今はサーバサイドじゃphpとpython、クライアントサイドはJavascriptやな
スマホのネイティブアプリも作ろうかと思ったけどPWAの技術使えばwebアプリをネイティブのように扱えるから辞めにした
0623おれさま ◆6CTEZS59O00a
垢版 |
2019/06/17(月) 12:38:35.08
UserForm上のCommandButton.Font.Bold プロパティだけど
一旦Trueにした後、他の処理でFalseにしようとしても戻らない現象がある
まっさらなファイルで試すと問題ない
何が干渉しているのやら。

内部的には細字に戻っているのに表示上Boldのままになってしまっているのかと思いきや
If .Font.Bold = True then
を入れると反応するので、どうやら内部的にもFalseへの設定を受け付けていないようだ
Fontの他の設定を挟んだりいろいろやってみたが受け付けてくれない

これは後々の課題としておいて、この場は違うフォントに変える事で我慢することにした
0625おれさま ◆6CTEZS59O00a
垢版 |
2019/06/21(金) 17:04:37.70
VBA関連は一段落したんだけど
貯まってるお仕事にも取りかからないといけない
なかなかC#に時間を割けない
0626わがはい ◆0BMoNHqNlM
垢版 |
2019/06/22(土) 12:50:44.51
休みないん?
ワイは土日に開発してるが

趣味がプログラミングみたいなもんやし
それで収入も得られるんだからおいしいもんやな
0630わがはい ◆0BMoNHqNlM
垢版 |
2019/07/02(火) 18:12:01.88
あらら、逃げちゃったw
所詮、お遊びでやってただけか
0634おれさま ◆6CTEZS59O00a
垢版 |
2019/07/09(火) 17:33:15.11
ちょい不安定な動きが報告されたんで修正
ListBoxの背景色変更が原因で
勝手にリストのトップにフォーカスが飛んでしまう
発見に手間取ったわ
こんなんエクセルのバグだよなぁ
0641わがはい ◆0BMoNHqNlM
垢版 |
2019/07/28(日) 14:14:46.67
もう報告せんの?
0646わがはい ◆0BMoNHqNlM
垢版 |
2019/08/04(日) 17:57:00.18
おっしっし
0648わがはい ◆0BMoNHqNlM
垢版 |
2019/08/08(木) 16:19:17.03
ふむ
0651おれさま ◆6CTEZS59O00a
垢版 |
2019/08/17(土) 02:56:26.17
2019/8/14配信のWindowsUpdateを適用すると、Windows 7/8.1/10(全バージョン)で、

・VBVisual Basic 6 (VB6)で作成したアプリケーション
・Visual Basic for Applications (VBA)で作成したマクロ
・Visual Basic Scripting Edition (VBScript)で作成したマクロやアプリケーション

が応答しなくなり、『invalid procedure call error.』と表示される場合があるという
不具合が発生している模様。






ってことなんだけど、引数にparamarray使ってるとダメとか
使ってないから大丈夫と言えるのかどうか
確認しておかないといけない
0653わがはい ◆0BMoNHqNlM
垢版 |
2019/08/23(金) 03:30:28.40
ぽん!
0656わがはい ◆0BMoNHqNlM
垢版 |
2019/09/11(水) 00:19:51.57
おーい、報告まだかね
0657わがはい ◆0BMoNHqNlM
垢版 |
2019/10/03(木) 01:42:16.37
たまに「俺、何千行のコード書いたことあるぜ」って自慢するやつがいるが、自分のこと無能って言ってるのわかっとるんかねぇ
いかに効率的なコードを書くかがエンジニアの腕の見せ所なのに
0658わがはい ◆0BMoNHqNlM
垢版 |
2019/10/18(金) 07:12:03.66
今週の応用情報技術者試験受けるから、模擬試験やってみた
午前問題86点、午後問題74点
両方とも60点以上で合格だから無事クリア
システムアーキテクチャや情報システム開発は年度によっては難しいときもあるが、まぁ大丈夫やろ
0660Mr.名無しさん
垢版 |
2019/11/28(木) 12:18:33.04
よく分からん
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況