パネルに背景画像を配置して、コンポーネントをオーバーレイする

戻る
JComponentのpaintComponent()メソッドの使い方がポイントです。





::::::::::::::
FormDeserializer.java
::::::::::::::
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.filechooser.*;

import java.io.*;

/**
$Id: FD.html,v 1.1 2009/06/22 16:11:43 kishi Exp kishi $
@author KISHI Yasuhiro
*/

public class FormDeserializer {

    static public FormPanel deserialize( JComponent obj ) {

        JFileChooser fileChooser = new JFileChooser( "../DATA" );

        FormPanel formPanel = null;

        // ファイルフィルターを適用
        fileChooser.addChoosableFileFilter( new MySerFileFilter() );

        if ( fileChooser.showOpenDialog( obj ) == JFileChooser.APPROVE_OPTION ) {
            JOptionPane.showMessageDialog(
                obj,
                fileChooser.getSelectedFile().getPath(),
                "FILE PATH",
                JOptionPane.INFORMATION_MESSAGE );

            File file = new File( fileChooser.getSelectedFile().getPath() );
            try {

                FileInputStream inFile = new FileInputStream( file );
                ObjectInputStream ois = new ObjectInputStream( inFile );

                formPanel = ( FormPanel ) ois.readObject();

                ois.close();
                inFile.close();
            } catch ( Exception e ) {
                e.printStackTrace();
            }

        } else {
            JOptionPane.showMessageDialog( obj, "ファイルが選択されていません", "WARNING", JOptionPane.WARNING_MESSAGE );
        }

        return formPanel;

    }


}

::::::::::::::
FormDesigner.java
::::::::::::::
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;

/**
$Id: FD.html,v 1.1 2009/06/22 16:11:43 kishi Exp kishi $
*/

public class FormDesigner extends JFrame {
    final private int WIDTH = 640;
    final private int HEIGHT = 480;

    public FormDesigner() {
        super( "シンプルフォームデザイナ" );

        try {
            // WindowsのLook&Feelにする
            UIManager.setLookAndFeel( "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" );
            SwingUtilities.updateComponentTreeUI( this );

        } catch ( Exception e ) {
            e.printStackTrace();
            System.exit( -1 );
        }

        //-----------------------------------------------------
        // 上部に表示するメニュー
        //-----------------------------------------------------
        MyMenuBar menuBar = new MyMenuBar();

        //-----------------------------------------------------
        // フォームを実際に配置するスクロールペイン
        //-----------------------------------------------------
        MainPane mainPane = new MainPane();

        //-----------------------------------------------------
        // 全ての部品をContainerに配置する
        //-----------------------------------------------------
        Container container = this.getContentPane();

        container.add( menuBar, BorderLayout.NORTH );
        container.add( mainPane, BorderLayout.CENTER );
        container.add( new JPanel(), BorderLayout.SOUTH );

        try {
            MyObservable.getInstance().addObserver( mainPane );
        } catch ( Exception e ) {
            e.printStackTrace();
        }

    }

    public static void main( String[] args ) {

        FormDesigner frame = new FormDesigner();

        /* 終了処理を追加 */
        frame.addWindowListener( new WindowAdapter() {
                                     public void windowClosing( WindowEvent e ) {
                                         System.exit( 0 );
                                     }
                                 }
                               );

        /** サイズと位置を指定 */
        frame.setBounds( 0, 0, frame.WIDTH, frame.HEIGHT );

        /** サイズを固定 */
        // 固定しない
        // frame.setResizable( false );
        //

        frame.setVisible( true );

    }
}

::::::::::::::
FormPanel.java
::::::::::::::
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.*;

import javax.imageio.*;

import javax.swing.*;
import java.io.*;
import java.util.*;

/**
* $Id: FD.html,v 1.1 2009/06/22 16:11:43 kishi Exp kishi $
* @author KISHI Yasuhiro
*/

public class FormPanel extends JPanel implements ActionListener, MouseListener {

    /**
    * 背景画像を格納するためのイメージアイコン(Imageクラスはシリアライズできないので直接は使わないが、画像の器として利用する)
    * ImageIconはJComponentを継承したクラスなのでシリアライズ可能である
    */
    private ImageIcon imageIcon = null;

