无法让我的面板另存为图像
Can't get my panel to save as an image
我做了一个简单的画图程序,但似乎有一些问题。首先,当我 运行 程序时,组件不会显示,直到我将鼠标拖到每个组件上。其次,我创建的 drawPanel 图像仅保存面板的背景,而不保存其上绘制的内容。另一个小问题是,当我通过下拉菜单更改点的大小时,在它下面绘制的任何内容都会被删除。任何关于清理我的代码或解决我的问题的建议都会很棒。
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class MyPaint extends JFrame implements MouseListener, MouseMotionListener, ActionListener {
//initialize coordinates somewhere offscreen
int myX = -100, myY = -100;
private JPanel bucket = new JPanel(new GridLayout(7, 2));
private JPanel northPanel = new JPanel(new GridBagLayout());
private JPanel drawPanel = new JPanel();
GridBagConstraints c = new GridBagConstraints();
private String[] pencilSize = {"1", "5", "10", "15", "20"};
private JComboBox sizeList = new JComboBox(pencilSize);
private JButton[] buttons = new JButton[11];
private Color[] colorList = {Color.RED, Color.BLUE, Color.ORANGE, Color.CYAN, Color.YELLOW, Color.GREEN,
Color.WHITE, Color.MAGENTA, Color.GRAY, Color.PINK, Color.BLACK};
private Color currentColor = Color.BLACK;
int radius = 5;
private JLabel thickness = new JLabel("Thickness");
private JButton clear = new JButton("Clear");
private JButton save = new JButton("Save");
private JButton open = new JButton("Open");
private JLabel image = new JLabel(" ");
JFileChooser fc = new JFileChooser();
// ******************* MyPaint **************
public MyPaint(){
super("MyPaint");
setSize(1000, 1000);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addMouseListener(this);
addMouseMotionListener(this);
setVisible(true);
setResizable(false);
sizeList.setEditable(true);
drawPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
for(int i = 0; i < buttons.length; i++){
buttons[i] = new JButton();
buttons[i].setBackground(colorList[i]);
buttons[i].addActionListener(this);
bucket.add(buttons[i]);
}
northPanel.add(clear);
clear.addActionListener(this);
northPanel.add(thickness);
northPanel.add(sizeList);
sizeList.addActionListener(this);
northPanel.add(open);
open.addActionListener(this);
northPanel.add(save);
save.addActionListener(this);
add(drawPanel, BorderLayout.CENTER);
add(bucket, BorderLayout.WEST);
add(northPanel, BorderLayout.NORTH);
}
// ******************* Override of paint **************
//paint the oval at the current location
public void paint(Graphics g){
g.setColor(currentColor);
if(myX > drawPanel.getX() + 10 && myY > drawPanel.getY() + 25)
g.fillOval(myX - radius, myY - radius, 2 * radius, 2 * radius);
}
// ******************* Mouse Events **************
public void mouseClicked(MouseEvent e){
myX = e.getX();
myY = e.getY();
repaint();
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseDragged(MouseEvent e){
myX = e.getX();
myY = e.getY();
repaint();
}
public void mouseMoved(MouseEvent e){
}
// ******************* Actions **************
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
for(int i = 0; i < buttons.length; i++)
if(source == buttons[i])
currentColor = colorList[i];
if(source == clear)
super.paint(getGraphics());
else if(source == sizeList)
radius = Integer.parseInt((String) sizeList.getSelectedItem());
//open a file
else if(source == open){
int returnValue = fc.showOpenDialog(null);
if (returnValue == fc.APPROVE_OPTION) {
File sf = fc.getSelectedFile();
try {
image.setIcon(new ImageIcon(ImageIO.read(sf)));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
super.paint(getGraphics());
drawPanel.add(image);
drawPanel.revalidate();
drawPanel.repaint();
}
}
//save a file
else if(source == save){
fc.setDialogTitle("Specify a file to save");
int userSelection = fc.showSaveDialog(drawPanel);
if (userSelection == JFileChooser.APPROVE_OPTION) {
File fileToSave = fc.getSelectedFile();
try{
BufferedImage image = new BufferedImage(drawPanel.getWidth(),
drawPanel.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
Graphics g = image.getGraphics();
drawPanel.printAll(g);
g.dispose();
ImageIO.write(image, "png", new File("pic.png"));
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
// ******************* Main **************
public static void main(String[] args){
MyPaint frame = new MyPaint();
frame.setVisible(true);
}
}
编辑:
我用 paintComponent() 替换了 paint() 但我仍然不知道如何在上面绘图,因为 g.fillOval...() 什么都不做
public void paintComponent(Graphics g) {
super.paintComponents(g);
g.setColor(currentColor);
g.fillOval(myX - radius, myY - radius, 2 * radius, 2 * radius);
if(img != null)
g.drawImage(img, 0, 0, null);
}
编辑 2:
小版
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class MySmallPaint extends JPanel implements MouseListener, MouseMotionListener, ActionListener{
int myX = 0, myY = 0;
int radius = 5;
JPanel drawPanel = new JPanel();
Dimension d = drawPanel.getPreferredSize();
BufferedImage img = new BufferedImage(d.width,d.height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = img.createGraphics();
public MySmallPaint(){
super();
setSize(1000, 1000);
addMouseListener(this);
addMouseMotionListener(this);
//add(drawPanel, BorderLayout.CENTER);
}
public void paintComponent(Graphics g) {
super.paintComponents(g);
g.fillOval(myX - radius, myY - radius, 2 * radius, 2 * radius);
if(img != null)
g.drawImage(img, 0, 0, null);
}
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
myX = e.getX();
myY = e.getY();
repaint();
}
@Override
public void mouseMoved(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseClicked(MouseEvent e) {
myX = e.getX();
myY = e.getY();
repaint();
}
@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
}
@Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public static void main(String[] args){
JFrame f = new JFrame("Swing Paint Demo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new MySmallPaint());
f.pack();
f.setVisible(true);
}
}
解决了一个问题:
您没有在您的 paint 方法覆盖中调用 super 的 paint 方法,这样做不允许 GUI 绘制它自己的组件。换句话说,你没有这样做:
public void paint(Graphics g) {
super.paint(g); // *************** missing ************
g.setColor(currentColor);
if (myX > drawPanel.getX() + 10 && myY > drawPanel.getY() + 25)
g.fillOval(myX - radius, myY - radius, 2 * radius, 2 * radius);
}
但话虽如此,我也强烈建议您不要像现在这样绘制,而是重写 JPanel 的 paintComponent 方法并在其中绘制。通过直接在 JFrame 上绘制,您可能会弄乱它如何绘制自身、组件、边框……正如您所发现的那样。 JFrames 是复杂的组件,包含许多子组件,包括 JRootPanes、contentPanes、JLayeredPanes、glasspanes 等,您真的不想冒险弄乱这些子组件的绘制。
接下来,要将图像保存在绘图中,绘制到 BufferedImage,然后在绘图 JPanel(附加了 MouseListener 的)paintComponent 中显示该 BufferedImage,例如:
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (myImage != null) {
g.drawImage(myImage, 0, 0, null);
}
}
因此,在您的鼠标侦听器中,您使用从图像上调用 getGraphics()
或 createGraphics()
获得的 Graphics 绘制此图像。前者获取一个 Graphics 对象,而后者获取一个 Graphics2D 对象。请注意,这与在 不推荐 的组件上调用 getGraphics()
不同(根据我的评论)。另请注意,以这种方式获得的任何 Graphics 对象都应在您使用完后丢弃,以免浪费资源。
I created a BufferedImage but how do I add it to my drawPanel / JFrame.
您的绘图 JPanel 可以将 BufferedImage 作为字段保存。当您需要在其上绘图时,您会获得其 Graphics 上下文,如上文所述——请注意,我更喜欢使用 createGraphics()
来获取 Graphics2D 对象,这样我就可以使用它的所有好东西,例如 Strokes。您将 BufferedImage 调整为您的 JPanel 的首选大小,然后按照我在上面显示的方式绘制它。
I am also unsure as how to draw on the buffered image.
如上所述。另请注意,如果您尝试创建连接图,通常最好绘制直线而不是椭圆形或椭圆形
举个简单的例子,一个没有你想要做的所有事情的例子......
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
@SuppressWarnings("serial")
public class SimpleDrawMain extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
private SimpleDrawPanel simpleDrawPanel = new SimpleDrawPanel(PREF_W, PREF_H);
private MyMouse myMouse = new MyMouse();
// drawStroke: thickness of lines drawn. Can change this as needed
private Stroke drawStroke = new BasicStroke(6f);
// drawColor -- change this as needed
private Color drawColor = Color.BLUE;
public SimpleDrawMain() {
simpleDrawPanel.addMouseListener(myMouse);
simpleDrawPanel.addMouseMotionListener(myMouse);
simpleDrawPanel.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
JPanel topPanel = new JPanel();
topPanel.add(new JButton(new SaveImageAction("Save", KeyEvent.VK_S)));
topPanel.add(new JButton(new ClearImageAction("Clear", KeyEvent.VK_C)));
setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(simpleDrawPanel, BorderLayout.CENTER);
}
private class MyMouse extends MouseAdapter {
private Graphics2D g2;
private Point point; // point to draw a line with
@Override
public void mousePressed(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
// get our Graphics object to draw with
g2 = simpleDrawPanel.getMyImage().createGraphics();
point = e.getPoint(); // get the first point
g2.setStroke(drawStroke); // set stroke and color
g2.setColor(drawColor);
}
@Override
public void mouseDragged(MouseEvent e) {
if (point == null) {
return;
}
drawOnImage(e);
}
@Override
public void mouseReleased(MouseEvent e) {
if (point == null) {
return;
}
drawOnImage(e);
// clean up things
g2.dispose();
g2 = null;
point = null;
}
private void drawOnImage(MouseEvent e) {
// better to draw a line between two points rather than an oval
// get 2nd point, and then using 2 points, create line to draw
Point p2 = e.getPoint();
int x1 = point.x;
int y1 = point.y;
int x2 = p2.x;
int y2 = p2.y;
g2.drawLine(x1, y1, x2, y2);
// reset the original point to the new point
point = p2;
simpleDrawPanel.repaint();
}
}
private class SaveImageAction extends AbstractAction {
public SaveImageAction(String name, int mnemonioc) {
super(name);
putValue(MNEMONIC_KEY, mnemonioc);
}
@Override
public void actionPerformed(ActionEvent e) {
BufferedImage img = simpleDrawPanel.getMyImage();
// TODO write code to save img to file
}
}
private class ClearImageAction extends AbstractAction {
public ClearImageAction(String name, int mnemonioc) {
super(name);
putValue(MNEMONIC_KEY, mnemonioc);
}
@Override
public void actionPerformed(ActionEvent e) {
simpleDrawPanel.clearImage();
}
}
private static void createAndShowGui() {
SimpleDrawMain mainPanel = new SimpleDrawMain();
JFrame frame = new JFrame("SimpleDraw");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setResizable(false);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class SimpleDrawPanel extends JPanel {
// preferred size dimensions for this JPanel
private int prefW;
private int prefH;
// image to draw on
private BufferedImage myImage;
public SimpleDrawPanel(int prefW, int prefH) {
this.prefW = prefW;
this.prefH = prefH;
myImage = new BufferedImage(prefW, prefH, BufferedImage.TYPE_INT_ARGB);
}
public BufferedImage getMyImage() {
return myImage;
}
public void clearImage() {
// simply create a new BufferedImage
myImage = new BufferedImage(prefW, prefH, BufferedImage.TYPE_INT_ARGB);
repaint();
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(prefW, prefH);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (myImage != null) {
g.drawImage(myImage, 0, 0, null);
}
}
}
我做了一个简单的画图程序,但似乎有一些问题。首先,当我 运行 程序时,组件不会显示,直到我将鼠标拖到每个组件上。其次,我创建的 drawPanel 图像仅保存面板的背景,而不保存其上绘制的内容。另一个小问题是,当我通过下拉菜单更改点的大小时,在它下面绘制的任何内容都会被删除。任何关于清理我的代码或解决我的问题的建议都会很棒。
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class MyPaint extends JFrame implements MouseListener, MouseMotionListener, ActionListener {
//initialize coordinates somewhere offscreen
int myX = -100, myY = -100;
private JPanel bucket = new JPanel(new GridLayout(7, 2));
private JPanel northPanel = new JPanel(new GridBagLayout());
private JPanel drawPanel = new JPanel();
GridBagConstraints c = new GridBagConstraints();
private String[] pencilSize = {"1", "5", "10", "15", "20"};
private JComboBox sizeList = new JComboBox(pencilSize);
private JButton[] buttons = new JButton[11];
private Color[] colorList = {Color.RED, Color.BLUE, Color.ORANGE, Color.CYAN, Color.YELLOW, Color.GREEN,
Color.WHITE, Color.MAGENTA, Color.GRAY, Color.PINK, Color.BLACK};
private Color currentColor = Color.BLACK;
int radius = 5;
private JLabel thickness = new JLabel("Thickness");
private JButton clear = new JButton("Clear");
private JButton save = new JButton("Save");
private JButton open = new JButton("Open");
private JLabel image = new JLabel(" ");
JFileChooser fc = new JFileChooser();
// ******************* MyPaint **************
public MyPaint(){
super("MyPaint");
setSize(1000, 1000);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addMouseListener(this);
addMouseMotionListener(this);
setVisible(true);
setResizable(false);
sizeList.setEditable(true);
drawPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
for(int i = 0; i < buttons.length; i++){
buttons[i] = new JButton();
buttons[i].setBackground(colorList[i]);
buttons[i].addActionListener(this);
bucket.add(buttons[i]);
}
northPanel.add(clear);
clear.addActionListener(this);
northPanel.add(thickness);
northPanel.add(sizeList);
sizeList.addActionListener(this);
northPanel.add(open);
open.addActionListener(this);
northPanel.add(save);
save.addActionListener(this);
add(drawPanel, BorderLayout.CENTER);
add(bucket, BorderLayout.WEST);
add(northPanel, BorderLayout.NORTH);
}
// ******************* Override of paint **************
//paint the oval at the current location
public void paint(Graphics g){
g.setColor(currentColor);
if(myX > drawPanel.getX() + 10 && myY > drawPanel.getY() + 25)
g.fillOval(myX - radius, myY - radius, 2 * radius, 2 * radius);
}
// ******************* Mouse Events **************
public void mouseClicked(MouseEvent e){
myX = e.getX();
myY = e.getY();
repaint();
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseDragged(MouseEvent e){
myX = e.getX();
myY = e.getY();
repaint();
}
public void mouseMoved(MouseEvent e){
}
// ******************* Actions **************
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
for(int i = 0; i < buttons.length; i++)
if(source == buttons[i])
currentColor = colorList[i];
if(source == clear)
super.paint(getGraphics());
else if(source == sizeList)
radius = Integer.parseInt((String) sizeList.getSelectedItem());
//open a file
else if(source == open){
int returnValue = fc.showOpenDialog(null);
if (returnValue == fc.APPROVE_OPTION) {
File sf = fc.getSelectedFile();
try {
image.setIcon(new ImageIcon(ImageIO.read(sf)));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
super.paint(getGraphics());
drawPanel.add(image);
drawPanel.revalidate();
drawPanel.repaint();
}
}
//save a file
else if(source == save){
fc.setDialogTitle("Specify a file to save");
int userSelection = fc.showSaveDialog(drawPanel);
if (userSelection == JFileChooser.APPROVE_OPTION) {
File fileToSave = fc.getSelectedFile();
try{
BufferedImage image = new BufferedImage(drawPanel.getWidth(),
drawPanel.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
Graphics g = image.getGraphics();
drawPanel.printAll(g);
g.dispose();
ImageIO.write(image, "png", new File("pic.png"));
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
// ******************* Main **************
public static void main(String[] args){
MyPaint frame = new MyPaint();
frame.setVisible(true);
}
}
编辑:
我用 paintComponent() 替换了 paint() 但我仍然不知道如何在上面绘图,因为 g.fillOval...() 什么都不做
public void paintComponent(Graphics g) {
super.paintComponents(g);
g.setColor(currentColor);
g.fillOval(myX - radius, myY - radius, 2 * radius, 2 * radius);
if(img != null)
g.drawImage(img, 0, 0, null);
}
编辑 2:
小版
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class MySmallPaint extends JPanel implements MouseListener, MouseMotionListener, ActionListener{
int myX = 0, myY = 0;
int radius = 5;
JPanel drawPanel = new JPanel();
Dimension d = drawPanel.getPreferredSize();
BufferedImage img = new BufferedImage(d.width,d.height, BufferedImage.TYPE_INT_RGB);
Graphics2D g = img.createGraphics();
public MySmallPaint(){
super();
setSize(1000, 1000);
addMouseListener(this);
addMouseMotionListener(this);
//add(drawPanel, BorderLayout.CENTER);
}
public void paintComponent(Graphics g) {
super.paintComponents(g);
g.fillOval(myX - radius, myY - radius, 2 * radius, 2 * radius);
if(img != null)
g.drawImage(img, 0, 0, null);
}
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
myX = e.getX();
myY = e.getY();
repaint();
}
@Override
public void mouseMoved(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseClicked(MouseEvent e) {
myX = e.getX();
myY = e.getY();
repaint();
}
@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
}
@Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public static void main(String[] args){
JFrame f = new JFrame("Swing Paint Demo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new MySmallPaint());
f.pack();
f.setVisible(true);
}
}
解决了一个问题:
您没有在您的 paint 方法覆盖中调用 super 的 paint 方法,这样做不允许 GUI 绘制它自己的组件。换句话说,你没有这样做:
public void paint(Graphics g) {
super.paint(g); // *************** missing ************
g.setColor(currentColor);
if (myX > drawPanel.getX() + 10 && myY > drawPanel.getY() + 25)
g.fillOval(myX - radius, myY - radius, 2 * radius, 2 * radius);
}
但话虽如此,我也强烈建议您不要像现在这样绘制,而是重写 JPanel 的 paintComponent 方法并在其中绘制。通过直接在 JFrame 上绘制,您可能会弄乱它如何绘制自身、组件、边框……正如您所发现的那样。 JFrames 是复杂的组件,包含许多子组件,包括 JRootPanes、contentPanes、JLayeredPanes、glasspanes 等,您真的不想冒险弄乱这些子组件的绘制。
接下来,要将图像保存在绘图中,绘制到 BufferedImage,然后在绘图 JPanel(附加了 MouseListener 的)paintComponent 中显示该 BufferedImage,例如:
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (myImage != null) {
g.drawImage(myImage, 0, 0, null);
}
}
因此,在您的鼠标侦听器中,您使用从图像上调用 getGraphics()
或 createGraphics()
获得的 Graphics 绘制此图像。前者获取一个 Graphics 对象,而后者获取一个 Graphics2D 对象。请注意,这与在 不推荐 的组件上调用 getGraphics()
不同(根据我的评论)。另请注意,以这种方式获得的任何 Graphics 对象都应在您使用完后丢弃,以免浪费资源。
I created a BufferedImage but how do I add it to my drawPanel / JFrame.
您的绘图 JPanel 可以将 BufferedImage 作为字段保存。当您需要在其上绘图时,您会获得其 Graphics 上下文,如上文所述——请注意,我更喜欢使用 createGraphics()
来获取 Graphics2D 对象,这样我就可以使用它的所有好东西,例如 Strokes。您将 BufferedImage 调整为您的 JPanel 的首选大小,然后按照我在上面显示的方式绘制它。
I am also unsure as how to draw on the buffered image.
如上所述。另请注意,如果您尝试创建连接图,通常最好绘制直线而不是椭圆形或椭圆形
举个简单的例子,一个没有你想要做的所有事情的例子......
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
@SuppressWarnings("serial")
public class SimpleDrawMain extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
private SimpleDrawPanel simpleDrawPanel = new SimpleDrawPanel(PREF_W, PREF_H);
private MyMouse myMouse = new MyMouse();
// drawStroke: thickness of lines drawn. Can change this as needed
private Stroke drawStroke = new BasicStroke(6f);
// drawColor -- change this as needed
private Color drawColor = Color.BLUE;
public SimpleDrawMain() {
simpleDrawPanel.addMouseListener(myMouse);
simpleDrawPanel.addMouseMotionListener(myMouse);
simpleDrawPanel.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
JPanel topPanel = new JPanel();
topPanel.add(new JButton(new SaveImageAction("Save", KeyEvent.VK_S)));
topPanel.add(new JButton(new ClearImageAction("Clear", KeyEvent.VK_C)));
setLayout(new BorderLayout());
add(topPanel, BorderLayout.PAGE_START);
add(simpleDrawPanel, BorderLayout.CENTER);
}
private class MyMouse extends MouseAdapter {
private Graphics2D g2;
private Point point; // point to draw a line with
@Override
public void mousePressed(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
// get our Graphics object to draw with
g2 = simpleDrawPanel.getMyImage().createGraphics();
point = e.getPoint(); // get the first point
g2.setStroke(drawStroke); // set stroke and color
g2.setColor(drawColor);
}
@Override
public void mouseDragged(MouseEvent e) {
if (point == null) {
return;
}
drawOnImage(e);
}
@Override
public void mouseReleased(MouseEvent e) {
if (point == null) {
return;
}
drawOnImage(e);
// clean up things
g2.dispose();
g2 = null;
point = null;
}
private void drawOnImage(MouseEvent e) {
// better to draw a line between two points rather than an oval
// get 2nd point, and then using 2 points, create line to draw
Point p2 = e.getPoint();
int x1 = point.x;
int y1 = point.y;
int x2 = p2.x;
int y2 = p2.y;
g2.drawLine(x1, y1, x2, y2);
// reset the original point to the new point
point = p2;
simpleDrawPanel.repaint();
}
}
private class SaveImageAction extends AbstractAction {
public SaveImageAction(String name, int mnemonioc) {
super(name);
putValue(MNEMONIC_KEY, mnemonioc);
}
@Override
public void actionPerformed(ActionEvent e) {
BufferedImage img = simpleDrawPanel.getMyImage();
// TODO write code to save img to file
}
}
private class ClearImageAction extends AbstractAction {
public ClearImageAction(String name, int mnemonioc) {
super(name);
putValue(MNEMONIC_KEY, mnemonioc);
}
@Override
public void actionPerformed(ActionEvent e) {
simpleDrawPanel.clearImage();
}
}
private static void createAndShowGui() {
SimpleDrawMain mainPanel = new SimpleDrawMain();
JFrame frame = new JFrame("SimpleDraw");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setResizable(false);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class SimpleDrawPanel extends JPanel {
// preferred size dimensions for this JPanel
private int prefW;
private int prefH;
// image to draw on
private BufferedImage myImage;
public SimpleDrawPanel(int prefW, int prefH) {
this.prefW = prefW;
this.prefH = prefH;
myImage = new BufferedImage(prefW, prefH, BufferedImage.TYPE_INT_ARGB);
}
public BufferedImage getMyImage() {
return myImage;
}
public void clearImage() {
// simply create a new BufferedImage
myImage = new BufferedImage(prefW, prefH, BufferedImage.TYPE_INT_ARGB);
repaint();
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(prefW, prefH);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (myImage != null) {
g.drawImage(myImage, 0, 0, null);
}
}
}