使用Java在鼠标单击上绘制一个形状

时间:2014-05-09 00:18:07

标签: java swing mouseevent actionlistener paintcomponent

我正在尝试创建一个java程序,当用户单击Frame时,它将在JFrame上绘制一个形状。我已经达到了设置接受不同形状并识别咔嗒声的程度,但我无法弄清楚如何实现形状的绘画。

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
import javax.swing.JComponent;

public class StamperFrame extends JFrame {

    private JButton circleButton, ovalButton, squareButton, rectButton;
    private int buttonValue = 0;

    public StamperFrame() {
        setTitle("Shape Stamper");
        setSize(500, 500);

        //Setting up the buttons and positioning them.
        JPanel buttonPanel = new JPanel();

        circleButton = new JButton("Circle");
        ovalButton = new JButton("Oval");
        squareButton = new JButton("Square");
        rectButton = new JButton("Rectangle");

        buttonPanel.add(circleButton);
        buttonPanel.add(ovalButton);
        buttonPanel.add(squareButton);
        buttonPanel.add(rectButton);
        getContentPane().add(buttonPanel, BorderLayout.SOUTH);
        //end button init



        //Setting up button logic
        circleButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                buttonValue = 1;
                System.out.println(buttonValue);
            }
        });
        ovalButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                buttonValue = 2;
                System.out.println(buttonValue);
            }
        });
        squareButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                buttonValue = 3;
                System.out.println(buttonValue);
            }
        });
        rectButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                buttonValue = 4;
                System.out.println(buttonValue);
            }
        });
        //end button click configuration

        getContentPane().addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                if (buttonValue == 1) {
                    System.out.println("Circle added at: " + e.getX() + "," + e.getY());
                } else if (buttonValue == 2) {
                    System.out.println("Oval added at: " + e.getX() + "," + e.getY());
                }else if (buttonValue == 3) {
                    System.out.println("Square added at: " + e.getX() + "," + e.getY());
                }else if (buttonValue == 4) {
                    System.out.println("Rectangle added at: " + e.getX() + "," + e.getY());
                }
            }
        });

    }
}

我知道它需要在我的鼠标事件中解决一些问题,但我无法弄清楚如何。

My Frame目前看起来像这样:http://puu.sh/8ELaR/c7252286c0.jpg

任何建议都将受到赞赏。

3 个答案:

答案 0 :(得分:1)

有关自定义绘画的两种方法,请参阅Custom Painting Approaches

  1. 添加对象以绘制到ArrayList
  2. 直接将对象绘制到BufferedImage上。
  3. 链接中的示例只绘制一个Rectanle,因此您显然需要修改代码以支持不同的Shapes,但它应该给您一些想法。

答案 1 :(得分:0)

确定。真正完整的aswer现在:

TL; DR :复制并粘贴以下代码:

package FinalExam;

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.*;

public class StamperFrame extends JFrame {

    private final JButton circleButton, ovalButton, squareButton, rectButton;

    private final JPanel shapesPanel;

    private Shape shape;
    private final int w = 100;
    private final int h = 200;

    private Object lastButtonPressed;

    public StamperFrame() {
        setTitle("Shape Stamper");
        setSize(500, 500);

        final Container contentPane = getContentPane();

        //Setting up the buttons and positioning them.
        JPanel buttonPanel = new JPanel();

        circleButton = new JButton("Circle");
        ovalButton = new JButton("Oval");
        squareButton = new JButton("Square");
        rectButton = new JButton("Rectangle");

        buttonPanel.add(circleButton);
        buttonPanel.add(ovalButton);
        buttonPanel.add(squareButton);
        buttonPanel.add(rectButton);

        contentPane.add(buttonPanel, BorderLayout.SOUTH);
        //end button init

        shapesPanel = new JPanel(){
            @Override
            public void paintComponent(Graphics graphics) {
                Graphics2D g = (Graphics2D) graphics;
                super.paintComponent(g); 
                if(shape != null) g.draw(shape);
            }

        };
        contentPane.add(shapesPanel, BorderLayout.CENTER);

        final ActionListener buttonPressed = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                lastButtonPressed = event.getSource();
            }
        };

        circleButton.addActionListener(buttonPressed);
        ovalButton.addActionListener(buttonPressed);
        squareButton.addActionListener(buttonPressed);
        rectButton.addActionListener(buttonPressed);

        contentPane.addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {

                int x = e.getX();
                int y = e.getY();

                if(lastButtonPressed == circleButton){
                    shape = new Ellipse2D.Double(x, y, w, w);
                    echo("Circle",x,y);
                } else if(lastButtonPressed == ovalButton){
                    shape = new Ellipse2D.Double(x, y, w, h);
                    echo("Oval",x,y);
                } else if (lastButtonPressed == squareButton){
                    shape = new Rectangle2D.Double(x, y, w, w);
                    echo("Square",x,y);
                } else if (lastButtonPressed == rectButton){
                    echo("Rectangle",x,y);
                    shape = new Rectangle2D.Double(x, y, w, h);
                } 

                shapesPanel.repaint();
            }

            private void echo(String shape, int x, int y){
                System.out.println(shape + " added at: " + x + "," + y);
            }

        });

    }
}

长解释

  1. 我们不需要变量buttonValue来记住按下了哪个按钮。该按钮是事件源,因此我们只是存储它,我们稍后可以知道哪一个被按下了。
  2. 我们不需要ActionListener的4个实例(每个按钮一个),因为它们都做同样的事情(将事件源存储为按下的"按钮&#39 ;
  3. 绘图技巧是通过使用JPanel(shapesPanel变量)作为"绘制画布"来完成的。我们扩展JPanel以覆盖paintComponent。此方法将使用Graphics2D
  4. 的形状绘制API
  5. ActionListener添加的contentPane将获得点击的x和y坐标,创建要绘制的Shape(基于最后lastButtonPressed的内容),将其存储在变量shape并向shapesPanel询问repaint()本身。

答案 2 :(得分:-1)

您可以在内容窗格中添加新的JPanel,可能位于中心

JPanel drawingPanel = new JPanel();
getContentPane().add(drawingPanel, BorderLayout.CENTER);

然后你会在每个按钮的动作listerner代码中调用代码来绘制JPanel的图形:

rectButton.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
           Graphics2D g = Graphics2D drawingPanel.getGraphics2D(); 
           g.draw(new java.awt.Rectangle(42,42,20,40);

        }
    });

依旧......

您需要熟悉Java2D才能完成FinalExam软件包的工作。