    /**
    * 背景色
    */
    private Color bgColor = null;

    /** 編集可能かどうか */
    private boolean isEditable;

    /** ポップアップメニューのインスタンス */
    private JPopupMenu popup = null;

    /** マウスのポイントしているX座標 */
    private int xPos = 0;
    /** マウスのポイントしているY座標 */
    private int yPos = 0;

    private Map<JComponent, String> componentMap = null;

    public FormPanel() {
        super();

        // レイアウトマネージャを使用しない
        setLayout( null );

        componentMap = new LinkedHashMap<JComponent, String>();

        // デフォルトの背景色を設定
        bgColor = new Color( 0x99, 0x00, 0xff );

        try {
            loadImage();
        } catch ( Exception e ) {
            e.printStackTrace();
        }
    }

    public void setEditable( boolean isEditable ) {
        this.isEditable = isEditable;

        popup = new JPopupMenu();
        // メニューの数に応じて適宜サイズを変更すること
        popup.setPopupSize( 150, 100 );

        JMenuItem menuCreateButton = new JMenuItem( "ボタン作成" );
        menuCreateButton.setActionCommand( "CREATE_BUTTON" );
        menuCreateButton.addActionListener( this );
        popup.add( menuCreateButton );

        JMenuItem menuCreateLabel = new JMenuItem( "ラベル作成" );
        menuCreateLabel.setActionCommand( "CREATE_LABEL" );
        menuCreateLabel.addActionListener( this );
        popup.add( menuCreateLabel );

        JMenuItem menuCreateTextFiled = new JMenuItem( "テキストフィールド作成" );
        menuCreateTextFiled.setActionCommand( "CREATE_TEXTFIELD" );
        menuCreateTextFiled.addActionListener( this );
        popup.add( menuCreateTextFiled );

        JMenuItem menuColorSelection = new JMenuItem( "背景色選択" );
        menuColorSelection.setActionCommand( "COLOR_SELECTION" );
        menuColorSelection.addActionListener( this );
        popup.add( menuColorSelection );

        addMouseListener( this );

        if ( isEditable ) {
            // 編集可能モードの場合は、パネル内の全てのコンポーネントに対して、MouseMotionListenerを付与する
            Component[] components = this.getComponents();
            System.out.println( "コンポーネントの数は、" + components.length );
            for ( int i = 0;i < components.length;i++ ) {
                // マウスドラッグのモーションリスナを登録
                MouseMotionListener motionListener = new MouseDraggedEventHandler( this, ( JComponent ) components[ i ] );
                components[ i ].addMouseMotionListener( motionListener );

                // コンポーネントに対してポップアップメニューを設定する
                PopupMenuSetter pms = new PopupMenuSetter( this, ( JComponent ) components[ i ] );
                pms.setPopupMenu();
            }
        }
    }

    public synchronized void putComponentMap( JComponent component, String name ) {

        if ( componentMap != null ) {
            componentMap.put( component, name );
        }
    }

    public Map getComponentMap() {
        return componentMap;
    }

    public void actionPerformed( ActionEvent e ) {

        if ( !isEditable ) {
            //----------------------------------------------
            // 編集不可の場合は何もしない
            //----------------------------------------------
            return ;
        }

        if ( e.getSource() instanceof JMenuItem ) {
            //---------------------------------------------------
            // 右クリックからのメニューを選択した場合
            //---------------------------------------------------
            JMenuItem source = ( JMenuItem ) ( e.getSource() );
            System.out.println( "Action Command is " + source.getText() );
            String command = e.getActionCommand();

            // ポップアップメニューを開いた座標値を求める
            // System.out.printf( "x=%3d, y=%3d: commnad=%s\n", xPos, yPos, command );

            if ( "COLOR_SELECTION".equals( command ) ) {

                // 背景色を選択する
                JColorChooser ch = new JColorChooser();
                Color color = ch.showDialog( this, "ボタンの色の選択", Color.white );

                if ( color != null ) {
                    bgColor = color;
                    this.repaint();
                }

            } else {
                // コンポーネント生成のメニュー(ファクトリメソッド)
                JComponentManager.createComponent( this, xPos, yPos, command );
            }
        }

    }
    public void mousePressed( MouseEvent e ) {
        if ( e.isPopupTrigger() ) {
            /* JPopupMenuを表示 */
            popup.show( e.getComponent(), e.getX(), e.getY() );
            xPos = ( int ) e.getX();
            yPos = ( int ) e.getY();
            popup.pack();
        }
    }

