简体   繁体   English

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

[英]Java - select shape in menu and draw in JPanel

I wanted to implement a menu in my JFrame where I can select which shape to draw. 我想在JFrame中实现一个菜单,从中可以选择要绘制的形状。 I have a class extending JFrame and a class extending JPanel: So in my frame I add the menu and the panel, simple as that. 我有一个扩展JFrame的类和一个扩展JPanel的类:所以在我的框架中,我添加了菜单和面板,就这么简单。 To discriminate between different shapes, I use an Enum object with 4 values (Rect, Ellipse, Line and FreeHand). 为了区分不同的形状,我使用了一个具有4个值(Rect,Ellipse,Line和FreeHand)的Enum对象。

The problem is that I cannot understand how to draw the shape on the JPanel, because I have a class MyShape and 4 different classes extending MyShape that overload MyShape's functions for the different shapes behaviours. 问题在于我无法理解如何在JPanel上绘制形状,因为我有一个MyShape类和4个扩展MyShape的不同类,这些类使MyShape的功能针对不同的形状行为重载。

Can you check my code and suggest me the best way to do it? 您可以检查我的代码并向我建议最好的方法吗?

Thank you! 谢谢!

Here is my code: 这是我的代码:

MyFrame.java 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);
}
}

DrawingArea.java DrawingArea.java

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

MyShape.java MyShape.java

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

}

MyRect.java MyRect.java

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

}
}

"The problem is that I cannot understand how to draw the shape on the JPanel, because I have a class MyShape and 4 different classes extending MyShape that overload MyShape's functions for the different shapes behaviours." “问题在于我无法理解如何在JPanel上绘制形状,因为我有一个MyShape类和4个扩展MyShape的不同类,这些类使MyShape的功能针对不同的形状行为重载。”

Have a MyShape selectedShape; MyShape selectedShape;一个MyShape selectedShape; in your DrawingArea class. 在您的DrawingArea类中。 And have a setter for it 并有一个二传手

public void setSelectedShape(MyShape selectedShape) {
    this.selectedShape = selectedShape;
    repaint();
}

You can paint the selected shape 您可以绘制选定的形状

protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D)g;
    if (selectedShaped != null) {
        selectedShape.draw(g2);
    }
}

Just call the setSelectedShape method from a listener in your frame class, whenever you want to draw a different shape. 每当您要绘制其他形状时,只需从框架类中的侦听器调用setSelectedShape方法即可。

If your shapes have different methods (other than those defined in the abstract class) you may want to invoke, check instanceof 如果形状具有不同的方法(抽象类中定义的方法除外),则可能需要调用,请检查instanceof

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM