プログラミングの最近のブログ記事

まあ、よくあるプログラムですが。

なんかに同意する意味でチェックボックスをチェックすることで、次のページに進むためのボタンが活性化し押せるようになる・・・って画面、よくありますな。あれ。

まあ、全然難しい話ではなくて、

JavaScript

<script type="text/javascript">
  function checkValue(fname, cbox, target){
    var check = document.forms[fname].elements[cbox];
    var btn = document.forms[fname].elements[target];

    if (check.checked) {
      btn.removeAttribute('disabled');
    }
    else {
      btn.setAttribute('disabled', 'disabled');
    }
  }
</script>

Form

<form id="form1">
  <input id="check" type="checkbox" onclick="checkValue('form1', 'check', 'btn')"> あれを更新してもいい?<br>
  <br>
  <input id="btn" type="button" value="あれを更新するよ" disabled="disabled">
</form>

て感じで OK。

最初は disabled 属性に disabled を指定しているので「非活性」の状態で、同意のチェックをしたら、disabled 属性を空にして「活性化」すると。

ただ、現在使っているフレームワークは JavaServer Faces (JSF) で、input タグは h:commandButton タグで設定するんだけど、なんか、disabled 属性が無視されるんですけど?(^^;

<h:commandButton type="submit" id="btn" value="次へ"  省略 disabled="disabled" />

みたいに設定してても、実際吐き出された input タグには disabled 属性が含まれていないという・・・
JSF はほとんど経験ないのでわかんないんだけど、でも、ググってみると h:commandButton タグに disabled 属性は存在するみたい。うーん、謎。なんか環境がカスタマイズされているのかね?今回、その辺の環境がわかる人が近くにいないので、別のやり方で対応。

まあ、やり方は色々あるわけで。

JavaScript

<script type="text/javascript">
  function init(){
    var btn = document.forms['form1'].elements['btn'];
    btn.disabled = true;
  }

  function checkValue(fname, cbox, target){
    var check = document.forms[fname].elements[cbox];
    var btn = document.forms[fname].elements[target];

    if (check.checked) {
      btn.disabled = false;
    }
    else {
      btn.disabled = true;
    }
  }
</script>

Form

<form id="form1">
  <input id="initFlg" type="hidden" value="1">
  <input id="check" type="checkbox" onclick="checkValue('form1', 'check', 'btn')"> あれを更新してもいい?<br>
  <br>
  <input id="btn" type="button" value="あれを更新するよ">
</form>

として、<body onload="init()"> で画面が表示された最初に1回だけ init 処理を実行する。
その処理で、ボタンを非活性にしているのであります。

もともと、desabled="disabled" という記述が input タグになければ setAttribute などのメソッドは使えないので、input タグの disabled というプロパティを操作している。true(非活性)か false(活性)をセットしているのだね。

最初の案より、init 処理が増えているだけ、ちょっと面倒かな。

いやあ、しかし、h:commandButton タグに disabled 属性が無視されるのは何でなんだろう。

識者の方、ご教授いただければ幸いです。
大学生になったんで、さっそく授業で C言語を習っている息子から質問LINEが来た。
(俺は日ごろ全然 C言語は使わないんだけど、まあ、入門問題くらいには答えられる(笑))

問題は、

int i;
i = 077;
printf("i = %f\n", i);

だと、

i = 63.000000

と表示されるものを、

i = 77

と表示されるように修正しろってもの。

息子は 077 が 8進数の記述だということがわからず、それでハマッている様子。

「答えはいらんから、ヒントをくれ」というので、「8進数と10進数の書き方。ちなみに、16進数は 0x77」とヒントを出すと、「そういうことか!!」と息子の答えが返ってきた。

int i;
i = 077;
printf("i = %02o\n", i);

と、printf の変換子だけ修正した形だ。8進数のまま 77と出したいんやな。(2桁の数字を 2桁で出すんで、02 はいらんけどな)

なるほど。俺は、「077 は 8進数なんで、10進数なら 77と書くんよ」という問題だと思ったので、

int i;
i = 77;
printf("i = %d\n", i);

じゃねえの?って回答したんだけど、実際、先生がどっちの意図で問題出してるかわからんので、どっちも正解やな。

息子は結局、「10進の 77を出せっていう問題な気がする」と、俺の回答案を採用するというてるんだけど、実際どっちかわからんし、せっかく自分で回答考えたんだから 8進の 77を表示するほうを提出せえよ・・・と言うてるんだけど。

いやあ、しかし、そのうち C言語のややこしい質問には答えられなくなるなあ。

「先生に、Perlじゃだめですか?って聞いてみい」と言わざるを得なくなるな(笑)

#ちなみに我が家では、長男坊にはいっさいプログラミングを教えてません。大学生になって初めてプログラミングに触れた息子(笑)
特に予備知識なく、Visual Studio 2017(以下 VS)をインストールしようとしたら、オプションに Unity も入ってたので同時インストールにチェック。
VS と一緒に、Unity 2017.2.0f3(64bit) がインストールされた。

で、最初は VS の「新しいプロジェクト」の中に「Unity アプリ」みたいなのがあんのかな?と思ったんだけど、違ってたのね。
VS(言語は C#)が Unity のスクリプト作成外部エディタとして機能するだけ。

20180207_unity.jpg

Unity 自体、ゲームエンジンでありながら統合開発環境(開発画面のことね)も自前で内蔵しているわけだけど、スクリプトのエディタ自体は外出しなのよね。元々、開発言語は C# でも JavaScript でも良いとしていたので、そのためだと思うけど。

Unity で各オブジェクトに特別な動作をさせようとすると(いやあ、物理落下や床への当たり判定など、基本的な動きはスクリプト書かないでもいいんで、本当にコードを書かないといけないのは「シナリオに沿ったゲームの動き」だけなんだけどね)、

1.オブジェクトを作成(「弾丸」とか「宇宙船」とか)
 画像を作成し、Project ウィンドウの Assets フォルダに配置。

2.C# スクリプトを作成
 Project ウィンドウで、「Create」ボタン→「C# Script」選択で VS 起動。

3.Visual Studio 上で C# のコードを書く。
 書き終わったら「Unity にアタッチ」ボタンを押すと、デバッグは行われ、Unity にコードが渡される。

4.C# スクリプトを目的のオブジェクトにアタッチ
 Project ウィンドウ上の C# のアイコンを Hierarchy ウィンドウ内の目的のオブジェクト(
「弾丸」とか「宇宙船」とか)名の上までドラッグ&ドロップ。

って感じの操作を行う。
ソースを修正した時は、3 の「Unity にアタッチ」の操作を繰り返す。

まあ、内蔵エディタに比べるとちょっと面倒だけど、いいところもある。

というのが、さっき Unity 触ってる最中にいきなり落ちちゃって、それまでに追加していたいくつかのオブジェクトが消えてしまった。「C# Script」オブジェクトも消えちゃったんだけど、VS は無事だったので試しにアタッチしてみたら、Assets フォルダにそのスクリプトの「C# Script」オブジェクトが復活した。おっほう。

「対象のオブジェクトがありません」とかエラーになると思ったのに。外部エディタでよかった(笑)
とりあえず Unity で 2D ゲームでも作ってみるか・・・と思って、背景とかキャラの画像を作って Assets にドラッグ&ドロップしようと思ったらできない。

画像をズズズっと Project ウィンドウの Assets フォルダ上までドラッグしていっても、マウスポインタが○に斜め線のマーク(駐車禁止マーク)のまま、ドロップすることが出来ないのだ。

ググってみると、「Assetsにドラッグ&ドロップすると、画像が取り込まれません」という、同じ症状に対する質問が Yahoo 知恵袋に上がってて、そのベストアンサーは「再インストールしてください」であった(^^;
質問者も「再インストールしたらうまくいきました」って喜んでるし(^^;
いいのか、それで?

20180208_uniry_assets.jpg

配布物が 11GB もあるものを再インストールするのか・・・と流石に絶望感に苛まれたけど、取り敢えず一旦 Unity を終了させ、もう一度起動してみる。

あれ?今度はちゃんとドラッグ&ドロップできたでぇ?(笑)

というわけで、うちの場合、「再インストールなんかせんでも、プログラムの再起動をしたら解決」であった(笑)

しっかり「うんこ画像」が Assets フォルダに入って、Unity を使ったゲーム開発が一歩進んだのであった(笑)
起動までのメモ。

Visual Studio 2017 をインストールすると Unity 2017.2.0f3 も一緒にインストールされたので(ま、自分でそう選択したからだけど)、取り敢えず単体で起動してみた。

Unity を起動すると、いきなり Unity ID 入れろとか言われたけど、「Sign in with google」か「Sign in with facebook」も選べるので、ここは Google の方で(笑)

次に License management 画面で、無償利用版の Unity Personal の方を選択。
(Unity Pro は 15,000円払って serial number を取得しないといかんからね)

例えば、マルチプレイだと 20人までしか同時プレイできないなどの制限が Personal 版にはあるが、それで全然十分だし。

License agreement 画面で開発者(つまり俺)が所属する組織の大きさとか確認されるので(試してないけど、企業は Unity Personal は使えんとかあるんかね?)、「The company or organization I represent earned less the $100,000 in gross revenue in the previous fiscal year.」を選択。
まあ、個人的な勉強に使うだけなので、「I don't use Unity in a professional capacity.」でも良いんだろうけど。

そしたら My Profile 画面に移るので、適当に情報入力。
これで、やっと Unity の開発画面に。

で、当然「No local projects」な状態なので、「New project」ボタンを押して新しいプロジェクトを作成しよう・・・ということで、とりあえず 2D ゲームでも作ってみるか。

ん?起動したら、いきなり「最新版の Unity 2017.3 にアップグレードすっか?」って聞かれたぞ(笑)
Visual Studio 的にどうなんかわからないので Skip かな・・・

<つづく>
また、久しぶりに VB.NET 開発チームに異動したので、勉強用に自宅の個人PC に Visual Studio 2013 Express を落とそうと思ったら、

We're sorry, this download is no longer available.

とか言われて。もう、落とせんですと?

ああ、そういや、Visual Studio ってもう 2017 だったね(^^;
しかも、自宅の PC に 2013 は入ってたんだわ(笑)

今回、会社の開発環境が(諸々の理由で)2013 なので、まあ、このままでもいいんだけど、せっかくなので最新版の 2017もインストールしよう。

とりあえず、C++ の開発は未来永劫予定はないので(今のお客さんで、どこも C++ 関係の話が出たことないし。C#.NET は何度かあったけど)、それ以外のコンポーネットを全部インストール。
しかし、まあ、Visual Studio に「Node.js 開発」や「Python 開発」の環境も含まれるのか(^^;
変な時代になったなあ(笑)

ところで、個人で勉強や開発をするのなら Visual Studio Community で良いと思うんだけど、Visual Studio Express もまだ残ってるんだね。

わざわざ Express を選ばないといけない状況って、どういう時なんだろう?
これも xhtml が厳密ゆえのエラーだけど。

XHTMLソース中で、

<script src=https://secure.exsample.com?id=hoge&num=234></script>

みたいな書き方していると、

Error Traced[line: 187] Open quote is expected for attribute "src" associated with an element type "script"

というエラーになる。ダブルクォーテーションなどで URL を囲って無いのが問題のようだ。xhtml 厳しい。

URL をダブルクォーテーションで囲むと、次は URL 中の&が引っかかるので、これは URL エンコードして、最終的に、

<script src="https://secure.exsample.com?id=hoge%26num=234"></script>

のように修正する。

まあ、属性の値をダブルクォーテーションで囲むのはやっとけよ!と思うけど(あの、属性値をダブルクォーテーションで括らない人って、何か理由があるのかね?単なる「見た目が好き」というクソみたいな理由で、セキュリティとのトレードオフを行ったのかね?)

属性値はきちんとダブルクォーテーション(or シングルクォーテーション)で囲みましょう!
例えば、tr タグの高さを if 文で切り分けているところ。

Struts JSP
<logic:equal name="hoge1" property="flg1" value="true">
<tr height="30">
</logic:equal>
<logic:notEqual name="hoge1" property="flg1" value="true">
<tr height="50">
</logic:notEqual>
  <td>
    <table>
     <tr>
       <td>hogehoge1</td>
    </tr>
  <logic:notEqual name="hoge1" property="flg1" value="true">
    <tr>
      <td>hogehoge2</td>
    </tr>
  </logic:notEqual>
    </table>
  </td>
</tr>

Struts であればこんな感じで書かれている処理。
flg1 が真(True)ではなかった時は入れ子になった table の高さが(hogehoge2 を出力する分だけ)高くなるので、その外側の tr タグの height 属性を 50にしているんだね(True の場合は 30)

これを単純に、

JSF XHTML
<c:if test="#{form.flg1}">
<tr height="30">
</c:if>
<c:if test="#{!form.flg1}">
<tr height="50">
</c:if>
  <td>
    <table>
     <tr>
       <td>hogehoge1</td>
    </tr>
  <c:if test="#{!form.flg1}">
    <tr>
      <td>hogehoge2</td>
    </tr>
  </c:if>
    </table>
  </td>
</tr>

このように書くと、xhtml 的には、(<c:if>タグで分岐していることは無視され)<tr>タグが2つ(height="30" のものと、"50" のもの)あるのに、閉じタグ(</tr>)の数がひとつ足りないので、

Errir Traced[line: 323] The element type "tr" must be terminated by the matching end-tag "</tr>".
 
というエラーになる。厳密やねえ、xhtml。

なので、この場合は、以下のように </tr> までの部分をひとつにまとめて if 文による分岐を行なってやる必要がある。
ちょっと二重コーディングになって無駄な気もするけど・・・

JSF XHTML
<c:if test="#{form.flg1}">
<tr height="30">
  <td>
    <table>
      <tr>
        <td>hogehoge1</td>
      </tr>
    </table>
  </td>
</tr>
</c:if>
<c:if test="#{!form.flg1}">
<tr height="50">
  <td>
    <table>
      <tr>
        <td>hogehoge1</td>
      </tr>
      <tr>
        <td>hogehoge2</td>
      </tr>
    </table>
  </td>
</tr>
</c:if>

ちなみに、「今時 tr タグの height 属性なんか使ってるの?CSS に直さなきゃ駄目!」みたいな青臭い原理主義的意見は無しで(笑)そういうこと言う人、ほんま現場じゃ使いにくいポンコツなんだろうなあと思われ(笑)
今回は色々な条件をもとに高度な判断で height 属性の修正は行なっておりません(笑)

あ、高さの値を変数化して height="#{form.trHeight}" みたいにすれば・・・ってのは、Java プログラムも修正する必要が出て来るので、今回の対応としては NG で。

・・・と思ったんだけど、<c:set> タグってのがあるんだから、

 JSF XHTML
<c:if test="#{form.flg1}">
<c:set var="heightsize" value="30">
</c:if>
<c:if test="#{!form.flg1}">
<c:set var="heightsize" value="50">
</c:if>
<tr height="#{heightsize}">
 <td>
    <table>
     <tr>
       <td>hogehoge1</td>
    </tr>
  <c:if test="#{!form.flg1}">
    <tr>
      <td>hogehoge2</td>
    </tr>
  </c:if>
    </table>
  </td>
</tr>

って書けばいいだけか。これが一番すっきりだなあ。
Web アプリケーションの開発では、Base64 エンコード/デコードを息をするように使うので(ホント?)、Java 8から導入されたという Java 標準の Base64 クラスを使ってみた。

さっき、「試しに JSF の新規プロジェクトを作成してみた」というエントリーで作ったプロジェクトを改造。

1.helloBean.java

・Base64 クラスのインポートを追加。

import java.util.Base64;

・変換後の文字列を格納する変数 b64 と getter を設定。

    private String b64;

    public String getB64() {
return b64;
    }

・send クラスに Base64 エンコード処理を追加

        this.b64 = "Base64 Encode=> " + Base64.getEncoder().encodeToString(this.name.getBytes());

2.output.xhtml

・Base64 エンコード結果の表示を追加

        <h:outputText value="#{helloBean.b64}" />

と、まあ、こんな感じで。

実際に実行してみる。

20170706_netbean6.jpg

20170706_netbean7.jpg

おお、なんかエンコードされている。

「猪俣 性交渉」が「kpaWk4FAkKuM8I/C」に変換されたんやな。

試しに、Perl で Base64 デコードプログラム作って、「kpaWk4FAkKuM8I/C」をデコードしてみる。

プログラムソースはこんな感じ。

#!/usr/bin/perl
use MIME::Base64;
print "Word=> ";
$w = <STDIN>;
chomp $w;
$w = decode_base64($w);
print "Decode Word=> $w\n";

じゃ、実際に実行。

$ ./b64decode.pl
Word=> kpaWk4FAkKuM8I/C
Decode Word=> 猪俣 性交渉

おお!!ちゃんと「猪俣 性交渉」に戻ったやん!!
あ、「猪俣 公章」って打ったつもりが「猪俣 性交渉」になってた!!
取りあえず新規プロジェクトを作ってみる。


このサイトの手順に則って進める。
ただ、JSF の最新バージョンだと。このサイトのソースのままだと多分上手く動かない。
たまたまこのサイトに辿り着いた人は、下記の俺のソースを参考にしてくれたほうが良いかも。

まずは、新規プロジェクトの「入れ物」の作成。
上記ページに載っているとおり。

20170706_netbean1.jpg

最後にフレームワークを選択してプロジェクト作成終了。
借り物 PC なので、色々 Java フレームワークが入ってるけど、JavaServer Faces を選択する。

実際の開発もこのページに沿って進める。

1.バッキングビーンの作成(helloBean.java)

import java.io.Serializable;
import javax.annotation.ManagedBean;
import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;

@ManagedBean
@RequestScoped
@Named(value = "helloBean")
public class helloBean implements Serializable{

    private String name = "";
    private int age;

    public String getName() {
return name;
    }
    public void setName(String name) {
this.name = name;
    }

    public int getAge() {
return age;
    }
    public void setAge(int age) {
this.age = age;
    }

    private String msg;

    public String getMsg() {
return msg;
    }

    public helloBean() {
    }

    @PostConstruct
    public void init(){
    }

    public String send(){
        this.msg = "Hello " + this.name;
        return "output.xhtml";
    }
    
}

2.入力画面の作成(input.xhtml)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html">
    <h:head>
        <title>JSFに触れてみよう</title>
        <meta charset="utf-8"/>
    </h:head>
    <h:body>
        <h:form>
            名前:<h:inputText value="#{helloBean.name}" />
            年齢:<h:inputText value="#{helloBean.age}" />
            <h:commandButton value="送信" action="#{helloBean.send()}" />
        </h:form>
    </h:body>
</html>

3.出力画面の作成(output.xhtml)

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
    <h:head>
        <title>JSFに触れてみよう</title>
        <meta charset="utf-8"/>
    </h:head>
    <h:body>
        <h:outputText value="#{helloBean.msg}" />
    </h:body>
</html>

4.GlassFish の起動

5.テスト画面へのアクセス(http://localhost:8080/hello/faces/input.xhtml)

実際に Form に入力して動かしてみる。

20170706_netbean4.jpg

20170706_netbean5.jpg

ちゃんと動いた。
その他に今日はアノテーションについて勉強しました。

このアーカイブについて

このページには、過去に書かれたブログ記事のうちプログラミングカテゴリに属しているものが含まれています。

前のカテゴリはパソコンです。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

月別 アーカイブ

電気ウナギ的○○ mobile ver.

携帯版「電気ウナギ的○○」はこちら