    public void mouseReleased( MouseEvent e ) {
        if ( e.isPopupTrigger() ) {
            /* JPopupMenuを表示 */
            popup.show( e.getComponent(), e.getX(), e.getY() );
            xPos = ( int ) e.getX();
            yPos = ( int ) e.getY();
            popup.pack();
        }
    }

    /** マウスがクリックされた時の処理 */
    public void mouseClicked( MouseEvent e ) {
        int modifier = e.getModifiers();

        // SHIFT,ALT,CTRLキーの押下の判別
        String s = getShiftAltCtrl( modifier );
        System.out.println( s );

        if ( ( modifier & InputEvent.BUTTON1_MASK ) != 0 ) {
            /** 左クリック **/
            System.out.println( "LEFT CLICK!" );

        } else if ( ( modifier & InputEvent.BUTTON2_MASK ) != 0 ) {
            /** DO NOTHING */
        } else if ( ( modifier & InputEvent.BUTTON3_MASK ) != 0 ) {
            /** 右クリック **/
            // ここは通らなくなってしまいます
            System.out.println( "ポップアップメニューが表示されます!" );
        }
    }

    private String getShiftAltCtrl( int modifier ) {
        StringBuffer sb = new StringBuffer();

        if ( ( modifier & InputEvent.SHIFT_MASK ) != 0 ) {
            sb.append( "SHIFT " );
        }

        if ( ( modifier & InputEvent.ALT_MASK ) != 0 ) {
            sb.append( "ALT " );
        }

        if ( ( modifier & InputEvent.CTRL_MASK ) != 0 ) {
            sb.append( "CTRL " );
        }

        return ( new String( sb ) );
    }

    public void mouseEntered( MouseEvent e ) {}
    public void mouseExited( MouseEvent e ) {}

    /**
    * ローカルファイルからイメージを読み出す
    */
    private void loadImage() throws Exception {

        if ( imageIcon == null ) {

            //---------------------------------------------------------------
            // 画像をローカルファイルから読み込む
            // シリアライズされたものをデシリアライズする場合も同様のチェックとなる
            //---------------------------------------------------------------
            Image bgImage = null;
            try {
                bgImage = ImageIO.read( new File( "bg1.jpg" ) );
            } catch ( IOException ex ) {
                throw ex;
            }

            imageIcon = new ImageIcon( bgImage );

        }

        this.validate();
        this.repaint();
    }

    /**
    * 注意: paint()メソッドでなく、paintComponent()メソッドを使うこと! 
    */
    public void paintComponent( Graphics g ) {

        int width = getWidth();
        int height = getHeight();

        g.setColor( bgColor );
        // 背景色でこのコンポーネントを全て塗りつぶす
        g.fillRect( 0 , 0 , width , height );

        Image bgImage = imageIcon.getImage();

        if ( bgImage != null ) {
            Graphics2D g2 = ( Graphics2D ) g;

            g2.drawImage( bgImage, 0, 0, this );

        }

    }

}
::::::::::::::
FormSerializer.java
::::::::::::::
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.filechooser.*;

import java.io.*;

/**
$Id: FD.html,v 1.1 2009/06/22 16:11:43 kishi Exp kishi $
@author KISHI Yasuhiro
*/

public class FormSerializer {

    static public void serialize( JComponent obj ) {

        JFileChooser fileChooser = new JFileChooser( "../DATA" );

        // ファイルフィルターを適用
        fileChooser.addChoosableFileFilter( new MySerFileFilter() );

        if ( fileChooser.showSaveDialog( obj ) == JFileChooser.APPROVE_OPTION ) {

            JOptionPane.showMessageDialog(
                obj,
                fileChooser.getSelectedFile().getPath(),
                "FILE PATH",
                JOptionPane.INFORMATION_MESSAGE );

            File file = new File( fileChooser.getSelectedFile().getPath() );
            try {
                FileOutputStream outFile = new FileOutputStream( file );
                ObjectOutputStream oos = new ObjectOutputStream( outFile );

                oos.writeObject( obj );
                oos.flush();

                oos.close();
                outFile.close();

                String fileName = file.getName();
                System.out.println( "ファイル名: " + fileName );
                if ( !fileName.endsWith( ".ser" ) ) {
                    System.out.println( "RENAMED!!" );

                    file.renameTo( new File( "../DATA", fileName + ".ser" ) );
                }

            } catch ( Exception e ) {
                e.printStackTrace();
            }

        } else {
            JOptionPane.showMessageDialog( obj, "You don't choose a file.", "WARNING", JOptionPane.WARNING_MESSAGE );
        }

    }


}

