java 窗体程序如何实现拖拽缩放图片

sknice 2012-02-01 03:56:52

要求:
1、选中图片后,通过鼠标拖拽改变图片的位置;
2、拖拽图片边框可以改变大小。

实现方法不限,Swing和SWT 都行。
开发工具不限,eclipse 和 netbeans 都行。

注意:是桌面程序,不是网页。



...全文
694 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
sknice 2012-02-03
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 ssyliusha 的回复:]

要让图片移动
只有一直刷新界面。
这个跟做游戏是一个道理。。

闪屏是因为双缓存原因,但是我记得我的图片对象就是双缓存的。。 或者你把 这些东西绘制在JPanel上面。。然后把JPanel放在JFrame上面 试一试。。JPanel自带双缓存的。。
[/Quote]
JPanel 也不行,还是闪屏,我感觉闪屏是不停的刷背景造成的,你以前做的时候会闪屏吗,
有没有办法,把图片放在一个控件里面显示,然后拖动的时候改变控件的位置和大小。
ssyliusha 2012-02-02
  • 打赏
  • 举报
回复
恩。。分分分。。 不知道这个分是干嘛的 好像很用的样子。。
ssyliusha 2012-02-02
  • 打赏
  • 举报
回复
要让图片移动
只有一直刷新界面。
这个跟做游戏是一个道理。。

闪屏是因为双缓存原因,但是我记得我的图片对象就是双缓存的。。 或者你把 这些东西绘制在JPanel上面。。然后把JPanel放在JFrame上面 试一试。。JPanel自带双缓存的。。
sknice 2012-02-02
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 ssyliusha 的回复:]

恩。。分分分。。 不知道这个分是干嘛的 好像很用的样子。。
[/Quote]
图片在拖动的过程中会闪屏,因为要刷窗体的背景然后在绘制图片,怎么才能解决这个问题呢
sknice 2012-02-01
  • 打赏
  • 举报
回复
好吧,
ssyliusha 2012-02-01
  • 打赏
  • 举报
回复
这些小问题就自己解决了撒,你不可能一点都不会吧
sknice 2012-02-01
  • 打赏
  • 举报
回复
代码测试过了,非常好,谢谢
只是有两个小问题:
1、图片在拖动的过程中会闪屏。
2、鼠标移到边框的时候没有改变形状,改变大小的过程中鼠标的形状显示也不正确。
sknice 2012-02-01
  • 打赏
  • 举报
回复
使用的Swing做的吗,怎么引用里面 awt 和swing 都有

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;

ssyliusha 2012-02-01
  • 打赏
  • 举报
回复
2个类
不知道怎么上传图片,也不知道怎么上传项目压缩包。。自己去网上随便找一张256*256大小的bmp类型的图片吧 改名为img.bmp就可以了。。。
图片位置 项目根目录创建一个images的文件夹 图片放里面!!



import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
/**
* 读取图片
* @author Administrator
*
*/
public class MyBufferedImage {

private BufferedImage image = new BufferedImage(256, 256, BufferedImage.TYPE_3BYTE_BGR);

public MyBufferedImage(){
File file = new File("images/img.bmp");
if(!file.exists())
return;
try {
BufferedImage imageRead = ImageIO.read(file);
Graphics g = image.getGraphics();
g.drawImage(imageRead, 0, 0, imageRead.getWidth(),imageRead.getHeight(), null);
} catch (IOException e) {
e.printStackTrace();
}
}

public BufferedImage getImage(){
return this.image;
}
}





import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;

public class MainFrame extends JFrame implements MouseListener,MouseMotionListener{

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

private static final long serialVersionUID = 1L;

private BufferedImage img; //绘制图片

private boolean isPressImage; //是否操作图片

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

private Point imagePoint; //图片位置

private int[] imageSize; //图片大小

private Point pressPoint; //press图片时的鼠标位置

public MainFrame(){
setSize(new Dimension(600,400));
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

initData();

setVisible(true);

this.getContentPane().addMouseListener(this);
this.getContentPane().addMouseMotionListener(this);
}

private void initData(){
img = new MyBufferedImage().getImage();
imagePoint = new Point(0, 0); //记录图片位置
imageSize = new int[]{img.getWidth(),img.getHeight()}; //记录图片大小
}


/**当前是否操作图片**/
private boolean isContains(Point point){
Rectangle rectangle = new Rectangle();
rectangle.x = imagePoint.x;
rectangle.y = imagePoint.y;
rectangle.width = imageSize[0];
rectangle.height = imageSize[1];
return rectangle.contains(point);
}

/**得到是否是点击的4个边中的1个(0,1,2,3,4)**/
private int getPressSide(Point point){
int side = 0;
Rectangle rectTop = new Rectangle(imagePoint.x+8,imagePoint.y,imageSize[0]-16,8);
Rectangle rectBottom = new Rectangle(imagePoint.x+8,imagePoint.y+imageSize[1]-8,imageSize[0]-16,8);
Rectangle rectLeft = new Rectangle(imagePoint.x,imagePoint.y+8,8,imageSize[1]-16);
Rectangle rectRight = new Rectangle(imagePoint.x+imageSize[0]-8,imagePoint.y+8,8,imageSize[1]-16);

if(rectTop.contains(point)){
setCursor(2);
return 1; //上
}else if(rectBottom.contains(point)){
setCursor(2);
return 2; //下
}else if(rectLeft.contains(point)){
setCursor(4);
return 3; //左
}else if(rectRight.contains(point)){
setCursor(4);
return 4; //右
}
return side; //中间
}
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub

}

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

}

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

}


