XMLで表現されたGUIテンプレートを作成してみる

戻る

これが生成されたGUI定義XMLファイルのサンプルです。





::::::::::::::
ComponentPropertySetter.java
::::::::::::::
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;

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

import java.util.*;

/**
* $Id: GUI-template.html,v 1.1 2009/06/22 16:11:44 kishi Exp kishi $
*/

public class ComponentPropertySetter {

    /**
    * 生成したコンポーネントにプロパティを与える
    * @param node DOMツリー上のノード
    * @param component コンポーネント
    */
    public static void setProperties( Node node, JComponent component ) {

        int x = 0, y = 0;
        int width = 0, height = 0;
        boolean isOpaque = true;

        // 子要素のリストを取得
        Node childNode = node.getFirstChild();

        while ( childNode != null ) {
            String nodeName = childNode.getNodeName();

            if ( nodeName.equals( "text" ) ) {
                String text = childNode.getFirstChild().getNodeValue();
                System.out.println( text );
                if ( component instanceof javax.swing.AbstractButton ) {
                    ( ( javax.swing.AbstractButton ) component ).setText( text );
                }
                if ( component instanceof javax.swing.JLabel	) {
                    ( ( javax.swing.JLabel ) component ).setText( text );
                }
            }

            if ( "x".equals( nodeName ) ) {
                String nodeValue = childNode.getFirstChild().getNodeValue();
                x = new Integer( nodeValue ).intValue();
            }
            if ( "y".equals( nodeName ) ) {
                String nodeValue = childNode.getFirstChild().getNodeValue();
                y = new Integer( nodeValue ).intValue();
            }
            if ( "width".equals( nodeName ) ) {
                String nodeValue = childNode.getFirstChild().getNodeValue();
                width = new Integer( nodeValue ).intValue();
            }
            if ( "height".equals( nodeName ) ) {
                String nodeValue = childNode.getFirstChild().getNodeValue();
                height = new Integer( nodeValue ).intValue();
            }

            if ( "isOpaque".equals( nodeName ) ) {
                String nodeValue = childNode.getFirstChild().getNodeValue();
                isOpaque = new Boolean( nodeValue ).booleanValue();
            }

            if ( "foregroundColor".equals( nodeName )
                    || "backgroundColor".equals( nodeName ) ) {
                setColor( nodeName, childNode, component );
            }

            // 次の要素へ
            childNode = childNode.getNextSibling();

        }

        component.setBounds( x, y, width, height );
        component.setOpaque( isOpaque );
    }

    private static void setColor( String ForB, Node node, JComponent component ) {

        int red = 0, green = 0, blue = 0;

        // 子要素のリストを取得
        Node childNode = node.getFirstChild();
        while ( childNode != null ) {
            String nodeName = childNode.getNodeName();
            String nodeValue = childNode.getFirstChild().getNodeValue();

            if ( "red".equals( nodeName ) ) {
                red = new Integer( nodeValue ).intValue();
            }
            if ( "green".equals( nodeName ) ) {
                green = new Integer( nodeValue ).intValue();
            }
            if ( "blue".equals( nodeName ) ) {
                blue = new Integer( nodeValue ).intValue();
            }
            // 次の要素へ
            childNode = childNode.getNextSibling();

        }
        if ( "foregroundColor".equals( ForB ) ) {
            component.setForeground( new Color( red, green, blue ) );
        }
        if ( "backgroundColor".equals( ForB ) ) {
            component.setBackground( new Color( red, green, blue ) );
        }

        System.out.printf( "%s -- %3d, %3d, %3d\n", ForB, red, green, blue );

    }


}
::::::::::::::
DocEditPanel.java
::::::::::::::
import java.awt.*;
import java.awt.event.*;
import java.awt.dnd.*;
import java.awt.geom.*;
import java.awt.image.*;

import javax.imageio.*;

import javax.swing.event.*;
import javax.swing.*;
import javax.swing.border.*;

import java.io.*;
import java.util.*;
import java.net.*;

/**
* $Id: GUI-template.html,v 1.1 2009/06/22 16:11:44 kishi Exp kishi $
* @author KISHI Yasuhiro
*/

public class DocEditPanel extends JPanel {

    /**
        * 背景イメージ
        */
    private Image image;
    private String bgImageURL = null;

    private Color bgColor = Color.white;

