国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

《java 桌面軟件開發(fā)》swing 以鼠標(biāo)為中心放大縮小移動(dòng)圖片

這篇具有很好參考價(jià)值的文章主要介紹了《java 桌面軟件開發(fā)》swing 以鼠標(biāo)為中心放大縮小移動(dòng)圖片。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

swing 使用Graphic2D 繪制圖片,要實(shí)現(xiàn)對(duì)圖片進(jìn)行縮放和自由拖動(dòng)。


1.以鼠標(biāo)所在的位置為中心,滾輪控制縮放

2.縮放后再支持鼠標(biāo)拖動(dòng)。

《java 桌面軟件開發(fā)》swing 以鼠標(biāo)為中心放大縮小移動(dòng)圖片,java桌面軟件,java,開發(fā)語(yǔ)言

基本原理:
利用scale() 函數(shù)。進(jìn)行縮放。但是要注意的地方是,如果是在?public void paintComponent(Graphics g) 里面通過這個(gè)Graphics g 參數(shù)獲取graphic對(duì)象進(jìn)行繪制,scale不會(huì)影響下一次的繪制。
一:所以,我們可以自行創(chuàng)建一個(gè) “繪圖區(qū)”, 創(chuàng)建一個(gè)空的ImageBuffer, 然后獲取這個(gè)ImageBuffer的 Graphics,? 后續(xù)全部往這個(gè)ImageBuffer的 Graphics 繪制.
二:? 最后在frame的paintComponent把我們這個(gè) 繪圖區(qū)原樣展示出來即可。 即,frame的
paintComponent只是固定將 繪圖區(qū)作為一個(gè)圖片繪制。
三:甚至可以創(chuàng)建多個(gè)ImageBuffer ,實(shí)現(xiàn)類似于ps多圖層的樣子,各個(gè)圖層獨(dú)立,paitComponent 匯總顯示圖層。
自己創(chuàng)建的ImageBuffer的 Graphics ,每次scale都是以上一次作為基礎(chǔ),累計(jì)的縮放。

利用transrate進(jìn)行移動(dòng),(移動(dòng)的是坐標(biāo)系)。 每次transrate都是以上一次作為基礎(chǔ),累計(jì)的平移。

來實(shí)現(xiàn)我們的關(guān)鍵代碼:
作為demo, 代碼盡量是一個(gè) main()到底:
swingDemo.java


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.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;

public class swingDemo {

	public static void main(String args[]) {
		new swingDemo();
	}

	public static Color BG_COLOR = new Color(128, 128, 128);

	public swingDemo() {
		JFrame mjf = new JFrame("圖片查看");
		ImagePanle mImgeView = new ImagePanle();
		mImgeView.setPreferredSize(new Dimension(500, 500));
		mImgeView.setMinimumSize(new Dimension(500, 500));
		mImgeView.setBackground(BG_COLOR);

		JMenuBar jmb = new JMenuBar();
		JMenu meSetting = new JMenu("文件");
		JMenuItem mOpen = new JMenuItem("打開");

		mOpen.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub

				BufferedImage curBufferedImg;
				JFileChooser fileChooser = new JFileChooser();
				fileChooser.setMultiSelectionEnabled(true);
				fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
				fileChooser.setMultiSelectionEnabled(false);
				int option = fileChooser.showOpenDialog(mjf);
				if (option == JFileChooser.APPROVE_OPTION) {
					try {
						File file = fileChooser.getSelectedFile();
						curBufferedImg = ImageIO.read(new File(file.getAbsolutePath()));
						mImgeView.updateImage(curBufferedImg);
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}

			}
		});

		meSetting.add(mOpen);
		jmb.add(meSetting);

		mjf.setJMenuBar(jmb);
		mjf.add(mImgeView);

		mjf.setMinimumSize(new Dimension(800, 600));
		mjf.setVisible(true);
		mjf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	}

	class ImagePanle extends JPanel {

		BufferedImage mSrcBuffeImg = null;
		private static final long serialVersionUID = 1L;
		private double mScale = 1.0;
		private static final boolean B_REAL_SIZE = true;
		private double mCurX = 0;
		private double mCurY = 0;
		private double mStartX = 0;
		private double mStartY = 0;
		private double mTranslateX = 0;
		private double mTranslateY = 0;

//		記錄最初原始坐標(biāo)系,用于清除背景
		AffineTransform mOriginTransform;
		BufferedImage mViewBufferImg;
		Graphics2D mViewG2d;

		void refreshView() {
			clear_buffer(mViewG2d, mOriginTransform, mViewBufferImg);
			mViewG2d.drawImage(mSrcBuffeImg, 0, 0, null);
			repaint();
		}

		void clear_buffer(Graphics2D g2d, AffineTransform org, BufferedImage bufImg) {
//			將保存的測(cè)量數(shù)據(jù),重新在經(jīng)過變換后的坐標(biāo)系上進(jìn)行繪制
			// 先恢復(fù)一下原始狀態(tài),保證清空的坐標(biāo)是全部,執(zhí)行清空,然后再切會(huì)來
			AffineTransform temp = g2d.getTransform();
			g2d.setTransform(org);
			g2d.clearRect(0, 0, bufImg.getWidth(), bufImg.getHeight());
			g2d.setTransform(temp);
		}

		public void updateImage(BufferedImage srcImage) {
			mSrcBuffeImg = srcImage;
			mViewBufferImg = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_ARGB);
			System.out.println("create buff image");
			mViewG2d = mViewBufferImg.createGraphics();
			mViewG2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
			mViewG2d.setBackground(BG_COLOR);
			System.out.println("crate bufg2d");
			mOriginTransform = mViewG2d.getTransform();
			refreshView();
		}

		private Point internal_getImagePoint(double mouseX, double mouseY) {

			// 不管是先平移后縮放還是先縮放后平移,都以 先減 再縮放的方式可以獲取正確
			double rawTranslateX = mViewG2d.getTransform().getTranslateX();
			double rawTranslateY = mViewG2d.getTransform().getTranslateY();
			// 獲取當(dāng)前的 Scale Transform
			double scaleX = mViewG2d.getTransform().getScaleX();
			double scaleY = mViewG2d.getTransform().getScaleY();

//        		不管是先平移后縮放還是先縮放后平移,都以 先減 再縮放的方式可以獲取正確
			int imageX = (int) ((mouseX - rawTranslateX) / scaleX);
			int imageY = (int) ((mouseY - rawTranslateY) / scaleY);

			return new Point(imageX, imageY);
		}

		public ImagePanle() {

//			啟用雙緩存
			setDoubleBuffered(true);

			this.addMouseWheelListener((MouseWheelListener) new MouseWheelListener() {
				@Override
				public void mouseWheelMoved(MouseWheelEvent e) {
					if (mViewG2d == null) {
						return;
					}
					mCurX = e.getX();
					mCurY = e.getY();

					int notches = e.getWheelRotation();
					if (notches < 0) {
						// 滾輪向上,放大畫布
						mScale = 1.1;

					} else {
						// 滾輪向下,縮小畫布
						mScale = 0.9;
					}

					Point imagePoint = internal_getImagePoint(e.getX(), e.getY());
					int imageX = imagePoint.x;
					int imageY = imagePoint.y;
					System.out.println("x:" + e.getX() + "y:" + e.getY() + ",imagex:" + imageX + "x" + imageY);

					double tralateX = mScale * imageX - imageX;
					double tralateY = mScale * imageY - imageY;

					mViewG2d.scale(mScale, mScale);
					mViewG2d.translate(-tralateX / mScale, -tralateY / mScale); // 圖片方大,就需要把坐標(biāo)往左移動(dòng),移動(dòng)的尺度是要考慮縮放的
					// 先恢復(fù)一下原始狀態(tài),保證清空的坐標(biāo)是全部,執(zhí)行清空,然后再切會(huì)來
					AffineTransform temp = mViewG2d.getTransform();
					mViewG2d.setTransform(mOriginTransform);
					mViewG2d.clearRect(0, 0, mViewBufferImg.getWidth(), mViewBufferImg.getHeight());
					mViewG2d.setTransform(temp);

					mViewG2d.drawImage(mSrcBuffeImg, 0, 0, null);
					repaint(); // 重新繪制畫布
				}

			});

			this.addMouseListener(new MouseListener() {

				@Override
				public void mouseReleased(MouseEvent e) {
					// TODO Auto-generated method stub
					System.out.println("mouseReleased:" + e.getX() + "x" + e.getY());
				}

				@Override
				public void mousePressed(MouseEvent e) {
					// TODO Auto-generated method stub
					System.out.println("mousePressed----:" + e.getX() + "x" + e.getY());
					mStartX = e.getX();
					mStartY = e.getY();
				}

				@Override
				public void mouseExited(MouseEvent e) {
					// TODO Auto-generated method stub

				}

				@Override
				public void mouseEntered(MouseEvent e) {
					// TODO Auto-generated method stub

				}

				@Override
				public void mouseClicked(MouseEvent e) {
					// TODO Auto-generated method stub
					System.out.println("mouseClicked----:" + e.getX() + "x" + e.getY());

				}
			});
			this.addMouseMotionListener(new MouseAdapter() {

				@Override
				public void mouseMoved(MouseEvent e) {
					// TODO Auto-generated method stub
				}

				@Override
				public void mouseDragged(MouseEvent e) {
					// TODO Auto-generated method stub
					if (mViewG2d == null) {
						return;
					}

					mCurX = e.getX();
					mCurY = e.getY();
					System.out.println("mouseDragged:" + e.getX() + "x" + e.getY() + "trans:" + (mCurX - mStartX) + ":"
							+ (mCurY - mStartY));

					// 平移坐標(biāo),也是相對(duì)于變換后的坐標(biāo)系而言的,所以
					double scaleX = mViewG2d.getTransform().getScaleX();
					double scaleY = mViewG2d.getTransform().getScaleY();

					// TODO mCurX - mStartX 太小,比如為2, 而scalX 比較大,比如為3 則移動(dòng)的時(shí)候回發(fā)生 (int)2/3 ==0; 不移動(dòng)。
					// 解決方案,把移動(dòng) ,全部在原始坐標(biāo)系上做,也就是最后繪制緩沖區(qū)的時(shí)候,drawimage(transX,transY)
					mTranslateX = (mCurX - mStartX) / scaleX;
					mTranslateY = (mCurY - mStartY) / scaleY;

					// 自身就是累計(jì)的
					mViewG2d.translate(mTranslateX, mTranslateY);

					mStartX = mCurX;
					mStartY = mCurY;
					System.out.println("mouseDragged: over+++");

					// 先恢復(fù)一下原始狀態(tài),保證清空的坐標(biāo)是全部,執(zhí)行清空,然后再切會(huì)來
					AffineTransform temp = mViewG2d.getTransform();
					mViewG2d.setTransform(mOriginTransform);
					mViewG2d.clearRect(0, 0, mViewBufferImg.getWidth(), mViewBufferImg.getHeight());
					mViewG2d.setTransform(temp);

					mViewG2d.drawImage(mSrcBuffeImg, 0, 0, null);
					repaint();
				}
			});

		}

		public void reset_scale() {
//			恢復(fù)到1.0 縮放,0,0 左上角對(duì)齊
			mCurX = 0;
			mCurY = 0;
			mScale = 1.0;
			mViewG2d.setTransform(mOriginTransform);
			mViewG2d.clearRect(0, 0, mViewBufferImg.getWidth(), mViewBufferImg.getHeight());
			mViewG2d.drawImage(mSrcBuffeImg, 0, 0, null);
			repaint(); // 重新繪制畫布
		}

		@Override
		public void paintComponent(Graphics g) {

			super.paintComponent(g);
			if (mViewBufferImg == null) {
				return;
			}
//			如果有多個(gè)“圖層”要注意圖層的順序
			Graphics2D g2d = ((Graphics2D) g);
			g2d.drawImage(mViewBufferImg, 0, 0, null);
			System.out.println("draw-----------:" + getWidth() + "x" + getHeight());
		}
	}

}


