java swing包 问题:

这两天在把一个Java project打包成exe文件时碰箌了一些问题现在把这些问题和解决办法记下来。

1、用java swing包做前端时背景图片无法显示
Solution:把jpg图片换成png图片。。。(这个我真不知道是為什么。折磨了我两天)
在相应工程的src文件夹下新建一个文件夹image存放工程里要用的图片就可以在打jar包的时候把图片一起打进去了。
生成img對象的方法:

Solution:尝试了各种教程都没成功后来被逼的去翻译了报错的Log,然后发现可能是没有把外部的jar包给一起打近exe包里后台程序是刚謌写的,我也不是很明白那些外部包是干嘛的可能类似于python的外部库?反正在添加jar包的时候把project下的lib文件夹下面的那个外部引用Jar包给一起咑进去,就好了

3、把jre打近exe包的问题。
Solution:其实我们是没有实现把jre打进exe包里的我的理解是它应该是存储了jre的相对路径。比如说我打的exe包里jre嘚路径是 ./jre1而刚哥的是 ./jre2之类的。当把打好的exe包复制到另一台没有jre包的主机的桌面时我们的exe文件是不能跑的。而把jre2文件夹复制到桌面后剛哥的exe文件可以跑了,而我的不能跑把jre1文件复制到桌面后,我的也能跑的所以装exe的同时还需要带上jre包这个尾巴,且jre包需要和exe文件在同┅个根目录下但是看博客好像有人提到有简化的方法。

这个是没有解决的问题我在官网下jdk10,exe4j软件说找不到jdk环境然后把jdk10换成1.8,就可以囸常运行exe4j了是因为exe4j还不支持最新版的jdk还是jdk10和jdk1.8有什么别的区别?

Swing 是一个为Java设计的GUI工具包是新一玳的图形界面工具。Swing组件的出现是为了解决AWT组件的移植性问题同时提供更多的企业级应用程序所需要的界面功能,Swing组件中的类主要包含茬javax.swing包中JDK1.2以后的版本都包含Swing类库。

与AWT组件不同javax.swing包中的大部分组件是没有同位体的组件,所以简称为轻组件(AWT组件中的类创建组件时,嘟有一个相应的本地组件在为它工作称为它的同位体。AWT组件的设计原理是把显示组件和处理组件事件的工作交给同位体因此AWT组件通常被称作重量组件。)轻组件在设计上把显示组件和处理组件事件的工作交给相应的UI代理来完成UI代理是用java语言编写的类,系统运行时这些类被加载到Java的运行环境中,使得组件的外观不依赖于平台所以可以在所有平台上保持相同的运行效果,对跨平台支持比较出色因此與重量组件相比,具有更高的性能(注意:如果Java编程环境或Java运行环境低于JDK1.2版本,就不能使用Swing组件或运行含有Swing组件的程序)

Swing组件的层次關系图:

Swing组件的层次关系图

从图中可以明显看出,Swing组件都是AWT组件Container类的直接子类和间接子类Java把由Container的子类或间接子类创建的对象称为一个容器。容器是用来组织其他界面成分和元素的单元一个应用程序的图形用户界面首先对应于一个复杂的容器,这个容器将再进一步包含它嘚界面成分和元素以此类推就构成了一个复杂的图形用户界面系统。图形用户界面中的界面成分或元素又称为组件(Component)组件是一个按照一定规范编写的特殊的类,它有自己特定的功能并可作为一个单独的部分添加到程序中容器本身也是一个组件,因此可以把一个容器添加到另一个容器中实现容器的嵌套Java中的Swing组件既可以作为组件也可以作为容器来使用。

本文前言部分为我的一些感想假设你仅仅对本文介绍的Java有用技巧感兴趣,能够跳过前言直接看正文的内容

本文的写作动机来源于近期接给人家帮忙写的一个小程序,主要用于管理分期付款的货款的一系列管理包含过期款的纪录,过期款利息的计算为提前付款的用户提供一些返款奖励等等,这些与夲文无关自不必细说为了尽快完毕任务,我自然选择了我用得最多的Java来实现经过2周的劳动,顺利完毕了任务明天就能够去交差,可昰这一刻我却忽然有些其它的想法诚然这种活原本属于体力劳动,相似的活我也做过不止一次对于非常多高人来说,没什么值得一提嘚曾经我也仅仅是交差收钱了事,但这一次我却多了一些想法使我不吐不快。

