"Simple" is "Best"

開発時に詰まったところや 調べた結果日本語での情報が無かったり古かったりした場合に自分用のメモとして高校生(?)が更新していくブログ

JAVAでコマンド版カウントダウンをしてみる

たまに、Youtubeなどで

コマンドプロンプト上で動くゲームを作る実況動画なるものがあるが

全てC系統で組んでいる

何故JAVAがないのかを考えてみると

System("cls")

がないことに気づく

素直にC系統を勉強して作ればいいだけかもしれないが

たまたまこのような記事を見つけたので

応用(と言うなの丸パクリ)してコマンドライン上で動く

カウントダウンアプリ(?)を作ってみる

 

使うもの

特筆して使うものは以下の2つ

  1. Thread.sleep()
  2. Process(ProcessBuilder)

 

大まかな仕組み

仕組みというほど大げさなものではないが

Whileループの中でSystem.out.printを使って一秒単位で画面上に秒数を表示する

画面の更新にはSE7から追加されたProcessを使う

1,2共にエラーをTry-catchしないといけないので

前回同様実装時には適切なエラー処理を

 

ソースコード

public class Main {
	public static void main ( String[] args ) {
		int c = 0;
		ProcessBuilder pb = new ProcessBuilder( "cmd", "/c", "cls" );
		while ( c < 10 ) {
			try {
				pb.inheritIO().start().waitFor();
				System.out.print( c );			//printlnではなくprint
				Thread.sleep( 1000 );
			} //以下エラー処理(省略)
			catch( InterruptedException iue ){} 
			catch( IOException ioe ){}
			c++;
		}
	}
}

これぞ5分クオリティ

 

解説(と言うかメモ)

見て一発でわかるプログラムなもんだから書くことなどなにもないのだが

ProcessBuilder pb = new ProcessBuilder( "cmd", "/c", "cls" );
pb.inheritIO().start().waitFor();

参考にしたサイトの方がよくわからないと仰っていたこの部分だけ調べたのでメモ

参考サイトの方では変数を使わず直接繋げてやっていられた

個人的にはこっちのほうが理解しやすかったのと

Whileの中でインスタンスを毎回生成すると言う無駄なことを防ぐためにこうした

 

一行目は普通のインスタンス作成

どうやら第一引数に起動したいプログラム名(?)

それ以降にそれぞれ分けてそのコマンドの引数

上記だと

コマンドプロンプト上でclsを実行する

というProcessBuilderインスタンスを作ることになる

次の行は1つずつ分解して考えてみる

 

inheritIO()

返り値はProcessであることに注意

リファレンスを見てみると

サブプロセスの標準入出力の入力元と出力先を、
現在の Java プロセスと同じものに設定します。

 とある

簡単に言えば

”結果をいま実行しているコマンドライン上に表示する”といった感じ(あくまでも感じ)

今回はclsなので動かしているコマンドライン上の画面がクリアされる

start()

これも返り値はProcess

名前の通り登録したプロセスを実行するメソッド

コヤツはいくつかエラーを吐くので

詳しくはこちらを確認

waitFor()

ラスト

返り値はint型、所謂終了コードを返してくれる

これは要求したプロセス(ここではcls)が終了するまで

JAVAの処理を中断するというもの

 

以上

これで二行目の文の説明(?)終了

 

もう少し実用的にするのであれば

最初に数値入力を促すウェザードを実装するか

引数で秒数を取得するなどして

時間の上限を動的にするといいかも

 

今後

最初に書いたように

コマンドライン上で動くゲームをJAVA作りたい

そんなこと考えながら

まず第一歩として画面の更新の方法をまとめてみた

そのうちに連載企画としてやってみたい

 

 

 

Win7でレジストリをいじってキー配列を変える

今の時期にWin7の話をするというのも時代遅れなきがするが

メモとして書いておく

 

最初に

当然の事ながら、レジストリをいじるので自己責任のもとで

バックアップは必須

これからすることによってパソコンがどうにかなったとしても

私は責任を取れない

 

今回は「Caps Lock」を「Alt」としてみる

参考サイトはこちら

How to Disable Caps Lock Key in Windows 7, 8, 10, or Vista

Windows/TIPS/レジストリを修正してCAPSLOCKの割り当て変更 - yanor.net/wiki

Windows Vista/XP/2000/NT4.0のキー配列の変更方法

主に二つ目を参考に話をすすめる

 

本題

レジストリ エディタを使って

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout

 にScancode Mapという名でバイナリ値を作成

 そこに以下の内容を入力

00 00 00 00 00 00 00 00
02 00 00 00 38 00 3A 00
00 00 00 00

f:id:bigbuddha:20170104072000p:plain

勉強タイム

 勉強がてら、一つ一つを読み解いていく

まず、一行目の008つはヘッダのようなのでそのまま入力

続いて、二行目

これは2つに分けて02 00 00 0038 00 3A 00に分けられる

一つ目の02 00 00 00は変更するキーが2つですよということ

 

ここで一つ疑問

1(Caps Lock) + 1(Alt) = 2

確かにその通りであるが

ここで一つ疑問

なぜ02が一番最初に来ているのか

普通に考えて最後に来るのが普通ちゃうんかい┌(`Д´)ノ)゚∀゚)

って思っていたが、ふと「リトル・エンディアン」を思い出して

あぁ、なるほどね~

なんて思った

「リトル・エンディアン」がわからない方は

Wikipediaに聞くなり、ググっていただくと幸せになれるかもしれない

 

無事疑問は解決し・・・

では次

 38 003A 00

最初の値が変更後(出力)の役割、次に変更前(入力)の役割

リトル・エンディアンだから、383A

38がAltのキーコードで3AがCaps Lockのキーコードである

有名どころを抑えておく

名称入力値
Alt(Right) 38E0
Alt(Left) 3800
Caps Lock 3A00
Ctrl(Right) 1DE0
Ctrl(Left) 1D00
Esc 0100
NumLock 4500
ScrollLock 4600
Win(Right) 5CE0
Win(Left) 5BE0

他のキーのコードは参考サイト二つ目に書かれている

ここではあえて実際に入力する際の値を表しているので

キーコードと言うと語弊がある

そこは適時読み直していただけたらと(;・∀・)

 

そして最後にNULL埋め

これで完了

複数キーを変更するときの値が

いまいち理解しきれていない(末尾のNULLの数とか)ので

今は書かないでおく

今後わかれば書き足すなり、新たに記事を作るなりしよう

JavaでAPIが叩きたい

 

なんとなくJavaAPIが叩きたくなったのでその時のメモ

今回は素のJAVA(SE8)で組んでみたいと思う

 

使用するAPIはこちら↓

GitHub API v3 | GitHub Developer Guide

これで自分のGist一覧を取得するためのAPIを叩いてみる

叩くだけであってそれで得られたJSONの処理はしない

何故ならできないからだ(`・∀・´)エッヘン!!

 

まずはコード

import java.io.*;
import java.net.URL;

