@634

JFC の おえかき。改訂版

Advertisement

Swing + Java2D

目標:コードの可読性の向上
機能は減ったけど、コード読みやすくなった(当社比)
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.io.*;
import java.util.*;
import javax.swing.*;

public class JfcPaint{
    public static void main(String[] args){
        JDialog.setDefaultLookAndFeelDecorated(true);
        JFrame.setDefaultLookAndFeelDecorated(true);

        // Look&Feel 設定
        try {
            javax.swing.plaf.metal.MetalLookAndFeel.setCurrentTheme(
                    new javax.swing.plaf.metal.DefaultMetalTheme());
            UIManager.setLookAndFeel(
                  "javax.swing.plaf.metal.MetalLookAndFeel");
        }catch (Exception e){
            e.getMessage();
            System.exit(0);
        }

        MyFrame mf = new MyFrame();
        mf.setTitle("ペイント");
        mf.setSize(400, 400);
        mf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mf.show();
    }
}

// フレームを管理するクラス
class MyFrame extends JFrame implements ActionListener{
    private JMenuBar menuBar;
    private JToolBar toolBar;
    private JColorChooser drawColorChooser;
    private JFileChooser fileChooser;
    private MyPanel panel;

    public MyFrame(){
        panel = new MyPanel();
        // レイアウト設定
        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(panel, "Center");

        // ツールバー設定
        getContentPane().add(createToolBar(), "South");

        // メニューバー設定
        setJMenuBar(createMenuBar());
    }

    // ツールバーを作るメソッド
    private JToolBar createToolBar(){
        toolBar = new JToolBar();
        toolBar.add(createButton("/", "figureLine"));
        toolBar.add(createButton("□", "figureRectangle"));
        toolBar.add(createButton("○", "figureEllipse"));
        toolBar.add(createButton("■", "figureFillRectangle"));
        toolBar.add(createButton("●", "figureFillEllipse"));
        return toolBar;
    }

    // ボタン作り
    private JButton createButton(String title, String cmd){
        JButton button = new JButton(title);
        button.setActionCommand(cmd);
        button.addActionListener(this);
        return button;
    }

    // メニュー作り
    private JMenu createMenu(String title, String cmd){
        JMenu menu = new JMenu(title);
        menu.setActionCommand(cmd);
        menu.addActionListener(this);
        return menu;
    }

    // メニューアイテム作り
    private JMenuItem createMenuItem(String title, String cmd){
        JMenuItem item = new JMenuItem(title);
        item.setActionCommand(cmd);
        item.addActionListener(this);
        return item;
    }

    // チェックボックスのメニューアイテム作り
    private JCheckBoxMenuItem createCheckBoxMenuItem(String title, String cmd){
        JCheckBoxMenuItem citem = new JCheckBoxMenuItem(title);
        citem.setActionCommand(cmd);
        citem.addActionListener(this);
        return citem;
    }

    // チェックボックスのメニューアイテム作り2
    private JCheckBoxMenuItem createCheckBoxMenuItem(String title, String cmd,
                                                     boolean checked){
        JCheckBoxMenuItem citem = new JCheckBoxMenuItem(title, checked);
        citem.setActionCommand(cmd);
        citem.addActionListener(this);
        return citem;
    }

    // ラジオボタンのメニューアイテム作り
    private JRadioButton createRadioButton(String title, String cmd){
        JRadioButton rbutton = new JRadioButton(title);
        rbutton.setActionCommand(cmd);
        rbutton.addActionListener(this);
        return rbutton;
    }

    // ラジオボタンのメニューアイテム作り2
    private JRadioButton createRadioButton(String title, String cmd,
                                           boolean selected){
        JRadioButton rbutton = new JRadioButton(title, selected);
        rbutton.setActionCommand(cmd);
        rbutton.addActionListener(this);
        return rbutton;
    }