::::::::::::::
JComponentFactory.java
::::::::::::::
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;

import javax.swing.*;
import java.io.*;
import java.util.*;

/**
$Id: FD.html,v 1.1 2009/06/22 16:11:43 kishi Exp kishi $
@author KISHI Yasuhiro
*/

public class JComponentFactory {

    public static JComponent getInstance( String command ) {

        JComponent component = null;
        if ( "CREATE_BUTTON".equals( command ) ) {
            component = new JButton( "JButton" + JComponentManager.getCount() );
        }
        if ( "CREATE_LABEL".equals( command ) ) {
            component = new JLabel( "JLabel" + JComponentManager.getCount() );
        }
        if ( "CREATE_TEXTFIELD".equals( command ) ) {
            component = new JTextField( 10 );
        }
        return component;

    }

}
::::::::::::::
JComponentManager.java
::::::::::::::
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;

import javax.swing.*;
import java.io.*;
import java.util.*;

/**
$Id: FD.html,v 1.1 2009/06/22 16:11:43 kishi Exp kishi $
@author KISHI Yasuhiro
*/

public class JComponentManager {

    public static void createComponent( FormPanel formPanel, int xPos, int yPos, String command ) {

        // コマンドに応じて適宜必要なコンポーネントのインスタンスを返す
        JComponent component = JComponentFactory.getInstance( command );
        component.setBounds( xPos, yPos, 100, 20 );

        formPanel.add( component );
        formPanel.validate();
        formPanel.repaint();

        // マウスドラッグのモーションリスナを登録
        MouseMotionListener motionListener = new MouseDraggedEventHandler( formPanel, component );
        component.addMouseMotionListener( motionListener );

        // プロパティを設定するためのサブウィンドウを表示する
        new PropertyEditor( xPos, yPos, formPanel, component );

        // コンポーネントに対してポップアップメニューを設定する
        PopupMenuSetter pms = new PopupMenuSetter( formPanel, component );
        pms.setPopupMenu();

    }

    public static int getCount() {

        int count = 0;
        try {
            count = MyObservable.getInstance().getCount();
        } catch ( Exception ex ) {
            ex.printStackTrace();
        }

        return count;
    }

}
::::::::::::::
MainPane.java
::::::::::::::
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;

import javax.swing.*;
import java.io.*;
import java.util.*;

/**
$Id: FD.html,v 1.1 2009/06/22 16:11:43 kishi Exp kishi $
*/

public class MainPane extends JScrollPane implements Observer {

    private FormPanel formPanel = null;

    public MainPane() {
        super();
        setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_ALWAYS );

        setToolTipText( "ここにコンポーネントを配置していきます" );

        setPreferredSize( new Dimension( 960, 720 ) );
    }

    /**
    * ペインにフォームを追加する
    */
    private void addFormPanel() {

        formPanel = new FormPanel();
        formPanel.setEditable( true );

        getViewport().add( formPanel );
    }

    private void removeFormPanel() {
        if ( formPanel != null ) {
            getViewport().remove( formPanel );
            formPanel = null;
        }
    }

    /**
    * 既に登録されたフォームの呼び出し
    */
    private void loadFormPanel() {

        formPanel = FormDeserializer.deserialize( this );

        if ( formPanel != null ) {
            System.out.println( formPanel );
            formPanel.setEditable( true );
            getViewport().add( formPanel );
        }
    }

    public void update( Observable obj, Object arg ) {

        System.out.println( this.getClass().getName() + ": update()" );
        System.out.println( "メッセージは、" + arg + " です" );

        if ( "CREATE".equals( arg ) ) {
            removeFormPanel();
            addFormPanel();
        }
        if ( "LOAD".equals( arg ) ) {
            removeFormPanel();
            loadFormPanel();
        }
        if ( "SAVE".equals( arg ) ) {
            // 現在編集中のフォーム(自分自身)を引き渡して、シリアライズする
            FormSerializer.serialize( formPanel );
        }

        this.validate();
        this.repaint();
    }


}
::::::::::::::
MouseDraggedEventHandler.java
::::::::::::::
import javax.swing.*;

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