    public DocEditPanel() {

        super();
        setLayout( null );

        TemplateLoader loader = null;
        // コンポートのインスタンスを取り出す
        try {
            loader = new TemplateLoader( "../bin/component-def.xml" );
            Map<String, JComponent> map = loader.getComponentMap();

            Iterator iterator = map.keySet().iterator();
            while ( iterator.hasNext() ) {
                String tagName = ( String ) iterator.next();
                JComponent component = map.get( tagName );

                this.add( component );
            }


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

        // 背景画像のURL
        bgImageURL = loader.getBgImageURL();
        if ( bgImageURL != null ) {
            try {
                System.out.println( "読み取り中・・・" );
                image = ImageIO.read( new URL( bgImageURL ) );
                System.out.println( "完了しました!" );
            } catch ( IOException ex ) {
                ex.printStackTrace();
            }
        }
    }

    public void paintComponent( Graphics g ) {

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

        g.setColor( bgColor );

        // 背景色で全て塗りつぶす
        g.fillRect( 0 , 0 , width , height );

        if ( image != null ) {
            Graphics2D g2 = ( Graphics2D ) g;
            g2.drawImage( image, 0, 0, this );
        }
    }
}
::::::::::::::
DocEditor.java
::::::::::::::
import java.awt.*;
import java.awt.event.*;
import java.awt.dnd.*;
import java.awt.geom.*;
import java.awt.image.*;

import javax.imageio.*;

import javax.swing.event.*;
import javax.swing.*;
import javax.swing.border.*;

import java.io.*;

/**
* $Id: GUI-template.html,v 1.1 2009/06/22 16:11:44 kishi Exp kishi $
* @author KISHI Yasuhiro
*/

public class DocEditor extends JFrame {

    public DocEditor() {
        super( "Doc作成画面" );

        setLayout( new FlowLayout() );

        try {
            // 外観を設定します
            UIManager.setLookAndFeel( "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" );
            // 外観を変更します
            SwingUtilities.updateComponentTreeUI( this );
        } catch ( Exception e ) {
            e.printStackTrace();
            System.exit( -1 );
        }

        setBackground( Color.white );

        DocEditPanel dePanel = new DocEditPanel();
        dePanel.setPreferredSize( new Dimension( 640, 480 ) );

        Container container = getContentPane();
        container.add( dePanel, BorderLayout.CENTER );

        setVisible( true );
        pack();

        addWindowListener( new WindowAdapter() {
                               public void windowClosing( WindowEvent event ) {
                                   dispose();
                                   System.exit( 0 );
                               }
                           }
                         );

    }

    public static void main( String[] args ) {

        new DocEditor();
    }

}

::::::::::::::
MenuPanel.java
::::::::::::::
import java.awt.*;
import java.awt.event.*;
import java.awt.dnd.*;
import java.awt.geom.*;
import java.awt.image.*;

import javax.imageio.*;

import javax.swing.event.*;
import javax.swing.*;
import javax.swing.border.*;

import java.io.*;
import java.util.*;
import java.net.*;

/**
* $Id: GUI-template.html,v 1.1 2009/06/22 16:11:44 kishi Exp kishi $
* @author KISHI Yasuhiro
*/

public class MenuPanel extends JPanel {

    public MenuPanel() {
        super();
    }


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

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

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

public class MouseDraggedEventHandler implements MouseMotionListener {

    private JComponent component;
    private Container container;

    /**
    * @param container コンテナ
    * @param component コンポーネント
    */
    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 ) { }

}

::::::::::::::
Proto1.java
::::::::::::::
import java.awt.*;
import java.awt.event.*;
import java.awt.dnd.*;
import java.awt.geom.*;
import java.awt.image.*;

import javax.imageio.*;

import javax.swing.event.*;
import javax.swing.*;
import javax.swing.border.*;

import java.io.*;

/**
* $Id: GUI-template.html,v 1.1 2009/06/22 16:11:44 kishi Exp kishi $
* @author KISHI Yasuhiro
*/

public class Proto1 extends JFrame {

