电脑升级-netcfg hlp文件下载
2023年3月31日发(作者:word2007)
图1
图2
图3
图4
图5
图6
怎么样,javaswing可视化编程。适合对javaswing有所了解的java爱好者。如果有兴趣
就继续往下看,别见笑!
包含的内容:
1.整个窗口为一个JFrame。
2.最上方的JMenuBar。
3.中间最大的那块区域——mainPanel。
4.右侧边栏——rightPanel。
5.底部的一栏——basePanel。
主要功能:
JMenuBar里设置了两个菜单项——File和Help。File里有打开文件、关闭文件和退出菜单
项。单击Open...或者按快捷键alt+O,弹出JFileChooser文件选择对话框,选择图片文件
(这里支持jpg、jpeg、gif、tif、tiff和png五种格式)后,图片将在mainPanel里显示。同
一文件夹下的其他图片文件显示在rightPanel,如果图片很多可以出现滑动条。basePanel
里有两个按钮和一个显示当前图片序号和图片总数的标签;按钮可以往上往下翻图片,主面
板、右侧边栏和标签都会动态更新。如果到了最后一张,“下一个”按钮被禁用;第一张时,
“上一个”被禁用。同理在右侧边栏里选图片其它地方也都可以动态更新。
点File里的Close时,会清空mainPanel,rightPanel和标签中显示的内容,禁用两个按钮,
效果(如图1)就像是还没有打开文件一样。
点退出时关闭Frame,结束程序。
下面正式开始介绍程序。
注:这里所讲的和提供的源码稍有差异,有兴趣的可以结合文中给出的代码去编写自己的类。
程序分为四部分,分别为三个面板的建立。最后组合在一起,放在一个JFrame里,加入菜
单栏,各种监听器。
PartI写主面板类——MainPanel
可以从JPanel继承。MainPanel相对与JPanel,多了一个图像显示的功能,所以里面一定
要有获取图片的方法,还必须重载paintComponent方法。
关于paintComponent这我想多说一点。可视化组件要完成显示的工作一般都要调用paint
方法,而paint方法又把绘图任务交给了三个方法:paintComponent,paintBorder,和
paintChildren。我们只需把需要个性定制的实现代码放在paintComponent方法里,在添加
你的代码之前记得一定要调用omponent。在写自己的实现方法前一定要记住
给自己留一条退路。什么退路?比如说我们前面提到的关闭文件方法,要实现一定的清理工
作,等价于不在原组件里画图。这里我们可以这样实现:
@override
publicvoidpaintComponent(Graphicsg)
{
intComponent(g);
/*Customizeyourpaintplanshere.*/
if(image!=null){/*假设image就是需要显示的图片*/
/*yourcodetopainttheimage*/
}
}
一般情况下,我们不能直接调用paint方法,当需要更新显示内容时直接调用repaint。repaint
先完成一定的清理工作然后会调用paint,paint又调用paintComponent,就可以显示出你
画的东西了。
要让MainPanel类获取图片,可以给它传一个ImageIcon,或图片文件或其它任何可以得
到图片的东西。我们从JFileChooser中得到的是图片文件,直接把图片文件或者经转化为
ImageIcon后作为参数传递给MainPanel。具体如下:
/*Mai*/
/*importeveryclassneededhere*/
publicclassMainPanelextendsJPanel
{
protectedFileimgFile;
protectedImageIconimg;
publicPaintImage()
{
/*addyourcodehere*/
}
publicvoidsetImageFile(FilenewImgFile)
{
imgFile=newImgFile;
ImageIconnewImg=newImageIcon(h());
setImage(newImg);
}
publicvoidsetImage(ImageIconnewImg)
{
img=newImg;
repaint();
}
publicvoidpaintComponent(Graphicsg)
{
Component(g);
if(img!=null){
ntImg(this,g,img);/*paintImg是类Util里的一个方法,用来画img*/
}
}
}
上述我们已经完成了MainPanel类的创建。下面写一个测试类,看看效果:
/*MainPanelTest.java*/
/*importneededclasseshere*/
publicclassMainPanelTest
{
privatestaticfinalImageIconpigImg=newImageIcon(“imgs/f”);
publicMainPanelTest(MainPanelmp)
{
JPanelpanel=newJPanel();
JButtonbtn=newJButton(“Loadimage”);
out(newBorderLayout());
mp.setPreferredSize(newDimension(350,350));
pa(mp);
ionListener(newActionListener(){
publicvoidactionPerformed(ActioneEvente){
ge(pigImg);
}
});
panel.add(btn);
Util.run(this,null);
}
publicstaticvoidmain(String[]args)
{
newMainPanelTest(newMainPanel());
}
}
运行时点击按钮即可载入图片。这里再一次地用到了Util类,有关Util请参考Util.java。
PartII创建右侧面板类——SlidePane
SlidePane的显示内容是一个列表,我们可以从JList继承。JList通过ListSelectionModel
可以设置三种选择模式:MULTIPLE_INTERVAL_SELECTION,
SINGLE_INTERVAL_SELECTION,SINGLE_SELECTION。由于每次mainPanel里只能
显示一张图片,故我们把它设置成单选模式(SINGLE_SELECTION)。
getSelectionModel().setSelectionMode(ListSelectionMode_SELECTION);
JList中每个元素的显示方式通过ListCellRenderer来管理。我们想要改变它的显示方式,
变成显示图标,我们就必须通过设置ListCellRenderer来实现。
ListCellRenderer是一个接口,里面只有一个方法:
ComponentgetListCellRendererComponent(JList<?extendsE>list,
Evalue,
intindex,
booleanisSelected,
booleancellHasFocus)
list是JList中所要显示的元素,value是当前选择的元素,index是当前选择元素的序号。
我们可以选择JLabel来实现这个方法,让list里放ImageIcon,然后把label的图标设置成
value就可以了。
如:
publicclassImageRendererextendsJLabelimplementsListCellRenderer
{
publicImageRenderer()
{
setOpaque(true);
setHorizontalAlignment(SwingC);
setVerticalAlignment(SwingConstant);
}
publicComponentgetListCellRendererComponent(JList<?extendsE>list,
Evalue,
intindex,
booleanisSelected,
booleancellHasFocus)
{
if(isSelected){
setBackground(list.getSelectionBackground());
setForeground(tSelectionForeground());
}
else{
setBackground(list.getBackground());
setForeground(lieground());
}
setIcon(value);
returnthis;
}
}
最后要出现滑动条的效果还需要把SlidePane加到JSlidePane里,不需要设置SlidePane的
大小,否则SlidePane的可视区域就局限于设置的大小里,超出部分不能通过滚动滑动条看
到。
PartIII创建BasePanel类
这里我们稍稍做一点改动,让按钮和面板标签中的显示内容想关联,让按钮来实现数组index
的移动。下面给出代码:
/*BaseP*/
/*importneededclasseshere*/
publicclassBasePanelextendsJPanel
{
JButtonlast;
JButtonnext;
privateJLabelprogress;
privateintindex;
privateintlength;
publicBasePanel()
{
setLayout(newFlowLayout());
setBorder(newMatteBorder(1,0,0,0,Co));
last=newJButton(“上一个”);
lionCommand(ActionCom_IMG);
next=newJButton(“下一个”);
ionCommand(Action_IMG);
progress=newJLabel(“/”);
setPreferredSize(newDimension(600,50));
add(last);
add(progress);
add(next);
}
publicvoidsetParam(intlength,intindex)throwsIllegalParameterException
{
if(index<0||length<0||length
thrownewIllegalParameterException();
}
=length;
setIndex(index);
}
publicvoidnext()
{
setIndex(index+1);
}
publicvoidlast()
{
setIndex(index-1);
}
publicintgetIndex()
{
returnindex;
}
publicvoidsetIndex(intindex)
{
=index;
if(index<=0){
tEnabled(false);
}
else{
last.setEnabled(true);
}
if(index>=length-1){
nbled(false);
}
else{
bled(true);
}
if(index==0&&length==0){
progrest(“/”);
}
else{
progret((index+1)+”/”+length);
}
}
}
两个button的监听器在这里暂时不加,因为BasePanel、SlidePane和MainPanel三者之
间要互相通信,在这里增加监听器只能实现对其自身的控制,不能改变别的面板的状态。故
监听器的功能等到了写主程序的时候再一并实现。
PartIV创建主程序
将前面几个容器都组合进来,实现一个menuBar,再写各类监听器,最后显示出来。
第一步:添加组件到面板
首先定义前面三个类的组件。
MainPanelmainPanel=newMainPanel();
SlidePanerightPanel=newSlidePane();
BasePanelbasePanel=newBasePanel();
然后把rightPanel加到JScrollPane里,
JScrollPanescrolledRightPanel=newJScrollPane(rightPanel);
再把mainPanel和scrolledRightPanel放到一个JSplitPane里,
JSplitPanesplitPanel=newJSplitPane(JSplitPane.HORIZONTAL_SPLIT,mainPanel,
scrolledRightPanel);
最后把splitPanel和basePanel装到一个容器中,容器使用BorderLayout排布。即:
这里主程序类继承自JPanel,其本身就是一个容器。
setLayout(newBorderLayout());
add(splitPanel,BoER);
add(basePanel,BorderLayo);
第二步:创建menuBar
仅以一个为例:
JMenuBarmenuBar=newJMenuBar();
JMenufileMenu=newJMenu(“File”);
(fileMenu);
JMenuItemfileOpenItem=newJMenuItem(“OpenFile”);
(fileOpenItem);
创建其它菜单或菜单项与此过程类似,不重复写了。
第三步:增加监听器
这一步最复杂,留在了最后作为压轴部分。首先让我们来盘点一下有哪些组件需要增加监听
器,都需要增加什么类型的监听器。
按照从上到下,从左到右的顺序:
菜单,Help菜单的各个菜单项。需要ActionListener。
2.mainPanel,当尺寸改变时,需要重新绘制,应增加ComponentListener。
3.rightPanel里,选择不同的文件时其它的面板需要更新。需要ListSelectionListener。
anel里两个按钮,需要ActionListener。
所有这些监听器的实现强烈建议使用内部类在主程序里实现,这样一来主程序中的变量可以
被这些类访问,你便拥有了更大的灵活性。但是你可以发现有多个组件需要同一种监听器,
当在一个组件上发生动作时,监听器就可以收到信号,但是它并不知道是谁发出的信号,这
带来了一个问题。有两种解决方式。第一,getSource方法获取源,然后判断。这种方法针
对类型单一的组件(比如都是JButton)比较好用,但是像我们这里的情况解决起来就不是
很合适。第二,在增加监听器的同时调用当前组件的setActionCommand方法设置动作命
令。当监听器收到触发信号后,调用getActionCommand,然后判断和哪个组件的相同。
下面增加监听器:
openFiionListener(this);
openFileItem.setActionCommand(ActionCommand.OPEN_FILE);
opccelerator(HotK_FILE);
„„
dComponentListener(newComponentAdapter(){
publicvoidcomponentResized(ComponentEvente)
{
mainPanel.repaint();
}
});
/*ListSelectionListener在后面说*/
ionListener(this);
ionCommand(ActionCom_IMG);
„„
setActionCommand方法里用到的String类型的参数都使用定义在ActionCommand里的常
量。菜单项设置了快捷键,按钮不支持。
主程序里实现ActionListener接口的方法如下:
publicvoidactionPerformed(ActionEvente)
{
Stringcommand=getActionCommand();
if(command==null)return;
switch(command)
{
caseActionComma_FILE:doOpenFile();
caseActionComm_FILE:doCloseFile();
„„
caseAction_IMG:showLastImg();
}
}
以下细说doOpenFile(),doCloseFile()和showLastImg(),actionPerformed里其它都略了。
doOpenFile()
点击OpenFile菜单,执行doOpenFile方法,首先应该弹出一个选择文件的对话框。定义
一个JFileChooser,使用里面的showOpenDialog,调用该方法后得到一个返回值。通过返
回值可以判断是否选择了文件,如果选择了文件就进一步处理。
首先可以用JFileChooser的getSelectedFile得到所选的文件curImageFile。由curImageFile
又可以得到当前目录下的图片文件列表imgFileList。把imgFileList传递给rightPanel和
basePanel里的两个按钮,因为打开文件后,不仅要在mainPanel里显示图片,而且右侧
边栏和下方的控制/状态栏也会被激活。这两个组件需要的正是一个文件数组。
调用MainPanel的setImageFile就可以显示当前图片。调用SlidePane的setListData就可
以把要显示的文件加入到列表里了,但是我们前面约定的SlidePane里的元素类型是
ImageIcon,这里不能直接提供File类型的元素列表,故转换后再调用setListData方法。
针对我们前面写的BasePanel类,只需要向其传递一个图片数组的长度和当前选定图片在
图片数组中的位置就可以了。所以doOpenFile就可以这样来写:
/*inthefielddeclaration*/
protectedFilecurImageFile;
protectedFile[]imgFiles;
protectedImageIconcurImage;
protectedImageIcon[]imgs;
protectedintindex;
„„
voiddoOpenFile()
{
JFileChooserjc=newJFileChooser();
intretValue=penDialog();
if(retValue!=JFilVE_OPTION){
/*specifyyourhandleoption*/
return;
}
/*herewedealwithwhenchooseapproveoption*/
curImageFile=jc.getSelectedFile();
imgFiles=arentFile().listFiles(newFilenameFilter(){
publicbooleanaccept(Filedir,Stringname){
/*tofilterouttheimageityourself.*/
}
});
imgs=newImageIcon[img];
for(inti=0;i<;i++){
imgs[i]=newImageIcon(imgFiles[i]);
if(imgFiles[i].equals(curImageFile)){
index=i;
}
}
curImage=imgs[index];
mainPge(curImage);
righttData(imgs);
rightectedIndex(index);
try{
basePanel.setParam(imgs.length,index);
}catch(IllegalParameterExceptonex){
newRuntimeException(“illegalparamter”);
}
}
doCloseFile()
这里要做的是模拟文件关闭以后三个面板上应该显示的东西,通过擦出是不明智的选择。在
开始设计的时候就需要考虑到这一步了,现在来看看解决方法:
MainPanel接受空的参数,故对它就这样写:mage(null);
RightPanel继承自JList,JList在调用setListData时不允许用null,如果这样会得到不可预
期的错误(doc里是这样说的),所以我们还是要给它传一个数组,把数组的长度弄成零就
可以达到目的,如下:
rstData(newImageIcon[]{});
{}里不包含任何元素,表明其长度为零。但是{}不能省,否则就是一个没有初始化的数组。
而对于BasePanel,setParam方法参数输入错误也抛出异常,但是可能你已经看出来了,
还是留下了一个空位,即setParam(0,0);这样既不会抛出异常,又可以禁用两个按钮,只是
标签上还有显示。
showLastImg()
有了前面的铺垫,这一方法实现起来就简单多了,首先改变index的值,再反映到相关联的
其它两个面板里。
voidshowLastImg()
{
basePan();
rigectedIndex(basePex());
mainPanel.setImage(rightPaectedValue());
}
直接调用BasePanel类里的方法就可以解决问题。
大家注意一下,这里这几个方法前面都没有加public,是因为这些都只是为了增强代码的可
读性刻意把一部分代码分离出来而增加的辅助方法,不需要别人调用,自己知道就可以了,
所以不加。
到此ActionListener已经讲得差不多了,而ComponentListener在增加监听器的时候就用
匿名内部类实现了,当检测到尺寸发生变化时就重画图片。最后来说说RightPanel
的ListSelectionListener。
这个接口里一个方法,
publicvoidvalueChanged(ListSelectionEvente);
当list里的选项发生变化时,我们应该通知mainPanel和basePanel做出相应的调整。即:
publicvoidvalueChanged(ListSelectionEvente)
{
tImage(rightPanectedValue());
basePex(rlectedIndex());
}
到此整个程序已经将完了,点此下载源码。
更多推荐
gif图片查看器
发布评论