欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Swing中按ctrl键同时移动鼠标拖动组件(类中多借口共享同一数据)

程序员文章站 2022-07-13 17:27:14
...

        都知道java中类只能单继承,但可以实现多个接口,但我发现实现多个接口之后,多个接口却不能共享同一个数据,应用开发中想实现:当用户按着ctrl键时,可以用鼠标点击拖动组件,比如说文本框。

编写一个监听实现KeyListener,NouseListener,MouseMotionListener三个接口,重写方法。定义一个全局变量boolean ctrlPressed;

@Override

public void keyPressed(KeyEvent e) {

if(e.getModifiers()==InputEvent.CTRL_MASK)

  {

  ctrlPressed=true;

  System.out.println("ctrl is pressed");

  }

}@Override

public void keyReleased(KeyEvent e) {

ctrlPressed=false;

System.out.println("ctrl release");

}

用户在按下ctrl的时候为true,在MouseMotionListener接口的方法中判断ctrlPressed是否为真。

public void mouseDragged(MouseEvent e) {

if(ctrlPressed)

{

...........//实现拖动

}

}

这么写也不会报错,结果呢,mouseDragged方法中ctrlPressed却一直是false,按照逻辑来说用户按着ctrl,在keyPressed已经更改了ctrlPressed=true了呀!所以咯,不同的接口的方法是不能共用同一个变量的,全局变量,ctrlPressed,在不同的监听域中创建了不同的存储单元,也可以说是私有化了!我的解决办法是,创建一个类SharedData,创建静态变量ctrlPressed,而在keyPressed,和MouseDagged方法中都是用这个静态变量就能共用了!下面是我的具体实现代码,这个监听类,这个类可以实现选中组件中间移动组件,四周放大缩小组件,用的时候只需要添加监听即可,三个都要加哦

diamend.addMouseMotionListener(new PainRectListener(mJFrame,diamend));

diamend.addMouseListener(new PainRectListener(mJFrame,diamend));

diamend.addKeyListener(new PainRectListener(mJFrame,diamend));

package com.msi.frame;

import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.KeyStroke;
/**
 * 組件拖動事件的監聽,任意組件都可以使用這個方法
 * @author sharkliu
 *
 */
public class PainRectListener implements KeyListener,MouseListener,MouseMotionListener{
	private JFrame mJFrame;
	private JTextPane panel;
	//private boolean ctrlPressed=false;
    public PainRectListener(JFrame mJFrame,JTextPane panel)
    {
    	this.mJFrame=mJFrame;
    	this.panel=panel;
    }
    
    /**当前是否操作图片**/
  	private boolean isContains(Point point){
  		Rectangle rectangle = new Rectangle();
  		rectangle.x=0;
  		rectangle.y = 0;
  		rectangle.width = ShareData.componentSize[0];
  		rectangle.height = ShareData.componentSize[1];
  		return rectangle.contains(point);
  	}
  	
  	/**得到是否是点击的4个边中的1个(0,1,2,3,4)**/
  	private int getPressSide(Point point){
  		int side = 0;
  		Rectangle rectTop = new Rectangle(0,0,ShareData.componentSize[0],8);
  		Rectangle rectBottom = new Rectangle(0,ShareData.componentSize[1]-8,ShareData.componentSize[0],8);
  		Rectangle rectLeft =  new Rectangle(0,8,8,ShareData.componentSize[1]-8); 
  		Rectangle rectRight = new Rectangle(ShareData.componentSize[0]-8,8,8,ShareData.componentSize[1]-8);
  		if(rectTop.contains(point)){
  			return 1;		//上
  		}else if(rectBottom.contains(point)){
  			System.out.println("下");
  			return 2;		//下
  		}else if(rectLeft.contains(point)){
  			System.out.println("左");
  			return 3; 		//左
  		}else if(rectRight.contains(point)){
  			System.out.println("右");
  			return 4;		//右
  		}
  		return side;		//中间
  	}
  	public void mouseDragged(MouseEvent e) {
  		System.out.println(ctrlPressed);
				if(ShareData.isPressComponent&&ShareData.ctrlPressed){
					System.out.println("mouseDragged ininin");
					Point nowPoint = e.getPoint();		//当前鼠标拖拽到的鼠标位置
					int diffX = nowPoint.x - ShareData.pressPoint.x;
					int diffY = nowPoint.y - ShareData.pressPoint.y;
					/**移动**/
					if(ShareData.moveSide == 0){	
						ShareData.componentPoint.x += diffX;
						ShareData.componentPoint.y += diffY;
					}
					/**收缩**/
					else{
						//收缩 下和右时
						if(ShareData.moveSide == 2 || ShareData.moveSide == 4){
							if(ShareData.moveSide == 2)			//拉下(只能拉长拉短)
								ShareData.componentSize[1] += diffY; 
							else						//拉右(只能拉宽拉窄)
								ShareData.componentSize[0] += diffX;
							
						}
						//收缩 上和左时
						else if(ShareData.moveSide == 1 || ShareData.moveSide == 3){
							if(ShareData.moveSide == 1){			//拉上边(只能拉长拉短)
								ShareData.componentPoint.y += diffY;
								ShareData.componentSize[1] -= diffY;
							}else{						//拉左边(只能拉宽拉窄)
								ShareData.componentPoint.x += diffX;
								ShareData.componentSize[0] -= diffX;
							}
							
						}
						        ShareData.pressPoint = nowPoint;
					}
					//拖動組件改變組件的的寬不能超出黑框區域,以及防止拖動時把組件給拖沒了當size小於0組件無法匯出,便消失了
					if( (ShareData.componentSize[0]>=20)&&(ShareData.componentSize[1]>=20))
					{
						System.out.println("e"+e.getComponent());
						
						
						
						panel.setBounds(ShareData.componentPoint.x, ShareData.componentPoint.y, ShareData.componentSize[0], ShareData.componentSize[1]);
						panel.setPreferredSize(new Dimension(ShareData.componentSize[0],ShareData.componentSize[1]));
						panel.setSize(ShareData.componentSize[0], ShareData.componentSize[1]);
						
						mJFrame.validate();// 重构内容面板  
  				 	    mJFrame.repaint();// 重绘内容面板 
						
				}
				}
	}
	private void paintRect(Graphics graphics) {
		graphics.drawLine(1, ShareData.componentSize[1]/2-1, ShareData.componentSize[0]/2-1, 1);
		graphics.drawLine(ShareData.componentSize[0]/2-1,2, ShareData.componentSize[0]-1, ShareData.componentSize[1]/2-1);
		graphics.drawLine(ShareData.componentSize[0]-1, ShareData.componentSize[1]/2-1, ShareData.componentSize[0]/2-1, ShareData.componentSize[1]-1);
		graphics.drawLine(ShareData.componentSize[0]/2-1, ShareData.componentSize[1]-1, 1, ShareData.componentSize[1]/2-1);
	}

