如何保存在 JPanel 中绘制的线条?
How can I save the lines painted in a JPanel?
我最初是在寻找一个库来为 java 制作 "mousewritten" 或 "handwritten" 签名。我没有找到任何东西,所以我只是想让用户在 JPanel 上绘制 canvas,然后他可以选择保存、重新绘制或取消签名。我遇到的问题是,当我试图将绘制的东西保存在 canvas 中时,我得到一个空的 .jpeg
到目前为止我的代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.colorchooser.*;
import javax.swing.event.*;
import java.awt.geom.Line2D;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
public class AES_Encryption extends JFrame implements ActionListener{
public BufferedImage image = new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);
//JPanel canvas = new JPanel();
JPanel buttonPanel = new JPanel();
Point lastPos = null;
Point startPos = null;
Point finishPos = null;
Graphics g;
JButton save = new JButton("Save");
JButton cancel = new JButton("Cancel");
JButton clear = new JButton("Clear");
JPanel canvas = new JPanel();
int changer = 1;
String path="";
public AES_Encryption () {
setLocation(100,100);
setSize(600,500);
setTitle("ENCODE SECTION");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
canvas.setBackground(Color.WHITE);
clear.addActionListener(this);
clear.setActionCommand("clear");
save.addActionListener(this);
save.setActionCommand("Save");
cancel.addActionListener(this);
cancel.setActionCommand("Cancel");
//add buttons here
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
buttonPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
buttonPanel.add(Box.createHorizontalGlue());
buttonPanel.add(save);
buttonPanel.add(Box.createRigidArea(new Dimension(10, 0)));
buttonPanel.add(clear);
buttonPanel.add(Box.createRigidArea(new Dimension(10, 0)));
buttonPanel.add(cancel);
//set the look
getContentPane().add(canvas, BorderLayout.CENTER);
getContentPane().add(buttonPanel, BorderLayout.SOUTH);
setVisible(true);
g = canvas.getGraphics();
g.setColor(Color.BLACK);
canvas.addMouseMotionListener(new MouseMotionListener () {
public void mouseDragged (MouseEvent m) {
Point p = m.getPoint() ;
if (changer==1){
g.drawLine(lastPos.x, lastPos.y, p.x, p.y) ;
}
lastPos = p ;
}
public void mouseMoved (MouseEvent m) {}
});
canvas.addMouseListener(new MouseListener () {
public void mouseClicked(MouseEvent e) {startPos = e.getPoint();}
public void mousePressed(MouseEvent e) {lastPos = e.getPoint();}
public void mouseReleased(MouseEvent e) {
lastPos = null;
finishPos = e.getPoint();
startPos = null;}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
});
}
public void actionPerformed(ActionEvent e) {
if("clear".equals(e.getActionCommand())) {
repaint();
}
if("Save".equals(e.getActionCommand())) {
captureCanvasImage myCanvas = new captureCanvasImage();
myCanvas.capture();
}
if("Cancel".equals(e.getActionCommand())) {
dispose();
}}
class captureCanvasImage {
public void capture(){
BufferedImage imagebuf=null;
try {
imagebuf = new Robot().createScreenCapture(canvas.bounds());
} catch (AWTException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Graphics2D graphics2D = imagebuf.createGraphics();
canvas.paint(graphics2D);
try {
ImageIO.write(imagebuf,"jpeg", new File("save1.jpeg"));
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("error");
}
}
}
/*
@Override
public void invalidate() {
super.invalidate();
this.paint(this.getGraphics());
}
*/
public static void main (String [] args) {
AES_Encryption p = new AES_Encryption();
p.setVisible(true);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
p.setLocation(dim.width/2-p.getSize().width/2, dim.height/2-p.getSize().height/2);
}
}
创建线的坐标时,将它们保存在列表中。
List<Point> points = new ArrayList<>(); // instance field.
canvas.addMouseMotionListener(new MouseMotionListener () {
public void mouseDragged (MouseEvent m) {
Point p = m.getPoint() ;
if (changer==1){
g.drawLine(lastPos.x, lastPos.y, p.x, p.y) ;
points.add(lastPos);// add it here.
}
lastPos = p ;
}
public void mouseMoved (MouseEvent m) {}
});
这是一个例子。您需要确定放置 points.add()
代码的位置。查看绘画示例here
已编辑:
这里有一个如何绘制window的例子。不要在 paint
或 paintComponent
等绘画环境之外使用图形上下文(例外情况是 buffered images
等,它们不会在 EDT
中绘画)。
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ExampleDrawDemo extends JPanel {
int WIDTH = 600;
int HEIGHT = 500;
JFrame frame = new JFrame();
List<Line> lines;
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new ExampleDrawDemo().start());
}
public void start() {
Random r = new Random();
Color[] color = {
Color.RED, Color.BLUE, Color.GREEN, Color.MAGENTA, Color.ORANGE,
Color.CYAN
};
// generate some lines.
lines = IntStream.range(0, 100).mapToObj(
i -> new Line(r, color[r.nextInt(color.length)])).collect(
Collectors.toList());
setPreferredSize(new Dimension(600, 500));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
// smooth lines
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// line thickness
g2d.setStroke(new BasicStroke(2));
for (Line line : lines) {
g2d.setColor(line.color);
g2d.drawLine(line.start.x, line.start.y, line.end.x, line.end.y);
}
g2d.dispose();
}
class Line {
Point start;
Point end;
Color color;
public Line(Random r, Color color) {
this.color = color;
start = new Point(r.nextInt(WIDTH), r.nextInt(HEIGHT));
end = new Point(r.nextInt(WIDTH), r.nextInt(HEIGHT));
}
}
}
我最初是在寻找一个库来为 java 制作 "mousewritten" 或 "handwritten" 签名。我没有找到任何东西,所以我只是想让用户在 JPanel 上绘制 canvas,然后他可以选择保存、重新绘制或取消签名。我遇到的问题是,当我试图将绘制的东西保存在 canvas 中时,我得到一个空的 .jpeg
到目前为止我的代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.colorchooser.*;
import javax.swing.event.*;
import java.awt.geom.Line2D;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
public class AES_Encryption extends JFrame implements ActionListener{
public BufferedImage image = new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);
//JPanel canvas = new JPanel();
JPanel buttonPanel = new JPanel();
Point lastPos = null;
Point startPos = null;
Point finishPos = null;
Graphics g;
JButton save = new JButton("Save");
JButton cancel = new JButton("Cancel");
JButton clear = new JButton("Clear");
JPanel canvas = new JPanel();
int changer = 1;
String path="";
public AES_Encryption () {
setLocation(100,100);
setSize(600,500);
setTitle("ENCODE SECTION");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
canvas.setBackground(Color.WHITE);
clear.addActionListener(this);
clear.setActionCommand("clear");
save.addActionListener(this);
save.setActionCommand("Save");
cancel.addActionListener(this);
cancel.setActionCommand("Cancel");
//add buttons here
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
buttonPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
buttonPanel.add(Box.createHorizontalGlue());
buttonPanel.add(save);
buttonPanel.add(Box.createRigidArea(new Dimension(10, 0)));
buttonPanel.add(clear);
buttonPanel.add(Box.createRigidArea(new Dimension(10, 0)));
buttonPanel.add(cancel);
//set the look
getContentPane().add(canvas, BorderLayout.CENTER);
getContentPane().add(buttonPanel, BorderLayout.SOUTH);
setVisible(true);
g = canvas.getGraphics();
g.setColor(Color.BLACK);
canvas.addMouseMotionListener(new MouseMotionListener () {
public void mouseDragged (MouseEvent m) {
Point p = m.getPoint() ;
if (changer==1){
g.drawLine(lastPos.x, lastPos.y, p.x, p.y) ;
}
lastPos = p ;
}
public void mouseMoved (MouseEvent m) {}
});
canvas.addMouseListener(new MouseListener () {
public void mouseClicked(MouseEvent e) {startPos = e.getPoint();}
public void mousePressed(MouseEvent e) {lastPos = e.getPoint();}
public void mouseReleased(MouseEvent e) {
lastPos = null;
finishPos = e.getPoint();
startPos = null;}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
});
}
public void actionPerformed(ActionEvent e) {
if("clear".equals(e.getActionCommand())) {
repaint();
}
if("Save".equals(e.getActionCommand())) {
captureCanvasImage myCanvas = new captureCanvasImage();
myCanvas.capture();
}
if("Cancel".equals(e.getActionCommand())) {
dispose();
}}
class captureCanvasImage {
public void capture(){
BufferedImage imagebuf=null;
try {
imagebuf = new Robot().createScreenCapture(canvas.bounds());
} catch (AWTException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Graphics2D graphics2D = imagebuf.createGraphics();
canvas.paint(graphics2D);
try {
ImageIO.write(imagebuf,"jpeg", new File("save1.jpeg"));
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println("error");
}
}
}
/*
@Override
public void invalidate() {
super.invalidate();
this.paint(this.getGraphics());
}
*/
public static void main (String [] args) {
AES_Encryption p = new AES_Encryption();
p.setVisible(true);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
p.setLocation(dim.width/2-p.getSize().width/2, dim.height/2-p.getSize().height/2);
}
}
创建线的坐标时,将它们保存在列表中。
List<Point> points = new ArrayList<>(); // instance field.
canvas.addMouseMotionListener(new MouseMotionListener () {
public void mouseDragged (MouseEvent m) {
Point p = m.getPoint() ;
if (changer==1){
g.drawLine(lastPos.x, lastPos.y, p.x, p.y) ;
points.add(lastPos);// add it here.
}
lastPos = p ;
}
public void mouseMoved (MouseEvent m) {}
});
这是一个例子。您需要确定放置 points.add()
代码的位置。查看绘画示例here
已编辑:
这里有一个如何绘制window的例子。不要在 paint
或 paintComponent
等绘画环境之外使用图形上下文(例外情况是 buffered images
等,它们不会在 EDT
中绘画)。
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ExampleDrawDemo extends JPanel {
int WIDTH = 600;
int HEIGHT = 500;
JFrame frame = new JFrame();
List<Line> lines;
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new ExampleDrawDemo().start());
}
public void start() {
Random r = new Random();
Color[] color = {
Color.RED, Color.BLUE, Color.GREEN, Color.MAGENTA, Color.ORANGE,
Color.CYAN
};
// generate some lines.
lines = IntStream.range(0, 100).mapToObj(
i -> new Line(r, color[r.nextInt(color.length)])).collect(
Collectors.toList());
setPreferredSize(new Dimension(600, 500));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(this);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
// smooth lines
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// line thickness
g2d.setStroke(new BasicStroke(2));
for (Line line : lines) {
g2d.setColor(line.color);
g2d.drawLine(line.start.x, line.start.y, line.end.x, line.end.y);
}
g2d.dispose();
}
class Line {
Point start;
Point end;
Color color;
public Line(Random r, Color color) {
this.color = color;
start = new Point(r.nextInt(WIDTH), r.nextInt(HEIGHT));
end = new Point(r.nextInt(WIDTH), r.nextInt(HEIGHT));
}
}
}