keymap定義のこと
今のPCでは、いわゆる106/109日本語キーボードを使っていない。
PowerMac G3なんかに付属していた古いUSBキーボードを使っている。
Ubuntu/Windowsともに、不自由はあまり感じないのだが、
ボリューム調整のキーとか、ディスクイジェクトのキーが効かなくて困ることが稀にある。
Ubuntu Mateをインストールしたら、このキーが効かなくて少しさみしかった。
そこで、キーボードのキーコードを調べて、機能を割り当てる方法を調べたので書いておく。
キーコードを調べる
xevコマンドを実行すると、キーイベントのモニタリングができるので、これを活用する。
.Xmodmapファイルを作る
ホームディレクトリに.Xmodmapというファイルを作る。
内容は下記のような具合に記述する。
keycode 122 = XF86AudioLowerVolume keycode 123 = XF86AudioRaiseVolume keycode 121 = XF86AudioMute keycode 169 = XF86Eject
.profileにコマンドを追記する
.Xmodmapファイル作成後にxmodmapコマンドを実行して.Xmodmapファイルを読みこませればOK。
.profileにコマンドを追記しておけば、ログイン後に自動で実行される。
# modify keymap xmodmap $HOME/.Xmodmap
- 参考文献
ubuntu-makeのこと
Android Studioをインストールしてみようと思って、
取得場所を探してみると、
ubuntu-makeの記事が目についた。
開発ツールの導入をサポートしてくれるアプリで、
これを使うと開発環境(この場合OSか)に合わせた"最新版"を導入できる、とのこと。
対象のツールも下記サイトによると多岐にわたっている。
はてなブックマーク - 第372回 Ubuntu Makeで簡単にAndroid開発環境を構築する:Ubuntu Weekly Recipe|gihyo.jp … 技術評論社
ファイルを探してページをめくるより、
こっちのほうが楽そうなので使ってみた。
ubuntu-makeはppaから導入する。
sudo add-apt-repository ppa:ubuntu-desktop/ubuntu-make sudo apt-get update sudo apt-get install ubuntu-make
使い方は簡単。
ターミナルから下記を実行すればOK。
umake android android-studio --accept-license
オプションの'--accept-license'はライセンス同意をスキップするオプション。
これを付けない場合は、ターミナルにライセンス条項が表示され、
同意をするかしないかを選ぶ必要があったらしいのだが、
実際に実行してみると、
そもそもライセンスが条項が取得できずにエラー終了してしまう。
そのため、このオプションを付けて実行した。
ubuntu-makeを実行するとインストールパスを問われるので、
適時修正後、enterを押すとダウンロードが始まる。
ダウンロードが終了するとubuntu-makeは終了してしまうので、
インストール先にあるandroid studioのインストーラを実行する必要がある。
結局のところ、
今回のubuntu-makeはインストーラのダウンロードだけしかしていないけど、
ファイルを探しまわる手間を考えると、
これはこれでありのような気がした。
あとは、eclipseをインストールするとどうなるかを試してみたいが、
eclipseはすでにあるので、
次のLTSをインストールする際に試してみようかな。
ちなみに、android-sdkやらndkもインストールできるとマニュアルには書いてあったけど、
ファイルが見つからないとかなんとかで、sdkのインストールはできなかった。
結局、sdkやndkはandroid studioのメニューからインストールした。
Android-x86のこと
スマホ嫌いでガラケー持ちだけど、androidが触りたくて
PC用Android OSであるAndroid-x86をインストールしてみた。
VirtualBoxにインストールするのが楽だけど、
速度が出ないのでノートPCに入れてみた。
ISOイメージはAndroid-x86の開発元から取得した。
インストールメディアを焼くのが面倒だったので
Unetbootinを使ってブータブルUSBメモリを作り、
ノートPCにインストールした。
UNetbootin - Homepage and Downloads
インストールで迷うところはあまりないが、
ディスクのパーティションについては、
予め作成しておくほうが楽みたい。
ちなみにLVMは使えないので、
インストールにはプライマリパーティションが必要。
ファイルシステムには
Android 4.4ベースの場合はext3まで、5以降はext4が使用できる。
Ubuntuなどとのデュアルブート環境を構築している場合は、
Grubを上書きしないように注意が必要かも。(yes, noの選択でスキップできる)
また、EFI用のBootメニューを作るかどうかも聞かれるので、
EFIが不要の場合は間違って設定してしまわないように注意する。
GrubのメニューにAndroid-x86の起動メニューを追加した際は、
Grub設定を直接編集せず、Grub Customizerをインストールして、ツールから編集を行った。
編集内容については、Unetbootinで作成したUSBメディア内のsysLinux.cfgを参考に書き加えた。
ちなみに1行目のroot='hd0,3'(sda3の意)やカーネルなどのパスについては、環境によって当然変える必要がある。
set root='hd0,3' linux /android-4.4-r5/kernel quiet root=/dev/ram0 androidboot.hardware=android_x86 src=/android-4.4-r5 initrd /android-4.4-r5/initrd.img
アプリによっては動かないものもあるけれど、
エミュレータよりはサクサク動かせるし、ストレスは少ない。
Ubuntu インストール時に手動でLVMパーティションを編成する方法
Ubuntuをインストールする際、
ディスクのパーティションをどうするかを選ぶことができるが、
位しかできない。
インストーラでは手動パーティション編成を選んでも、LVM管理の操作は行えない。
パーティションを自分で編集し、
なおかつLVM管理としたい場合はどうしたら良いのかがわからなかった。
調べてみると、インストーラを起動する前に、事前にディスク操作が必要らしい。
少し古いがこの記事が役に立った。
ubuntu12.04 LTSまでの記述だったが、14.04 LTSでも同じ操作で問題なかった。
UbuntuDesktopLVM - Community Help Wiki
ここの手順は基本コマンドで対応するのだけれど、
なるべくGUIで操作したかったので、
そのあたりを記録しておく。
以下、実施した手順。
UbuntuのLive CDなりUSBメディアなりで起動。
ルートを含む起動中のディスクは編集できないので、別のメディアから起動する。
Dashからディスクを起動
画面から既存のパーティションを削除して、まずは物理的にパーティションを切る。
ここではBoot領域、Ubuntu領域、別OS領域とした。
領域名 | タイプ | フォーマット | 備考 |
boot領域 | primary | ext2 | 自動インストール時に/bootがext2だったので。 |
Ubuntu領域 | extended | - | 拡張領域に論理領域を作る事になる。 |
別OS領域 | primary | ext4 | ここにインストールするOSがLVMを扱えるなら、このようにパーティションをわけずに、LVM論理パーティションの一つにできるのだが。 |
Gparted (Gparted パーティション編集ツール)を起動
Live CDに含まれるGpartedを使用して拡張領域に論理領域を作成する。
(画像は作成後のもの。作成時はマウントポイントもラベルもブランクでOK)
/dev/sda2の拡張領域上にカーソルを合わせると、ツールバーの追加ボタンが有効になるので押す。
領域サイズとファイルシステムタイプを問われるので、
領域サイズは"すべて"、ファイルシステムタイプは"lvm2 pv"とする。
ダイアログを閉じるとパーティションは"新規追加"みたいな表示だけで、まだ確定されていない。
編集内容はツールバーの保存ボタンを押すと反映される。
ここまではLVM管理の受け皿を作ったに過ぎず、
実際のボリューム設定はコマンドで行った。
参考元の記事を見ながらやれば、間違いが少ない。
pvcreate 論理領域に物理ボリュームを作る
sudo pvcreate /dev/sda5
vgcreate ボリュームグループを作る
sudo vgcreate ubuntu-vg /dev/sda5
lvcreate 論理ボリューム、論理swapを作る
sudo lvcreate -L 16G -n lvswap ubuntu-vg sudo lvcreate -l 100%FREE -n lvroot ubuntu-vg
lvdisplay 論理ボリュームの確認
sudo lvdisplay
mkfs.XXX mkswap ファイルシステムの作成
sudo mkfs.ext4 /dev/mapper/ubuntu--vg-lvroot
sudo mkswap -f /dev/mapper/ubuntu--vg-lvswap
ファイルシステムの名前(/dev/mapper以下)はグループ名+"-"+倫理ボリューム名にする。
その際、名称に"-"を含んでいる場合は、"--"としてエスケープしないといけない。
コマンドはファイルシステムがext4用のものとswap用のもので異なるが、
使い方はだいたい同じ。
インストーラを起動
インストーラで手動選択を選ぶと、インストール先選択にLVM管理の論理ボリュームが表示されるので、
boot領域に/boot, ubuntu-vg-lvrootに/, ubuntu-vg-lvswapにswapをそれぞれ設定する。
ブートローダのインストール先は/dev/sdaとする。
インストールが完了し、再起動後、問題がなければOK。
参考記事では、再起動前にマウントしてみろとか書いてあったけど、
イマイチ理由が読み取れなかったので無視した。
というわけで、手動でディスク割り+LVM適用は、結構めんどくさいが、
最初にやっておけば、LVM管理の論理ボリュームは領域の増減が楽なので後々悩む必要がなくなるかもしれない。
ソフトウェアアップデートに失敗する時の対処方法
一度サボりぐせがつくと、いけませんね。
このブログ、1ヶ月以上放置してしまった。
ま、気を取り直して、書くだよ。
えっと、表題どおり、
ウチのPCが更新できなくなってしまった。
apt-get updateをかけると、こんなエラーで止まってしまう。
W: http://jp.archive.ubuntu.com/ubuntu/dists/trusty-updates/main/binary-amd64/Packages の取得に失敗しました ハッシュサムが適合しません W: http://jp.archive.ubuntu.com/ubuntu/dists/trusty-updates/universe/binary-amd64/Packages の取得に失敗しました ハッシュサムが適合しません W: http://jp.archive.ubuntu.com/ubuntu/dists/trusty-updates/main/binary-i386/Packages の取得に失敗しました ハッシュサムが適合しません W: http://jp.archive.ubuntu.com/ubuntu/dists/trusty-updates/universe/binary-i386/Packages の取得に失敗しました ハッシュサムが適合しません E: いくつかのインデックスファイルのダウンロードに失敗しました。これらは無視されるか、古いものが代わりに使われます。
URLにあるサーバーが何らかの事情で変わってしまったみたい。
更新できないのも困りものなので、更新サーバーを変更して対処してみる。
これは知らなかったのだが、
一口に日本サーバーといっても複数あるようなので、
別のサーバーをチョイスしてみることにした。
- [システム設定]のパネルから[ソフトウェアとアップデート]を選択し、ダイアログを表示する。
- Ubuntuソフトウェアのタブにあるダウンロード元を「日本のサーバー」から「その他..」を選ぶ。
- サーバー選択のツリーにある日本のサーバー群から好きなものを選ぶ。迷ったら[最適なサーバーを探す]ボタンを押して選んでもらう。
- [サーバーの選択]ボタンを押してダイアログを閉じる。
これで問題なく更新ができるようになった。
Ubuntuを使っていると日々、色々なことがあるねぇ。。
JavaEE 7をやってみよう。 JSF 画面遷移 その2
その1のつづき。
登録画面用のManaged Beanを作る。
その前に、Managed Beanで使う艦種情報検索用の機能をJPAの回で作ったEJBに追加する。
WarshipServiceLocal.java
EJBモジュールのインターフェイス。
ここにgetAllTypeList()とgetWarship(Warship key)を追加する。
getAllTypeList()は艦種リストを取得するメソッド。
主に艦種選択リストのデータ取得に使用する。
getWarship(Warship key)は艦艇IDから艦艇情報を取得するメソッド。
これはまだ使う予定は無いが、更新を作るときに使うのでついでに作る。
package ejbModule; import java.util.List; import javax.ejb.Local; import model.Warship; import model.WarshipType; @Local public interface WarshipServiceLocal { public List<Warship> getAllList(); public List<WarshipType> getAllTypeList(); public Warship getWarship(Warship key); }
WarshipService.java
getAllTypeList()とgetWarship(Warship key)の実装を追加する。
getAllTypeList()に関しては、getAllListメソッドと同じ作りなので楽勝。
条件を付ける方にしても、プライマリキーで検索する場合では、
すでにEntityManaegerに用意されているfindメソッドを使えば良いのでこれまた楽勝。
findメソッドの第1パラメータが取得するクラス、第2パラメータがキー値。
この場合、取得クラスはWarshipクラスで、キー値はStringのID。
もっとも、対象テーブルが複合キーだったりすると、
このやり方は通用しないのだが(なんせ、第2パラメータに渡せるのはキー値そのものだから)、
そのことについてはまた、別の機会に。
package ejbModule; import java.util.List; import javax.ejb.LocalBean; import javax.ejb.Stateless; import javax.ejb.TransactionAttribute; import javax.ejb.TransactionAttributeType; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import model.Warship; import model.WarshipType; /** * Session Bean implementation class WarshipService */ @Stateless @LocalBean @TransactionAttribute(TransactionAttributeType.REQUIRED) public class WarshipService implements WarshipServiceLocal { @PersistenceContext private EntityManager entityManager; /** * Default constructor. */ public WarshipService() { } @Override public List<Warship> getAllList() { return entityManager.createNamedQuery("Warship.findAll", Warship.class).getResultList(); } @Override public List<WarshipType> getAllTypeList() { return entityManager.createNamedQuery("WarshipType.findAll", WarshipType.class).getResultList(); } @Override public Warship getWarship(Warship key) { return entityManager.find(Warship.class, key.getId()); } }
EJBを直したら、次はManaged Bean。
WarshipDefault.java
艦種、艦名保持用のフィールド、
艦種リスト取得、
艦艇取得を共通化するためのabstractクラス。
編集画面でも同じような構成の画面になるので、こんなクラスを作成してみた。
新規登録画面でのManaged Beanはこれを継承したものとなる。
package app.manage; import javax.annotation.PostConstruct; import javax.ejb.EJB; import javax.faces.model.ListDataModel; import model.Warship; import model.WarshipType; import ejbModule.WarshipServiceLocal; public abstract class WarshipDefault { @EJB protected WarshipServiceLocal ejb; /** 入力フィールド値の格納用 **/ private Warship warship; @PostConstruct private void init() { warship = new Warship(); warship.setWarshipType(new WarshipType()); } public ListDataModel<WarshipType> findAllWarshipType() { return new ListDataModel<WarshipType>(ejb.getAllTypeList()); } public void find() { Warship key = new Warship(); key.setId(getWarshipId()); warship = ejb.getWarship(key); } public Warship getWarship() { return warship; } public void setWarship(Warship warship) { this.warship = warship; } public abstract Integer getWarshipId(); public abstract void update(); }
WarshipRegister.java
今のところ登録処理は作ってないので、
実質、空実装に等しいが、登録メソッドも作った。
package app.manage; import javax.enterprise.context.RequestScoped; import javax.inject.Named; @RequestScoped @Named(value="WarshipReg") public class WarshipRegister extends WarshipDefault { @Override public Integer getWarshipId() { // 新規登録ではfindを使わないため、空実装 return null; } @Override public void update() { // TODO ejbに登録メソッドを作成後に実装 } }
ここまでで、ひとまず、Java側はおしまい。
新規登録画面のinsert.xhtmlに艦種リストの呼び出しと登録メソッドの呼び出しを追加する。
insert.xhtml
入力項目の格納先には、Managed Beanに用意したフィールドをあてがう*1。
フィールドはWarshipクラスなので、Warshipクラスのメンバをそれぞれ指定することになる。
艦種選択リストのOptionタグに当たる部分については、selectItemsタグを使ってListDataModelから生成できる。
selectItemsタグはselectOneMenuタグの中に記述する。
使い方はdataTableタグと似ている。
valueにはリスト値を、varにはその要素を表す変数名を指定できる点は、全く同じ。
他に、itemLabelには表示する値、itemValueには選択時に送信される値を設定する。
itemLabelEscpedは文字通り表示値をエスケープするか否かで、trueにすれば、
HTMLコードもそのまんま文字として出力できる。
あとは、登録時の呼び出しとして、
登録ボタンにactionListenerを追加した。
actionListenerには、登録メソッドたる、updateメソッドの呼び出しを記述した。
actionListenerはManaged Beanのメソッドの呼び出しが行える。
ただし、呼び出すメソッドにはパラメータを持たせることが出来ない。
戻り値はvoidかStringであることが条件。
JSFでは、actionLisener → actionの順で処理が行われるので、
actionListenerを使えば、メソッド呼び出し後に画面遷移を行うことができる。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"> <h2><h:outputLabel value="#{staticText['warship.reg.lblSreenTitle']}" /></h2> <hr/> <h:messages id="errorText" layout="table" errorClass="error-message"/> <h:outputLabel value="#{staticText['warship.reg.lblWarshipType']}" /> <h:selectOneMenu id="warshipType" value="#{WarshipReg.warship.warshipType.typeId}" styleClass="warship-type-select" > <f:selectItems value="#{WarshipReg.findAllWarshipType()}" var="warshipType" itemLabel="#{warshipType.name}" itemValue="#{warshipType.typeId}" itemLabelEscaped="true" /> </h:selectOneMenu> <h:outputLabel value="#{staticText['warship.reg.lblWarshipName']}" /> <h:inputText id="warshipName" value="#{WarshipReg.warship.name}" styleClass="warship-name-input" required="true" autocomplete="off" /> <br/> <h:commandButton value="#{staticText['warship.reg.btnRegister']}" action="catalog" actionListener="#{WarshipReg.update()}" /> <h:commandButton value="#{staticText['warship.reg.btnRegisterAndRegister']}" /> </ui:composition>
といったところで、テスト実行。
画面を動かしてメニューから新規登録を選ぶと入力画面へ遷移でき、
入力画面では艦種選択リストが表示できている。
また、艦名を入力した後に登録ボタンを押すと一覧画面に遷移できる。
こんな感じで選択リストの表示と、登録ボタンの処理はできた。
次回はJPAの続きとして新規登録(Insert)の実装を行う。
*1:ほんとは、入力項目と1対1とフィールドを設けたほうがわかりやすいとは思うけど、色々思ってこうした