4

インターフェイス専用のクラスとキャンバス専用のクラスの 2 つのクラスを実装して、ユーザーが図形を描画できるようにします。

基本的に、私のボタンの 1 つを取り上げましょう。これは、匿名クラスでアクションを初期化する Jbutton bCircle です。特定の部分だけを入れました:

public class Application extends JFrame implements ActionListener {

    toolBar.add(Box.createHorizontalGlue());
    toolBar.add(Box.createVerticalGlue());
    toolBar.add(bSquare, toolBar.getComponentCount() - 1);
    toolBar.add(bCircle, toolBar.getComponentCount() - 1);
    bCircle.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent event){
        //Action ?????
    }
});
    toolBar.add(bRectangle, toolBar.getComponentCount() - 1);
    toolBar.add(bTriangle, toolBar.getComponentCount() - 1);
    toolBar.add(bErase, toolBar.getComponentCount() - 1);
    toolBar.setOrientation(SwingConstants.VERTICAL);
    container.add(toolBar, BorderLayout.WEST);
}

もう 1 つのクラスでは、canvas をクリックしたときに Jbutton bCircle の選択状態を実行するアクションを次に示します。

public class DrawingCanvas extends JPanel implements MouseListener, MouseMotionListener {

    public void mousePressed(MouseEvent e) {
    // TODO Auto-generated method stub
        if(e.getSource() == bCircle) {
            shapes.add(new Circle(e.getX(),e.getY()));
        }
        repaint();
    }
}

shapesキャンバスを掃除しやすくするために形状をストックする ArrayListCircleであり、円の描画のみを含むクラスです。

最後の目的は、ユーザーが最初に 4 つの形状を表す 4 つのボタンをクリックし、次にキャンバス上でマウスを押して描画できるようにすることです。しかし、これらの2つのクラスをリンクする方法がわかりません。助けてください。

前もって感謝します、

PS : 2 回目に更新した完全な Application クラス (インターフェイス):

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;

public class Application extends JFrame implements ActionListener {

{
    //Set appearance Look & Feel for the window
try { javax.swing.UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
    } catch(Exception e) {
        e.printStackTrace();
    }
}

    private DrawingCanvas canvas = new DrawingCanvas();
    private JPanel container = new JPanel();
    private JPanel commandes = new JPanel();
    private JMenuBar menu = new JMenuBar();
    private JMenu newFile = new JMenu();
    private JMenu open = new JMenu(); 
    private JMenu save = new JMenu();
    private JFileChooser fileChooser;
    private JToolBar toolBar = new JToolBar();

    private JButton bSquare = new JButton("Square");
    private JButton bRectangle = new JButton("Rectangle");
    private JButton bCircle = new JButton("Circle");
    private JButton bTriangle = new JButton("Triangle");
    private JButton bErase = new JButton("CLEAR");

    //public static boolean bIsSelected = false;

    public Application(){

    this.setTitle("Animation");         
    this.setSize(579, 432); 
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLocationRelativeTo(null);
    this.setVisible(true);

        container.setBackground(Color.white);
    container.setLayout(new BorderLayout());
    container.add(canvas, BorderLayout.CENTER);
    this.setContentPane(container);

    toolBar.add(Box.createHorizontalGlue());
        toolBar.add(Box.createVerticalGlue());
        toolBar.add(bSquare, toolBar.getComponentCount() - 1);
        toolBar.add(bCircle, toolBar.getComponentCount() - 1);

        bCircle.addActionListener(new SampleActionListener(canvas, new Circle()));

            toolBar.add(bRectangle, toolBar.getComponentCount() - 1);
        toolBar.add(bTriangle, toolBar.getComponentCount() - 1);
        toolBar.add(bErase, toolBar.getComponentCount() - 1);
        bErase.addActionListener(new ActionListener(){
              public void actionPerformed(ActionEvent erase){
                 canvas.getShapes().clear();
                 repaint();
              }
            });
        toolBar.setOrientation(SwingConstants.VERTICAL);
        container.add(toolBar, BorderLayout.WEST);

        menu.add(newFile);
        newFile.setIcon(new ImageIcon("src/images/new.png"));
        menu.add(open);
        open.setIcon(new ImageIcon("src/images/open.png"));
        menu.add(save);
        save.setIcon(new ImageIcon("src/images/save.png"));
        this.setJMenuBar(menu);  

      }  

    public class SampleActionListener implements ActionListener {

        private final DrawingCanvas canvas2;
        private final ShapeGenerator shapeGenerator;

        public SampleActionListener(DrawingCanvas canvas, ShapeGenerator shapeGenerator) {
            this.canvas2 = canvas;
            this.shapeGenerator = shapeGenerator;
        }

        public void actionPerformed(ActionEvent event) {
           this.canvas2.setShapeGenerator(shapeGenerator);
        }
    }
    @Override
    public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub

    }   

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Application App = new Application();

    }
}

2 回目にアップロードされたキャンバスのクラスは次のとおりです。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;

import javax.swing.JPanel;



public class DrawingCanvas extends JPanel implements MouseListener {

private ArrayList<Shape> shapes = new ArrayList<>();
private Shape shapeUnderMouse = null;

public ArrayList<Shape> getShapes() {
    return shapes;
}

public void setShapes(ArrayList<Shape> shapes) {
    this.shapes = shapes;
}

public DrawingCanvas() {
    super();
    addMouseListener(this);
}

public void paint(Graphics g){
    for(int i = 0;i < shapes.size();i++){
        shapes.get(i).paint(g);
    }    
}


@Override
public void mouseClicked(MouseEvent e) {
    // TODO Auto-generated method stub

}

@Override
public void mouseEntered(MouseEvent arg0) {
    // TODO Auto-generated method stub

}

@Override
public void mouseExited(MouseEvent arg0) {
    // TODO Auto-generated method stub

}

public void addShape(Shape anyShape)
{
        shapes.add(anyShape);
}

@Override
public void mousePressed(MouseEvent e) {

    shapes.add(this.shapeGenerator.getGeneratedShape(e.getX(), e.getY()));
    repaint();
}
@Override
public void mouseReleased(MouseEvent arg0) {
    // TODO Auto-generated method stub

}

public void setShapeGenerator(ShapeGenerator shapeGenerator) {
    // TODO Auto-generated method stub

}

さて、クラス形状:

import javax.swing.JPanel;

public class Shape extends JPanel{

protected int posX;
protected int posY;

/*public Shape(int posX, int posY) {
    super();
    this.posX = posX;
    this.posY = posY;
}*/

public int getPosX() {
    return posX;
}

public void setPosX(int posX) {
    this.posX = posX;
}

public int getPosY() {
    return posY;
}

public void setPosY(int posY) {
    this.posY = posY;
}

}

私の小さなサークルクラス:

import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Ellipse2D.Float;

import javax.swing.JPanel;

public class Circle extends Shape implements ShapeGenerator{

/*public Circle(int posX, int posY) {
    super(posX, posY);
    // TODO Auto-generated constructor stub
}*/

public void paint(Graphics g){
    g.fillOval(posX,posY,40,40);
    g.setColor(Color.blue);
  } 

public Shape getGeneratedShape(int x, int y) {
    return new Ellipse2D.Float(x, y, 10, 10); //--> does not work, ask me to change       method type to a float
    return new Circle();
    }

} そして最後に、すべてのクラスが別々のクラスにあるインターフェースです:
public interface ShapeGenerator {

Shape getGeneratedShape(int posX, int posY);

}
4

3 に答える 3

2

実際、それはとても簡単です。匿名クラスを使用しないでください。

たとえば、コードでは、定義済みのリスナーをアタッチするだけです。例えば ​​:

bCircle.addActionListener(new SampleActionListener(pan, new CircleShapeGenerator()));

ここに SampleActionListener ウィッチが ActionListener インターフェイスを実装しています

public class SampleActionListener implements ActionListener {

    private final DrawingCanvas canvas;
    private final ShapeGenerator shapeGenerator;

    public SampleActionListener(DrawingCanvas canvas, ShapeGenerator shapeGenerator) {
        this.canvas = canvas;
        this.shapeGenerator = shapeGenerator;
    }

    public void actionPerformed(ActionEvent event) {
       this.canvas.setShapeGenerator(shapeGenerator);
    }
}

ここにクラス CircleShapeGenerator があります

public class CircleShapeGenerator implements ShapeGenerator {
    public Shape getGeneratedShape(int x, int y) {
        return new Ellipse2D.Float(x, y, 10, 10);
    }
}

およびインターフェイス ShapeGenerator

public interface ShapeGenerator {
      Shape getGeneratedShape(int x, int y);
}

また、長方形のボタンにアクション リスナーを追加する場合は、非常に簡単です。このクラスを作成します。

public class RectangleShapeGenerator implements ShapeGenerator {
     public Shape getGeneratedShape(int x, int y) {
       return new Rectangle2D.Float(x, y, 10, 10);
      }
}

アプリケーション クラスに、次のコードを追加します。

toolBar.add(bRectangle, toolBar.getComponentCount() - 1);
bRectangle.addActionListerner(pan, new RectangleShapeGenerator() )

DrawingCanvas のメソッド paint には、次のようなコードを使用する必要があると思います。

for (Shape s : shapes) {
       Graphics2D g2 = (Graphics2D) g;
       g2.draw(s);
}

BR、パトゥーシュ

私の英語で申し訳ありません、私はそれが本当に完璧ではないことを知っています...

于 2012-12-09T02:06:51.687 に答える
0

まず、クラス Shape を削除します。その必要はありません。Shape は Java で定義されたインターフェースです。代わりにこのインターフェイスを使用してください。

DrawingCanvas クラスの ShapeGenerator のセッターは何もしません。それで追加します。メソッド paint が正しくありません。

public class DrawingCanvas extends JPanel implements MouseListener {

    // Shape here is the java.awt.Shape from java.
    private ArrayList<Shape> shapes = new ArrayList<>();
    private ShapeGenerator shapeGenerator;

    ...
    ...

    public void paint(Graphics g){
        super.paint(g);
        for (Shape s : shapes) {
            Graphics2D g2 = (Graphics2D) g;
            g2.draw(s);
        } 
    }

    ...

    @Override
    public void mousePressed(MouseEvent e) {
        shapes.add(this.shapeGenerator.getGeneratedShape(e.getX(), e.getY()));
        repaint();
    }


    public void setShapeGenerator(ShapeGenerator shapeGenerator) {
        this.shapeGenerator = shapeGenerator;
    }
}

クラス Circle は本当に複雑です。シンプルで、このメソッドにはペイント メソッドは必要ありません。クラス Circle は本当に単純です:

public class Circle implements ShapeGenerator{

    public Shape getGeneratedShape(int x, int y) {
        // This will return a java.awt.Shape instance
        return new Ellipse2D.Float(x, y, 10, 10);
    }
}

そして、それだけだと思います。

于 2012-12-09T22:43:13.027 に答える
0

これがあなたの問題の解決策です。しかし、それは本当に汚いです...私が言ったように、JPanelから継承された形状を持つ意味はありません!!

public class Application extends JFrame implements ActionListener {

    {
        // Set appearance Look & Feel for the window
        try {
            javax.swing.UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private final DrawingCanvas pan = new DrawingCanvas();
    // don't use to many field, it's confusing and not necessary.
    // you can do local var instead.
    private final JPanel container = new JPanel();

    private final JPanel commandes = new JPanel();

    private final JMenuBar menu = new JMenuBar();

    private final JMenu newFile = new JMenu();

    private final JMenu open = new JMenu();

    private final JMenu save = new JMenu();

    private JFileChooser fileChooser;

    private final JToolBar toolBar = new JToolBar();

    private final JButton bSquare = new JButton("Square");

    private final JButton bRectangle = new JButton("Rectangle");

    private final JButton bCircle = new JButton("Circle");

    private final JButton bTriangle = new JButton("Triangle");

    private final JButton bErase = new JButton("CLEAR");

    public Application() {

        this.setTitle("Animation");
        this.setSize(579, 432);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
        this.setVisible(true);

        container.setBackground(Color.white);
        container.setLayout(new BorderLayout());
        container.add(pan, BorderLayout.CENTER);
        this.setContentPane(container);

        toolBar.add(Box.createHorizontalGlue());
        toolBar.add(Box.createVerticalGlue());
        toolBar.add(bSquare, toolBar.getComponentCount() - 1);
        toolBar.add(bCircle, toolBar.getComponentCount() - 1);
        bCircle.addActionListener(new SampleActionListener(pan, new CircleShapeGenerator()));
        toolBar.add(bRectangle, toolBar.getComponentCount() - 1);
        // bRectangle.addActionListener(new SampleActionListener(pan, new
        // RectangleShapeGenerator()));
        toolBar.add(bTriangle, toolBar.getComponentCount() - 1);
        toolBar.add(bErase, toolBar.getComponentCount() - 1);
        toolBar.setOrientation(SwingConstants.VERTICAL);
        container.add(toolBar, BorderLayout.WEST);

        menu.add(newFile);
        newFile.setIcon(new ImageIcon("src/images/new.png"));
        menu.add(open);
        open.setIcon(new ImageIcon("src/images/open.png"));
        menu.add(save);
        save.setIcon(new ImageIcon("src/images/save.png"));
        this.setJMenuBar(menu);

    }

    @Override
    public void actionPerformed(ActionEvent arg0) {
        // TODO Auto-generated method stub

    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Application App = new Application();
    }
}

CircleShapeGenerator クラスを保持します

public class CircleShapeGenerator implements ShapeGenerator {

    @Override
    public CircleShape getGeneratedShape(int x, int y) {
        CircleShape c = new CircleShape();
        c.setCanvasX(x);
        c.setCanvasY(y);
        return c;
    }

}

円形

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;

public class CircleShape extends Shape {

    private final Ellipse2D.Float ellipse2D;

    public CircleShape() {
        this.ellipse2D = new Ellipse2D.Float();
        this.setRadius(20);
    }


    private void setRadius(int r) {
        this.ellipse2D.height = r;
        this.ellipse2D.width = r;
    }

    @Override
    public void setCanvasX(int canvasX) {
        this.canvasX = canvasX;
        this.ellipse2D.x = canvasX;
    }

    @Override
    public void setCanvasY(int canvasY) {
        this.canvasY = canvasY;
        this.ellipse2D.y = canvasY;
    }

    @Override
    public java.awt.Shape getTrueShape() {
        return this.ellipse2D;
    }

}

シェイプを編集するためのコンテキスト メニューのクラス

import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;

class ContextualShapeMenu extends JPopupMenu {

    private final Shape shape;

    public ContextualShapeMenu(Shape shape) {
        this.shape = shape;
        JMenuItem anItem = new JMenuItem("Edit the size");
        add(anItem);
    }
}

DrawingCanvas クラス

import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JPanel;

import com.google.common.collect.Lists;

public class DrawingCanvas extends JPanel implements MouseListener {

    protected ArrayList<Shape> shapes = new ArrayList<Shape>();

    private ShapeGenerator shapeGenerator;

    public ArrayList<Shape> getShapes() {
        return shapes;
    }

    public void setShapes(ArrayList<Shape> shapes) {
        this.shapes = shapes;
    }

    public DrawingCanvas() {
        super();
        addMouseListener(this);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        for (Shape s : shapes) {
            s.paint(g);
        }
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        switch (e.getButton()) {
        case MouseEvent.BUTTON1:
            shapes.add(this.shapeGenerator.getGeneratedShape(e.getX(), e.getY()));
            break;
        default:
            Shape shape = getShapeUnderMouse(e);
            if (shape != null) {
                ContextualShapeMenu menu = new ContextualShapeMenu(shape);
                menu.show(e.getComponent(), e.getX(), e.getY());
            }
        }
        repaint();
    }

    private Shape getShapeUnderMouse(MouseEvent e) {
        List<Shape> reversed = Lists.reverse(this.shapes);
        for (Shape s : reversed) {
            if (s.contains(e.getX(), e.getY())) {
                return s;
            }
        }
        return null;
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // Do nothing
    }

    @Override
    public void mouseExited(MouseEvent e) {
        // Do nothing
    }

    @Override
    public void mousePressed(MouseEvent e) {
        // Do nothing
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        // Do nothing
    }

    public void setShapeGenerator(ShapeGenerator shapeGenerator) {
        this.shapeGenerator = shapeGenerator;
    }
}

まだActionListenerです。名前を変更します。

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class SampleActionListener implements ActionListener {

    private final DrawingCanvas canvas;

    private final ShapeGenerator shapeGenerator;

    public SampleActionListener(DrawingCanvas canvas, ShapeGenerator shapeGenerator) {
        this.canvas = canvas;
        this.shapeGenerator = shapeGenerator;
    }

    @Override
    public void actionPerformed(ActionEvent event) {
        this.canvas.setShapeGenerator(shapeGenerator);
    }
}

ShapeGenerator インターフェース

public interface ShapeGenerator {

    Shape getGeneratedShape(int x, int y);

}

そして少なくとも、最も愚かなクラス: Shape

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import javax.swing.JPanel;

public abstract class Shape extends JPanel implements java.awt.Shape {

    protected int canvasX;

    protected int canvasY;

    public int getCanvasX() {
        return canvasX;
    }

    public abstract java.awt.Shape getTrueShape();

    public abstract void setCanvasX(int canvasX);

    public int getCanvasY() {
        return canvasY;
    }

    public abstract void setCanvasY(int canvasY);

    @Override
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.draw(this.getTrueShape());
    }

    @Override
    public Rectangle getBounds() {
        return getTrueShape().getBounds();
    }

    @Override
    public Rectangle2D getBounds2D() {
        return getTrueShape().getBounds2D();
    }

    @Override
    public boolean contains(int x, int y) {
        return this.getTrueShape().contains(x, y);
    }

    @Override
    public boolean contains(double x, double y) {
        return this.getTrueShape().contains(x, y);
    }

    @Override
    public boolean contains(Point2D p) {
        return this.getTrueShape().contains(p);
    }

    @Override
    public boolean contains(Point p) {
        return this.getTrueShape().contains(p);
    }

    @Override
    public boolean intersects(double x, double y, double w, double h) {
        return this.getTrueShape().intersects(x, y, w, h);
    }

    @Override
    public boolean intersects(Rectangle2D r) {
        return this.getTrueShape().intersects(r);
    }

    @Override
    public boolean contains(double x, double y, double w, double h) {
        return this.getTrueShape().contains(x, y, w, h);
    }

    @Override
    public boolean contains(Rectangle2D r) {
        return this.getTrueShape().contains(r);
    }

    @Override
    public PathIterator getPathIterator(AffineTransform at) {
        return this.getTrueShape().getPathIterator(at);
    }

    @Override
    public PathIterator getPathIterator(AffineTransform at, double flatness) {
        return this.getTrueShape().getPathIterator(at, flatness);
    }

}

グアバ ライブラリを追加したので、Lists クラスは見つかりません。それをプロジェクトに追加するか、他のライブラリを使用するか、リストを逆にするメソッドを作成してください。

頑張って、将来そのようなものを作らないでください!!! コーディングホラーです。

ちなみに私はフランスから来ました。

于 2012-12-10T22:50:02.877 に答える