Newer
Older
Zemi01 / src / main / java / info / istlab / Zemi01 / RectangleFrame.java
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);
// }
// }
// }