public class GithubApi {
private static final String API_URL = "https://api.github.com/users/[UserID]/gists"; //叩くAPI private static URL url = null; private static BufferedReader br = null; private static InputStreamReader isr = null; public static void main ( String[] args ) { try { System.out.println( conectGetJson() ); } catch ( Exception e ) { e.printStackTrace(); } }
/* 実際にAPIを叩いて得たJSONを文字列として返す
適当に組んでいるのでエラーは投げてます
当然のことながら実際に実装する際は各自で適切な処理を*/ public static String conectGetJson() throws Exception { url = new URL( API_URL ); String readLine = ""; String writeContent = "";
/* ここから読み込むための定型文 */ isr = new InputStreamReader( url.openStream() ); br = new BufferedReader( isr ); while ( ( readLine = br.readLine() ) != null ) writeContent = writeContent + readLine;//ここで読み込んだ内容を変数に保存している return writeContent; } }

こんな感じですね

相も変わらず読みにくいコード(汗)

コメントの通り、実装の際は適切なエラー処理をお願いしますm(__)m

 

組んでから気付いたのですが

普通にJavaでHTMLやら読み込むときとまったく同じですね

結局やってることは同じということでしょうか

あえて今回は「APIを叩く」ということに焦点を置きました

 

本当はJSONのパースまでできたらいいんですけどね

面倒くさそうなので現段階では手を付けていません

Androidだと標準APIでできるんですけどねぇ

楽そうなパースの方法がありましたらコメントしてもらえば嬉しいです

 

CardViewをListViewを使って表示させる

前々からCardViewをいじってみたくて調べていると

入れ子にしたりFor文回したりと意味がわからんことをやっていたので

ListViewで実装してみる

RecyclerViewに実装する方法は日本語であったが

ListViewに実装する方法はすぐに見つからなかったので

書き記しておく

 

目標

こんな感じになればOK

今回は素材を用意するのが面倒くさかったので

ImageViewを単色で塗りつぶした

f:id:bigbuddha:20161023213928p:plain

 

下準備

CardViewはサポートライブラリなので

build.gradeに例のあれを書き足してあげないといけない

compile "com.android.support:cardview-v7:+"

 

必要なクラスやレイアウト

必要なクラスやレイアウトを最初に書き出しておく

  1. MainActivity
  2. CardViewのレイアウト
  3. CardViewに表示させる情報
  4. CustomAdapter

このぐらいかな

3には色の情報(色名と色コード)を保存する

1.MainActivity

とりあえず中身は最後にちょちょっと実装するとして

Layoutを組む

 

<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android">

<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

</LinearLayout>

私はActivityのLayoutを一から書く派なので、

手元のコードと少し違うかもしれないが、問題はない

 

2.CardViewのLayout

"layout"フォルダを右クリックし、

[New]→[Layout resource file]を選択

名前は"card.xml"にしておいた

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">

<android.support.v7.widget.CardView
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="140dp"
card_view:cardCornerRadius="4dp"
android:layout_margin="16px">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f0f0f0">

<ImageView
android:id="@+id/image"
android:layout_width="120dp"
android:layout_height="120dp"
android:layout_margin="8dp"/>

<TextView
android:id="@+id/text"
android:text="CardView"
android:textSize="30dp"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1" />
</LinearLayout>

</android.support.v7.widget.CardView>

</LinearLayout>

CardViewの中にLinearLayoutを突っ込んで

「ImageView・TextView」の順に書いただけ

高さや横幅はお好みで

 

3.CardViewに載せる情報

CardViewに載せたい情報は

  1. 色の名前
  2. 色コード

の2つだけ

private String colorName = "";
private String colorCode  = "";

両方フィールドとしてprivateで宣言して

インスタンス化のときに代入してやる

あとで取り出すのでgetterを忘れずに

public class Card {

private String colorCode = "";
private String colorName = "";

public Card(String colorName, String colorCode) {
this.colorCode = colorCode;
this.colorName = colorName;
}

//↓getter
public String getColorName() {
return this.colorName;
}

public String getColorCode() {
return this.colorCode;
}

}

publicでもいいのかもしれないが

まぁ、無難にprivate

アクセス修飾子の勉強もせんとなぁ

 

4.CustomAdapter

これが一番面倒くさい

が、一番楽しい

public class ColorInfoAdapter extends ArrayAdapter<Card> {

private List<Card> cardList = null;

public ColorInfoAdapter(Context context, int resourceId, List<Card> cardList) {
super(context, resourceId, cardList);

this.cardList = cardList;
}

@Override
public int getCount() {
return cardList.size();
}

@Override
public Card getItem(int position) {
return cardList.get(position);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder viewHolder;

if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.card, null);
viewHolder = new ViewHolder(convertView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder)convertView.getTag();
}

final Card CARDINFO = getItem(position);
if (CARDINFO != null) {
viewHolder.getColorName().setText(CARDINFO.getColorName());
viewHolder.getColorImage().setBackgroundColor(Color.parseColor(CARDINFO.getColorCode()));
convertView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getContext(), CARDINFO.getColorName(), Toast.LENGTH_SHORT).show();
}
});
}

return convertView;
}

private class ViewHolder {
private ImageView colorImage = null;
private TextView colorName = null;

public ViewHolder(View view) {
colorImage = (ImageView)view.findViewById(R.id.image);
colorName = (TextView) view.findViewById(R.id.text);
}

public ImageView getColorImage() {
return this.colorImage;
}

public TextView getColorName() {
return this.colorName;
}

}
}

ArrayAdapterを継承してやる

もちろんジェネリクスは先程作ったCard

 

フィールドで

private List cardList = null;

としてやる 

インスタンスはそのまんま

 

次にgetCount・,getItenを記述

何回もView#findViewByIdをすると処理が重いので

維持するためのViewHolderを作成

 フィールドでTextViewとImageViewを宣言してやる

あとはインスタンスで代入

書けたらgetViewをOverride

さっき作ったクラスをfinalで宣言

 

後はいつも通りのnullチェックですな

最後にTagをセットしてやる

そうすることで、あとでもっかい何かするときに

getTagだけで取り戻せる

 

さぁ、ラスト

さっきのクラスを使っていつも通り

setTextなりsetBackgroundColorなりをする

Cardに保存されているColorCodeはString型なんで

Color#parseColorで求めているint型に直してやる

 

おまけ

convertViewはCardViewなので

CardViewに対してOnClickなどが書きたい場合は

convertView.setOnClickListenear(...);

と書いてやる

 

今回は押したCardViewの色名をTost表示するようにした

 

