20191224のJavaに関する記事は6件です。

RecyclerView上のボタンを押した時の処理をリストごとに変化させる

はじめに

Androidアプリ開発でリスト表示を作るためにRecyclerViewを利用しますよね。
RecyclerView上にボタンを設置して、リストから他の画面に遷移する時、何番目のリストのボタンが押されたかを知りたい時ありますよね。
RecyclerView.Adapter上で「何番目のボタンが押されたか」は割とすぐ取得できるのですが、それをMainActivityで使う時に少しハマったのでメモ。

RecyclerViewについて

概要についてはこちらの記事が分かりやすかったのでこちらを参照ください。
RecyclerViewの基本

やりたいこと

  • RecyclerView上にボタンを配置し、ボタンを押した時に画面遷移させたい。
  • ボタンを押したリストの行数によって遷移先での挙動を変化させたい。

画面遷移する時のボタンを押した時の処理のイメージはこんな感じ。
遷移先の画面に対して、何番目のリストのボタンが押されたかを教えてあげたい

ちなみにRecyclerView.AdapterはActivtyクラスを継承していないので画面遷移ができません。
そのため、MainActivity上で何番目のリストが押されたかを知り、画面遷移することが必要になります。

MainActivity
@Override                                                                             
public void onClick(View view) {                                                      
    int line = getLine(); //どうにかして押したリストの行数を取得したい                             
    Intent hoge = new Intent(MainActivity.this, HogeActivity.class);
    hoge.putExtra("line", line);                   
    startActivity(hoge);                                                              
}    

まずその前に

RecyclerViewに含まれるボタンを押した時に、MainActivity上での処理を行いたいので
RecyclerView.AdapterのリスナーにMainActivityのOnClickListenerを登録しておきます。
これでリスト上でボタンを押した時に、MainActivty上のOnClick()が呼び出されるようリスナーの設定ができます。

RecyclerAdapter.java
public void setOnItemClickListener(View.OnClickListener listener){
        m_listener = listener;
}

public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    // - get element from your dataset at this position
    // - replace the contents of the view with that element
    final int pos = position;
    // リスト上のボタンが押された時に上で登録したクリックリスナーを呼び出してあげる
    holder.m_btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            m_listener.onClick(view);
        }
    });
}
MainActivity.java
RecyclerView.Adapter rAdapter = new RecycleAdapter(data);
rAdapter.setOnItemClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        int line = getLine(); //どうにかして押したリストの行数を取得したい                             
        Intent hoge = new Intent(MainActivity.this, HogeActivity.class);
        hoge.putExtra("line", line);                   
        startActivity(hoge);  
    }
});    

本題

今の状態のままだと、どのリストのボタンを押しても同じ処理が行われてしまいます。

RecyclerView.AdapterにonBindViewHolderというメソッドがあります。
これはリストの項目が作られるたびに呼び出されるメソッドです。
そして引数であるpositionがまさに何番目のリストが作成されたか、という値を表しています。

このpositionの値を、リスト上のボタンのクリックリスナー内でRecyclerViewのメンバ変数に登録するよう実装します。
こうすることでボタンが押された時にその行数の値がRecycleViewAdapterのメンバ変数(m_line)に登録されます。

そしてそのm_lineを外部から参照できるようなメソッドを作成し、それをMainActivityのOnClick()内で呼び出すよう実装します。
あとは遷移先のHogeActivityで値を取得して、それによって処理を変えてあげればOKですね。

RecyclerAdapter.java
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    // - get element from your dataset at this position
    // - replace the contents of the view with that element
    final int pos = position;
    holder.m_btn.setOnClickListener(new View.OnClickListener() { 
        @Override
        public void onClick(View view) {
            m_line = pos; //行数を登録
            m_listener.onClick(view); //登録した直後にMainのOnClickを呼び出す
        }
    });
}

public int getLine(){
    return m_line; //行数を取得
}
MainActivity.java
final RecyclerView.Adapter rAdapter = new RecycleAdapter(list);
recyclerView.setAdapter(rAdapter);
((RecycleAdapter) rAdapter).setOnItemClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        int line = ((RecycleAdapter) rAdapter).getLine(); //ここでm_lineの値を取得
        Intent edit = new Intent(MainActivity.this, HogeActivity.class);
        edit.putExtra("line", line);
        startActivity(edit);
    }
});

