Java-在菜单中选择形状并在JPanel中绘制

Java-在菜单中选择形状并在JPanel中绘制,java,swing,graphics,paintcomponent,Java,Swing,Graphics,Paintcomponent,我想在JFrame中实现一个菜单,在这里我可以选择要绘制的形状。 我有一个扩展JFrame的类和一个扩展JPanel的类:所以在我的框架中,我添加了菜单和面板,就这么简单。为了区分不同的形状,我使用了一个具有4个值(矩形、椭圆、直线和徒手)的枚举对象 问题是,我无法理解如何在JPanel上绘制形状,因为我有一个类MyShape和4个扩展MyShape的不同类,它们为不同的形状行为重载MyShape的函数 你能检查一下我的代码并给我建议最好的方法吗 谢谢大家! 这是我的密码: MyFrame.ja

我想在JFrame中实现一个菜单,在这里我可以选择要绘制的形状。 我有一个扩展JFrame的类和一个扩展JPanel的类:所以在我的框架中,我添加了菜单和面板,就这么简单。为了区分不同的形状,我使用了一个具有4个值(矩形、椭圆、直线和徒手)的枚举对象

问题是,我无法理解如何在JPanel上绘制形状,因为我有一个类MyShape和4个扩展MyShape的不同类,它们为不同的形状行为重载MyShape的函数

你能检查一下我的代码并给我建议最好的方法吗

谢谢大家!

这是我的密码:

MyFrame.java

public class MainFrame extends JFrame implements Runnable,ActionListener {

JMenuBar menuBar;
JMenu menu;
JMenu subMenu = new JMenu();
JMenu subMenu2 = new JMenu();

JMenuItem menuItemActionsDraw;
JMenuItem menuItemActionsMove;
JMenuItem menuItemActionsResize;
JMenuItem menuItemActionsDel;

JMenuItem menuItemRect;
JMenuItem menuItemOval;
JMenuItem menuItemLine;
JMenuItem menuItemFreeHand;

DrawingArea area;

public MainFrame(){

}

public static void main(String[] args) {
    // TODO Auto-generated method stub
    MainFrame mframe = new MainFrame();
    SwingUtilities.invokeLater(mframe);

}

@Override
public void run() {
    // TODO Auto-generated method stub
    final JFrame jf = new JFrame("ShapeDraw");
    area = new DrawingArea();

    createMenu();
    jf.setJMenuBar(menuBar);
    jf.add(area);

    jf.pack();
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jf.setVisible(true);

}   

@Override
public void actionPerformed(ActionEvent arg0) {
    // TODO Auto-generated method stub
    JMenuItem source = (JMenuItem)(arg0.getSource());

    if (source.equals(menuItemActionsDraw)){

    }
    else if (source.equals(menuItemActionsMove)){

    }
    else if (source.equals(menuItemActionsResize)){

    }
    else if (source.equals(menuItemActionsDel)){

    }
    else if (source.equals(menuItemRect)){
        //MyRect rect = new MyRect(x, y, width, heigth);
        DrawingArea.shape = EnumShapes.RECT;

    }
    else if (source.equals(menuItemOval)){

    }
    else if (source.equals(menuItemLine)){

    }
    else if (source.equals(menuItemFreeHand)){

    }
}

public void createMenu(){
    menuBar = new JMenuBar();
    menu = new JMenu("Menu");

    subMenu = new JMenu("Actions");

    menuItemActionsDraw = new JMenuItem("Draw");
    menuItemActionsMove = new JMenuItem("Move");
    menuItemActionsResize = new JMenuItem("Resize");
    menuItemActionsDel = new JMenuItem("Delete");

    menuItemRect = new JMenuItem("Rect");
    menuItemOval = new JMenuItem("Oval");
    menuItemLine = new JMenuItem("Line");
    menuItemFreeHand= new JMenuItem("FreeHand");

    subMenu.add(menuItemActionsDraw);
    subMenu.add(menuItemActionsMove);
    subMenu.add(menuItemActionsResize);
    subMenu.add(menuItemActionsDel);

    menuItemActionsDraw.addActionListener(this);
    menuItemActionsMove.addActionListener(this);
    menuItemActionsResize.addActionListener(this);
    menuItemActionsDel.addActionListener(this);

    menu.add(subMenu);

    subMenu2 = new JMenu("Shapes");

    menuItemRect.addActionListener(this);
    menuItemOval.addActionListener(this);
    menuItemLine.addActionListener(this);
    menuItemFreeHand.addActionListener(this);

    subMenu2.add(menuItemRect);
    subMenu2.add(menuItemOval);
    subMenu2.add(menuItemLine);
    subMenu2.add(menuItemFreeHand);

    menu.add(subMenu2);

    menuBar.add(menu);
}
}
public class DrawingArea extends JPanel implements MouseInputListener, MouseMotionListener {

public ArrayList<MyShape> displayList = new ArrayList<MyShape>();
public static EnumShapes shape;
public MyRect rect;
public Graphics2D g2d;

public DrawingArea() {
    super();
    this.setLayout(new BorderLayout());
    super.setPreferredSize(new Dimension(500,500));
    setBorder(BorderFactory.createLineBorder(Color.black));

    addMouseListener(this);
    addMouseMotionListener(this);
}

@Override
public void paintComponent(Graphics g){

}

@Override
public void mouseClicked(MouseEvent arg0) {
    // 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

}

@Override
public void mousePressed(MouseEvent arg0) {
    // TODO Auto-generated method stub
    switch(shape){
    case RECT:
        rect = new MyRect(arg0.getX(), arg0.getY(), 0, 0);
    case OVAL:
        // to do stuff
    case LINE:
        // to do stuff
    case FREEHAND:
        // to do stuff
    default:
        break;
    }
    repaint();

}

@Override
public void mouseReleased(MouseEvent arg0) {
    // TODO when finished dragging, add shape to displayList
    //displayList.add(rect);
}

@Override
public void mouseDragged(MouseEvent arg0) {
    // TODO while mouse is dragged, set new width and height and repaint

    // I should use x and y and calculate the distance between x2 and y2,
    // and then set the difference as width and height

    switch(shape){
    case RECT:
        rect.setWidthHeight(arg0.getX()-rect.x, rect.y-arg0.getY());
        rect.draw(g2d);
    case OVAL:
        // to do stuff
    case LINE:
        // to do stuff
    case FREEHAND:
        // to do stuff
    default:
        break;
    }
}

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

}