import java.io.*;
/**
$Id: FD.html,v 1.1 2009/06/22 16:11:43 kishi Exp kishi $
@author KISHI Yasuhiro
*/

public class MouseDraggedEventHandler implements MouseMotionListener {

    private JComponent component;
    private Container container;

    public MouseDraggedEventHandler( Container container, JComponent component ) {

        this.container = container;
        this.component = component;
    }

    public void mouseDragged( MouseEvent argEvent ) {

        // System.out.printf( "(%3d,%3d)\n", argEvent.getX() , argEvent.getY() );

        if ( argEvent.getX() < 0 || argEvent.getY() < 0 ) {
            Rectangle objBounds = component.getBounds();

            component.setLocation( objBounds.x + argEvent.getX(), objBounds.y + argEvent.getY() );
        } else {
            Rectangle objBounds = component.getBounds();

            if ( objBounds.x <= objBounds.x + argEvent.getX() && objBounds.x + argEvent.getX() <= objBounds.x + objBounds.width &&
                    objBounds.y <= objBounds.y + argEvent.getY() && objBounds.y + argEvent.getY() <= objBounds.y + objBounds.height ) {

                component.setLocation( objBounds.x + argEvent.getX(), objBounds.y + argEvent.getY() );
            } else {
                component.setLocation( argEvent.getX(), argEvent.getY() );
            }
        }

        container.validate();
        container.repaint();
    }

    public void mouseMoved( MouseEvent argEvent ) { }

}

::::::::::::::
MyMenuBar.java
::::::::::::::
import java.util.*;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/**
* $Id: FD.html,v 1.1 2009/06/22 16:11:43 kishi Exp kishi $
* @author KISHI Yasuhiro
*/

public class MyMenuBar extends JMenuBar {

    public MyMenuBar() {
        super();
        addJMenu();
    }

    /**
    * メニューを追加する
    */
    private void addJMenu() {

        Action action = new MyMenuBarAction();

        JMenu fileMenu = new JMenu( "ファイル" );
        JMenu otherMenu = new JMenu( "その他メニュー" );

        JMenu subMenu1 = new JMenu( "サブメニュー1" );
        JMenu subMenu2 = new JMenu( "サブメニュー2" );
        otherMenu.add( subMenu1 );
        otherMenu.add( subMenu2 );

        // 各メニューアイテムに対してのアクションを指定
        addMenuItem( fileMenu, action, "新規フォーム作成", "CREATE" );
        addMenuItem( fileMenu, action, "既存フォーム読込", "LOAD" );
        addMenuItem( fileMenu, action, "保存(シリアライズ)", "SAVE" );
        addMenuItem( fileMenu, action, "終了", "EXIT" );

        addMenuItem( subMenu1, action, "機能A", "FUNC_A" );
        addMenuItem( subMenu1, action, "機能B", "FUNC_B" );

        addMenuItem( subMenu2, action, "その1", "OTHER_1" );
        addMenuItem( subMenu2, action, "その2", "OTHER_2" );
        addMenuItem( subMenu2, action, "その3", "OTHER_3" );

        this.add( fileMenu );
        this.add( otherMenu );
    }

    private void addMenuItem( JMenu menu, Action action, String description, String commandName ) {
        JMenuItem item = new JMenuItem( description );
        menu.add( item );
        item.setActionCommand( commandName );
        item.addActionListener( action );
    }

}
::::::::::::::
MyMenuBarAction.java
::::::::::::::
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

/**
* $Id: FD.html,v 1.1 2009/06/22 16:11:43 kishi Exp kishi $
* @author KISHI Yasuhiro
*/

public class MyMenuBarAction extends AbstractAction {

    public MyMenuBarAction() {
        super();
    }

    public void actionPerformed( ActionEvent event ) {
        String command = event.getActionCommand();

        // 実行されたコマンドをダンプします
        System.out.println( command );

        if ( "EXIT".equals( command ) ) {
            System.exit( 0 );
        } else {
            try {
                // メッセージをObserverに通知
                MyObservable.getInstance().castUpdateMessage( command );
            } catch ( Exception e ) {
                e.printStackTrace();
            }
        }
    }
}

::::::::::::::
MyObservable.java
::::::::::::::
import java.io.*;
import java.util.*;

/**
* $Id: FD.html,v 1.1 2009/06/22 16:11:43 kishi Exp kishi $
* シングルトンにしなければならない
* This should be singleton
*/

public class MyObservable extends Observable {

    private static MyObservable uniqueInstance = null;

    private static int count = 0;

    public static MyObservable getInstance() throws Exception {
        if ( uniqueInstance == null ) {
            uniqueInstance = new MyObservable();
            System.out.println( uniqueInstance.getClass().getName() + " がインスタンス化されました。" );
        }

        return uniqueInstance;
    }

    public void castUpdateMessage( String message ) {
        setChanged();
        notifyObservers( message );
    }

    public static synchronized int getCount() {
        return ++count;
    }

}

::::::::::::::
MySerFileFilter.java
::::::::::::::
import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.filechooser.*;

import java.io.*;

/**
$Id: FD.html,v 1.1 2009/06/22 16:11:43 kishi Exp kishi $
@author KISHI Yasuhiro
*/

public class MySerFileFilter extends javax.swing.filechooser.FileFilter {
    // java.io.FileFilterと名前が衝突するので注意!

    public boolean accept( java.io.File f ) {
        // ディレクトリなら表示
        if ( f.isDirectory() ) {
            return true;
        }
        // ファイルなら拡張子がserのものだけを表示
        String fileName = f.getName();
        int extIndex = fileName.lastIndexOf( "." );
        if ( extIndex >= 0 ) {
            if ( fileName.substring( extIndex ).equals( ".ser" ) ) {
                return true;
            }
        }
        return false;
    }

    public String getDescription() {
        return "シリアライズされたファイル(*.ser)";
    }

}

::::::::::::::
PopupMenuSetter.java
::::::::::::::
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;

import javax.swing.*;
import java.io.*;
import java.util.*;

/**
* $Id: FD.html,v 1.1 2009/06/22 16:11:43 kishi Exp kishi $
* @author KISHI Yasuhiro
*/

public class PopupMenuSetter {

    private FormPanel panel = null;
    private JComponent component = null;
    private JPopupMenu popup = null;

    public PopupMenuSetter( FormPanel panel, JComponent component ) {
        this.panel = panel;
        this.component = component;
    }
    public void setPopupMenu() {

        popup = new JPopupMenu();
        popup.setBackground( Color.yellow );

        addMenuItem( "プロパティ変更", "MODIFY_PROP" );
        addMenuItem( "■削除", "KILL_ITSELF" );

        component.addMouseListener( new MouseAdapter() {
                                        public void mousePressed( MouseEvent e ) {
                                            if ( e.isPopupTrigger() ) {
                                                /* JPopupMenuを表示 */
                                                popup.show( e.getComponent(), e.getX(), e.getY() );
                                            }
                                        }

                                        public void mouseReleased( MouseEvent e ) {
                                            if ( e.isPopupTrigger() ) {
                                                /* JPopupMenuを表示 */
                                                popup.show( e.getComponent(), e.getX(), e.getY() );
                                            }
                                        }
                                    }
                                  );

    }

    /** ポップアップメニューにメニューアイテムを追加する */
    private void addMenuItem( String text, String commandName ) {
        JMenuItem menuItem = new JMenuItem( text );
        menuItem.setBackground( Color.green );
        menuItem.setActionCommand( commandName );
        menuItem.addActionListener( new MyAction() );
        popup.add( menuItem );
    }

    /**
    * アクションクラス
    */
    private class MyAction extends AbstractAction {