5.MainActivity(再び)

一周回ってMainActivity

今回こそはコードを書く


public class ColorCardListActivity extends AppCompatActivity {

//変数宣言
private List<Card> cardList = null;
private ColorInfoAdapter adapter = null;
private ListView listView = null;

private final String[] COLORCODES = {"black", "red", "blue", "green", "yellow","white" };
private final String[] COLORNAMES = {"黒", "赤", "青", "緑", "黄", "白"};

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_color_card_list);

listView = (ListView)findViewById(R.id.listView);

cardList = new ArrayList<>();
for (int i = 0; i < COLORNAMES.length; i++) {
cardList.add(new Card(COLORNAMES[i], COLORCODES[i]));
}

adapter = new ColorInfoAdapter(this, R.layout.card, cardList);
listView.setAdapter(adapter);
}
}

 String配列2つは、色の名前とコードを対応させて保存している

Mapでも良かったがなんだかんだ言って面倒くさいので

配列2つにしておく

あとはListにfor文で情報を入れて

そいつをadapterに渡してListViewにセット

以上

f:id:bigbuddha:20161023230112p:plain

無事表示された

Tostもしっかり表示されている

 

MinecraftのMODを自作してみる on Ubuntu

友達がModdingをしたいと言っており

教えるがために自分も勉強するために自機の

Ubuntu上でModding環境を構築した際の覚書

WinやMacは調べればわんさかでてくるが

Linuxはあまりなかったので書いておく

結論を言ってしまえば

WinでもMacでもLinuxでも大差はない

と言うか違いはない気がする

Editorが何かだけである

今回はIntellij IDEAを使う

バージョンは1.9

参考リンクはこちら

esperia.hatenablog.com

qiita.com

1,ダウンロード

Minecraft ForgeからMDKなるものをダウンロードする

ModDevelopmentKitだろうか

最近の名称らしい

DLしてきたZipを解凍しておく

2,構築(?)

この行為が構築であるとは断言できないが

恐らく構築であろう

Linux系統でModdingをしようと思ってらっしゃる方で

ここで止まる方もいたかもしれない

まずcd "DLしてきたMDKのディレクトリ"で移動

続いてこちらのコマンドを実行

&&でつなぐのはオススメしない

    #これでMinecraftとForgeをデコンパイルとビルドをしているらしい
    ./gradlew setupDecompWorkspace
    #Intellij用の環境ファイルを作成
    ./gradlew genIntellijRuns

無事終了したらIDEAを起動

Import Projectで先程のディレクトリ内の

build.gradleを選択

しばしすると、無事ロードされる

あとは参考リンクの2つめの記事に

書いてあるコードを写経する

3,実行

注:コードは書き終えているものとする

やはり自作したら試したくなるものである

IDEAでの実行は

[View → ToolWindow → Gradle ]

[Tasks → forgegradle → runClient]

で無事実行できる(はず)

以上

f:id:bigbuddha:20160924091339p:plain

ChromiumでFlashPlayerを使えるようにする

注意

現在この方法ではFlashが入れられません

そもそもFlash自体が2020年に廃止となるので

Flashを諦めることをおすすめします

 

UbuntuChromiumを使用しているのだが

Flashが使えずに悩んでいた

Flash自体は危ないものだがないと困る時がある

と、言うことでPepperFlashPlayerを入れてみる

こちらのサイトを参考にした

 

とりあえずパッケージを検索

apt-cache search pepperflashplugin-nonfree

 

そうすると以下が引っかかる

pepperflashplugin-nonfree - Pepper Flash Player - browser plugin

 

見つけたら早速インストール

sudo apt install pepperflashplugin-nonfree

 

無事インストールできたら、続いてChromiumにインストール

sudo update-pepperflashplugin-nonfree --install

 

最後にChromiumを起動して以下のリンクへ
無事適用されているかを確認

chrome://flash/

 

f:id:bigbuddha:20160826224837p:plain

 

これで無事ChromiumFlashがインストールされた

 

Radikoのプレイヤー(Flashがないと表示されない)↓

f:id:bigbuddha:20160826225319p:plain

 

 

 

 

 

Stringの空検査

あるアプリで

EditText内に入力されている文字が空か否か

を調べるために以下のようにしていた
(textはString型)

if (text != "") {

だがうまくいかない

なぜだろうと考えていたら

文字列の一致はequals()を使うことを思い出した

if (!text.equals("")) {

 これで無事textが入力されてなかった場合

はじかれるようになった

 

  • 案外忘れやすいんだよな(;・∀・)