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); // } // } // }