透明界面实现.docx

上传人:b****3 文档编号:5397531 上传时间:2023-05-08 格式:DOCX 页数:19 大小:223.85KB
下载 相关 举报
透明界面实现.docx_第1页
第1页 / 共19页
透明界面实现.docx_第2页
第2页 / 共19页
透明界面实现.docx_第3页
第3页 / 共19页
透明界面实现.docx_第4页
第4页 / 共19页
透明界面实现.docx_第5页
第5页 / 共19页
透明界面实现.docx_第6页
第6页 / 共19页
透明界面实现.docx_第7页
第7页 / 共19页
透明界面实现.docx_第8页
第8页 / 共19页
透明界面实现.docx_第9页
第9页 / 共19页
透明界面实现.docx_第10页
第10页 / 共19页
透明界面实现.docx_第11页
第11页 / 共19页
透明界面实现.docx_第12页
第12页 / 共19页
透明界面实现.docx_第13页
第13页 / 共19页
透明界面实现.docx_第14页
第14页 / 共19页
透明界面实现.docx_第15页
第15页 / 共19页
透明界面实现.docx_第16页
第16页 / 共19页
透明界面实现.docx_第17页
第17页 / 共19页
透明界面实现.docx_第18页
第18页 / 共19页
透明界面实现.docx_第19页
第19页 / 共19页
亲,该文档总共19页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

透明界面实现.docx

《透明界面实现.docx》由会员分享,可在线阅读,更多相关《透明界面实现.docx(19页珍藏版)》请在冰点文库上搜索。

透明界面实现.docx

透明界面实现

想做一个透明的界面,无奈Java中的虽然有JFrame.setOpacity();但是这个东西,不好用。

后来发现是通过抓取屏幕背景作为自己的背景图片。

然后实现伪透明。

桌面背景是很有可能更换的,因此要在适当的时机抓取新的屏幕背景最为自己的背景。

这个似乎可以用线程来实现,但是感觉很消耗资源,毕竟桌面背景不是每隔一段时间就更新的。

先解释一个屏幕绘制的这个过程。

首先是抓取整个屏幕,然后我们选择合适的坐标,将我们的界面所覆盖的那一部分屏幕区域,绘制上去。

这样当我们的界面移动时,只要修改适当的坐标,以取得当前覆盖的屏幕区域进行绘制。

下面是这个代码片段。

有一个地方在解释一下。

Java代码

1@Override

2

3publicvoidpaintComponent(Graphicsg){

4

5super.paintComponent(g);

6

7//this.paint(g);

8

9

10

11Pointpos=this.getLocationOnScreen();

12

13Pointoffset=newPoint(-pos.x,-pos.y);

14

15//有一个问题就是为什么这边要用复数

16

17g.drawImage(background,offset.x,offset.y,null);

18

19}

我们看到这个offset.x和offset.y是负数,也许我们感到困惑。

这个只要搞张图片,用这个方法放在JFrame上,实现一下就明白了。

我们分析一下抓取屏幕背景的过程:

当我们的界面抓取屏幕背景并作为自己的背景进行绘制后,如果屏幕的背景发生了变化,那么一定是我们的界面失去了焦点。

这个时候操作的不在是我们的界面,因此可以将其隐藏起来。

而当我们要操作我们的界面时,即获得焦点时,我们这时候再抓取屏幕背景就可以了。

因此不需要用线程的,用监听器就可以。

除了要用到焦点的监听器之外,我们还需要组件监听器,这个是监听界面的移动,大小的变化等,以及时重绘。

这个思路是没有问题的。

在实现的过程中可能会出现一些小问题。

一些让我们头痛的BUG。

第一个BUG:

我们可能会把自己本身作为背景的一部分抓取过来,这就露馅了。

于是当我们的界面失去焦点时,我们必须把这个界面隐藏起来,放在屏幕之外的位置。

这样抓取的时候,就不会露馅了。

第二个BUG:

我们思路是这样的,windowsGainedFocus(WindowEvente)即得到焦点的监听器,方法的内容是这样的,抓取屏幕背景,进行重绘。

windowsLostFocus(WindowEvente)失去焦点监听器,方法的内容是,将界面隐藏起来。

我们的步骤是这样的,我们抓取屏幕背景是在这样的情况发生的,我们失去了焦点,界面隐藏,然后得到焦点,抓取屏幕,绘制屏幕。

但是这个步骤在程序运行刚开始时是不成立的,即程序一开始我们就直接得到了焦点,这个时候我们抓取屏幕,但是由于我们的界面还没有来的及隐藏,这就会出现第一个BUG的情况。

解决方法是:

设置一个标志fresh,是否抓取屏幕。

还有第三个BUG。

这个我们先等一下,看一下解决了上述两个问题之后的效果。

下面是完整代码(两个类):