    public Proto1() {
        super( "配置したコンポーネントの内容を全てXMLにて出力する" );

        setLayout( new FlowLayout() );

        try {
            // 外観を設定します
            UIManager.setLookAndFeel( "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" );
            // 外観を変更します
            SwingUtilities.updateComponentTreeUI( this );
        } catch ( Exception e ) {
            e.printStackTrace();
            System.exit( -1 );
        }

        setBackground( Color.white );

        //---------------------------------------------------------------
        // テンプレート用のパネルを追加
        //---------------------------------------------------------------
        TemplateEditPanel tPanel = new TemplateEditPanel();
        tPanel.setPreferredSize( new Dimension( 640, 480 ) );

        Container container = getContentPane();
        container.add( new MenuPanel(), BorderLayout.NORTH );
        container.add( tPanel, BorderLayout.CENTER );
        container.add( new StatusPanel(), BorderLayout.SOUTH );

        setVisible( true );
        pack();

        addWindowListener( new WindowAdapter() {
                               public void windowClosing( WindowEvent event ) {
                                   dispose();
                                   System.exit( 0 );
                               }
                           }
                         );

    }

    public static void main( String[] args ) {

        new Proto1();
    }

}
::::::::::::::
StatusPanel.java
::::::::::::::
import java.awt.*;
import java.awt.event.*;
import java.awt.dnd.*;
import java.awt.geom.*;
import java.awt.image.*;

import javax.imageio.*;

import javax.swing.event.*;
import javax.swing.*;
import javax.swing.border.*;

import java.io.*;
import java.util.*;
import java.net.*;

/**
* $Id: GUI-template.html,v 1.1 2009/06/22 16:11:44 kishi Exp kishi $
* @author KISHI Yasuhiro
*/

public class StatusPanel extends JPanel {

    public StatusPanel() {
        super();
    }


}

::::::::::::::
TemplateEditPanel.java
::::::::::::::
import java.awt.*;
import java.awt.event.*;
import java.awt.dnd.*;
import java.awt.geom.*;
import java.awt.image.*;

import javax.imageio.*;

import javax.swing.event.*;
import javax.swing.*;
import javax.swing.border.*;

import java.io.*;
import java.util.*;
import java.net.*;

/**
* $Id: GUI-template.html,v 1.1 2009/06/22 16:11:44 kishi Exp kishi $
* @author KISHI Yasuhiro
*/

public class TemplateEditPanel extends JPanel {

    /**
    * XMLファイル
    */
    private final String xmlFile = "component-def.xml";

    /**
    * 背景イメージ
    */
    private Image image;

    private Color bgColor = Color.white;

    public TemplateEditPanel() {
        super();
        setLayout( null );

        TemplateSaver saver = new TemplateSaver( xmlFile, this );

        //////////////////////////////////////////////
        // ボタン
        //////////////////////////////////////////////
        JButton button1 = new JButton( "ボタン1" );
        button1.setBounds( 200, 200, 100, 100 );
        button1.setBackground( Color.cyan );
        saver.addComponent( "共通タグA", button1 );
        button1.addMouseMotionListener( new MouseDraggedEventHandler( this, button1 ) );

        //////////////////////////////////////////////
        // ラベル(不透明)
        //////////////////////////////////////////////
        JLabel label1 = new JLabel( "***ラベル1" );
        label1.setBounds( 300, 50, 100, 100 );
        label1.setBackground( Color.yellow );
        // 透明にしない
        label1.setOpaque( true );
        saver.addComponent( "リテラルB", label1 );
        label1.addMouseMotionListener( new MouseDraggedEventHandler( this, label1 ) );

        //////////////////////////////////////////////
        // ラベル(透明)
        //////////////////////////////////////////////
        JLabel label2 = new JLabel( "ケンブリッジ・オックスフォード・マサチューセッツ株式会社" );
        label2.setBounds( 220, 400, 400, 50 );
        label2.setBackground( new Color( 0xff, 0xff, 0xff ) );
        // 透明にする
        label2.setOpaque( false );
        saver.addComponent( "事業体名", label2 );

        label2.addMouseMotionListener( new MouseDraggedEventHandler( this, label2 ) );

        // 外部イメージURL
        URL imageURL = null;
        try {
            imageURL = new URL( "http://cponrally.typepad.jp/blog/images/daishi.gif" );
            image = ImageIO.read( imageURL );
        } catch ( IOException ex ) {
            ex.printStackTrace();
        }
        if ( imageURL != null ) {
            saver.addBackgroundImage( imageURL );
        }

        // XMLに出力します
        try {
            saver.writeToXML();
        } catch ( Exception e ) {
            e.printStackTrace();
        }
    }

    public void paintComponent( Graphics g ) {

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

        g.setColor( bgColor );

        // 背景色で全て塗りつぶす
        g.fillRect( 0 , 0 , width , height );

        if ( image != null ) {
            Graphics2D g2 = ( Graphics2D ) g;
            g2.drawImage( image, 0, 0, this );
        }
    }
}
::::::::::::::
TemplateLoader.java
::::::::::::::
import javax.xml.parsers.*;
import org.w3c.dom.*;
import java.io.*;

import javax.swing.*;

import java.util.*;

/**
* $Id: GUI-template.html,v 1.1 2009/06/22 16:11:44 kishi Exp kishi $
* DOMを使ってXML内の全要素の属性、値を取得
*/

public class TemplateLoader {

    private Map<String, JComponent> componentMap = null;
    private String bgImageURL = null;

    /**
    * @param fileName テンプレート情報を記述したファイル
    */
    public TemplateLoader( String fileName ) throws Exception {

        componentMap = new LinkedHashMap();

        try {
            // ドキュメントビルダーファクトリを生成
            DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();

            // ドキュメントビルダーを生成
            DocumentBuilder builder = dbfactory.newDocumentBuilder();

            // パースを実行してDocumentオブジェクトを取得
            Document document = builder.parse( new File( fileName ) );

            Node node = document.getDocumentElement();
            traverse( node );

        } catch ( Exception e ) {
            throw e;
        }
    }

    private void traverse( Node node ) {

        // 子要素のリストを取得
        Node childNode = node.getFirstChild();

        while ( childNode != null ) {
            String nodeName = childNode.getNodeName();

            if ( nodeName.equals( "bgImageURL" ) ) {
                bgImageURL = childNode.getFirstChild().getNodeValue();
                System.out.println( bgImageURL );
            }

            if ( nodeName.equals( "component" ) ) {

                // getAttribute()はElementクラスが持つメソッドなのでキャストする必要がある
                String tagName = ( ( Element ) childNode ).getAttribute( "tagName" );
                String type = ( ( Element ) childNode ).getAttribute( "type" );

                System.out.println( tagName + " : " + type );

                createComponentMap( childNode, tagName, type );
            }

            // 次の要素へ
            childNode = childNode.getNextSibling();

        }
    }

