package info.istlab.Zemi01;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;
/**
* 中央が透明の、ドラッグで動かせるWindow群
* おまけ機能として、右クリックメニューから、画面キャプチャができるようにしている。
*
* 全体が透明のウィンドウを作成すると、マウスクリックが透過せずに不便なので、
* 今回は上下左右に細い半透明ウィンドウを配置して、枠を構成している。
* 右上でウィンドウを閉じる機能、右下で枠をリサイズする機能、ダブルクリックで画面キャプチャ
*
* @param args
*/
public class RectangleFrame implements MouseListener, MouseMotionListener {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
RectangleFrame rf = new RectangleFrame(400, 300);
rf.setVisible(true);
JPopupMenu menu = new JPopupMenu();
JMenuItem cancelMI = new JMenuItem("(close menu)"); // なにもしないメニュー。メニューを閉じるためのメニュー
menu.add(cancelMI);
menu.addSeparator();
JMenuItem captureMI = new JMenuItem("capture");
captureMI.addActionListener(
e -> ScreenCapture.capture(rf.getInnerRect(), System.getProperty("user.dir")));
menu.add(captureMI);
JMenuItem exitMI = new JMenuItem("exit");
exitMI.addActionListener(e -> System.exit(0));
menu.add(exitMI);
rf.registerPopupMenu(menu);
}
});
}
// ここで、画面中心にウィンドウ表示するため、いろいろ計算する
public static Point centerOfScreen(Dimension winSize) {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
return new Point((screenSize.width - winSize.width) / 2, (screenSize.height - winSize.height) / 2);
}
public void setVisible(boolean f) {
for (int i = 0; i < 4; i++) {
rects[i].setVisible(f);
}
}
public void setBackground(Color c) {
for (int i = 0; i < 4; i++) {
rects[i].setBackground(c);
}
}
/**
* 内部サイズ
*
* @return
*/
public Dimension getInnerDim() {
return new Dimension(width - frameWidth * 2, height - frameWidth * 2);
}
/**
* 内部矩形の左上の点
*
* @return
*/
public Point getInnerPos() {
return new Point(location.x + frameWidth, location.y + frameWidth);
}
/**
* 内部矩形
*
* @return
*/
public Rectangle getInnerRect() {
return new Rectangle(getInnerPos(), getInnerDim());
}
TransparentRect[] rects = new TransparentRect[4];
Point location;
int width, height, frameWidth;
Point pressP;
Point pressWinP; // マウスプレスしたときの、RectangleFrameの位置
boolean resizeMode = false;
Dimension dim;
JPopupMenu popupMenu;
/**
* コンストラクタ
*
* @param w
* @param h
*/
public RectangleFrame(int w, int h) {
width = w;
height = h;
frameWidth = 10;
location = RectangleFrame.centerOfScreen(new Dimension(w, h));
for (int i = 0; i < 4; i++) {
rects[i] = new TransparentRect(this);
// rects[i].setFocusableWindowState(true);
}
layout();
System.out.println("つかいかた:ドラッグで枠移動、右下で枠をリサイズする、ダブルクリックで画面キャプチャ、右上でウィンドウを閉じる");
}
public void registerPopupMenu(JPopupMenu pM) {
popupMenu = pM;
// for (int i = 0; i < 4; i++) {
// rects[i].addKeyListener( new EscapeCloseKeyListener(popupMenu));
// }
}
public void layout() {
rects[0].setLocation(location.x, location.y);
rects[0].setSize(width, frameWidth);
rects[1].setLocation(location.x, location.y + frameWidth);
rects[1].setSize(frameWidth, height - frameWidth * 2);
rects[2].setLocation(location.x + width - frameWidth, location.y + frameWidth);
rects[2].setSize(frameWidth, height - frameWidth * 2);
rects[3].setLocation(location.x, location.y + height - frameWidth);
rects[3].setSize(width, frameWidth);
for (int i = 0; i < 4; i++) {
rects[i].toFront();
}
}
public void setLocation(int px, int py) {
location.setLocation(px, py);
layout();
}
public void setSize(int w, int h) {
width = w;
height = h;
layout();
}
@Override
public void mouseDragged(MouseEvent e) {
Point curP = e.getLocationOnScreen();
int diffx = curP.x - pressP.x;
int diffy = curP.y - pressP.y;
// System.out.println(diffx+" "+diffy);
if (resizeMode) {
if (dim.width + diffx > frameWidth * 2 && dim.height + diffy > frameWidth * 2) {
setSize(dim.width + diffx, dim.height + diffy);
}
} else {
setLocation(pressWinP.x + diffx, pressWinP.y + diffy);
}
}
@Override
public void mouseMoved(MouseEvent e) {
if (e.getComponent() == rects[3] &&
e.getPoint().x > rects[3].getWidth() - frameWidth) {
e.getComponent().setCursor(new Cursor(Cursor.SE_RESIZE_CURSOR));
} else if (e.getComponent() == rects[0] &&
e.getPoint().x > rects[0].getWidth() - frameWidth) {
setBackground(new Color(255, 0, 0, 100));
} else {
e.getComponent().setCursor(new Cursor(Cursor.MOVE_CURSOR));
setBackground(new Color(0, 0, 0, 80));
}
}
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2)
ScreenCapture.capture(this.getInnerRect(), System.getProperty("user.dir"));
}
@Override
public void mousePressed(MouseEvent e) {
pressP = e.getLocationOnScreen();
pressWinP = rects[0].getLocationOnScreen();
resizeMode = false;
if (e.getButton() == MouseEvent.BUTTON3) {
if (popupMenu != null) {
popupMenu.show(e.getComponent(), e.getX(), e.getY());
// e.getComponent().requestFocus();
} // System.exit(0);
}
if (e.getComponent() == rects[3] &&
e.getPoint().x > rects[3].getWidth() - frameWidth) {
resizeMode = true;
dim = new Dimension(width, height);
}
if (e.getComponent() == rects[0] &&
e.getPoint().x > rects[0].getWidth() - frameWidth) {
Toolkit.getDefaultToolkit().beep();
setVisible(false);
// すぐに終了するとBeep音が聞こえないので、すこし待つ
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
System.exit(0);
}
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
setBackground(new Color(0, 0, 0, 80));
if (e.getComponent() == rects[3] &&
e.getPoint().x > rects[3].getWidth() - frameWidth) {
rects[3].setCursor(new Cursor(Cursor.SE_RESIZE_CURSOR));
} else if (e.getComponent() == rects[0] &&
e.getPoint().x > rects[0].getWidth() - frameWidth) {
setBackground(new Color(255, 0, 0, 100));
}
}
@Override
public void mouseExited(MouseEvent e) {
setBackground(new Color(0, 0, 0, 30));
e.getComponent().setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
}
/**
* 半透明の部品
*
* 0000000000000000000000000
* 11 22
* 11 22
* 11 22
* 11 22
* 3333333333333333333333333
*
*/
class TransparentRect extends JWindow {
public TransparentRect(RectangleFrame parent) {
setBackground(new Color(0, 0, 0, 30));
addMouseListener(parent);
addMouseMotionListener(parent);
}
}
// class EscapeCloseKeyListener extends KeyAdapter {
// JPopupMenu target;
// public EscapeCloseKeyListener(JPopupMenu t){
// target = t;
// }
// public void keyPressed(KeyEvent e){
// System.out.println(e.getKeyCode());
// if (e.getKeyCode() == KeyEvent.VK_ESCAPE){
// target.setVisible(false);
// }
// }
// }