源代码地址:github
运行环境:win10,因为用了dll文件,不跨平台!
程序GUI界面(很简陋):
截屏效果:
图片信息:
程序编写思路:
首先Java程序在失去焦点后无法使用全局快捷键的功能,例如实现Esc+Shift+Ctrl同时按下启动任务管理器。
为此这里使用了c++编写的动态链接库dll文件,JIntellitype.jar包内已经用c++实现了全局快捷键接口,JIntellitype.jar包相关资料百度上有。
该程序绑定了全局快捷键ctrl+alt+q,当快捷键同时按下时,该Java程序全屏截图,并把图片铺满jframe窗口,jframe窗口最大化,隐藏窗口边框及上面的图标,鼠标点击滑动时绘制矩形线段,鼠标弹起时,矩形绘制结束,剪裁矩形内图片并保存到桌面Screen目录
Java程序打包软件:exe4j
代码:
import com.melloware.jintellitype.*;
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Main {
public static void main(String[] args) {
JFrame jFrame=new JFrame("截屏软件");
jFrame.setLayout(null);
JPanel jPanel=new JPanel(null);
//jPanel.setBackground(Color.GRAY);
jPanel.setBounds(0,0,400,400);
JTextArea jTextArea=new JTextArea();
jTextArea.append("\n");
jTextArea.append(" 使用说明\n");
jTextArea.append("\n");
jTextArea.append(" 开启截屏:快捷键Ctrl+Alt+Q\n");
jTextArea.append(" 取消截屏:快捷键Esc\n");
jTextArea.append(" 退出程序:快捷键Ctrl+Alt+W\n");
jTextArea.append(" 图片地址:桌面Screen目录");
jTextArea.setBounds(55,30,270,180);
jTextArea.setFont(new Font("宋体",Font.PLAIN,18));
jTextArea.setEnabled(false);
jTextArea.setDisabledTextColor(Color.BLACK);//字体颜色
jTextArea.setBorder(BorderFactory.createLoweredBevelBorder());
jPanel.add(jTextArea);
JButton j1=new JButton("启动");
j1.setFont(new Font("宋体",Font.PLAIN,20));
j1.setBounds(65,250,100,50);
j1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
jFrame.setVisible(false);
JIntellitype.getInstance().registerHotKey(1, JIntellitype.MOD_CONTROL+JIntellitype.MOD_ALT , (int) 'Q');//alt+shift+Q为快捷键
JIntellitype.getInstance().registerHotKey(2, JIntellitype.MOD_CONTROL+JIntellitype.MOD_ALT , (int) 'W');
JIntellitype.getInstance().addHotKeyListener(new HotkeyListener() {
@Override
public void onHotKey(int i) {
if(i==1){
JIntellitype.getInstance().unregisterHotKey(1);
new Screen().getWholeScreenShot();
JIntellitype.getInstance().registerHotKey(1, JIntellitype.MOD_CONTROL+JIntellitype.MOD_ALT , (int) 'Q');
}else if(i==2){
JIntellitype.getInstance().unregisterHotKey(1);
JIntellitype.getInstance().unregisterHotKey(2);
try {
Thread.sleep(200);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
JOptionPane.showMessageDialog(null," 程序已成功退出","提示",JOptionPane.PLAIN_MESSAGE);
System.exit(0);
}
}
});
}
});
jPanel.add(j1);
JButton j2=new JButton("退出");
j2.setFont(new Font("宋体",Font.PLAIN,20));
j2.setBounds(215,250,100,50);
j2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
jFrame.setVisible(false);
System.exit(0);
}
});
jPanel.add(j2);
jFrame.add(jPanel);
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setBounds(((Toolkit.getDefaultToolkit().getScreenSize().width)/2)-200, ((Toolkit.getDefaultToolkit().getScreenSize().height)/2)-200,400,400);
jFrame.setVisible(true);
}
}
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileSystemView;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Screen {
private String svaeDirPath;//文件目录路径
private final String format;//图片格式
private int x_start, y_start, x_end, y_end;
private boolean isRectageVisual = false;
private final Date nowTime;//当前时间
private final SimpleDateFormat ft;//时间格式
private final int screenWidth;
private final int screenHeight;
Screen(){
File desktopDir = FileSystemView.getFileSystemView().getHomeDirectory();
String desktopPath = desktopDir.getAbsolutePath();
svaeDirPath = desktopPath + "/Screen";
File dir = new File(svaeDirPath);
if (!dir.exists())
dir.mkdir();
format = "png";
nowTime = new Date();
ft = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
Dimension screensize = Toolkit.getDefaultToolkit().getScreenSize();
screenWidth = (int) screensize.getWidth();
screenHeight = (int) screensize.getHeight();
}
public void getWholeScreenShot() {
BufferedImage bufferedImage;
try {
Robot robot = new Robot();
bufferedImage = robot.createScreenCapture(new Rectangle(0, 0, screenWidth, screenHeight));
String absolutePath = svaeDirPath + "/" + ft.format(nowTime) + "." + format;
File saveFile = new File(absolutePath);
ImageIO.write(bufferedImage, format, saveFile);
setVisual(absolutePath, bufferedImage);
} catch (AWTException | IOException e) {
e.printStackTrace();
}
}
private void setVisual(String absolutePath, BufferedImage bufferedImage) {
ImageIcon icon = new ImageIcon(absolutePath);
Image image = icon.getImage();
JFrame jframe = new JFrame();
JLabel jLabel = new JLabel(icon);
JPanel jPanel = new JPanel() {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(image, 0, 0, null);
g2.setStroke(new BasicStroke(2.0f));
g2.setColor(Color.BLUE);
if (isRectageVisual) {
if(x_start>x_end&&y_start<y_end){
g.drawRect(x_end, y_start, x_start - x_end, y_end - y_start);
}else if (x_start>x_end&&y_start>y_end) {
g.drawRect(x_end, y_end, x_start - x_end, y_start - y_end);
}else if (x_start<x_end&&y_start>y_end){
g.drawRect(x_start,y_end,x_end-x_start,y_start-y_end);
}else{
g.drawRect(x_start, y_start, x_end - x_start, y_end - y_start);
}
}
}
};
jframe.addMouseListener(new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
x_start = e.getX();
y_start = e.getY();
x_end = e.getX();
y_end = e.getY();
isRectageVisual = true;
}
@Override
public void mouseReleased(MouseEvent e) {
x_end = e.getX();
y_end = e.getY();
isRectageVisual = true;
BufferedImage cutedImage=null;
if(x_start>x_end&&y_start<y_end){
cutedImage = bufferedImage.getSubimage(x_end, y_start, x_start - x_end, y_end - y_start);
}else if(x_start>x_end&&y_start>y_end) {
cutedImage = bufferedImage.getSubimage(x_end, y_end, x_start - x_end, y_start - y_end);
}else if (x_start<x_end&&y_start>y_end){
cutedImage=bufferedImage.getSubimage(x_start,y_end,x_end-x_start,y_start-y_end);
}else {
cutedImage = bufferedImage.getSubimage(x_start, y_start, x_end - x_start, y_end - y_start);
}
String absolutePath = svaeDirPath + "/" + ft.format(nowTime) + "." + format;
File saveFile = new File(absolutePath);
try {
ImageIO.write(cutedImage, format, saveFile);
} catch (IOException ioException) {
ioException.printStackTrace();
}
try {
Thread.sleep(100);
} catch (InterruptedException interruptedException) {
interruptedException.printStackTrace();
}
jframe.setVisible(false);
JOptionPane.showMessageDialog(null,"截图成功!","提示",JOptionPane.PLAIN_MESSAGE);
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
});
jframe.addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
jframe.setVisible(false);
}
}
});
jframe.addMouseMotionListener(new MouseMotionListener() {
@Override
public void mouseDragged(MouseEvent e) {
x_end = e.getX();
y_end = e.getY();
jPanel.repaint();
jPanel.paintImmediately(new Rectangle());
}
@Override
public void mouseMoved(MouseEvent e) {
}
});
jLabel.setOpaque(false);
jframe.add(jLabel);
jframe.getContentPane().add(jPanel);
jframe.setResizable(false);
jframe.setSize(screenWidth, screenHeight);
jframe.setUndecorated(true);
jframe.setCursor(Cursor.CROSSHAIR_CURSOR);
jframe.setVisible(true);
}
}