	public void mouseMoved(MouseEvent e) {
		
        Rectangle rectTop = new Rectangle(0,0,ShareData.componentSize[0],8);
 		
 		Rectangle rectBottom = new Rectangle(0,ShareData.componentSize[1]-8,ShareData.componentSize[0],8);
 		
 		Rectangle rectLeft =  new Rectangle(0,8,8,ShareData.componentSize[1]-8);
 		
 		Rectangle rectRight = new Rectangle(ShareData.componentSize[0]-8,8,8,ShareData.componentSize[1]-8);
 			
 					if(rectTop.contains(e.getPoint())){
 			 			e.getComponent().setCursor(new Cursor(Cursor.N_RESIZE_CURSOR));
 			 		}else if(rectBottom.contains(e.getPoint())){
 			 			System.out.println("下");
 			 			e.getComponent().setCursor(new Cursor(Cursor.S_RESIZE_CURSOR));
 			 		}else if(rectLeft.contains(e.getPoint())){
 			 			e.getComponent().setCursor(new Cursor(Cursor.W_RESIZE_CURSOR));
 			 		}else if(rectRight.contains(e.getPoint())){
 			 			e.getComponent().setCursor(new Cursor(Cursor.E_RESIZE_CURSOR));
 			 		} 	
 			 		else{
 					e.getComponent().setCursor(new Cursor(Cursor.MOVE_CURSOR));
 			 		}
 			
	}
	public void mouseClicked(MouseEvent e) {	
	}

	/**把組件所占的矩阵用变量表示出来(便于判断是否操作图片)**/
	/**
	 * 
	 * 跟新初始化數
	 * */
	public void mousePressed(MouseEvent e) {
		ShareData.componentPoint=e.getComponent().getLocation();
		ShareData.componentSize[0]=e.getComponent().getSize().width;
		ShareData.componentSize[1]=e.getComponent().getSize().height;
		//這是爲了區分對待圖片和文本,圖片隨時可以拖動,不受管控
				if(isContains(new Point(e.getPoint().x, e.getPoint().y))){
					ShareData.moveSide = getPressSide(new Point(e.getPoint().x, e.getPoint().y));		//记录操作图片的边
					ShareData.isPressComponent = true;
					ShareData.pressPoint = e.getPoint();
				}else{
					ShareData.isPressComponent = false;
				}
		}
	public void mouseReleased(MouseEvent e) {
		ShareData.isPressComponent = false;
		ShareData.pressPoint = null;
	}
	public void mouseEntered(MouseEvent e) {}
	 public void mouseExited(MouseEvent e) {}

	@Override
	public void keyTyped(KeyEvent e) {}

	@Override
	public void keyPressed(KeyEvent e) {
		if(e.getModifiers()==InputEvent.CTRL_MASK)
  		{
  			ShareData.ctrlPressed=true;
  			System.out.println("ctrl is pressed");
  		}
	}

	@Override
	public void keyReleased(KeyEvent e) {
		ShareData.ctrlPressed=false;
		System.out.println("ctrl release");
	}
	}	   

 

package com.msi.frame;

import java.awt.Component;
import java.awt.Point;

import javax.swing.JComponent;

/**
 * 名字為共享數據,專門記錄工具欄點擊了那些屬性,
 * 在版面繪製的時候,可先查看這個類中有哪些動作
 * @author sharkliu
 *
 */
public class ShareData {
public static int textFont=12;
public static int textStyle;

public static boolean dragable=false;//可拖動
public static boolean editable=true;//可編輯
public static Component selectCompoment=null;
public static int layer=1000;//

/*
 * 控制組件移動、變形等需要共用到的數據
 */
public static int[]componentSize=new int[]{1,1};//組件大小
public static boolean isPressComponent=false;		//是否操作組件、圖片或者文本框

public static int moveSide=0;		//拉升的边(0:移动 1:上 2:下 3:左 4:右)

public static Point componentPoint;		//組件(圖片或者文本框)位置

public static Point pressPoint;		//press組件时的鼠标位置
//控制文字樣式的按鈕背景變換
public static boolean isBorder=false;
public static boolean isItalic=false;
public static boolean isUnderline=false;
public static String CMD="";
public static boolean ctrlPressed=false;
	
}