public void setShape(EnumShapes shape){
    this.shape = shape;
}
}
public abstract class MyShape {
protected int x;
protected int y;
protected int width;
protected int height;
protected EnumShapes shape;

public MyShape(int x, int y, int width, int height){
    this.x=x;
    this.y=y;
    this.width=width;
    this.height=height;
}

public abstract void draw(Graphics2D g);
public abstract void fill(Graphics2D g);
public abstract void setFrame(double x, double y, double width, double height);
public abstract void drawSelectionBox(Graphics2D g);

public void setWidthHeight(int width, int height) {
    // TODO Auto-generated method stub
    this.width = width;
    this.height = height;
}

}
public class MyRect extends MyShape {

public MyRect(int x, int y, int width, int height) {
    super(x, y, width, height);
    // TODO Auto-generated constructor stub
}

@Override
public void draw(Graphics2D g) {
    // TODO Auto-generated method stub
    g.drawRect(x, y, width, height);
}

@Override
public void fill(Graphics2D g) {
    // TODO Auto-generated method stub

}

@Override
public void setFrame(double x, double y, double width, double height) {
    // TODO write stuff

}

@Override
public void drawSelectionBox(Graphics2D g) {
    // TODO write stuff

}
}
DrawingArea.java

public class MainFrame extends JFrame implements Runnable,ActionListener {

JMenuBar menuBar;
JMenu menu;
JMenu subMenu = new JMenu();
JMenu subMenu2 = new JMenu();

JMenuItem menuItemActionsDraw;
JMenuItem menuItemActionsMove;
JMenuItem menuItemActionsResize;
JMenuItem menuItemActionsDel;

JMenuItem menuItemRect;
JMenuItem menuItemOval;
JMenuItem menuItemLine;
JMenuItem menuItemFreeHand;

DrawingArea area;

public MainFrame(){

}

public static void main(String[] args) {
    // TODO Auto-generated method stub
    MainFrame mframe = new MainFrame();
    SwingUtilities.invokeLater(mframe);

}

@Override
public void run() {
    // TODO Auto-generated method stub
    final JFrame jf = new JFrame("ShapeDraw");
    area = new DrawingArea();

    createMenu();
    jf.setJMenuBar(menuBar);
    jf.add(area);

    jf.pack();
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jf.setVisible(true);

}   

@Override
public void actionPerformed(ActionEvent arg0) {
    // TODO Auto-generated method stub
    JMenuItem source = (JMenuItem)(arg0.getSource());

    if (source.equals(menuItemActionsDraw)){

    }
    else if (source.equals(menuItemActionsMove)){

    }
    else if (source.equals(menuItemActionsResize)){

    }
    else if (source.equals(menuItemActionsDel)){

    }
    else if (source.equals(menuItemRect)){
        //MyRect rect = new MyRect(x, y, width, heigth);
        DrawingArea.shape = EnumShapes.RECT;

    }
    else if (source.equals(menuItemOval)){

    }
    else if (source.equals(menuItemLine)){

    }
    else if (source.equals(menuItemFreeHand)){

    }
}

public void createMenu(){
    menuBar = new JMenuBar();
    menu = new JMenu("Menu");

    subMenu = new JMenu("Actions");

    menuItemActionsDraw = new JMenuItem("Draw");
    menuItemActionsMove = new JMenuItem("Move");
    menuItemActionsResize = new JMenuItem("Resize");
    menuItemActionsDel = new JMenuItem("Delete");

    menuItemRect = new JMenuItem("Rect");
    menuItemOval = new JMenuItem("Oval");
    menuItemLine = new JMenuItem("Line");
    menuItemFreeHand= new JMenuItem("FreeHand");

    subMenu.add(menuItemActionsDraw);
    subMenu.add(menuItemActionsMove);
    subMenu.add(menuItemActionsResize);
    subMenu.add(menuItemActionsDel);

    menuItemActionsDraw.addActionListener(this);
    menuItemActionsMove.addActionListener(this);
    menuItemActionsResize.addActionListener(this);
    menuItemActionsDel.addActionListener(this);

    menu.add(subMenu);

    subMenu2 = new JMenu("Shapes");

    menuItemRect.addActionListener(this);
    menuItemOval.addActionListener(this);
    menuItemLine.addActionListener(this);
    menuItemFreeHand.addActionListener(this);

    subMenu2.add(menuItemRect);
    subMenu2.add(menuItemOval);
    subMenu2.add(menuItemLine);
    subMenu2.add(menuItemFreeHand);

    menu.add(subMenu2);

    menuBar.add(menu);
}
}
public class DrawingArea extends JPanel implements MouseInputListener, MouseMotionListener {

public ArrayList<MyShape> displayList = new ArrayList<MyShape>();
public static EnumShapes shape;
public MyRect rect;
public Graphics2D g2d;

public DrawingArea() {
    super();
    this.setLayout(new BorderLayout());
    super.setPreferredSize(new Dimension(500,500));
    setBorder(BorderFactory.createLineBorder(Color.black));

    addMouseListener(this);
    addMouseMotionListener(this);
}

@Override
public void paintComponent(Graphics g){

}

@Override
public void mouseClicked(MouseEvent arg0) {
    // 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

}

@Override
public void mousePressed(MouseEvent arg0) {
    // TODO Auto-generated method stub
    switch(shape){
    case RECT:
        rect = new MyRect(arg0.getX(), arg0.getY(), 0, 0);
    case OVAL:
        // to do stuff
    case LINE:
        // to do stuff
    case FREEHAND:
        // to do stuff
    default:
        break;
    }
    repaint();

}

@Override
public void mouseReleased(MouseEvent arg0) {
    // TODO when finished dragging, add shape to displayList
    //displayList.add(rect);
}

@Override
public void mouseDragged(MouseEvent arg0) {
    // TODO while mouse is dragged, set new width and height and repaint

    // I should use x and y and calculate the distance between x2 and y2,
    // and then set the difference as width and height

    switch(shape){
    case RECT:
        rect.setWidthHeight(arg0.getX()-rect.x, rect.y-arg0.getY());
        rect.draw(g2d);
    case OVAL:
        // to do stuff
    case LINE:
        // to do stuff
    case FREEHAND:
        // to do stuff
    default:
        break;
    }
}

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

}