--EndFragment-->

Java代码

20packagetransparentUI2;

21

22importjava.awt.Point;

23importjava.awt.event.ComponentEvent;

24importjava.awt.event.ComponentListener;

25importjava.awt.event.MouseEvent;

26importjava.awt.event.MouseListener;

27importjava.awt.event.WindowEvent;

28importjava.awt.event.WindowFocusListener;

29

30importjavax.swing.JFrame;

31

32publicclassTestUIextendsJFrameimplementsWindowFocusListener,

33ComponentListener{

34privateJPaneUIjp;

35privatebooleanfresh=false;

36privatePointtem_point;

37

38

39publicstaticvoidmain(Stringargs[]){

40newTestUI();

41}

42

43publicTestUI(){

44this.setSize(200,300);

45this.setLocationRelativeTo(null);

46this.setDefaultCloseOperation(3);

47jp=newJPaneUI();

48this.add(jp);

49this.addComponentListener(this);

50this.addWindowFocusListener(this);

51

52this.setVisible(true);

53

54}

55

56@Override

57publicvoidwindowGainedFocus(WindowEvente){

58//TODOAuto-generatedmethodstub

59this.refresh();

60fresh=false;

61}

62

63@Override

64publicvoidwindowLostFocus(WindowEvente){

65//TODOAuto-generatedmethodstub

66

67fresh=true;

68tem_point=this.getLocation();//记录屏幕消失之前的坐标

69this.setLocation(-2000,-2000);

70}

71

72publicvoidrefresh(){

73

74if(fresh){

75

76jp.updateBackground();

77//此时P应该重新被赋值了p存放应该就是刷新之前的位置

78this.setLocation(tem_point);

79if(tem_point.x<0||tem_point.y<0)

80this.setLocation(0,0);

81jp.repaint();

82

83}

84}

85

86

87@Override

88publicvoidcomponentResized(ComponentEvente){

89//TODOAuto-generatedmethodstub

90

91this.repaint();

92}

93

94@Override

95publicvoidcomponentMoved(ComponentEvente){

96//TODOAuto-generatedmethodstub

97//this.updateBackground();

98this.repaint();

99}

100

101@Override

102publicvoidcomponentShown(ComponentEvente){

103//TODOAuto-generatedmethodstub

104System.out.println("是不是在执行这个方法");

105//refresh();

106this.repaint();

107}

108

109@Override

110publicvoidcomponentHidden(ComponentEvente){

111//TODOAuto-generatedmethodstub

112

113}

114

115

116}

Java代码

117packagetransparentUI2;

118

119importjava.awt.Dimension;

120importjava.awt.Graphics;

121importjava.awt.Image;

122importjava.awt.Point;

123importjava.awt.Rectangle;

124importjava.awt.Robot;

125importjava.awt.Toolkit;

126importjava.awt.event.ComponentEvent;

127importjava.awt.event.ComponentListener;

128importjava.awt.event.WindowEvent;

129importjava.awt.event.WindowFocusListener;

130

131importjavax.swing.JFrame;

132importjavax.swing.JPanel;

133

