简体   繁体   English

如何在JPanel上绘制2D形状

[英]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. 所以我才刚刚开始学习Java GUI,并且布局和组件都减少了,但是我对事件处理感到恐惧。 This is my first meaningful GUI project and I desperately need some guidance. 这是我第一个有意义的GUI项目,我迫切需要一些指导。 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. 我的布局很好,我只是不知道如何根据ComboBox中的选择绘制矩形,椭圆形或直线形。 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. 可能最简单的方法是使用JPanel并覆盖它的paintComponent方法。

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. 为此,我将附加MouseListener ,因为要在其中物理添加形状和鼠标事件的位置与生成它们的组件相关。

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). 这可以通过一个简单的设置器和一些约定的值(例如enumstatic final常量)来完成。

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. 当用户按下并释放鼠标时,您将需要确定要创建的形状并将该形状添加到某种List ,您将需要调用repaint来通知重新绘制管理器您想要重新绘制组件。

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... 调用paintComponent ,您将循环浏览形状列表,并根据要对形状执行的操作调用Graphics2D#draw和/或Graphics2D#fill

You could also take a look at this simular question for more ideas. 您也可以看看这个类似的问题以获取更多想法。

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

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