    /**
    * @param node DOMツリー上のノード
    * @param tagName 共通タグ名 
    * @param type クラス名
    */
    private void createComponentMap( Node node, String tagName, String type ) {
        try {
            // インスタンス化
            JComponent component = ( JComponent ) Class.forName( type ).newInstance();

            // コンポーネントのマップ
            componentMap.put( tagName, component );

            ComponentPropertySetter.setProperties( node, component );

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

    public Map getComponentMap() {
        return componentMap;
    }

    public String getBgImageURL() {
        return bgImageURL;
    }

    public static void main( String[] args ) throws Exception {

        TemplateLoader loader = new TemplateLoader( "../bin/component-def.xml" );
        Map<String, JComponent> map = loader.getComponentMap();

        Iterator iterator = map.keySet().iterator();
        while ( iterator.hasNext() ) {
            String tagName = ( String ) iterator.next();
            JComponent component = map.get( tagName );

            System.out.print( "【" + tagName + "】" );
            System.out.println( component );

            System.out.println();
        }

        System.out.println();
        System.out.println( "背景画像のURL=" + loader.getBgImageURL() );

    }
}

::::::::::::::
TemplateSaver.java
::::::::::::::
import java.awt.*;
import java.awt.event.*;
import java.awt.dnd.*;
import java.awt.geom.*;
import java.awt.image.*;

import javax.imageio.*;

import javax.swing.event.*;
import javax.swing.*;
import javax.swing.border.*;

import java.io.*;
import java.util.*;
import java.net.*;

/**
* $Id: GUI-template.html,v 1.1 2009/06/22 16:11:44 kishi Exp kishi $
* @author KISHI Yasuhiro
*/

public class TemplateSaver {
    private final String DOUBLE_QUOTE = "\"";

    /**
    * テンプレートを格納するパネル
    */
    private TemplateEditPanel panel;

    private URL imageURL = null;
    /**
    * 出力先XML
    */
    private String xmlFile;

    /**
    * 共通タグ名とコンポートネントを格納するMAP
    */
    private Map<String, JComponent> componentMap = null;

    /**
    * @param xmlFile 出力XMLファイル名
    * @param panel テンプレートを格納するパネル
    */
    public TemplateSaver( String xmlFile, TemplateEditPanel panel ) {
        this.xmlFile = xmlFile;
        this.panel = panel;
        componentMap = new LinkedHashMap();
    }

    /**
    * @param tagName 共通タグ名
    * @param component コンポーネント
    */
    public void addComponent( String tagName, JComponent component ) {

        panel.add( component );

        componentMap.put( tagName, component );
    }

    /**
    * @param imageURL 背景画像のURLをセットする
    */
    public void addBackgroundImage( URL imageURL ) {
        this.imageURL = imageURL;
    }

    /**
    * XMLとしてファイル出力する
    */
    public void writeToXML() throws Exception {
        // BufferedWriter writer = new BufferedWriter( new OutputStreamWriter( System.out ) );
        BufferedWriter writer = new BufferedWriter( new FileWriter( xmlFile ) );

        writer.write( "<?xml version=" + sandwich( "1.0" ) + " encoding=" + sandwich( "Shift_JIS" ) + " ?>" );
        writer.write( "<template>" );

        // 背景で使用する画像URL
        writeBackgroundImageURL( imageURL , writer );

        Iterator iterator = componentMap.keySet().iterator();
        while ( iterator.hasNext() ) {
            String tagName = ( String ) iterator.next();
            JComponent component = componentMap.get( tagName );

            writeComponentBegin( tagName, component, writer );
            writeTextElement( component, writer );
            writeBounds( component, writer );
            writeColor( component, writer );
            writeComponentEnd( component, writer );

        }
        writer.write( "</template>" );

        writer.flush();
    }

    private void writeColor( JComponent component, Writer writer ) throws Exception {
        Color fgColor = component.getForeground();
        Color bgColor = component.getBackground();

        writer.write( "<isOpaque>" );
        writer.write( new Boolean( component.isOpaque() ).toString() );
        writer.write( "</isOpaque>" );

        writer.write( "<foregroundColor>" );
        printColor( fgColor, writer );
        writer.write( "</foregroundColor>" );

        writer.write( "<backgroundColor>" );
        printColor( bgColor, writer );
        writer.write( "</backgroundColor>" );
    }

    private void printColor( Color color, Writer writer ) throws Exception {

        int R = color.getRed();
        int G = color.getGreen();
        int B = color.getBlue();

        writer.write( "<red>" );
        writer.write( new Integer( R ).toString() );
        writer.write( "</red>" );
        writer.write( "<green>" );
        writer.write( new Integer( G ).toString() );
        writer.write( "</green>" );
        writer.write( "<blue>" );
        writer.write( new Integer( B ).toString() );
        writer.write( "</blue>" );
    }

    private void writeBackgroundImageURL( URL imageURL, Writer writer ) throws Exception {
        writer.write( "<bgImageURL>" + imageURL.toString() + "</bgImageURL>" );
    }

    private void writeTextElement( JComponent component, Writer writer ) throws Exception {
        if ( component instanceof javax.swing.AbstractButton ) {
            writer.write( "<text>" + ( ( javax.swing.AbstractButton ) component ).getText() + "</text>" );
        }
        if ( component instanceof javax.swing.JLabel ) {
            writer.write( "<text>" + ( ( javax.swing.JLabel ) component ).getText() + "</text>" );
        }
    }

    /**
    * コンポーネントの位置とサイズを取得して書き出す
    * @param component 対象となるコンポーネント
    * @param writer 出力先
    */
    private void writeBounds( JComponent component, Writer writer ) throws Exception {
        int width = component.getWidth();
        int height = component.getHeight();
        int x = component.getX();
        int y = component.getY();

        writer.write( "<x>" + x + "</x>" );
        writer.write( "<y>" + y + "</y>" );
        writer.write( "<width>" + width + "</width>" );
        writer.write( "<height>" + height + "</height>" );
    }

    private void writeComponentBegin( String tagName, JComponent component, Writer writer ) throws Exception {
        writer.write( "<component tagName="
                      + sandwich( tagName )
                      + " type=" + sandwich( component.getClass().getName() ) );
        writer.write( ">" );

    }
    private void writeComponentEnd( JComponent component, Writer writer ) throws Exception {
        writer.write( "</component>" );
    }

    /**
    * @param source 入力文字列
    * ダブルクォートで文字列を挟んだ結果を返す
    */
    private String sandwich( String source ) {
        return DOUBLE_QUOTE + source + DOUBLE_QUOTE;
    }

}

戻る inserted by FC2 system