public void setShape(EnumShapes shape){
    this.shape = shape;
}
}
public abstract class MyShape {
protected int x;
protected int y;
protected int width;
protected int height;
protected EnumShapes shape;

public MyShape(int x, int y, int width, int height){
    this.x=x;
    this.y=y;
    this.width=width;
    this.height=height;
}

public abstract void draw(Graphics2D g);
public abstract void fill(Graphics2D g);
public abstract void setFrame(double x, double y, double width, double height);
public abstract void drawSelectionBox(Graphics2D g);

public void setWidthHeight(int width, int height) {
    // TODO Auto-generated method stub
    this.width = width;
    this.height = height;
}

}
public class MyRect extends MyShape {

public MyRect(int x, int y, int width, int height) {
    super(x, y, width, height);
    // TODO Auto-generated constructor stub
}

@Override
public void draw(Graphics2D g) {
    // TODO Auto-generated method stub
    g.drawRect(x, y, width, height);
}

@Override
public void fill(Graphics2D g) {
    // TODO Auto-generated method stub

}

@Override
public void setFrame(double x, double y, double width, double height) {
    // TODO write stuff

}

@Override
public void drawSelectionBox(Graphics2D g) {
    // TODO write stuff

}
}
MyRect.java

public class MainFrame extends JFrame implements Runnable,ActionListener {

JMenuBar menuBar;
JMenu menu;
JMenu subMenu = new JMenu();
JMenu subMenu2 = new JMenu();

JMenuItem menuItemActionsDraw;
JMenuItem menuItemActionsMove;
JMenuItem menuItemActionsResize;
JMenuItem menuItemActionsDel;

JMenuItem menuItemRect;
JMenuItem menuItemOval;
JMenuItem menuItemLine;
JMenuItem menuItemFreeHand;

DrawingArea area;

public MainFrame(){

}

public static void main(String[] args) {
    // TODO Auto-generated method stub
    MainFrame mframe = new MainFrame();
    SwingUtilities.invokeLater(mframe);

}

@Override
public void run() {
    // TODO Auto-generated method stub
    final JFrame jf = new JFrame("ShapeDraw");
    area = new DrawingArea();

    createMenu();
    jf.setJMenuBar(menuBar);
    jf.add(area);

    jf.pack();
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jf.setVisible(true);

}   

@Override
public void actionPerformed(ActionEvent arg0) {
    // TODO Auto-generated method stub
    JMenuItem source = (JMenuItem)(arg0.getSource());

    if (source.equals(menuItemActionsDraw)){

    }
    else if (source.equals(menuItemActionsMove)){

    }
    else if (source.equals(menuItemActionsResize)){

    }
    else if (source.equals(menuItemActionsDel)){

    }
    else if (source.equals(menuItemRect)){
        //MyRect rect = new MyRect(x, y, width, heigth);
        DrawingArea.shape = EnumShapes.RECT;

    }
    else if (source.equals(menuItemOval)){

    }
    else if (source.equals(menuItemLine)){

    }
    else if (source.equals(menuItemFreeHand)){

    }
}

public void createMenu(){
    menuBar = new JMenuBar();
    menu = new JMenu("Menu");

    subMenu = new JMenu("Actions");

    menuItemActionsDraw = new JMenuItem("Draw");
    menuItemActionsMove = new JMenuItem("Move");
    menuItemActionsResize = new JMenuItem("Resize");
    menuItemActionsDel = new JMenuItem("Delete");

    menuItemRect = new JMenuItem("Rect");
    menuItemOval = new JMenuItem("Oval");
    menuItemLine = new JMenuItem("Line");
    menuItemFreeHand= new JMenuItem("FreeHand");

    subMenu.add(menuItemActionsDraw);
    subMenu.add(menuItemActionsMove);
    subMenu.add(menuItemActionsResize);
    subMenu.add(menuItemActionsDel);

    menuItemActionsDraw.addActionListener(this);
    menuItemActionsMove.addActionListener(this);
    menuItemActionsResize.addActionListener(this);
    menuItemActionsDel.addActionListener(this);

    menu.add(subMenu);

    subMenu2 = new JMenu("Shapes");

    menuItemRect.addActionListener(this);
    menuItemOval.addActionListener(this);
    menuItemLine.addActionListener(this);
    menuItemFreeHand.addActionListener(this);

    subMenu2.add(menuItemRect);
    subMenu2.add(menuItemOval);
    subMenu2.add(menuItemLine);
    subMenu2.add(menuItemFreeHand);

    menu.add(subMenu2);

    menuBar.add(menu);
}
}
public class DrawingArea extends JPanel implements MouseInputListener, MouseMotionListener {

public ArrayList<MyShape> displayList = new ArrayList<MyShape>();
public static EnumShapes shape;
public MyRect rect;
public Graphics2D g2d;

public DrawingArea() {
    super();
    this.setLayout(new BorderLayout());
    super.setPreferredSize(new Dimension(500,500));
    setBorder(BorderFactory.createLineBorder(Color.black));

    addMouseListener(this);
    addMouseMotionListener(this);
}

@Override
public void paintComponent(Graphics g){

}

@Override
public void mouseClicked(MouseEvent arg0) {
    // 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

}

@Override
public void mousePressed(MouseEvent arg0) {
    // TODO Auto-generated method stub
    switch(shape){
    case RECT:
        rect = new MyRect(arg0.getX(), arg0.getY(), 0, 0);
    case OVAL:
        // to do stuff
    case LINE:
        // to do stuff
    case FREEHAND:
        // to do stuff
    default:
        break;
    }
    repaint();

}

@Override
public void mouseReleased(MouseEvent arg0) {
    // TODO when finished dragging, add shape to displayList
    //displayList.add(rect);
}

@Override
public void mouseDragged(MouseEvent arg0) {
    // TODO while mouse is dragged, set new width and height and repaint

    // I should use x and y and calculate the distance between x2 and y2,
    // and then set the difference as width and height

    switch(shape){
    case RECT:
        rect.setWidthHeight(arg0.getX()-rect.x, rect.y-arg0.getY());
        rect.draw(g2d);
    case OVAL:
        // to do stuff
    case LINE:
        // to do stuff
    case FREEHAND:
        // to do stuff
    default:
        break;
    }
}

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

}

