非フォーカスComponentでのキーイベント取得

非フォーカスComponentでキーイベントを取得するサンプルコード。
AWTではフォーカスのないComponentや非表示状態のComponentはキーイベントを取得することができないため、ポップアップメニューのような機能が作りづらい。
そのため、BD-Jでは表示状態に関わらずXletがキーイベントを取得できる仕組みとして、EventManagerを用意している。

 

本サンプルでは、以下の2つのXletTitleを構成する。
  • Monitor.java: Pop up menuキーの押下で、”POPUP on”の表示・非表示がトグルされる
  • Main.java: paint()が呼び出された回数をカウントアップする

 

Monitor.java

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
 
import javax.tv.xlet.Xlet;
import javax.tv.xlet.XletContext;
 
import org.bluray.ui.event.HRcEvent;
import org.dvb.event.EventManager;
import org.dvb.event.UserEvent;
import org.dvb.event.UserEventListener;
import org.dvb.event.UserEventRepository;
import org.havi.ui.HScene;
import org.havi.ui.HSceneFactory;
import org.havi.ui.HScreen;
 
public class Monitor extends Component implements Xlet, UserEventListener {
    int x=100, y=100;
    boolean popup_on = false;
    HScene hs = null;
    public void initXlet(XletContext xc){
        try {
            hs= HSceneFactory.getInstance().getFullScreenScene(
                    HScreen.getDefaultHScreen().getDefaultHGraphicsDevice());
            this.setBounds(hs.getBounds());
            hs.add(this);
            // UserEventRepositoryの生成
            UserEventRepository uer = new UserEventRepository("test");
            // POPUP menu keyの登録
            uer.addKey(HRcEvent.VK_POPUP_MENU);
            // 自分自身をリスナーに登録
            EventManager.getInstance().addUserEventListener(this, uer);
        } catch (Throwable thr){
        }
    }
 
    public void paint(Graphics g){
        Font font = new Font(null, java.awt.Font.BOLD, 192);
        g.setColor(Color.white);
        g.setFont(font);
        g.drawString("POPUP on", 100, 300);
    }
    public void startXlet(){    }
    public void pauseXlet(){    }
    public void destroyXlet(boolean unconditional){}
    // UserEventListnerを実装
    public void userEventReceived(UserEvent e) {
        if( e.getCode() == HRcEvent.VK_POPUP_MENU && e.getType() == HRcEvent.KEY_RELEASED ){
            if( popup_on == false ){ // 非表示状態の場合、表示
                popup_on = true;
                hs.show();
            } else {
                popup_on = false;
                hs.setVisible(false);
            }
        }
    }
}

Main.java

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
 
import javax.tv.xlet.Xlet;
import javax.tv.xlet.XletContext;
 
import org.havi.ui.HScene;
import org.havi.ui.HSceneFactory;
import org.havi.ui.HScreen;
 
public class Main extends Component implements Xlet{
    int x, y, w = 960, h = 540;
    int count = 0;
    public void initXlet(XletContext xc){
        try {
           Thread.sleep(500); // HSceneの取得を遅らせないとなぜか常に最前面になってしまう
            HScene hs= HSceneFactory.getInstance().getFullScreenScene(
                    HScreen.getDefaultHScreen().getDefaultHGraphicsDevice());
            this.setBounds(hs.getBounds());
            hs.add(this);
            hs.setVisible(true);
        } catch (Throwable thr){
        }
    }
    public void paint(Graphics g ){
        g.setColor(Color.blue);
        g.fillRect(0, 0, w, h);
        g.setColor(Color.white);
        g.setFont(new Font(null, Font.BOLD, 48));
        g.drawString(Integer.toString(count), 100, 100);
        g.drawString(Integer.toString(count), w-100, h-100);
        count++;
    }
    public void startXlet(){}
    public void pauseXlet(){}
    public void destroyXlet(boolean unconditional){}
}

 


関連する項目

コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください