无法管理在两个类之间使用ActionListener

时间:2012-12-09 00:18:45

标签: java swing actionlistener java-2d

我尝试实现两个类,一个专用于接口,另一个专用于画布,允许用户在其上绘制形状。

所以基本上,让我们拿一个我的按钮,这是我的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);
}

在另一个类中,这是我想要在单击画布时执行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是一个放置形状的ArrayList,使画布更容易清理,Circle是一个只包含圆形图的类。

最后,目的是允许用户首先点击代表四个形状的四个按钮,然后通过在画布上按下的鼠标绘制它们。但我不知道如何将这两个课程联系起来,请帮助我,

提前致谢,

P.S:我第二次更新的完整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();

    }
}

这是画布的类,也是第二次上传:

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();
    }

} 最后是界面,所有类都在不同的类中:
    公共接口ShapeGenerator {

Shape getGeneratedShape(int posX, int posY);

}

4 个答案:

答案 0 :(得分: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中的方法绘制,我认为你应该使用这样的代码:

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

BR, Patouche

对不起我的英语,我知道这不是很完美......

答案 1 :(得分:0)

首先,删除你的类Shape。你不需要。 Shape是Java定义的接口。请改用此界面。

DrawingCanvas类中ShapeGenerator的setter不执行任何操作。所以添加它。你的方法油漆不正确。

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;
    }
}

你的班级圈真的很复杂。这很简单,这种方法不需要任何绘画方法。你上课圈子非常简单:

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);
    }
}

我认为,就是这样。

答案 2 :(得分:0)

我无法删除类Shape,这是我工作的一部分:看看我必须遵循的说明:

定义继承自JPanel的类Shape。这个类应该有共同的形状 画布上的x和y位置等属性,侧面数量,如何查找区域以及如何查找周长等信息。 [5]

分别为每个形状定义四个类,并确保它们继承自Shape类并覆盖paint()方法,以便可以在画布上绘制形状。 [20]

实现一个类DrawingCanvas,允许用户单击它并绘制特定形状。请注意,此类应实现MouseListener和MouseMotionListener。建议使用可以存储画布上绘制的所有形状的数组列表。在这种情况下,请确保正确使用多态技术。 [25]

实现类应用程序并形成可提供相同功能的用户界面 功能如上图所示。 [20]

在DrawingCanvas中添加此类功能,以便用户可以: 在画布上移动形状[5],双击形状并显示其属性[5],调整形状大小[10],实现保存,打开和新选项。 [5]

感谢您提出我的问题。你顺便去哪儿?

答案 3 :(得分: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);
    }

}

我添加了番石榴图书馆,因此,您将找不到列表类。将其添加到您的项目中,使用其他图书馆或创建一个方法来反转您的列表。

祝你好运,将来也不会做出类似的事情!它的编码恐怖。

顺便说一下,我来自法国。