コンポーネントが配置されたBorder

下のような枠線の上にコンポーネントが配置できるBorderです

![WS000131.JPG](https://qiita-image-store.s3.amazonaws.com/0/45331/63ba2c30-aa6b-4c32-19de-c1c28fcd4ce1.jpeg)

```java:ComponentBorder.java
package net.hoge.fuga;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.border.Border;

/**
 * コンポーネント付の枠線
 */
public class ComponentBorder implements Border, MouseListener, MouseMotionListener, SwingConstants
{
    /** 枠からの距離 */
    private static final int BORDER_OFFSET = 5;

    /** 枠線の上に配置するコンポーネント */
    private Component _borderedComponent = null;

    /** 枠の中に納めるコンポーネントコンテナ */
    private JComponent _container = null;

    /** 枠線の種類 */
    private Border _border = null;

    /**
     * コンストラクタ
     * @param comp 枠線の上に載せるコンポーネント
     * @param container 枠の中に納めるコンポーネント
     * @param border 枠線の種類
     */
    public ComponentBorder( JComponent comp, JComponent container, Border border )
    {
        this._borderedComponent = comp;
        this._container = container;
        this._border = border;
        comp.setOpaque( true );
        container.addMouseListener( this );
        container.addMouseMotionListener( this );
    }

    @Override
    public boolean isBorderOpaque()
    {
        return true;
    }

    @Override
    public void paintBorder( Component c, Graphics g, int x, int y, int width, int height )
    {
        Insets borderInsets = _border.getBorderInsets( c );
        Insets insets = getBorderInsets( c );
        int temp = ( insets.top - borderInsets.top ) / 2;
        _border.paintBorder( c, g, x, y + temp, width, height - temp );
        Dimension size = _borderedComponent.getPreferredSize();
        Rectangle rect = new Rectangle( BORDER_OFFSET, 0, size.width, size.height );
        SwingUtilities.paintComponent( g, _borderedComponent, (Container)c, rect );
        _borderedComponent.setBounds( rect );
    }

    @Override
    public Insets getBorderInsets( Component c )
    {
        Dimension size = _borderedComponent.getPreferredSize();
        Insets insets = _border.getBorderInsets( c );
        insets.top = Math.max( insets.top, size.height );
        return insets;
    }

    /**
     * マウスイベントの配信
     * @param me マウスイベント
     */
    private void dispatchEvent( MouseEvent me )
    {
        if( _borderedComponent == null )
        {
            return;
        }
        _borderedComponent.dispatchEvent( new MouseEvent( _borderedComponent, me.getID(), me.getWhen(), me.getModifiers(), me.getPoint().x, me
            .getPoint().y, me.getClickCount(), me.isPopupTrigger(), me.getButton() ) );
        _container.repaint();
    }

    @Override
    public void mouseClicked( MouseEvent me )
    {
        dispatchEvent( me );
    }

    @Override
    public void mouseEntered( MouseEvent me )
    {
        dispatchEvent( me );
    }

    @Override
    public void mouseExited( MouseEvent me )
    {
        dispatchEvent( me );
    }

    @Override
    public void mousePressed( MouseEvent me )
    {
        dispatchEvent( me );
    }

    @Override
    public void mouseReleased( MouseEvent me )
    {
        dispatchEvent( me );
    }

    @Override
    public void mouseMoved( MouseEvent me )
    {
        dispatchEvent( me );
    }

    @Override
    public void mouseDragged( MouseEvent me )
    {
        dispatchEvent( me );
    }
}

```