最後に

なんだかものすごく回りくどい実装になってしまいましたが
押した行数をMainActivityに伝える方法が自力ではこれしか見つからなかったのでこんな実装になってしまいました。
「いやいや、そんなことしなくてもhogehogeすれば一発やん...」というのがあればぜひご教授ください。

最後の最後に

自分が作ったアプリからコード抜粋して少し修正しているので、文章とソースコードの変数名が一致していなかったりする場合もあります。
そこは脳内変換お願いします。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

gcviewerの使い方メモ

久しぶりにgcviewerを使ったのでメモを残しておく。

環境

  • OS: Windows 8.1
  • Java: java version "1.8.0_231"
  • Gcviewer: gcviewer-1.36-SNAPSHOT.jar

起動

  1. gcviewerのjarをダブルクリックする
    021.PNG
    →以下の画面が表示される 002.png
  2. ウィンドウ内にGCログのテキストファイルをDrag&Dropする
    →以下のような画面になる 020.png

表示の変更

  1. メニュー > View > Data Panel をチェックオフ
    →右側のデータパネルが消えて広くなる 004.png
  2. 時間列の周辺を右クリック > Log start time をチェックオン
    →時間列が時刻表示になる(GCログにタイムスタンプが入っている場合) 005.png
  3. Total Heapをチェックオン
    →トータルヒープサイズが赤で表示される 006.png
  4. Total Heapをオフにし、Tenured Generation, Young Generationをチェックオン
    →Young世代のサイズが黄色で、Tenured世代(Old世代)のサイズが紫で表示される。 通常、Young Generation + Tenured Generation = Total Heap 007.png
  5. Used Tenured Heap, Used young Heapをチェックオン
    →各世代の中のヒープ使用量が線で見えるようになる。縦線はGCによってメモリが解放されたことを表す。 008.png
  6. GCログの開始/終了がウィンドウ全体に納まるように上部のセレクトボックスで比率を調整する。
    009.png
  7. Used Heapをチェックオン
    →これまではYoung世代とTenured世代を別々に表示していたが、これでYoung世代とTenured世代の合計(=ヒープ使用量)が青で見れるようになる 010.png
  8. Full GC Linesをチェックオン
    →Full GCが黒線で見えるようになる 011.png

チェック観点

  1. Young世代のヒープ使用量が、Young GC後に下まで下がっているか。
  2. Tenured世代のヒープ使用量が、Full GC後に下まで下がっているか。

私自身、実はGCログの評価方法はよくわかっていない。
このグラフではTenured世代がたまってきているが、次のFull GCで下まで解放されれば良い、のかな?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GCViewerの使い方メモ

久しぶりにJVMのGCログを確認するためにGCViewerを使ったのでメモを残しておく。

環境

  • OS: Windows 8.1
  • Java: java version "1.8.0_231"
  • Gcviewer: gcviewer-1.36-SNAPSHOT.jar

ダウンロード

以下のページでなるべく最新バージョンの「download | download mac version」のリンクをクリックし、ダウンロードする。
https://github.com/chewiebug/GCViewer/wiki/Changelog

Windowsの場合はjarファイルがダウンロードされるので、任意のフォルダに配置する。

起動

  1. gcviewerのjarをダブルクリックする
    021.PNG
    →以下の画面が表示される 002.png
  2. ウィンドウ内にGCログのテキストファイルをdrag and dropする
    →以下のような画面になる 020.png

