/**
* 非矩形Window表示サンプル
* @author MSLABO
* @version 1.0
*/
import java.awt.Shape;
import javax.swing.ImageIcon;
import java.awt.Image;
import java.awt.geom.GeneralPath;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.Rectangle;
import java.awt.Frame;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.MouseInfo;
import javax.swing.JOptionPane;
import processing.awt.PSurfaceAWT;
import javax.swing.JPopupMenu;
import javax.swing.JMenuItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* フレーム用Shape管理クラス
*/
class FrameShapeMng{
Shape shape; //非矩形領域
ImageIcon icon; //アイコン画像
PImage pimg; //PROCESSING用画像
/**
* コンストラクタ
* @param fileName:画像ファイルパス
*/
FrameShapeMng( String fileName ){
//画像ファイルをアイコン画像化
icon = new ImageIcon( fileName );
//アイコン画像からShapeを得る
shape = getImageShape( icon );
//アイコン画像からPROCESSING用画像を得る
Image img = icon.getImage();
pimg = new PImage( img );
}
/**
* アイコン画像の不透明部分を Shapeにする関数
* @param icon:アイコン画像
* @return Shape:作成した Shapeオブジェクト
*/
Shape getImageShape(ImageIcon icon){
//Shape領域作成
GeneralPath shape = new GeneralPath();
//アイコン画像と同じ大きさのARGBイメージバッファ生成
final BufferedImage bi = new BufferedImage(icon.getIconWidth(),
icon.getIconHeight(),
BufferedImage.TYPE_INT_ARGB);
//イメージバッファにアイコン画像を描画する
icon.paintIcon(null, bi.createGraphics(), 0, 0);
ColorModel cm = bi.getColorModel();
//イメージバッファの不透明画素をShape化する
for(int y = 0; y < bi.getHeight(); y++){
for(int x = 0; x < bi.getWidth(); x++){
// 不透明ならShapeに追加する
if(cm.getAlpha(bi.getRGB(x, y)) > 0){
int start = x; //追加開始横位置
int notTransparentWidth = 0; //追加する画素数
//横1ラインの中で、連続している不透明画素を数える
while((x < bi.getWidth()) &&
(cm.getAlpha(bi.getRGB(x++, y)) > 0)){
notTransparentWidth++;
}
//不透明画素部分をマスクとして、Shapeに追加する
shape.append(new Rectangle(start,y,notTransparentWidth,1),true);
}
}
}
return( shape );
}
}
int imgIndex; //表示画像位置
ArrayList<FrameShapeMng> myShape ; //Shape管理クラスのList
PImage dispImg; //PROCESSING用表示画像
JPopupMenu popup; //ポップアップメニュー
Point startPt; //マウスドラッグ開始座標
/**
* PROCESSING 初期処理関数
*/
void setup() {
//画面のチラつきを防止するため、直ちに実行結果Windowを
//画面外に押しやり、非表示にする
surface.setLocation( -300, -300 );
surface.setVisible( false );
//PSurfaceが持つFrameを得る
Frame frame = getFrame();
//Frameを画面から切り離す(なるべく早い段階で行う事)
frame.removeNotify();
//タイトルバーを削除する
frame.setUndecorated( true );
//Frameを画面に接続する(Frameの変更終了)
frame.addNotify();
//実行結果Windowのサイズ変更を許可する
surface.setResizable( true );
//Shape管理クラスを、画像分だけ生成する
myShape = new ArrayList<FrameShapeMng>();
myShape.add( new FrameShapeMng( dataPath("") + "\\" + "anzu1.png" ) );
myShape.add( new FrameShapeMng( dataPath("") + "\\" + "anzu2.png" ) );
myShape.add( new FrameShapeMng( dataPath("") + "\\" + "anzu3.png" ) );
//最初のクラスからアイコンとShapeを取り出し、実行結果Windowのサイズ
//を調整し、実行結果WindowにShapeをセットする
imgIndex = 0;
FrameShapeMng work = myShape.get( imgIndex );
surface.setSize( work.icon.getIconWidth(), work.icon.getIconHeight());
frame.setShape( work.shape );
//AP終了のためのポップアップメニューを作成する
//PopupMenu pAct = new PopupMenu();
//popup = new JPopupMenu();
//JMenuItem exitMenuItem = new JMenuItem("終了");
//exitMenuItem.addActionListener( pAct );
//popup.add( exitMenuItem );
//適当な位置に実行結果Windowを表示する
surface.setVisible(true);
surface.setLocation( 100,100 );
//PROCESSING用の表示画像を取得しておく
dispImg = work.pimg;
}
/**
* ポップアップメニュー選択イベント受け取り用クラス
*/
//class PopupMenu implements ActionListener {
// @Override
// public void actionPerformed( ActionEvent e ) {
// String command = e.getActionCommand();
// if (command.equals("終了")) {
// //終了メニューが選択されたのでAP終了
// exit();
// }
// }
//}
/**
* PSurface(実行結果Window)が持つFrameを得る
* @return Frame:Frameオブジェクト
*/
Frame getFrame() {
PSurfaceAWT.SmoothCanvas canvas;
canvas = (PSurfaceAWT.SmoothCanvas)getSurface().getNative();
return( (Frame)canvas.getFrame() );
}
/**
* PROCESSING マウス押下イベント
* @param e:PROCESSINGマウスイベント
*/
void mousePressed( MouseEvent e ){
//マウスが押下されたスクリーン座標を記録する
PointerInfo pi = MouseInfo.getPointerInfo();
startPt = pi.getLocation();
}
/**
* PROCESSING マウスドラッグイベント
* @param e:PROCESSINGマウスイベント
*/
void mouseDragged( MouseEvent e ){
//マウスが移動したスクリーン座標を取得する
PointerInfo pi = MouseInfo.getPointerInfo();
Point nowPt = pi.getLocation();
//どこ程度動いたかを計算し、画面を移動する
int sabunX = nowPt.x - startPt.x ;
int sabunY = nowPt.y - startPt.y ;
int x = getFrame().getX() + sabunX;
int y = getFrame().getY() + sabunY;
surface.setLocation( x, y );
//次の移動のために、現在のマウスカーソル位置を更新
startPt = nowPt;
}
/**
* PROCESSING マウスクリックイベント
* @param e:PROCESSINGマウスイベント
*/
void mouseClicked( MouseEvent e ){
Frame frame = getFrame();
//ダブルクリックされたら、Shapeを切り替える
if( e.getCount() > 1 ){
imgIndex++;
if( imgIndex >= myShape.size() ){
imgIndex = 0;
}
//新しいShapeを実行結果Windowにセットする
FrameShapeMng work = myShape.get( imgIndex );
surface.setSize(work.icon.getIconWidth(), work.icon.getIconHeight());
frame.setShape( work.shape );
//PROCESSING用の表示画像を取得しておく
dispImg = work.pimg;
return;
}
//右クリックされたら、ダイアログBOXを開いて
//終了するか問い合わせる
if( e.getButton() == RIGHT ){
//ポップアップメニューを表示する
//popup.show( getFrame().getComponent(0), ex, ey );
//popup.repaint();
int ans = JOptionPane.showConfirmDialog(getFrame().getComponent(0),
"終了しますか?", "問い合わせ",
JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if( ans == JOptionPane.YES_OPTION ){
//YESなのでAP終了
exit();
}
}
}
/**
* PROCESSING 描画処理関数
*/
void draw() {
background(0);
image( dispImg, 0, 0 );
}