134publicclassJPaneUIextendsJPanel{

135privateJFrameframe;

136privateImagebackground;

137privatePointfinal_point;

138

139publicJPaneUI(){

140updateBackground();

141}

142

143//获得当前屏幕快照

144publicvoidupdateBackground(){

145try{

146Robotrbt=newRobot();

147Toolkittk=Toolkit.getDefaultToolkit();

148Dimensiondim=tk.getScreenSize();

149background=rbt.createScreenCapture(newRectangle(0,0,(int)dim

150.getWidth(),(int)dim.getHeight()));

151}catch(Exceptionex){

152}

153

154}

155

156@Override

157publicvoidpaintComponent(Graphicsg){

158super.paintComponent(g);

159//this.paint(g);

160

161Pointpos=this.getLocationOnScreen();

162Pointoffset=newPoint(-pos.x,-pos.y);

163//有一个问题就是为什么这边要用复数

164g.drawImage(background,offset.x,offset.y,null);

165}

现在将第三个BUG:

本来是这样的我们操作另一个界面时,我们的界面会失去焦点,而等到我们操作我们的界面时,我们才能获得焦点。

但是现在有一个例外的情况,就是我们操作的另一个界面的最小化或者是关闭的按钮,这样我们的界面在失去焦点之后,马上得到焦点。

就是因为这个时间很短,所以我们抓取屏幕的动作,抓到不改抓到的东西就是其他界面消失过程中的图像。

我们的界面消失有一个渐变的过程,这个过程被我们抓到了,然后的结果就是这个样子。

如图:

--EndFragment-->

第一张是word的界面,当最小化时,我们的界面就会捕捉到他的一个渐变的过程。

这个确实很烦人。

解决办法就是,遇到这种情况时,系统多抓几次屏幕。

但是会出另一个问题,就是屏幕会闪烁,于是双缓冲也得来。

下面是完整的代码:

Java代码

166packagetransparentUI;

167

168importjava.awt.Point;

169importjava.awt.event.ComponentEvent;

170importjava.awt.event.ComponentListener;

171importjava.awt.event.MouseEvent;

172importjava.awt.event.MouseListener;

173importjava.awt.event.WindowEvent;

174importjava.awt.event.WindowFocusListener;

175

176importjavax.swing.JFrame;

177

178publicclassTestUIextendsJFrameimplementsWindowFocusListener,

179ComponentListener,MouseListener{

180privateJPaneUIjp;

181privatebooleanfresh=false;

182privatePointtem_point;

183privateintmany_fresh;

184

185publicstaticvoidmain(Stringargs[]){

186newTestUI();

187}

188

189publicTestUI(){

190this.setSize(200,300);

191this.setLocationRelativeTo(null);

192this.setDefaultCloseOperation(3);

193jp=newJPaneUI();

194this.add(jp);

195this.addComponentListener(this);

196this.addWindowFocusListener(this);

197this.addMouseListener(this);

198this.setVisible(true);

199

200}

201

202@Override

203publicvoidwindowGainedFocus(WindowEvente){

204//TODOAuto-generatedmethodstub

205this.refresh();

206fresh=false;

207}

208

209@Override

210publicvoidwindowLostFocus(WindowEvente){

211//TODOAuto-generatedmethodstub

212

213fresh=true;

214tem_point=this.getLocation();//记录屏幕消失之前的坐标

215this.setLocation(-2000,-2000);

216}

217

218publicvoidrefresh(){

219//inti=6;

220if(fresh){

221if(many_fresh<=1){

222jp.updateBackground();

223//此时P应该重新被赋值了p存放应该就是刷新之前的位置

224this.setLocation(tem_point);

225if(tem_point.x<0||tem_point.y<0)

226this.setLocation(0,0);

227jp.repaint();

228}

229while(many_fresh>1){

230//p=this.getLocationOnScreen();

231this.setLocation(-2000,-2000);

232

233jp.updateBackground();

234//此时P应该重新被赋值了p存放应该就是刷新之前的位置

235this.setLocation(tem_point);

236if(tem_point.x<0||tem_point.y<0)

237this.setLocation(0,0);

238jp.repaint();

239try{

240Thread.sleep(5);

241}catch(InterruptedExceptione){

242//TODOAuto-generatedcatchblock

243e.printStackTrace();

244}

245

246many_fresh--;

247}

248

249}

250}

251

252

253@Override

254publicvoidcomponentResized(ComponentEvente){

255//TODOAuto-generatedmethodstub

256

257this.repaint();

258}

259

260@Override

261publicvoidcomponentMoved(ComponentEvente){

262//TODOAuto-generatedmethodstub

263//this.updateBackground();

264this.repaint();

265}

266

267@Override

268publicvoidcomponentShown(ComponentEvente){

269//TODOAuto-generatedmethodstub

270System.out.println("是不是在执行这个方法");

271//refresh();

272this.repaint();

273}

274

275@Override

276publicvoidcomponentHidden(ComponentEvente){

277//TODOAuto-generatedmethodstub

278

279}

280

281@Override

282publicvoidmouseClicked(MouseEvente){

283//TODOAuto-generatedmethodstub

284

285}

286

287@Override

288publicvoidmousePressed(MouseEvente){

289//TODOAuto-generatedmethodstub

290

291}

292

293@Override

294publicvoidmouseReleased(MouseEvente){

295//TODOAuto-generatedmethodstub

296

297}

298

299@Override

300publicvoidmouseEntered(MouseEvente){

301//TODOAuto-generatedmethodstub

302many_fresh=1;//这个是不能改的

303System.out.println("mouseEntered这个应该执行了吧"+many_fresh);

304}

305

306@Override

307publicvoidmouseExited(MouseEvente){

308//TODOAuto-generatedmethodstub

309

310many_fresh=6;//这个时候获得焦点就要多次刷新,6次是试出来的比较好的刷新效果,当然5次或者其他的这个自己设置,

311//不要纠结这个数字,可以更改

312System.out.println("这个应该执行了吧mouseExited"+many_fresh);

313}

314

315}

Java代码

316packagetransparentUI;

317

318importjava.awt.Dimension;

319importjava.awt.Graphics;

320importjava.awt.Image;

321importjava.awt.Point;

322importjava.awt.Rectangle;

323importjava.awt.Robot;

324importjava.awt.Toolkit;

325

326

327importjavax.swing.JFrame;

328importjavax.swing.JPanel;

329

330publicclassJPaneUIextendsJPanel{

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2