表示の変更

  1. メニュー > View > Data Panel をチェックオフ
    →右側のデータパネルが消えて広くなる 004.png
  2. 時間列の周辺を右クリック > Log start time をチェックオン
    →時間列が時刻表示になる(GCログにタイムスタンプが入っている場合) 005.png
  3. Total Heapをチェックオン
    →トータルヒープサイズが赤で表示される
    ここでは-Xms(開始サイズ)と-Xmx(最大サイズ)を同値に設定しているため、トータルヒープサイズは横一直線になっている。 006.png
  4. Total Heapをオフにし、Tenured Generation, Young Generationをチェックオン
    →Young世代のサイズが黄色で、Tenured世代(Old世代)のサイズが紫で表示される。 通常、Young Generation + Tenured Generation = Total Heap 007.png
  5. Used Tenured Heap, Used young Heapをチェックオン
    →各世代の中のヒープ使用量が線で見えるようになる。縦線はGCによってメモリが解放されたことを表す。 008.png
  6. GCログの開始/終了がウィンドウ全体に納まるように上部のセレクトボックスで比率を調整する(★重要)。
    これをしないと、一部の範囲しか確認せずに問題ないと思っていしまう可能性がある。今回はこのタイミングで比率を調整したが、なるべく早めにやって全体を見れる状態にしてから調査を始めたほうがよい。
    グラフからわかること
  7. Young GCが結構頻繁に発生している。Yong GCによってYoung世代はほぼ解放される(灰色の線が黄色領域の下まで落ちている)
  8. Tenured世代のFull GCが2回発生している。どちらもほぼ下まで落ちているので、解放はできている。その後Tenured領域のメモリが増えていっているのが気になる。おそらくこの後再度Full GCが発生するが、その時に下まで解放されれば問題はないのではないか(自信なし) 009.png
  9. Used Heapをチェックオン
    →これまではYoung世代とTenured世代を別々に表示していたが、これでYoung世代とTenured世代の合計(=ヒープ使用量)が青で見れるようになる 010.png
  10. Full GC Linesをチェックオン
    →Full GCが黒線で見えるようになる 011.png

チェック観点

  1. Young世代のヒープ使用量が、Young GC後に下まで下がっているか。
  2. Tenured世代のヒープ使用量が、Full GC後に下まで下がっているか。

私自身、実はGCログの評価方法はよくわかっていない。
このグラフではTenured世代が増えてきているが、次のFull GCで下まで解放されれば良い、のかな?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaはExcel文書を作成します

Spire.XLS for Java機能が豊富なエクセルのセットです,JavaアプリケーションでExcelファイルの作成、編集、変換、印刷をサポートします。本論文では、Spire.XLS for Javaを使ってExcelファイルを作成し、データを追加する方法を紹介します。

使用ツール:Free Spire.XLS for Java (無料版)

https://www.e-iceblue.com/Introduce/free-xls-for-java.html

Jarファイルの取得と導入:

Method 1:ホームページを通じてjarファイルのカバンをダウンロードします。ダウンロード後、ファイルを解凍して、libフォルダの下のSpire.xls.jarファイルをJavaプログラムに導入します。

https://www.e-iceblue.com/Download/xls-for-java-free.html

Method 2:maven倉庫設置による導入。

https://www.e-iceblue.com/Tutorials/Licensing/How-to-install-Spire.PDF-for-Java-from-Maven-Repository.html

import com.spire.xls.*;
import java.awt.*;

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

        //新しいWorkbookの実例
        Workbook workbook = new Workbook();

        //最初のシートを取得します。(新しいWorkbookはデフォルトではシートが3つあります)
        Worksheet sheet = workbook.getWorksheets().get(0);

        //最初のシートの名前を設定します
        sheet.setName("Data Sheet");

        // 列の最初のセルスタイルを作成します
        CellStyle style1 = workbook.getStyles().addStyle("Header Style");
        style1.getFont().setSize(12f);
        style1.getFont().setColor(Color.BLACK);
        style1.getFont().isBold(true);
        style1.setHorizontalAlignment(HorizontalAlignType.Center);
        style1.setVerticalAlignment(VerticalAlignType.Center);

        //データセルのスタイルを設定
        CellStyle style2 = workbook.getStyles().addStyle("Data Style");
        style2.getFont().setSize(10f);
        style2.getFont().setColor(Color.BLACK);

        //列の先頭セルにデータを追加し、スタイルを適用します
        for (int column=1; column<5; column++)
        {
            CellRange header =sheet.getCellRange(1,column);
            header.setValue("Column " + column );
            header.setStyle(style1);
            header.setColumnWidth(15f);
        }

        //データセルにデータを追加し、スタイルを適用します
        for (int row=2; row<11; row++)
        {
            for (int column=1; column<5; column++)
            {
                CellRange cell = sheet.getCellRange(row, column);
                cell.setValue("Data " + row + ", " + column);
                cell.setStyle(style2);
            }
        }

        //結果ファイルを保存
        workbook.saveToFile("CreateExcel.xlsx", FileFormat.Version2013);
    }
}

