简体   繁体   中英

How to draw 2D shapes onto a JPanel

so I just started learning java GUI and I have layouts and components down but I am just dreadful at event handling. This is my first meaningful GUI project and I desperately need some guidance. I have my layout good to go I just do not know how to get it to draw a Rectangle, Oval or Line based on selections in the ComboBoxes. Here is my code so far:

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.event.*;

import java.awt.Graphics2D;
import java.util.ArrayList;

public class PaintApp extends JFrame {

    private int x, y, posX, posY, width, height;
    private Graphics2D g;

    private JButton undo;
    private JButton clear;
    private JComboBox color;
    private JComboBox shape;
    private JCheckBox fill;
    private JLabel statusBar;

    private static final String[] pickColor =
        {"Black", "Blue", "Green", "Red"};


    private static final String[] pickShape =
        {"Line", "Oval", "Rectangle"};

    PaintApp(){
        super("Paint");

        // north panel
        JPanel buttonPanel = new JPanel();
        undo = new JButton("Undo");
        buttonPanel.add(undo);
        add(buttonPanel, BorderLayout.NORTH);

        clear = new JButton("Clear");
        buttonPanel.add(clear);
        add(buttonPanel, BorderLayout.NORTH);

        color = new JComboBox(pickColor);
        buttonPanel.add(color);
        add(buttonPanel, BorderLayout.NORTH);
        color.addItemListener(new ItemListener() {
              public void itemStateChanged(ItemEvent e) {
                  if(color.getSelectedItem().equals("Red")){
                      System.out.println("Color: " + color.getSelectedItem());
                  }else if(color.getSelectedItem().equals("Blue")){
                      System.out.println("Color: " + color.getSelectedItem());
                  }else if(color.getSelectedItem().equals("Green")){
                      System.out.println("Color: " + color.getSelectedItem());
                  }else if(color.getSelectedItem().equals("Black")){
                      System.out.println("Color: " + color.getSelectedItem());
                  }
              }
            }); 

        shape = new JComboBox(pickShape);
        buttonPanel.add(shape);
        add(buttonPanel, BorderLayout.NORTH);
        shape.addItemListener(new ItemListener() {
              public void itemStateChanged(ItemEvent e) {
                  if(shape.getSelectedItem().equals("Line")){
                      System.out.println("Shape: " + shape.getSelectedItem());
                  }else if(shape.getSelectedItem().equals("Oval")){
                      System.out.println("Shape: " + shape.getSelectedItem());
                  }else {
                      System.out.println("Shape: " + shape.getSelectedItem());
                  }
              }
            });     

        fill = new JCheckBox("Filled");
        buttonPanel.add(fill);
        add(buttonPanel, BorderLayout.NORTH);

        // center panel
        JPanel paintPanel = new JPanel();
        paintPanel.setBackground(Color.WHITE);
        add(paintPanel, BorderLayout.CENTER);

        // south panel
        statusBar = new JLabel("Mouse is off the canvas!");
        add(statusBar, BorderLayout.SOUTH);

        // mouse handler
        MouseHandler handler = new MouseHandler();
        paintPanel.addMouseListener(handler);
        paintPanel.addMouseMotionListener(handler);
        buttonPanel.addMouseListener(handler);
        buttonPanel.addMouseMotionListener(handler);
    }   

    private class MouseHandler implements MouseInputListener {

        public void mouseDragged(MouseEvent e) {
            statusBar.setText(String.format("(%d,%d)", 
                    e.getX(), e.getY()));
        }

        public void mouseMoved(MouseEvent e) {
            statusBar.setText(String.format("(%d,%d)", 
                    e.getX(), e.getY()));

        }

        public void mouseClicked(MouseEvent e) {
            String x = String.valueOf(color.getSelectedItem());

        }

        public void mousePressed(MouseEvent e) {
            posX = e.getX();
            posY = e.getY();
            width = posX - x;
            height = posY - y;
        }

        public void mouseReleased(MouseEvent e) {
            posX = e.getX();
            posY = e.getY();
            width = posX - x;
            height = posY - y;

        }

        public void mouseEntered(MouseEvent e) {

        }

        public void mouseExited(MouseEvent e) {
            statusBar.setText("Mouse is off the canvas!");

        }       
    }
}

public interface MyShape {

    void draw(Graphics2D g);
}

public class MyRect extends Rectangle2D.Float implements MyShape{

    Graphics2D g;
    int x, y, posX, posY;
    Color color;

    MyRect(Graphics2D g, int x, int y, int posX, int posY, Color color){
        this.g = g;
        this.x = x;
        this.y = y;
        this.posX = posX;
        this.posY = posY;
        this.color = color;
    }

    public void draw(Graphics2D g){
        g = (Graphics2D) g;
        g.setColor(color);
        g.drawRect(x, y, (posX - x), (posY - y));
    }

}

public class MyOval extends Ellipse2D.Float implements MyShape{

    Graphics2D g;
    int x, y, posX, posY;
    Color color;

    MyOval(Graphics2D g, int x, int y, int posX, int posY, Color color){
        this.g = g;
        this.x = x;
        this.y = y;
        this.posX = posX;
        this.posY = posY;
        this.color = color;
    }

    public void draw(Graphics2D g){
        g = (Graphics2D) g;
        g.setColor(color);
        g.drawOval(x, y, (posX - x), (posY - y));
    }
}

public class MyLine extends Line2D.Float implements MyShape{

    Graphics2D g;
    int x, y, posX, posY;
    Color color;

    MyLine(Graphics2D g, int x, int y, int posX, int posY, Color color){
        this.g = g;
        this.x = x;
        this.y = y;
        this.posX = posX;
        this.posY = posY;
        this.color = color;
    }

    public void draw(Graphics2D g){
        g = (Graphics2D) g;
        g.setColor(color);
        g.drawLine(x, y, (posX - x), (posY - y));
    }
}

    public static void main(String[] args){

        PaintApp p = new PaintApp();
        p.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        p.setSize(700,700);
        p.setResizable(false);
        p.setVisible(true);

    }

}

Start by taking a look at

Basically, you need some kind of surface onto which to render your shapes. Probably the easiest is to use a JPanel and override it's paintComponent method.

To this I would attach your MouseListener , because this where you want to physically add the shapes and mouse events are contextual to the component that generated them.

You will need to provide some means by which the controls can tell the "paint surface" what to paint. This can be done via a simple setter and some agreed on values (like an enum or static final constants).

When the user presses and releases the mouse, you will need to determine what shape to create and add that shape to some kind of List , you will need to call repaint to notify the repaint manager that you want your component repainted.

When paintComponent is called, you would then loop through the list of shapes and call Graphics2D#draw and/or Graphics2D#fill depending on what it is you want to do with the shape...

You could also take a look at this simular question for more ideas.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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