@Override
public void mousePressed(MouseEvent e) {
/**把图片所占的矩阵用变量表示出来(便于判断是否操作图片)**/
if(isContains(new Point(e.getPoint().x+4, e.getPoint().y+30))){

moveSide = getPressSide(new Point(e.getPoint().x+4, e.getPoint().y+30)); //记录操作图片的边

isPressImage = true;
pressPoint = e.getPoint();
}else{
isPressImage = false;
}
}

@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
isPressImage = false;
pressPoint = null;
setCursor(0);
}

@Override
public void mouseDragged(MouseEvent arg0) {
// TODO Auto-generated method stub
if(isPressImage){
Point nowPoint = arg0.getPoint(); //当前鼠标拖拽到的鼠标位置
int diffX = nowPoint.x - pressPoint.x;
int diffY = nowPoint.y - pressPoint.y;
/**移动**/
if(moveSide == 0){
setCursor(1);
this.imagePoint.x += diffX;
this.imagePoint.y += diffY;
pressPoint = nowPoint;
}
/**收缩**/
else{
//收缩 下和右时
if(moveSide == 2 || moveSide == 4){
if(moveSide == 2) //拉下(只能拉长拉短)
this.imageSize[1] += diffY;
else //拉右(只能拉宽拉窄)
this.imageSize[0] += diffX;

}
//收缩 上和左时
else if(moveSide == 1 || moveSide == 3){
if(moveSide == 1){ //拉上边(只能拉长拉短)
this.imagePoint.y += diffY;
this.imageSize[1] -= diffY;
}else{ //拉左边(只能拉宽拉窄)
this.imagePoint.x += diffX;
this.imageSize[0] -= diffX;
}

}
pressPoint = nowPoint;
}
repaint();
}
}

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

}

public void paint(Graphics g){
super.paint(g);
g.drawImage(img, imagePoint.x, imagePoint.y, imageSize[0],imageSize[1], null);
}

public void update(Graphics g){
paint(g);
}

public void repaint(Graphics g){
paint(g);
}
}


ssyliusha 2012-02-01
  • 打赏
  • 举报
回复

了解。。思想是一样的。。
sknice 2012-02-01
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 ssyliusha 的回复:]

以前在学校做项目时写过。 那一块只是很小很小的一块 代码很多而且又找不到了。。我重新给你写个例子把~
[/Quote]

谢谢了,其实我的要求和你描述还不太一样,我希望是在边框任何位置都可以拖拽改变大小,就像eclipse 或 netbeans 开发环境中拖拽控件那样的效果。
ssyliusha 2012-02-01
  • 打赏
  • 举报
回复
以前在学校做项目时写过。 那一块只是很小很小的一块 代码很多而且又找不到了。。我重新给你写个例子把~
sknice 2012-02-01
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 ssyliusha 的回复:]

有空了 给你做。。不急吧。。
[/Quote]

如果有以前做好的就贴出来,不用专门给我做了
ssyliusha 2012-02-01
  • 打赏
  • 举报
回复
有空了 给你做。。不急吧。。
sknice 2012-02-01
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 ssyliusha 的回复:]

移动:
当你在图片上按下鼠标的时候,记录当前鼠标坐标point clickPoint;,然后
移动鼠标的时候,通过鼠标移动事件,来得到当前鼠标位置 和 clickPoint
的x,y的差。 然后在鼠标移动事件里重绘界面。(可以用个boolean值来做标志判断当前是否该重绘)

在graphics放啊里面,drawImage(img,w,h,x+x差,y+y差,null);

改变大……
[/Quote]
大哥,做过这样的例子吗,或者哪里可以找到这样的例子吗
ssyliusha 2012-02-01
  • 打赏
  • 举报
回复
移动:
当你在图片上按下鼠标的时候,记录当前鼠标坐标point clickPoint;,然后
移动鼠标的时候,通过鼠标移动事件,来得到当前鼠标位置 和 clickPoint
的x,y的差。 然后在鼠标移动事件里重绘界面。(可以用个boolean值来做标志判断当前是否该重绘)

在graphics放啊里面,drawImage(img,w,h,x+x差,y+y差,null);

改变大小:
首先 把窗体布局管理设置为null(这样就可以组件就根据自己来设置了)
声明4个button(大小自己定,样式也自己定) 放在图片的4个角(button的点击事件用于缩放图片,图片移动的时候也要同时移动button)
只需要 按下事件和拖拽事件:
按下记录当前坐标,拖拽时把当前坐标与按下时的坐标作比较,得到的x与y的差得值 来决定放大或者缩小图片。

移动图片就是改变图片的位置x,y
收缩图片就是改变图片的大小w,d
就这样。

sknice 2012-02-01
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 yingping_hui_520 的回复:]

停下!
[/Quote]
为什么?
yingping_hui_520 2012-02-01
  • 打赏
  • 举报
回复
停下!
mp19901204 2012-02-01
  • 打赏
  • 举报
回复
关注中。。。。。
内容概要:本文围绕“非线性流量的数据驱动Koopman模型预测控制研究”展开,提出一种基于数据驱动的Koopman算子理论方法,用于构建非线性系统的线性化状态空间模型,并结合模型预测控制(MPC)实现对复杂非线性系统的高效控制。研究通过引入扩展动态模态分解(EDMD)等观测函数,将非线性动力学映射至高维特征空间,在该空间中实现近似线性化表征,进而融合线性MPC框架进行优化求解。全文系统阐述了Koopman算子的数学基础、隐式线性化机制及在非线性流量控制中的建模流程,并通过Matlab代码完成了算法实现与仿真实验,验证了该方法在处理无精确物理模型、强非线性、时变动态系统中的有效性与鲁棒性,尤其适用于工业流程控制、能源系统调度等实际工程场景。; 适合人群:具备自动控制理论、非线性系统分析基础,熟悉Matlab编程,从事控制工程、系统辨识、智能优化、能源系统建模等方向的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于难以建立精确数学模型的复杂非线性系统(如流体动力系统、电力电子系统、机器人动力学等)的建模与实时控制;②实现数据驱动下的模型预测控制,提升系统响应速度与控制精度;③为先进控制策略(如MPC)提供一种可行的线性化建模范式,推动现代控制理论与数据科学、机器学习的深度融合。; 阅读建议:建议读者结合提供的Matlab代码深入理解Koopman方法的具体实现过程,重点关注观测函数构造、核函数选择、矩阵逼近、降维处理及MPC控制器设计等关键技术环节,并尝试将其迁移至其他非线性系统中进行复现实验与性能对比,以全面掌握其适用范围与局限性。
内容概要:本文详细介绍了一种基于Simulink的光伏储能单相逆变器并网仿真模型,系统涵盖了光伏阵列、储能单元、DC-AC单相逆变器及并网接口的完整结构,重点实现了储能环节的能量管理与逆变器并网控制策略的建模仿真。通过Simulink平台构建系统模型,验证了逆变器输出电能质量、并网稳定性以及控制系统的动态响应性能,采用SPWM调制、PI闭环控制等关键技术,确保并网电流与电网电压同频同相,满足并网电能质量要求。该模型不仅可用于分布式能源系统的仿真研究,还可作为新能源并网技术的教学与工程实践工具。; 适合人群:电气工程、自动化、新能源科学与工程等相关专业的高校本科生、研究生、科研人员,以及从事光伏发电系统设计、储能控制与并网技术研发的工程技术人员。; 使用场景及目标:①深入理解光伏储能系统中能量转换、存储与并网控制的整体工作原理;②支持课程设计、毕业设计或科研项目中对单相逆变器控制策略(如SPWM、PI调节、锁相技术等)的仿真验证与参数优化;③为后续研究更复杂的控制算法(如MPPT、低电压穿越、谐波抑制等)提供可扩展的仿真基础平台。; 阅读建议:建议结合MATLAB/Simulink环境动手搭建与调试模型,逐步理解各模块(如光伏建模、储能充放电控制、逆变器驱动、锁相环、PI调节器等)的功能与交互关系,重点关注控制系统的设计逻辑与参数整定过程,并可通过修改负载条件或电网参数测试系统鲁棒性,为进一步拓展至三相系统或多机并网场景奠定基础。

62,622

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