public void setShape(EnumShapes shape){
    this.shape = shape;
}
}
public abstract class MyShape {
protected int x;
protected int y;
protected int width;
protected int height;
protected EnumShapes shape;

public MyShape(int x, int y, int width, int height){
    this.x=x;
    this.y=y;
    this.width=width;
    this.height=height;
}

public abstract void draw(Graphics2D g);
public abstract void fill(Graphics2D g);
public abstract void setFrame(double x, double y, double width, double height);
public abstract void drawSelectionBox(Graphics2D g);

public void setWidthHeight(int width, int height) {
    // TODO Auto-generated method stub
    this.width = width;
    this.height = height;
}

}
public class MyRect extends MyShape {

public MyRect(int x, int y, int width, int height) {
    super(x, y, width, height);
    // TODO Auto-generated constructor stub
}

@Override
public void draw(Graphics2D g) {
    // TODO Auto-generated method stub
    g.drawRect(x, y, width, height);
}

@Override
public void fill(Graphics2D g) {
    // TODO Auto-generated method stub

}

@Override
public void setFrame(double x, double y, double width, double height) {
    // TODO write stuff

}

@Override
public void drawSelectionBox(Graphics2D g) {
    // TODO write stuff

}
}
“问题是,我无法理解如何在JPanel上绘制形状,因为我有一个类MyShape和4个扩展MyShape的不同类,这些类会为不同的形状行为重载MyShape的函数。”

选择一个
MyShape形状在您的
绘图区域中。还有一个二传手

public void setSelectedShape(MyShape selectedShape) {
    this.selectedShape = selectedShape;
    repaint();
}
可以绘制选定的形状

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D)g;
    if (selectedShaped != null) {
        selectedShape.draw(g2);
    }
}
只要从frame类中的侦听器调用
setSelectedShape
方法,就可以绘制不同的形状

如果您的形状有不同的方法(抽象类中定义的方法除外),您可能需要调用,请选中
instanceof

if (selectedShape instanceof MyRect) {
    // do something
}