//保存BMP格式的过滤器 private class BMPfilter extends javax.swing.filechooser.FileFilter{ public BMPfilter(){ } public boolean accept(File file){ if(file.toString().toLowerCase().endsWith(".bmp")|| file.isDirectory()){ return true; } else return false; } public String getDescription(){ return "*.BMP(BMP图像)"; } }
//保存JPG格式的过滤器 private class JPGfilter extends javax.swing.filechooser.FileFilter{ public JPGfilter(){ } public boolean accept(File file){ if(file.toString().toLowerCase().endsWith(".jpg")|| file.isDirectory()){ return true; } else return false; } public String getDescription(){ return "*.JPG(JPG图像)"; } }
//保存GIF格式的过滤器 private class GIFfilter extends javax.swing.filechooser.FileFilter{ public GIFfilter(){ } public boolean accept(File file){ if(file.toString().toLowerCase().endsWith(".gif")|| file.isDirectory()){ return true; } else return false; } public String getDescription(){ return "*.GIF(GIF图像)"; } }
//保存PNG格式的过滤器 private class PNGfilter extends javax.swing.filechooser.FileFilter{ public boolean accept(File file){ if(file.toString().toLowerCase().endsWith(".png")|| file.isDirectory()){ return true; } else return false; } public String getDescription(){ return "*.PNG(PNG图像)"; } }
//一个临时类,用于显示当前的屏幕图像 private class Temp extends JPanel implements MouseListener,MouseMotionListener{ /** * */ private static final long serialVersionUID = 1L; private BufferedImage bi; private int width,height; private int startX,startY,endX,endY,tempX,tempY; private JFrame jf; private Rectangle select=new Rectangle(0,0,0,0);//表示选中的区域 private Cursor cs=new Cursor(Cursor.CROSSHAIR_CURSOR);//表示一般情况下的鼠标状态(十字线) private States current=States.DEFAULT;// 表示当前的编辑状态 private Rectangle[] rec;//表示八个编辑点的区域 //下面四个常量,分别表示谁是被选中的那条线上的端点 public static final int START_X=1; public static final int START_Y=2; public static final int END_X=3; public static final int END_Y=4; private int currentX,currentY;//当前被选中的X和Y,只有这两个需要改变 private Point p=new Point();//当前鼠标移的地点 private boolean showTip=true;//是否显示提示.如果鼠标左键一按,则提示就不再显示了
//一个内部类,它表示一个面板,一个可以被放进tabpane的面板
//也有自己的一套处理保存和复制的方法
private class PicPanel extends JPanel implements ActionListener{
/**
*
*/
private static final long serialVersionUID = 1L;
JButton save,copy,close;//表示保存,复制,关闭的按钮
BufferedImage get;//得到的图片
public PicPanel(BufferedImage get){
super(new BorderLayout());
this.get=get;
initPanel();
}
private void initPanel(){
save=new JButton("保存(S)");
copy=new JButton("复制到剪帖板(C)");
close=new JButton("关闭(X)");
save.setMnemonic('S');
copy.setMnemonic('C');
close.setMnemonic('X');
JPanel buttonPanel=new JPanel();
buttonPanel.add(copy);
buttonPanel.add(save);
buttonPanel.add(close);
JLabel icon=new JLabel(new ImageIcon(get));
this.add(new JScrollPane(icon),BorderLayout.CENTER);
this.add(buttonPanel,BorderLayout.SOUTH);
save.addActionListener(this);
copy.addActionListener(this);
close.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
Object source=e.getSource();
if(source==save){
doSave(get);
}else if(source==copy){
doCopy(get);
}else if(source==close){
get=null;
doClose(this);
}
}
}
//保存BMP格式的过滤器
private class BMPfilter extends javax.swing.filechooser.FileFilter{
public BMPfilter(){
}
public boolean accept(File file){
if(file.toString().toLowerCase().endsWith(".bmp")||
file.isDirectory()){
return true;
} else
return false;
}
public String getDescription(){
return "*.BMP(BMP图像)";
}
}
//保存JPG格式的过滤器
private class JPGfilter extends javax.swing.filechooser.FileFilter{
public JPGfilter(){
}
public boolean accept(File file){
if(file.toString().toLowerCase().endsWith(".jpg")||
file.isDirectory()){
return true;
} else
return false;
}
public String getDescription(){
return "*.JPG(JPG图像)";
}
}
//保存GIF格式的过滤器
private class GIFfilter extends javax.swing.filechooser.FileFilter{
public GIFfilter(){
}
public boolean accept(File file){
if(file.toString().toLowerCase().endsWith(".gif")||
file.isDirectory()){
return true;
} else
return false;
}
public String getDescription(){
return "*.GIF(GIF图像)";
}
}
//保存PNG格式的过滤器
private class PNGfilter extends javax.swing.filechooser.FileFilter{
public boolean accept(File file){
if(file.toString().toLowerCase().endsWith(".png")||
file.isDirectory()){
return true;
} else
return false;
}
public String getDescription(){
return "*.PNG(PNG图像)";
}
}
//一个临时类,用于显示当前的屏幕图像
private class Temp extends JPanel implements MouseListener,MouseMotionListener{
/**
*
*/
private static final long serialVersionUID = 1L;
private BufferedImage bi;
private int width,height;
private int startX,startY,endX,endY,tempX,tempY;
private JFrame jf;
private Rectangle select=new Rectangle(0,0,0,0);//表示选中的区域
private Cursor cs=new Cursor(Cursor.CROSSHAIR_CURSOR);//表示一般情况下的鼠标状态(十字线)
private States current=States.DEFAULT;// 表示当前的编辑状态
private Rectangle[] rec;//表示八个编辑点的区域
//下面四个常量,分别表示谁是被选中的那条线上的端点
public static final int START_X=1;
public static final int START_Y=2;
public static final int END_X=3;
public static final int END_Y=4;
private int currentX,currentY;//当前被选中的X和Y,只有这两个需要改变
private Point p=new Point();//当前鼠标移的地点
private boolean showTip=true;//是否显示提示.如果鼠标左键一按,则提示就不再显示了
public Temp(JFrame jf,BufferedImage bi,int width,int height){
this.jf=jf;
this.bi=bi;
this.width=width;
this.height=height;
this.addMouseListener(this);
this.addMouseMotionListener(this);
initRecs();
}
private void initRecs(){
rec=new Rectangle[8];
for(int i=0;i<rec.length;i++){
rec[i]=new Rectangle();
}
}
public void paintComponent(Graphics g){
g.drawImage(bi,0,0,width,height,this);
g.setColor(Color.RED);
g.drawLine(startX,startY,endX,startY);
g.drawLine(startX,endY,endX,endY);
g.drawLine(startX,startY,startX,endY);
g.drawLine(endX,startY,endX,endY);
int x=startX<endX?startX:endX;
int y=startY<endY?startY:endY;
select=new Rectangle(x,y,Math.abs(endX-startX),Math.abs(endY-startY));
int x1=(startX+endX)/2;
int y1=(startY+endY)/2;
g.fillRect(x1-2,startY-2,5,5);
g.fillRect(x1-2,endY-2,5,5);
g.fillRect(startX-2,y1-2,5,5);
g.fillRect(endX-2,y1-2,5,5);
g.fillRect(startX-2,startY-2,5,5);
g.fillRect(startX-2,endY-2,5,5);
g.fillRect(endX-2,startY-2,5,5);
g.fillRect(endX-2,endY-2,5,5);
rec[0]=new Rectangle(x-5,y-5,10,10);
rec[1]=new Rectangle(x1-5,y-5,10,10);
rec[2]=new Rectangle((startX>endX?startX:endX)-5,y-5,10,10);
rec[3]=new Rectangle((startX>endX?startX:endX)-5,y1-5,10,10);
rec[4]=new Rectangle((startX>endX?startX:endX)-5,(startY>endY?startY:endY)-5,10,10);
rec[5]=new Rectangle(x1-5,(startY>endY?startY:endY)-5,10,10);
rec[6]=new Rectangle(x-5,(startY>endY?startY:endY)-5,10,10);
rec[7]=new Rectangle(x-5,y1-5,10,10);
if(showTip){
g.setColor(Color.CYAN);
g.fillRect(p.x,p.y,170,20);
g.setColor(Color.RED);
g.drawRect(p.x,p.y,170,20);
g.setColor(Color.BLACK);
g.drawString("请按住鼠标左键不放选择截图区",p.x,p.y+15);
}
}
//根据东南西北等八个方向决定选中的要修改的X和Y的座标
private void initSelect(States state){
switch(state){
case DEFAULT:
currentX=0;
currentY=0;
break;
case EAST:
currentX=(endX>startX?END_X:START_X);
currentY=0;
break;
case WEST:
currentX=(endX>startX?START_X:END_X);
currentY=0;
break;
case NORTH:
currentX=0;
currentY=(startY>endY?END_Y:START_Y);
break;
case SOUTH:
currentX=0;
currentY=(startY>endY?START_Y:END_Y);
break;
case NORTH_EAST:
currentY=(startY>endY?END_Y:START_Y);
currentX=(endX>startX?END_X:START_X);
break;
case NORTH_WEST:
currentY=(startY>endY?END_Y:START_Y);
currentX=(endX>startX?START_X:END_X);
break;
case SOUTH_EAST:
currentY=(startY>endY?START_Y:END_Y);
currentX=(endX>startX?END_X:START_X);
break;
case SOUTH_WEST:
currentY=(startY>endY?START_Y:END_Y);
currentX=(endX>startX?START_X:END_X);
break;
default:
currentX=0;
currentY=0;
break;
}
}
public void mouseMoved(MouseEvent me){
doMouseMoved(me);
initSelect(current); // current:当前状态(state)
if(showTip){
p=me.getPoint();
repaint();
}
}
private void doMouseMoved(MouseEvent me){
if(select.contains(me.getPoint())){
this.setCursor(new Cursor(Cursor.MOVE_CURSOR));
current=States.MOVE;
} else{
States[] st=States.values();
for(int i=0;i<rec.length;i++){
if(rec[i].contains(me.getPoint())){
current=st[i];
this.setCursor(st[i].getCursor());
return;
}
}
this.setCursor(cs);
current=States.DEFAULT;
}
}
public void mouseExited(MouseEvent me){
}
public void mouseEntered(MouseEvent me){
}
public void mouseDragged(MouseEvent me){
int x=me.getX();
int y=me.getY();
// 分别处理一系列的(光标)状态(枚举值)
if(current==States.MOVE){
startX+=(x-tempX);
startY+=(y-tempY);
endX+=(x-tempX);
endY+=(y-tempY);
tempX=x;
tempY=y;
}else if(current==States.EAST||current==States.WEST){
if(currentX==START_X){
startX+=(x-tempX);
tempX=x;
}else{
endX+=(x-tempX);
tempX=x;
}
}else if(current==States.NORTH||current==States.SOUTH){
if(currentY==START_Y){
startY+=(y-tempY);
tempY=y;
}else{
endY+=(y-tempY);
tempY=y;
}
}else if(current==States.NORTH_EAST||current==States.NORTH_EAST||
current==States.SOUTH_EAST||current==States.SOUTH_WEST){
if(currentY==START_Y){
startY+=(y-tempY);
tempY=y;
}else{
endY+=(y-tempY);
tempY=y;
}
if(currentX==START_X){
startX+=(x-tempX);
tempX=x;
}else{
endX+=(x-tempX);
tempX=x;
}
}else{
startX=tempX;
startY=tempY;
endX=me.getX();
endY=me.getY();
}
this.repaint();
}
public void mousePressed(MouseEvent me){
showTip=false;
tempX=me.getX();
tempY=me.getY();
}
public void mouseReleased(MouseEvent me){
if(me.isPopupTrigger()){ // 右键
if(current==States.MOVE){
showTip=true;
p=me.getPoint();
startX=0;
startY=0;
endX=0;
endY=0;
repaint();
} else{ // 普通情况
jf.dispose();
updates();
}
}
}
public void mouseClicked(MouseEvent me){
if(me.getClickCount()==2){
//Rectangle rec=new Rectangle(startX,startY,Math.abs(endX-startX),Math.abs(endY-startY));
Point p=me.getPoint();
if(select.contains(p)){
if(select.x+select.width<this.getWidth()&&select.y+select.height<this.getHeight()){
get=bi.getSubimage(select.x,select.y,select.width,select.height);
jf.dispose();
updates();
}else{
int wid=select.width,het=select.height;
if(select.x+select.width>=this.getWidth()){
wid=this.getWidth()-select.x;
}
if(select.y+select.height>=this.getHeight()){
het=this.getHeight()-select.y;
}
get=bi.getSubimage(select.x,select.y,wid,het);
jf.dispose();
updates();
}
}
}
}
} @Override
public void windowActivated(WindowEvent arg0) {
// TODO Auto-generated method stub
} @Override
public void windowClosed(WindowEvent arg0) {
// TODO Auto-generated method stub
this.dispose();
} @Override
public void windowClosing(WindowEvent arg0) {
// TODO Auto-generated method stub
} @Override
public void windowDeactivated(WindowEvent arg0) {
// TODO Auto-generated method stub
} @Override
public void windowDeiconified(WindowEvent arg0) {
// TODO Auto-generated method stub
} @Override
public void windowIconified(WindowEvent arg0) {
// TODO Auto-generated method stub
} @Override
public void windowOpened(WindowEvent arg0) {
// TODO Auto-generated method stub
}
}//一些表示状态的枚举
enum States{
NORTH_WEST(new Cursor(Cursor.NW_RESIZE_CURSOR)),//表示西北角
NORTH(new Cursor(Cursor.N_RESIZE_CURSOR)),
NORTH_EAST(new Cursor(Cursor.NE_RESIZE_CURSOR)),
EAST(new Cursor(Cursor.E_RESIZE_CURSOR)),
SOUTH_EAST(new Cursor(Cursor.SE_RESIZE_CURSOR)),
SOUTH(new Cursor(Cursor.S_RESIZE_CURSOR)),
SOUTH_WEST(new Cursor(Cursor.SW_RESIZE_CURSOR)),
WEST(new Cursor(Cursor.W_RESIZE_CURSOR)),
MOVE(new Cursor(Cursor.MOVE_CURSOR)),
DEFAULT(new Cursor(Cursor.DEFAULT_CURSOR));
private Cursor cs;
States(Cursor cs){
this.cs=cs;
}
public static void main(String[] args){
new CaptureScreen();
}
public Cursor getCursor(){
return cs;
}
}
高手,上面的类型运行后,效果如下:
我做了一个全局键盘监视器,能够让我的用户点击组合键后,直接把上面的窗口调用出来.
但是我看到:
我的用户希望能够在“长期使用”我的软件作品的过程中,希望能够“尽可能节省自己的时间”,我看到:
腾讯的QQ,在点击了快捷键的时候,能够:“直接画取图片的区域”.
上面的代码经过我的初步研究,我把第一张帖子中的第19行代码修改成了下面的结果:
public static void main(String[] args){
new CaptureScreen().doStart();
}
运行后的效果,还是有“上面图片中的运行界面的一闪而过”,让用户的体验,不是最佳.
并且,高手,您可以运行一下小弟贴出的代码,他在用户画完取图片的区域后,“双击图片区域”,出现下面的界面:
这也是没有QQ的取图片功能强劲的一点:
QQ能够让用户“点击一下”,“进行保存到文件”的选择,“点击两下”,“进行保存到剪贴板的功能直接调用”.
可是在上面的取图片的功能中,如果把这个功能嵌入我的系统,将会有:
让用户在这个功能上感到很麻烦,从而让我的IM在这个字段上输给QQ的缺陷出现.
希望能够得到高手的指导:
小弟上面的代码,如何修改,能够把“图片1”中的界面让小弟调用了本类型后,能够像QQ一样,直接进行图片的取图区域的选择,并且,如何修改,能够让小弟贴出的第二张图片上面代码所输给腾讯的字段,进行优化?
希望得到高手的指导!!!!!
小弟将把今后发送私信的频率,减少到原先的“5%".
谢谢5#楼的CSDN技术无冕帝王withiter版主的再次亲临指导!!!!
谢谢#6楼的郎晴大哥的精神鼓励!!!!
小弟感谢CSDN的技术培养与诸位大大的不断帮助!!
有CSDN!!!!无小弟的梦想不落地开花结果!!!!!!
QQ实现的”选择取图片的区域“的”选框画完后“”能够直接选择保存按钮“的功能,是怎么实现的?
是借助了什么机制和方法做出来的?
双击添加到剪切板,是一个相对比较好实现的功能.
但是,在用户选择完毕后,出现的这个界面:
版主,请问:
QQ是通过什么技术方法实现的”用户选择完毕后“,“能够让下面的工具栏出现”的功能的.
腾讯用了什么方法,什么类型实现的这个功能
谢谢CSDN无冕帝王
希望改善。
不过总体效果还是不错。