?文章來源地址http://www.zghlxwxcb.cn/news/detail-742206.html

到了這里,關(guān)于《java 桌面軟件開發(fā)》swing 以鼠標(biāo)為中心放大縮小移動(dòng)圖片的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 我想開發(fā)一款跨平臺(tái)桌面軟件,請(qǐng)告訴我qt、electron、tauri、pyqt、flutter分別適合開發(fā)哪些跨平臺(tái)桌面

    我想開發(fā)一款跨平臺(tái)桌面軟件,請(qǐng)告訴我qt、electron、tauri、pyqt、flutter分別適合開發(fā)哪些跨平臺(tái)桌面

    不同的跨平臺(tái)桌面開發(fā)工具適用于不同的應(yīng)用場(chǎng)景和開發(fā)者需求。以下是關(guān)于 Qt、Electron、Tauri、PyQt、Flutter 的簡(jiǎn)要說明,以幫助你更好地選擇適合你項(xiàng)目的工具: Qt: 適用場(chǎng)景: Qt 是一個(gè)強(qiáng)大的 C++ 框架,適用于開發(fā)需要高性能和原生外觀的桌面應(yīng)用。它具有廣泛的平臺(tái)支持

    2024年02月22日
    瀏覽(95)
  • WinFrom、C# 學(xué)習(xí)記錄五 開發(fā)一個(gè)鼠標(biāo)自動(dòng)點(diǎn)擊小軟件

    WinFrom、C# 學(xué)習(xí)記錄五 開發(fā)一個(gè)鼠標(biāo)自動(dòng)點(diǎn)擊小軟件

    ? ? ? ? 經(jīng)常會(huì)被問到需要點(diǎn)擊軟件的,主要都是玩游戲的盆友,但是也有其它用途的。所以簡(jiǎn)單弄了一個(gè),打算每當(dāng)有時(shí)間,有需求,就加一些小功能。 ? ? ? ? 這里主要是要記錄一下相關(guān)開發(fā)工作,也記錄一些使用/更新的信息。 ????????【2022/08/22】版本v1.0(初始版

    2024年02月16日
    瀏覽(94)
  • 音視頻開發(fā):Qt在視頻剪輯3D桌面軟件獲勝, 嵌入式不敵安卓

    音視頻開發(fā):Qt在視頻剪輯3D桌面軟件獲勝, 嵌入式不敵安卓

    1 Qt Android嵌入式應(yīng)用層開發(fā)方向?qū)Ρ?? 大家都知道啊,做嵌入式linux設(shè)備,一些沒有屏幕,比如安防攝像頭,門鈴之類的,另外一些嵌入式設(shè)備是有觸控屏,在觸控屏上還跑應(yīng)用軟件的,這種比如商場(chǎng)各種自動(dòng)售賣機(jī),鐵路賣票,銀行自助服務(wù),車載系統(tǒng)等。 10年前,我大學(xué)

    2024年02月09日
    瀏覽(21)
  • js 以鼠標(biāo)滾輪位置為中心縮放、放大以及邊界判斷

    js 以鼠標(biāo)滾輪位置為中心縮放、放大以及邊界判斷

    項(xiàng)目需求為頁(yè)面上實(shí)現(xiàn)拖拽節(jié)點(diǎn)和可以在頁(yè)面中通過滑動(dòng)滾輪來縮放節(jié)點(diǎn)顯示(以鼠標(biāo)位置為縮放中心點(diǎn))從而放大到可以看到詳細(xì)的信息,節(jié)點(diǎn)有10000個(gè)。特此記錄下實(shí)現(xiàn)細(xì)節(jié) 初始化變量 為節(jié)點(diǎn)綁定拖拽事件,拖拽事件的邊界使用 Math 進(jìn)行判斷,比起 if 判斷更加清晰快捷

    2024年02月11日
    瀏覽(90)
  • Java中規(guī)模軟件開發(fā)實(shí)訓(xùn)——簡(jiǎn)單計(jì)算器制作

    Java中規(guī)模軟件開發(fā)實(shí)訓(xùn)——簡(jiǎn)單計(jì)算器制作

    ? 博主: 命運(yùn)之光 ?? 專欄: Python星辰秘典 ?? 專欄: web開發(fā)(html css js) ?? 專欄: Java經(jīng)典程序設(shè)計(jì) ?? 博主的其他文章: 點(diǎn)擊進(jìn)入博主的主頁(yè) 前言: 在現(xiàn)代社會(huì)中,計(jì)算器是我們生活中不可或缺的工具之一。它們可以輕松地進(jìn)行各種數(shù)值計(jì)算,從簡(jiǎn)單的加減乘除

    2024年02月12日
    瀏覽(32)
  • vue 實(shí)現(xiàn)圖片以鼠標(biāo)為中心放大,并可以隨意在div內(nèi)拖動(dòng)

    需求:前端接收后端傳過來圖片渲染,并且可以直接在渲染的地方,以鼠標(biāo)滾輪為中心放大圖片,還可以隨意拖動(dòng)圖片 調(diào)研:目前有很多現(xiàn)成的插件都是,點(diǎn)擊圖片,然后彈出遮罩層,在遮罩層里面操作,由于不符合需求,就只能自己寫了。 開始使用了css3 的scale ,但是發(fā)現(xiàn)

    2024年02月10日
    瀏覽(95)
  • JAVA開發(fā)運(yùn)維(軟件一體化可觀測(cè)平臺(tái)的功能)

    JAVA開發(fā)運(yùn)維(軟件一體化可觀測(cè)平臺(tái)的功能)

    軟件可觀測(cè)是軟件度量的一種。旨在對(duì)軟件的數(shù)字體驗(yàn)、業(yè)務(wù)運(yùn)營(yíng)、網(wǎng)絡(luò)性能、應(yīng)用性能、基礎(chǔ)設(shè)施、IT流程進(jìn)行監(jiān)控和數(shù)據(jù)刻畫。使開發(fā)人員和運(yùn)維人員更好的對(duì)軟件進(jìn)行優(yōu)化維護(hù)。 一、數(shù)字體驗(yàn): 用戶會(huì)話 了解用戶使用路徑,追查使用過程中影響用戶體驗(yàn)的慢請(qǐng)求、慢

    2024年02月05日
    瀏覽(28)
  • Java中規(guī)模軟件開發(fā)實(shí)訓(xùn)——掌握財(cái)務(wù)自由的關(guān)鍵!解鎖智能家庭記賬系統(tǒng)的神奇力量?。彝ビ涃~軟件)

    Java中規(guī)模軟件開發(fā)實(shí)訓(xùn)——掌握財(cái)務(wù)自由的關(guān)鍵!解鎖智能家庭記賬系統(tǒng)的神奇力量!(家庭記賬軟件)

    ? 博主: 命運(yùn)之光 ?? 專欄: Python星辰秘典 ?? 專欄: web開發(fā)(html css js) ?? 專欄: Java經(jīng)典程序設(shè)計(jì) ?? 博主的其他文章: 點(diǎn)擊進(jìn)入博主的主頁(yè) 前言: 財(cái)務(wù)自由,理想生活的關(guān)鍵之一就是有效的財(cái)務(wù)管理。但是,很多人在家庭記賬上遇到了困惑和挑戰(zhàn)。幸運(yùn)的是,

    2024年02月12日
    瀏覽(39)
  • Java中規(guī)模軟件開發(fā)實(shí)訓(xùn)——簡(jiǎn)單的文本編輯器(代碼注釋詳解)

    Java中規(guī)模軟件開發(fā)實(shí)訓(xùn)——簡(jiǎn)單的文本編輯器(代碼注釋詳解)

    ? 博主: 命運(yùn)之光 ?? 專欄: Python星辰秘典 ?? 專欄: web開發(fā)(html css js) ?? 專欄: Java經(jīng)典程序設(shè)計(jì) ?? 博主的其他文章: 點(diǎn)擊進(jìn)入博主的主頁(yè) 前言: 在現(xiàn)代社會(huì)中,計(jì)算器是我們生活中不可或缺的工具之一。它們可以輕松地進(jìn)行各種數(shù)值計(jì)算,從簡(jiǎn)單的加減乘除

    2024年02月13日
    瀏覽(24)
  • Java開發(fā)手冊(cè)之單元測(cè)試,軟件測(cè)試端簡(jiǎn)單易用的SPI框架

    Java開發(fā)手冊(cè)之單元測(cè)試,軟件測(cè)試端簡(jiǎn)單易用的SPI框架

    【推薦】編寫單元測(cè)試代碼遵守 BCDE 原則,以保證被測(cè)試模塊的交付質(zhì)量。 B:Border,邊界值測(cè)試,包括循環(huán)邊界、特殊取值、特殊時(shí)間點(diǎn)、數(shù)據(jù)順序等。 C:Correct,正確的輸入,并得到預(yù)期的結(jié)果。 D:Design,與設(shè)計(jì)文檔相結(jié)合,來編寫單元測(cè)試。 E:Error,強(qiáng)制錯(cuò)誤信息輸

    2024年04月25日
    瀏覽(40)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包