        public MyAction() {
            super();
        }
        public void actionPerformed( ActionEvent event ) {
            String command = event.getActionCommand();

            // 実行されたコマンドをダンプします
            System.out.println( command );

            if ( command.equals( "KILL_ITSELF" ) ) {
                // 親オブジェクトからこのインスタンスを削除する
                panel.remove( component );

                // このメソッドを呼ばないと即時に反映されないので必ず再描画する!
                panel.validate();
                panel.repaint();

            }
            if ( command.equals( "MODIFY_PROP" ) ) {
                // プロパティを設定するためのサブウィンドウを表示する
                int xPos = component.getX() + 10;
                int yPos = component.getY() + 10;
                new PropertyEditor( xPos, yPos, panel, component );
            }

        }

    }
}

::::::::::::::
PropertyEditor.java
::::::::::::::
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

import java.util.*;

/**
* $Id: FD.html,v 1.1 2009/06/22 16:11:43 kishi Exp kishi $
*/
public class PropertyEditor extends JFrame implements ActionListener {

    private JComponent component = null;
    private FormPanel formPanel = null;
    /**
    * 共通タグ名入力用のテキストフィールド
    */
    private JTextField nameTF = null;
    /**
    * JButtonやJLabelで表示する文字列
    */
    private JTextField descriptionTF = null;

    public PropertyEditor( int xPos, int yPos, FormPanel formPanel, JComponent component ) {

        super( "コンポーネントのプロパティ編集" );
        setBounds( xPos, yPos, 480, 600 );

        this.formPanel = formPanel;
        this.component = component;

        JPanel panel = new JPanel();
        panel.setPreferredSize( new Dimension( 300, 100 ) );
        panel.setLayout( new GridLayout( 4, 2 ) );

        //----------------------------------------------------------
        // 1行目
        //----------------------------------------------------------
        JLabel label1 = new JLabel( "コンポーネントの種別", JLabel.RIGHT );
        panel.add( label1 );

        String componentTypeName = component.getClass().getName();
        JTextField tf1 = new JTextField( 10 );
        tf1.setText( componentTypeName );
        tf1.setEnabled( false );
        panel.add( tf1 );

        //----------------------------------------------------------
        // 2行目
        //----------------------------------------------------------
        JLabel label2 = new JLabel( "共通タグ名", JLabel.RIGHT );
        panel.add( label2 );

        nameTF = new JTextField( 10 );
        // コンポーネントに名称が設定されている場合は、初期値として表示
        Map componentMap = formPanel.getComponentMap();
        if ( componentMap != null && componentMap.containsKey( component ) ) {
            nameTF.setText( ( String ) componentMap.get( component ) );
        }
        panel.add( nameTF );

        //----------------------------------------------------------
        // 4行目
        //----------------------------------------------------------
        JLabel label3 = new JLabel( "テキスト", JLabel.RIGHT );
        panel.add( label3 );

        descriptionTF = new JTextField( 10 );

        //
        // もう少し綺麗に書きたい
        //
        if ( component instanceof JButton ) {
            descriptionTF.setText( ( ( JButton ) component ).getText() );
        } else if ( component instanceof JLabel ) {
            descriptionTF.setText( ( ( JLabel ) component ).getText() );
        } else {
            // 使用不可にする
            descriptionTF.setEnabled( false );
        }
        panel.add( descriptionTF );

        //----------------------------------------------------------
        // 4行目
        //----------------------------------------------------------
        JLabel label4 = new JLabel( "", JLabel.RIGHT );
        panel.add( label4 );

        JButton submit = new JButton( "更新" );
        submit.addActionListener( this );
        submit.setActionCommand( "SUBMIT" );
        panel.add( submit );

        //----------------------------------------------------------
        // パネルをコンテナに配置
        //----------------------------------------------------------
        Container container = getContentPane();
        container.add( panel );

        setVisible( true );
        pack();
    }

    public void actionPerformed( ActionEvent event ) {
        String command = event.getActionCommand();

        if ( "SUBMIT".equals( command ) ) {
            // コンポーネントの共通タグ名を更新する
            formPanel.putComponentMap( component, nameTF.getText() );

            // JButtonあるいはJLabelの場合は、テキストを更新する
            if ( component instanceof JButton ) {
                ( ( JButton ) component ).setText( descriptionTF.getText() );
            } else if ( component instanceof JLabel ) {
                ( ( JLabel ) component ).setText( descriptionTF.getText() );
            } else {
                /** Do nothing */
            }

            // ウィンドウを閉じる
            this.dispose();
        }
    }


}
戻る inserted by FC2 system