在 Java 中制作屏幕截图的 JTextPane 坐标
Coordinates of a JTextPane to make a Screenshot in Java
我希望有人能帮助我,这就是我想做的。
我有一个 JTextPane,我想截取该特定 JTextPane 坐标和大小的屏幕截图,到目前为止,我可以使用 JTextPane 的大小截取屏幕截图,但我无法获取屏幕截图始终获取的特定坐标(0,0) 坐标。
这是我的方法:
void capturaPantalla ()
{
try
{
int x = txtCodigo.getX();
int y = txtCodigo.getY();
Rectangle areaCaptura = new Rectangle(x, y, txtCodigo.getWidth(), txtCodigo.getHeight());
BufferedImage capturaPantalla = new Robot().createScreenCapture(areaCaptura);
File ruta = new File("P:\captura.png");
ImageIO.write(capturaPantalla, "png", ruta);
JOptionPane.showMessageDialog(null, "Codigo de barras guardado!");
}
catch (IOException ioe)
{
System.out.println(ioe);
}
catch(AWTException ex)
{
System.out.println(ex);
}
}
当您在任何 Swing 组件上调用 getX()
和 getY()
时,您将获得相对于组件容器而非屏幕的 x 和 y ,而不是屏幕。相反,您想要组件相对于屏幕的位置,并通过 getLocationOnScreen()
基于该位置获取位置
Point p = txtCodigo.getLocationOnScreen();
int x = p.x;
int y = p.y;
根据 MadProgrammer 的评论,您可以简单地在您的 txtCodigo 组件上调用 printAll(Graphics g)
,传入从适当大小的 BufferedImage 获得的 Graphics 对象并放弃使用 Robot。
Dimension d = txtCodigo.getSize();
BufferedImage img = new BufferedImage(d.width, d.height, BufferedImage.TYPE_INT_ARGB);
Graphics g = img.getGraphics();
txtCodigo.printAll(g);
g.dispose();
// use ImageIO to write BufferedImage to file
两种方法比较:
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.swing.*;
@SuppressWarnings("serial")
public class RobotVsPrintAll extends JPanel {
private static final int WORDS = 400;
private JTextArea textArea = new JTextArea(20, 40);
private JScrollPane scrollPane = new JScrollPane(textArea);
private Random random = new Random();
public RobotVsPrintAll() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < WORDS; i++) {
int wordLength = random.nextInt(4) + 4;
for (int j = 0; j < wordLength; j++) {
char myChar = (char) (random.nextInt('z' - 'a' + 1) + 'a');
sb.append(myChar);
}
sb.append(" ");
}
textArea.setText(sb.toString());
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JButton robot1Btn = new JButton(new Robot1Action("Robot 1"));
JButton robot2Btn = new JButton(new Robot2Action("Robot 2"));
JButton printAllBtn = new JButton(new PrintAllAction("Print All"));
JPanel btnPanel = new JPanel();
btnPanel.add(robot1Btn);
btnPanel.add(robot2Btn);
btnPanel.add(printAllBtn);
setLayout(new BorderLayout());
add(scrollPane, BorderLayout.CENTER);
add(btnPanel, BorderLayout.PAGE_END);
}
private void displayImg(BufferedImage img) {
ImageIcon icon = new ImageIcon(img);
JOptionPane.showMessageDialog(this, icon, "Display Image",
JOptionPane.PLAIN_MESSAGE);
}
private class Robot1Action extends AbstractAction {
public Robot1Action(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
try {
Component comp = scrollPane.getViewport();
Point p = comp.getLocationOnScreen();
Dimension d = comp.getSize();
Robot robot = new Robot();
Rectangle screenRect = new Rectangle(p.x, p.y, d.width, d.height);
BufferedImage img = robot.createScreenCapture(screenRect);
displayImg(img);
} catch (AWTException e1) {
e1.printStackTrace();
}
}
}
private class Robot2Action extends AbstractAction {
public Robot2Action(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
try {
Component comp = textArea;
Point p = comp.getLocationOnScreen();
Dimension d = comp.getSize();
Robot robot = new Robot();
Rectangle screenRect = new Rectangle(p.x, p.y, d.width, d.height);
BufferedImage img = robot.createScreenCapture(screenRect);
displayImg(img);
} catch (AWTException e1) {
e1.printStackTrace();
}
}
}
private class PrintAllAction extends AbstractAction {
public PrintAllAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
public void actionPerformed(ActionEvent e) {
Dimension d = textArea.getSize();
BufferedImage img = new BufferedImage(d.width, d.height, BufferedImage.TYPE_INT_ARGB);
Graphics g = img.getGraphics();
textArea.printAll(g);
g.dispose();
displayImg(img);
}
}
private static void createAndShowGui() {
RobotVsPrintAll mainPanel = new RobotVsPrintAll();
JFrame frame = new JFrame("Robot Vs PrintAll");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
如果您使用 printAll 打印文本组件,您将获得整个文本组件,甚至是未显示在 JScrollPane 视口中的部分。
您可以使用 Screen Image class 为您完成所有工作。您所要做的就是指定要捕获的组件。
代码为:
BufferedImage bi = ScreenImage.createImage( component );
您可以使用以下方法将图像保存到文件:
ScreenImage.writeImage(bi, "imageName.jpg");
本次class将使用Swing组件的绘画方式,比使用Robot效率更高
我希望有人能帮助我,这就是我想做的。
我有一个 JTextPane,我想截取该特定 JTextPane 坐标和大小的屏幕截图,到目前为止,我可以使用 JTextPane 的大小截取屏幕截图,但我无法获取屏幕截图始终获取的特定坐标(0,0) 坐标。
这是我的方法:
void capturaPantalla ()
{
try
{
int x = txtCodigo.getX();
int y = txtCodigo.getY();
Rectangle areaCaptura = new Rectangle(x, y, txtCodigo.getWidth(), txtCodigo.getHeight());
BufferedImage capturaPantalla = new Robot().createScreenCapture(areaCaptura);
File ruta = new File("P:\captura.png");
ImageIO.write(capturaPantalla, "png", ruta);
JOptionPane.showMessageDialog(null, "Codigo de barras guardado!");
}
catch (IOException ioe)
{
System.out.println(ioe);
}
catch(AWTException ex)
{
System.out.println(ex);
}
}
当您在任何 Swing 组件上调用 getX()
和 getY()
时,您将获得相对于组件容器而非屏幕的 x 和 y ,而不是屏幕。相反,您想要组件相对于屏幕的位置,并通过 getLocationOnScreen()
Point p = txtCodigo.getLocationOnScreen();
int x = p.x;
int y = p.y;
根据 MadProgrammer 的评论,您可以简单地在您的 txtCodigo 组件上调用 printAll(Graphics g)
,传入从适当大小的 BufferedImage 获得的 Graphics 对象并放弃使用 Robot。
Dimension d = txtCodigo.getSize();
BufferedImage img = new BufferedImage(d.width, d.height, BufferedImage.TYPE_INT_ARGB);
Graphics g = img.getGraphics();
txtCodigo.printAll(g);
g.dispose();
// use ImageIO to write BufferedImage to file
两种方法比较:
import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.swing.*;
@SuppressWarnings("serial")
public class RobotVsPrintAll extends JPanel {
private static final int WORDS = 400;
private JTextArea textArea = new JTextArea(20, 40);
private JScrollPane scrollPane = new JScrollPane(textArea);
private Random random = new Random();
public RobotVsPrintAll() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < WORDS; i++) {
int wordLength = random.nextInt(4) + 4;
for (int j = 0; j < wordLength; j++) {
char myChar = (char) (random.nextInt('z' - 'a' + 1) + 'a');
sb.append(myChar);
}
sb.append(" ");
}
textArea.setText(sb.toString());
textArea.setLineWrap(true);
textArea.setWrapStyleWord(true);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
JButton robot1Btn = new JButton(new Robot1Action("Robot 1"));
JButton robot2Btn = new JButton(new Robot2Action("Robot 2"));
JButton printAllBtn = new JButton(new PrintAllAction("Print All"));
JPanel btnPanel = new JPanel();
btnPanel.add(robot1Btn);
btnPanel.add(robot2Btn);
btnPanel.add(printAllBtn);
setLayout(new BorderLayout());
add(scrollPane, BorderLayout.CENTER);
add(btnPanel, BorderLayout.PAGE_END);
}
private void displayImg(BufferedImage img) {
ImageIcon icon = new ImageIcon(img);
JOptionPane.showMessageDialog(this, icon, "Display Image",
JOptionPane.PLAIN_MESSAGE);
}
private class Robot1Action extends AbstractAction {
public Robot1Action(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
try {
Component comp = scrollPane.getViewport();
Point p = comp.getLocationOnScreen();
Dimension d = comp.getSize();
Robot robot = new Robot();
Rectangle screenRect = new Rectangle(p.x, p.y, d.width, d.height);
BufferedImage img = robot.createScreenCapture(screenRect);
displayImg(img);
} catch (AWTException e1) {
e1.printStackTrace();
}
}
}
private class Robot2Action extends AbstractAction {
public Robot2Action(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
try {
Component comp = textArea;
Point p = comp.getLocationOnScreen();
Dimension d = comp.getSize();
Robot robot = new Robot();
Rectangle screenRect = new Rectangle(p.x, p.y, d.width, d.height);
BufferedImage img = robot.createScreenCapture(screenRect);
displayImg(img);
} catch (AWTException e1) {
e1.printStackTrace();
}
}
}
private class PrintAllAction extends AbstractAction {
public PrintAllAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
public void actionPerformed(ActionEvent e) {
Dimension d = textArea.getSize();
BufferedImage img = new BufferedImage(d.width, d.height, BufferedImage.TYPE_INT_ARGB);
Graphics g = img.getGraphics();
textArea.printAll(g);
g.dispose();
displayImg(img);
}
}
private static void createAndShowGui() {
RobotVsPrintAll mainPanel = new RobotVsPrintAll();
JFrame frame = new JFrame("Robot Vs PrintAll");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
如果您使用 printAll 打印文本组件,您将获得整个文本组件,甚至是未显示在 JScrollPane 视口中的部分。
您可以使用 Screen Image class 为您完成所有工作。您所要做的就是指定要捕获的组件。
代码为:
BufferedImage bi = ScreenImage.createImage( component );
您可以使用以下方法将图像保存到文件:
ScreenImage.writeImage(bi, "imageName.jpg");
本次class将使用Swing组件的绘画方式,比使用Robot效率更高