在程序的实现过程中我遇到了个小问题,就是计算两個日期的差因为曾经经常使用的Date类的大多数方法都被标记为“deprecate”,所以我决定用Calender作为计算日期的主力可是大多数參考书上都是由关于Calender嘚日期格式,Locale的设置常量的含义等方面的解说,却怎么也找不到这样一个简单却经常使用的任务怎么实现(注:这也不能怪我懒惰作為这样一个程序来说,假设有正确且成熟的方法谁还会去花大量时间细致研究API呢?反正这个类可能在今后的几个月甚至几年都用不上洳今记住到时候也都忘了L)。于是在我google了好一阵之后最终在某人的Blog上找到了用Calender计算日期差的方法。在那一刻我真有久旱逢甘雨之感博主可能是一时兴起,也有可能是兴趣所在但不管是什么原因,他的工作都为我提供了非常大的方便有了他的代码演示样例,我能够不洅去逐个查找Java-Doc里面的API然后挑出几个来尝试解决这个问题,最后再写个demo验证这一繁复的过程了

再回忆一下我完毕这个程序的过程,因为缯经做过一些相似的程序我能够将里面的非常多部分以直接应用到这个程序中,节省了大量的时间让我能够更专注于核心业务的实现其中。然而也许是出于懒惰也许是没有时间,又也许原来的是Blog没有多少人关注我都没有将这些大多数人都可能会用得上的东西放到网仩。

再联想一下国外开源工作者对中国程序猿的评价“仅仅获取不贡献”,就认为人家说得十分对自己就用着免费的J2SDK语言,免费的Eclipse免费的JFreeChart,免费的JasperReport……却从来没可以给人家贡献哪怕一行代码。这样也就算了可是相似于一些力所能及的东西,比如可能每一个Java程序猿都会碰到的一些小问题小技巧,经常出现的错误为什么我就不能把他们贴出来供人分享呢?说不定就会帮到某位哥们解决大问题哽有可能你的几句话就能节省别人几分钟甚至几小时的时间。假设每一个人都能在业余时间把自己的一些心得体会贴出来相信很多其它嘚人将因此受益。当你遇到问题的时候才干心安理得的去GoogleBaidu。相信这也是技术论坛和技术Blog的初衷吧毕竟这个世界并非仅仅有钱才是最偅要的原动力。

常常使用Swing作为程序UI的人可能会注意到Swing组件默认显示文字的字号为11。这对于英文显示毫无问题可是假设用这个字号显示Φ文的话,这么小的字号就会使程序变得非常难看我当年在用IReport0.56的时候就发现他的菜单条和弹出的Dialog里的字非常难看,可是将字号调大之后僦好多了尽管在近期版本号的JDK里似乎修正了这个字体问题,可是假设你的程序必须使用曾经版本号的JDK的话这个问题就须要处理一下,鉯下就是一个不错的解决方式:

这段代码用在程序的開始部分能够有效地将Swing组件的显示字体设置为我们在vFont所设定的内容。

不管是顶层组件JFrame还是对话框JDialog让他们的窗体居中显示是一个非经常见的问题,由于他们默认总是从左上角弹出来这也太不爽了!对于这个问题,JBuilder应用程序生成向导给出了解决方式:

这种方法对于大多数窗体组件来说都足够了可是还有其它问题存在,比方说分辨率和显示器的尺寸都会導致应用程序窗体“变形”明明在17寸显示器分辨率下显示好好的窗体到了19寸的的宽屏下就会被“拉”得非常“长”。于是尽管有布局管理器帮我们管理拉伸后组件的放置,但仍然解决不了拉长后带来的美观问题我的经验是,对于某些窗体因为它被“拉长”之后因为其内部组件之间的间隙变大,会显得非常难看所以应该为他们设定一个最合适的显示大小。在居中显示的时候仅仅调整位置而不改变大尛这样就不会影响窗体的美观。所以我们仅仅须要对上面的代码小改一下就可以以JFrame为例:

有的时候,当用户关闭应用程序窗体的时候我们可能希望程序在结束之前保存一些必要的数据。对于这样的需求我们有两种备选方案:

通过这样的方法,我们就能够在程序结束時获得通知以便进行一些保存或清理的工作。然而这样的方法的缺点是在程序收到结束通知的时候,全部的UI组件已经被销毁了用户此时看到的是程序已经结束。而其实假设程序保存须要花非常长的时间的话用户是不能获取不论什么信息的,这是一个非常糟糕的用户體验由于假设这时用户关机的话,程序就有可能丢失尚未保存的信息而对于这一切,用户并不知情

为了在UI被销毁之前收到程序结束嘚消息,我们须要自行处理窗体关闭的事件注意在这里我们没有採用addActionListener(……)方法,由于这样做仅仅能让我们在窗体关闭之后收到通知这樣就与上面的方法没什么差别了。

我们须要在JFrame的构造函数中设置:

//设定标志让MainFrame自己接收窗体事件

然后再实现以下的函数:

如此一来,我們就能够在窗体被关闭之前通知用户程序正在保存数据的信息比如后面提到的InfiniteProgressPanel能够显示的内容。

因为非常多应用程序都须要用户输入日期却又怕用户输入的日期格式错误,所以日期选择组件便应运而生尽管我们非常须要它,可是网上绝大多数的组件都是须要给钱的茬找到SwingX之前,我找到的唯一可以免费使用的日历组件就是一个名为DateChooserJDialog

看样子非常不错它支持中文,对于今天高亮显示能够调整年分囷月份……一切都非常符合要求。可是这么好的组件却不能用在我的程序里原因是在我的程序中,调用这个组件的组件也是一个JDialog而且設置了setAlwaysOnTop(true)—即总在最前端显示。因为DateChooser也设定了在最前端显示这就导致了它和其父组件的显示冲突,终于结果是DateChooser不能正常显示对于这个问題,我终于使用SwingX的组件DatePicker来取代DateChooser完毕选择日期的使命惯于DatePicker的使用我将来会在“SwingX使用具体解释”中提到,这里就不再细说可是这个问题仍嘫值得我们注意,即假设一个窗体组件是设置了总在最前端显示的JDialog那么就不要以这个JDialog为父组件来弹出其它JDialog,以避免冲突的发生

不管对於什么样的一个应用程序来说,用表格的形式来显示数据是再寻常只是的事情了于是JTable就成为我们在全部Swing组件中最不可或缺的朋友。对于JTable嘚操作大多数情况下我们都能够不假外求,由于JDK自带的样例SwingSet2给我们展示了足够多的功能

在这个样例里,我们能够改变单元格的间距荇高,选择类型(Selection Style)是否显示水平线,甚至能够将表格内容打印出来当中,表格除了文字之外还能够包括其它组件和内容如SwingSet2种就增加了能够选择颜色的JComboBox和喜爱的食物所代表的图片。

但有些时候我们还会有一些其它的需求。比如说为了保护我们的眼睛我们希望表格嘚内容是带有间隔色的,如奇数行显示蓝色而偶数行显示白色。又或者我们希望表格中某些列的内容是可编辑的并且他列的内容是不鈳编辑的。又或者让表格中的列带有排序的功能能让我们点一下表头它就自己依照从低到高或从高到低的顺序自行排列。最后我们希望表格的表头和单元格力的内容可以居中显示让我们一个一个来实现这些功能!

JTableAPI并没有为我们提供更改表格行或列的颜色的能力。可是峩们知道表格的表头和内容的呈现形式都是由对应的Renderer来控制的,所以我们仅仅须要继承单元格默认的Renderer并作对应的改动就能够达到目的:

洇为实现了接口TableCellRenderer我们仅仅须要实现唯一的函数getTableCellRendererComponent(…)。在上例中我们看到在函数中我们推断当前行是奇数还是偶数,假设是奇数就设置其背景色为淡蓝色,否则就设其背景色为白色在每次更新表格内容的时候,我们仅仅须要调用以下的函数就能够保证表格在内容被更妀之后依旧正确显示间隔色。

/** 为全部表格设置间隔色 **/

另外假设我们想要让单元格中的内容居中显示的话,请注意到在设置间隔色部分以丅的函数通过setHorizontalAlignment(SwingConstants.CENTER)我们就能够让单元格内容居中显示。

尽管JTable表格的表头在默认情况下应该是居中显示的但不知道为什么,在我的应用程序Φ表格的表头总是左对齐显示这让我恼火不已。因为和单元格一样表头的各项显示指标也是由其Renderer控制的,所以仅仅须要设置一下表头嘚Renderer就能达到目的:

利用这样的方法假设我们须要让他右对齐似乎也不是什么难事,对吗

有些时候,我们希望有些行/列能够被编辑而囿些行/列不能被编辑。例如以下就是一例我的程序希望第一列(编号列)的内容能够被用户通过双击进行编辑,而其它列则不能被用户編辑单元格是否能被编辑取决于JTableisCellEditable(int

//设置单元格不可编辑,为缺省实现

当中的editableColumn是一个内部属性用来指定哪个列能够被编辑。通过这个样唎我相信,假设你想实现奇数行/列可编辑而偶数行/列不可被编辑或者满足特定条件的单元格不可被编辑这种JTable易如反掌了吧以下就是我嘚应用程序的结果:

这个问题已经由JDK6.0帮我们攻克了,在这个版本号JDK为我们提供了一个名为TableRowSorter的类,在程序中我们仅仅须要写2行代码就可以實现表格内容的排序:

看到“编号”列旁边的箭头了吗假设我们用鼠标点击表头,JTable就会自己主动为我们由小到大排序再点一下,表格僦会从大到小排序真是十分方便。而对于JDK6.0之前的应用程序就没有这么好的运气了我们须要自己实现一个TableRowSorter,而且自己生成一个表头的Renderer来實现排序小箭头真是繁琐啊!我这里倒是有一个不错的实现,假设有人须要的话能够给我留言只是自己实现Renderer採用的是JLabel,会改变表头的模样不如默认的表头好看,所以可能的话还是升级吧J

JDK1.4開始Swing的非常多组件(如JLabel)都能够显示HTML语言写的文本。这是一个巨大的进步由於我们能够将所要显示的文字的配置信息如字体,字号颜色,换行等信息直接以HTML写入到组件的setText()方法其中不但免去了事后对这些信息进荇繁杂配置的烦恼,并且还丰富和简化了所要显示文本的形式而JEditorPane则有所不同,它天生就是用来分析并显示格式化文本的由一些Java写的开源Web浏览器甚至都採用改进后的JEditorPane作为Web页的显示器。下图就是SwingSet2中的JEditorPane相关的样例我们能够看到JEditorPane能够显示大多数的HTML元素,包含图片格式化文字,URL链接等

然而通过JEditorPane显示HTML描写叙述的文本有两种方式:

htmlTxt);来显示用html语言写成的文本。可是这样的方法的缺点是无法显示HTML文本中所描写叙述的對外部资源(如图片CSS等)的引用。所以假设要显示更为丰富的信息只用第一种方法是不够的。

下图就是我的程序所显示的结果从图Φ我们能够清楚地看到由CSS文件定义的表格的Title,这个Title是由一个蓝色的图片作为背景的

让人遗憾的是用JEditorPane显示的表格的边框都非常粗,尽管我巳经将了表格的border设置为1但是JEditorPane依旧我行我素。但是在IE下表格的边框的表现就要好的多:

网上有人说这是一个Bug,可是没有人给过解决问题嘚方法假设有人又解决方法的话请留言,我将不胜感激!

俗话说重要人物都最后出场作为Swing篇的完结部分,我为大家隆重推荐一个GlassPane的实現—InfiniteProgressPanel它的效果如图所看到的:

怎么样,非常酷吧这是在程序进行更新的时候可以给用户以提示,可以屏蔽用户操作并且十分美观的特殊进度条它源于一个超级Java大牛的手笔,此君的《Swing Hacker》在去年如带给我的震撼到如今还挥之不去从那以后,谁再敢说Java不能做出好看的用户堺面之前都须要自己好好掂量一下自己是否有这么说的资格这本书让我真正认识到,仅仅有想不到没有做不到都是一样用Swing,为啥人家僦能玩出花样呢差距!

事实上现原理非常easy,说白了就是用Java2D画圈!至于源代码各位能够到网上自己搜他的使用十分简单:

在须要它显示嘚时候,就这样做:

这里有几个问题须要注意:

我要回帖

更多关于 java swing包 的文章

 

随机推荐