効果図:
Sample.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VSCodeでJava開発環境を整える

はじめに

VSCodeでJavaの開発を行う際、何も設定を行わないと使い物になりません。ネットとかで調べてもJavaが使えるようになるところまでしか紹介していない記事が多いので、ガチでJavaの開発をしたい人のために、設定すべき内容を紹介したいと思います。

前提

プラグインのインストール

VSCodeでJavaを開発するためのインストーラーがありますが、これだけだと足りません。
他に便利なものがあるので紹介します。

  • Java IDE
    ClassやInterfaceなど、Javaに関連したファイルがクラス定義やパッケージが定義された状態で作成されます。

  • Lombok Annotations Support for VS Code
    自動生成でお馴染みのLombokをVSCodeでサポートするためのプラグインです。Lombok関連のアノテーションをVSCodeが認識できるようになります。

フォーマッター定義ファイルの作成

VSCodeでJavaのフォーマッターを指定する箇所があるのですが、URLまたはローカルファイルパスが指定できます。今回はカスタマイズしたいので、まずは独自のフォーマッターを作成します。定義ファイルをテキストファイルなどで作成もできるのですが、GUI上のほうがプレビューなどもあるので、今回はEclipseを使います。

(1) Eclipseを起動し、[Preferences]を開きます。
(2) [Java]-[Code Style]-[Formatter]を選択します。
(3) [New]ボタンをクリックします。
(4) [Profile name]に任意の名前(ここでは「MyFormatter」)を入力し、「OK」ボタンをクリックします。
(5) 以下のフォーマット設定を行います。  

カテゴリ 項目
Indentation Tab policy spaces only
Line Wrapping Never join already wrapped lines チェック

(6) 設定が完了したら、「OK」ボタンをクリックします。
(7) [Active Profile]から上記で作成したもの(MyFormatter)を選択し、[Export All]ボタンをクリックし、ローカルに保存します。保存するファイル名は「formatter.xml」としておきます。

設定値の概要

  • Tab policy: spaces only
    タブ使用時に、スペースに変換します。
  • Never join already wrapped lines: チェック
    改行済みのコードはフォーマットされません。これがないと、1行の最大サイズの範囲内で、改行されたコードが結合されて(改行が削除されて)しまいます。

VSCodeの設定

[Settings]を開き、以下の設定を行います。

項目 設定値
Editor: Detect Indentation チェックなし
Editor: Format On Save チェック
Java › Format › Settings: Url /path/to/formatter.xml
Java › Format › Settings: Profile MyFormatter
Java › Save Actions: Organize Imports チェック

設定値の概要

  • Editor: Detect Indentation
    インデントの扱い(タブをスペースにするとか、いくつインデントするとかなど)をファイルごとに設定可能にするかの設定です。チェックがない場合はフォーマット定義に従います。
  • Editor: Format On Save
    保存時にフォーマットが自動で実行されます。
  • Java › Format › Settings: Url
    フォーマット定義ファイルを指定します。ここで定義されたフォーマットが実行されます。
  • Java › Format › Settings: Profile
    フォーマット定義ファイルに設定したプロファイル名です。どのプロファイルを適用するか設定します。
  • Java › Save Actions: Organize Imports
    保存時にインポートの最適化が実行されます。未使用のインポート削除、インポートのソートが実行されます。

おわりに

これで最低限、Javaを開発できる環境が整いました。
他にこれやったほうがいいという意見がありましたら、教えていただけると幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

今さらjavaのアノテーションについて理解した

はじめに

業務でjavaのコードを書いているときに、@~~~という文字を何度も目にしてはいましたが、
「なんじゃこれ?まあいいや」って思って無視してました。
でもある時、「javadocとはなんぞや?」と思って調べて理解したら、一緒にアノテーション
も理解できたので、自分メモ用として投稿します。

参考にしたサイト

以下のサイトが私を救ってくれました。ありがとうございます。
https://www.atmarkit.co.jp/ait/articles/1105/19/news127.html

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む