java - 如何在 JPanel 上绘制 2D 形状

标签 java swing awt shapes

所以我刚刚开始学习java GUI,我已经有了布局和组件,但我在事件处理方面很糟糕。这是我的第一个有意义的 GUI 项目,我迫切需要一些指导。我的布局已经准备好了,我只是不知道如何让它根据组合框中的选择绘制矩形、椭圆形或线条。这是到目前为止我的代码:

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

    }

}

最佳答案

首先看一下

基本上,您需要某种表面来渲染形状。也许最简单的方法是使用 JPanel 并重写它的 paintComponent 方法。

为此,我将附加您的 MouseListener,因为您想要物理添加形状和鼠标事件的位置与生成它们的组件相关。

您需要提供一些方法来让控件告诉“绘制表面”要绘制什么。这可以通过一个简单的 setter 和一些商定的值(例如 enumstatic final 常量)来完成。

当用户按下并释放鼠标时,您将需要确定要创建什么形状并将该形状添加到某种List中,您将需要调用repaint 通知重绘管理器您希望重绘组件。

当调用 paintComponent 时,您将循环遍历形状列表并调用 Graphics2D#draw 和/或 Graphics2D#fill,具体取决于你想用这个形状做什么...

您还可以查看this simular question获取更多想法。

关于java - 如何在 JPanel 上绘制 2D 形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26665932/

相关文章:

java - 如何在 awt 或 swing 窗口上使用后处理

java - Oracle 11g 中超出最大进程数

java - JButton setIcon 更新错误

java - 不能在 JFrame 中绘制超过一个正方形

java - JPanel 的问题

java - AWT(扩展)修饰符何时保证有效?

java - 具有空布局的 JViewports?

java - 获取所有以指定Runnable运行的线程

java - 标记界面的目的是什么?

java - 如何从 Web 应用程序内部使用 Netty - 正确配置的步骤