    // ラジオボタンのメニューアイテム作り3
    private JRadioButton createRadioButton(String title, String cmd,
                                boolean selected, ButtonGroup group){
        JRadioButton rbutton = new JRadioButton(title, selected);
        rbutton.setActionCommand(cmd);
        rbutton.addActionListener(this);
        group.add(rbutton);
        return rbutton;
    }

    // メニューバー作り
    private JMenuBar createMenuBar(){
        menuBar = new JMenuBar();
        JMenu menu;
        JMenu w_menu;

        menu = createMenu("ファイル", "file");
        menu.add(createMenuItem("開く", "open"));
        menu.add(createMenuItem("保存", "save"));
        menu.add(new JSeparator());
        menu.add(createMenuItem("終了", "quit"));
        menuBar.add(menu);

        menu = createMenu("編集", "edit");
        menu.add(createMenuItem("画面消去", "clear"));
        menuBar.add(menu);

        menu = createMenu("設定", "conf");
        w_menu = createMenu("図形", "figure");
        w_menu.add(createMenuItem("直線", "figureLine"));
        w_menu.add(createMenuItem("矩形", "figureRectangle"));
        w_menu.add(createMenuItem("楕円", "figureEllipse"));
        w_menu.add(createMenuItem("矩形(塗りつぶし)", "figureFillRectangle"));
        w_menu.add(createMenuItem("楕円(塗りつぶし)", "figureFillEllipse"));
        menu.add(w_menu);
        w_menu = createMenu("線の太さ", "lineBold");
        w_menu.add(createMenuItem(" 1px","lineBold1"));
        w_menu.add(createMenuItem(" 2px","lineBold2"));
        w_menu.add(createMenuItem(" 3px","lineBold3"));
        w_menu.add(createMenuItem(" 4px","lineBold4"));
        w_menu.add(createMenuItem(" 5px","lineBold5"));
        w_menu.add(createMenuItem(" 6px","lineBold6"));
        w_menu.add(createMenuItem(" 7px","lineBold7"));
        w_menu.add(createMenuItem(" 8px","lineBold8"));
        w_menu.add(createMenuItem(" 9px","lineBold9"));
        w_menu.add(createMenuItem("10px","lineBold10"));
        menu.add(w_menu);
        menu.add(new JSeparator());
        menu.add(createMenuItem("描画色選択","drawColor"));
        menu.add(createMenuItem("補助色選択","subColor"));
        menu.add(createMenuItem("背景色選択", "backColor"));
        menu.add(new JSeparator());
        menu.add(createCheckBoxMenuItem("ツールバーの表示", "toolbar",   true));
        menu.add(createCheckBoxMenuItem("アンチエイリアス", "antialias", false));
        menuBar.add(menu);
        menu = createMenu("ヘルプ", "help");
        w_menu = createMenu("Look & Feel", "landf");
        ButtonGroup lfGroup = new ButtonGroup();
        w_menu.add(createRadioButton("metal",   "metal",   true , lfGroup));
        w_menu.add(createRadioButton("motif",   "motif",   false, lfGroup));
        w_menu.add(createRadioButton("windows", "windows", false, lfGroup));
        menu.add(w_menu);
        menu.add(createMenuItem("バージョン情報", "version"));
        menuBar.add(menu);

        return menuBar;
    }

    // 保存
    private void savePicture(){
        fileChooser = MyJFileChooser.getInstance();

        try{
            int returnVal = fileChooser.showSaveDialog(this);
            if(returnVal == JFileChooser.APPROVE_OPTION){
                File file = fileChooser.getSelectedFile();
                FileOutputStream fos = new FileOutputStream(file);
                ObjectOutputStream oos = new ObjectOutputStream(fos);
                oos.writeObject(panel.getVector());
                oos.close();
                fos.close();
            }
        }catch(IOException ioe){
            System.err.println(ioe);
        }
    }

    // 開く
    private void openPicture(){
        fileChooser = MyJFileChooser.getInstance();

        try{
            int returnVal = fileChooser.showOpenDialog(this);
            if(returnVal == JFileChooser.APPROVE_OPTION){
                File file = fileChooser.getSelectedFile();
                FileInputStream fis = new FileInputStream(file);
                ObjectInputStream ois = new ObjectInputStream(fis);
                panel.setVector((Vector)ois.readObject());
                ois.close();
                fis.close();
                panel.repaint();
            }
        }catch(IOException e){
            System.err.println(e);
        }catch(ClassNotFoundException e){
            System.err.println(e);
        }
    }

    // 描画色選択
    private void chooseColor(){
        drawColorChooser = MyJColorChooser.getInstance();
        panel.setColor(drawColorChooser.showDialog(
            this, "描画色選択", panel.getColor()));
    }

    // 補助色選択
    private void chooseSubColor(){
        drawColorChooser = MyJColorChooser.getInstance();
        panel.setSubColor(drawColorChooser.showDialog(
            this, "補助色選択", panel.getSubColor()));
    }

    // 背景色選択
    private void chooseBackColor(){
        drawColorChooser = MyJColorChooser.getInstance();
        panel.setBackground(drawColorChooser.showDialog(
            this, "背景色選択", panel.getBackground()));
    }

    // イベント
    public void actionPerformed(ActionEvent e){
        //ファイルメニュー
        if(e.getActionCommand() == "open"){
            openPicture();
        }else if(e.getActionCommand() == "save"){
            savePicture();
        }else if(e.getActionCommand() == "quit"){
            System.exit(0);
        }

        //編集メニュー
        if(e.getActionCommand() == "clear"){
            panel.setVector(new Vector());
            panel.repaint();
        }

        //設定メニュー
        if(e.getActionCommand() == "figureLine"){
            panel.setFigureFlag(1);
        }else if(e.getActionCommand() == "figureRectangle"){
            panel.setFigureFlag(2);
        }else if(e.getActionCommand() == "figureEllipse"){
            panel.setFigureFlag(3);
        }else if(e.getActionCommand() == "figureFillRectangle"){
            panel.setFigureFlag(4);
        }else if(e.getActionCommand() == "figureFillEllipse"){
            panel.setFigureFlag(5);
        }

        if(e.getActionCommand() == "lineBold1"){
            panel.setLineSize(1);
        }else if(e.getActionCommand() == "lineBold2"){
            panel.setLineSize(2);
        }else if(e.getActionCommand() == "lineBold3"){
            panel.setLineSize(3);
        }else if(e.getActionCommand() == "lineBold4"){
            panel.setLineSize(4);
        }else if(e.getActionCommand() == "lineBold5"){
            panel.setLineSize(5);
        }else if(e.getActionCommand() == "lineBold6"){
            panel.setLineSize(6);
        }else if(e.getActionCommand() == "lineBold7"){
            panel.setLineSize(7);
        }else if(e.getActionCommand() == "lineBold8"){
            panel.setLineSize(8);
        }else if(e.getActionCommand() == "lineBold9"){
            panel.setLineSize(9);
        }else if(e.getActionCommand() == "lineBold10"){
            panel.setLineSize(10);
        }

        if(e.getActionCommand() == "drawColor"){
            chooseColor();
        }else if(e.getActionCommand() == "subColor"){
            chooseSubColor();
        }else if(e.getActionCommand() == "backColor"){
            chooseBackColor();
        }

        if(e.getActionCommand() == "toolbar"){
            toolBar.setVisible(!toolBar.isVisible());
        }

        if(e.getActionCommand() == "antialias"){
            panel.setAntialias(!panel.getAntialias());
            panel.repaint();
        }

        // ヘルプメニュー
        if(e.getActionCommand() == "version"){
            JOptionPane.showMessageDialog(getContentPane(),
                    "おえかき\nバージョン 1.0");
        }else if(e.getActionCommand() == "metal"){
            try{
                UIManager.setLookAndFeel(
                    "javax.swing.plaf.metal.MetalLookAndFeel");
                SwingUtilities.updateComponentTreeUI(this);
            }catch(Exception ex){
                System.out.println("Error L&F Setting");
            }
        }else if(e.getActionCommand() == "motif"){
            try{
                UIManager.setLookAndFeel(
                    "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
                SwingUtilities.updateComponentTreeUI(this);
            }catch(Exception ex){
                System.out.println("Error L&F Setting");
            }
        }else if(e.getActionCommand() == "windows"){
            try{
                UIManager.setLookAndFeel(
                    "com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
                SwingUtilities.updateComponentTreeUI(this);
            }catch(Exception ex){
                System.out.println("Error L&F Setting");
            }
        }
    }
}

// パネル(描画領域)を管理するクラス
class MyPanel extends JPanel implements MouseMotionListener, MouseListener{
    Point start;
    Point end;
    private int figureFlag;
    private boolean antialiasFlag;
    private Color drawColor;
    private Color subColor;
    private float size;
    private Vector figureBox;

    public MyPanel(){
        drawColor = Color.black;
        subColor = Color.cyan;
        antialiasFlag = false;
        figureFlag = 1;
        size = 1.0f;
        figureBox = new Vector();
        start = new Point();
        end = new Point();

        setBackground(Color.white);
        addMouseListener(this);
        addMouseMotionListener(this);
    }

    // 線の太さ設定
    public void setLineSize(float f){
        size = f;
    }

    // 線の太さを返す
    public float getLineSize(){
        return size;
    }

    // アンチエイリアス設定
    public void setAntialias(boolean b){
        antialiasFlag = b;
    }

    // アンチエイリアスモードを返す
    public boolean getAntialias(){
        return antialiasFlag;
    }

    // 図形の種類を設定
    public void setFigureFlag(int n){
        figureFlag = n;
    }

    // 図形の種類を返す
    public int getFigureFlag(){
        return figureFlag;
    }

    // 描画色設定
    public void setColor(Color c){
        drawColor = c;
    }

    // 描画色取得
    public Color getColor(){
        return drawColor;
    }

    // 補助色設定
    public void setSubColor(Color c){
        subColor = c;
    }

    // 補助色を返す
    public Color getSubColor(){
        return subColor;
    }

    // 図形を管理するVectorを設定
    public void setVector(Vector v){
        figureBox = v;
    }

    // 図形を管理するVectorを返す
    public Vector getVector(){
        return figureBox;
    }

    // 描画
    public void paint(Graphics g){
        super.paint(g);

        //情報
        g.setColor(subColor);
        g.fillRect(0, 0, 10, 10);
        g.setColor(Color.black);
        g.drawRect(0, 0, 10, 10);
        g.setColor(drawColor);
        g.fillRect(5, 5, 10, 10);
        g.setColor(Color.black);
        g.drawRect(5, 5, 10, 10);


        Graphics2D g2 = (Graphics2D)g;

        // アンチエイリアス設定
        if(antialiasFlag){
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        }

        // 図形描画
        for(int i = 0; i < figureBox.size(); i++){
            ((Figure)figureBox.elementAt(i)).Draw(g2);
        }
    }

    // マウスドラッグ
    public void mouseDragged(MouseEvent e){
        end.setLocation(e.getX(), e.getY());
        ((Figure)figureBox.lastElement()).setEnd(end);

        repaint();
    }

    // マウスボタン押下
    public void mousePressed(MouseEvent e){
        start.setLocation(e.getX(), e.getY());
        end.setLocation(e.getX(), e.getY());

        switch(figureFlag){
            case 1:
                figureBox.add(new LineData(start, end, drawColor, size));
                break;
            case 2:
                figureBox.add(new RectangleData(start, end, drawColor, size));
                break;
            case 3:
                figureBox.add(new EllipseData(start, end, drawColor, size));
                break;
            case 4:
                figureBox.add(new FillRectangleData(start, end, drawColor, size));
                break;
            case 5:
                figureBox.add(new FillEllipseData(start, end, drawColor, size));
                break;
        }
   }

    public void mouseReleased(MouseEvent e){}
    public void mouseClicked(MouseEvent e){}
    public void mouseMoved(MouseEvent e){}
    public void mouseEntered(MouseEvent e){}
    public void mouseExited(MouseEvent e){}
}

abstract class Figure implements Serializable{
    protected Point start;
    protected Point end;
    protected Color col;
    protected float size;

    public Figure(){};

    public Figure(Point sp, Point ep, Color c, float s){
        start = (Point)sp.clone();
        end = (Point)ep.clone();
        col = c;
        size = s;
    }

    public void setColor(Color c){
        col = c;
    }

    public void setStart(Point s){
        start = (Point)s.clone();
    }

    public void setEnd(Point e){
        end = (Point)e.clone();
    }

    abstract void Draw(Graphics2D g2);
}

class LineData extends Figure{
    public LineData(Point start, Point end, Color c, float s){
        super(start, end, c, s);
    }

    public void Draw(Graphics2D g2){
        g2.setColor(col);
        g2.setStroke(new BasicStroke(size));
        g2.draw(new Line2D.Double(start, end));
    }
}

class RectangleData extends Figure{
    public RectangleData(Point sp, Point ep, Color c, float s){
        super(sp, ep, c, s);
    }

    public void Draw(Graphics2D g2){
        g2.setColor(col);
        g2.setStroke(new BasicStroke(size));
        g2.draw(new Rectangle2D.Double(
                       start.getX()<end.getX()?start.getX():end.getX(),
                       start.getY()<end.getY()?start.getY():end.getY(),
                       Math.abs(start.getX()-end.getX()),
                       Math.abs(start.getY()-end.getY())));
    }
}

class EllipseData extends Figure{
    public EllipseData(Point sp, Point ep, Color c, float s){
        super(sp, ep, c, s);
    }

    public void Draw(Graphics2D g2){
        g2.setColor(col);
        g2.setStroke(new BasicStroke(size));
        g2.draw(new Ellipse2D.Double(
                       start.getX()<end.getX()?start.getX():end.getX(),
                       start.getY()<end.getY()?start.getY():end.getY(),
                       Math.abs(start.getX()-end.getX()),
                       Math.abs(start.getY()-end.getY())));
    }
}

class FillRectangleData extends Figure{
    public FillRectangleData(Point sp, Point ep, Color c, float s){
        super(sp, ep, c, s);
    }

    public void Draw(Graphics2D g2){
        g2.setColor(col);
        g2.setStroke(new BasicStroke(size));
        g2.fill(new Rectangle2D.Double(
                       start.getX()<end.getX()?start.getX():end.getX(),
                       start.getY()<end.getY()?start.getY():end.getY(),
                       Math.abs(start.getX()-end.getX()),
                       Math.abs(start.getY()-end.getY())));
    }
}

class FillEllipseData extends Figure{
    public FillEllipseData(Point sp, Point ep, Color c, float s){
        super(sp, ep, c, s);
    }

    public void Draw(Graphics2D g2){
        g2.setColor(col);
        g2.setStroke(new BasicStroke(size));
        g2.fill(new Ellipse2D.Double(
                       start.getX()<end.getX()?start.getX():end.getX(),
                       start.getY()<end.getY()?start.getY():end.getY(),
                       Math.abs(start.getX()-end.getX()),
                       Math.abs(start.getY()-end.getY())));
    }
}

final class MyJFileChooser{
    private static JFileChooser chooser = new JFileChooser();

    private MyJFileChooser(){};

    public static JFileChooser getInstance(){
        return chooser;
    }
}

final class MyJColorChooser{
    private static JColorChooser chooser = new JColorChooser();

    private MyJColorChooser(){};

    public static JColorChooser getInstance(){
        return chooser;
    }
}
実行結果サンプル
実行サンプル

Advertisement

ショートカット

634トップページ
このカテゴリのトップページに戻る
634ラボ
   UIコレクションギャラリー

サイト検索

Google

Web サイト内

Y!ログール