| |
大 连 理 工 大 学 计 算 机 系 邓继光 翟丽萍 张丽滨
---- 一.java 简 介
---- java 技 术 是 一 个 崭 新 的 技 术, 它 从c++ 中 吸 收 了 许 多 强 有 力 的 成 分, 并 且 带 有 许 多 新 的 特 征, 如
? ? ?
---- java 标 准 类 库 中 对internet 和web 内 建 的 支 持, 使 得 开 发 者 可 方 便 地 开 发 网 络 应 用。 ---- 自 从java 诞 生 以 来, 众 多 的 公 司 已 致 力 于java 开 发 平 台 的 研 制,sun,microsoft,borland 和symantec 争 相 推 出 了 自 己 的java 开 发 平 台。javasoft 公 司 推 出 的jdk 以 其 灵 活 性 和 强 大 功 能 得 到 了 众 多 开 发 者 的 青 睐。
---- 二. jdk1.1.1 中 的 菜 单 功 能
---- 在jdk1.1.1 中 菜 单 功 能 具 体 由java.awt.menu ,java.awt.menubar ,java.awt.menucomponent ,java.awt.menuitem ,java.awt.menushortcut 实 现, 其 继 承 关 系 如 下:
java.lang.object java.awt.menucomponent java.awt.menuitem java.awt.menu java.awt.popupmenu java.awt.menubar java.awt.menushortcut
---- 在java.awt.frame 中 实 现 了java.awt.menucontainer, 利 用 其setmenubar 方 法 即 可 提 供 菜 单 服 务。 但 一 个application 中 只 应 有 一 个frame(dialog 除 外) 同 时 存 在, 否 则 所 有 的component 不 能 构 成 一 个 整 体(frame 可 被 自 由 拖 动), 这 样 如 仅 利 用jdk1.1.1 提 供 的 功 能,application 中 只 能 存 在 一 个 菜 单。 由frame 的 ---- ? ? ?
---- frame 是 一 个container, 它 可 以 装 入 多 个panel, 如 能 在panel 中 实 现 菜 单 功 能, 就 可 以 在application 中 提 供 多 菜 单 服 务 了。
---- 三. 在panel 中 实 现 菜 单 功 能
---- 在panel 中 实 现 菜 单 功 能 可 有 如 下 三 种 途 径
---- 1. 模 仿java.awt.frame 的 菜 单 服 务, 在panel 中 加 入 菜 单 功 能
---- 2. 利 用jdk 提 供 的 部 分 功 能, 和 自 己 的component 组 合 完 成
---- 3. 完 全 用 自 己 的component 实 现
---- java.awt.frame 和java.awt.panel 各 自 的 继 承 关 系 如 下:
java.lang.object java.awt.component java.awt.container java.awt.window java.awt.frame java.awt.panel
---- 由 继 承 关 系 可 以 看 出, 要 模 仿java.awt.frame 的 菜 单 服 务, 在panel 中 加 入 菜 单 功 能, 是 比 较 困 难 的, 况 且,jdk 文 档 中 并 未 提 供 完 整 的 源 代 码。 ---- 如 要 完 全 用 自 己 的component 实 现, 则 需 考 虑 复 杂 的 屏 幕 刷 新 和 事 件 处 理 问 题, 也 是
---- ? ? ?
---- 而 利 用jdk1.1.1 的java.awt.component 中 提 供 的popupmenu 功 能, 在 上 面 加 上label, 在 鼠 标 点 击label 时, 弹 出popupmenu, 以 此 模 仿frame 提 供 的 菜 单 服 务, 可 以 较 容 易 的 在panel 中 加 入 菜 单 功 能。 具 体 实 现 如 下:
---- // 此listener 用 于 发 出menubarlabel 点 击 事 件
public interface menubarlabellistener { public void processlabelclick(string labelname); }
import java.awt.* ; import java.awt.event.* ; import java.util.*;
//menubarlabel 用 于 模 拟java.awt.menubar 的 功 能 public class menubarlabel extends canvas implements mouselistener { protected color foreground = color.black ; protected color background = color.lightgray; protected string xlabel ; protected boolean disabled = false ; protected menubarlabellistener listener=null;
public menubarlabel(string xlabel) { this.xlabel = new string(xlabel); setfont(new font("courier",font.plain,16)); setbackground(background); addmouselistener(this); }
public void addlistener(menubarlabellistener listener) { this.listener=listener; }
public string getname() { return xlabel; }
public void paint(graphics g) { dimension dm = getsize(); int width = dm.width; int height= dm.height; g.setcolor(foreground);
int descent = g.getfontmetrics().getdescent(); g.drawstring(xlabel,0,height-descent); } public void mouseclicked(mouseevent evt){ ;} public void mouseentered(mouseevent evt){ ;} public void mousepressed(mouseevent evt) { background=color.blue.darker().darker(); paint(); if (null !=listener) listener.processlabelclick(xlabel); }
public void mouseexited(mouseevent evt) { background=color.lightgray; setbackground(background); }
public void mousereleased(mouseevent evt) { background=color.lightgray; setbackground(background); }
public void setforeground(color foreground) { this.foreground = foreground; repaint(); }
public void setbackground(color background) { this.background = background; repaint(); }
public void paint() { graphics g=getgraphics(); if (null==g) return; dimension dm = getsize(); int width = dm.width; int height= dm.height; int descent = g.getfontmetrics().getdescent(); int height1=g.getfontmetrics().getheight(); g.setcolor(color.blue.darker().darker()); g.fillrect(0,height-height1,width,height1); g.setcolor(color.white); g.drawstring(xlabel,0,height-descent); g.dispose(); }
public void paintback() { graphics g=getgraphics(); if (null==g) return; dimension dm = getsize(); int width = dm.width; int height= dm.height; int descent = g.getfontmetrics().getdescent(); g.setcolor(color.lightgray); g.fillrect(0,0,width,height); g.setcolor(foreground); g.drawstring(xlabel,0,height-descent); g.dispose(); } }
// 此listener 用 于 提 供 所 有 的 菜 单 选 择 事 件 public interface menupanellistener { public void processmymenu(object source,object label); //you can use source to indentify different items with same label }
//menupanel 提 供 菜 单 功 能 服 务 import java.awt.*; import java.awt.event.*; import java.util.*; /** *pay attention: *1.the menupanel′s height >==26, 26 recommended *2.you can not change the background of the menu because popup * menu′s backgroud can not be changed */
public class menupanel extends panel implements actionlistener,menubarlabellistener
{ panel mymenubar=new panel(); panel popuppanel=new panel(); menubarlabel previouslabel=null; menupanellistener listener=null; font labelfont=new font("courier",font.plain,16); private vector labelvector=new vector(); private vector popupvector=new vector(); int maxwidth=0;
public menupanel()
{ setlayout(null); mymenubar.setlayout(null); mymenubar.setbackground(color.lightgray); add(mymenubar); add(popuppanel); mymenubar.setbounds(0,0,400,25); popuppanel.setlayout(null); popuppanel.setbounds(0,26,400,500); popuppanel.setvisible(false); setfont(labelfont); }
public void addlistener(menupanellistener listener) { this.listener=listener; }
private void addmenuitemlistener(menucomponent menu) { ((menuitem)menu).addactionlistener(this); if (menu instanceof menu || menu instanceof popupmenu) for (int i=0;i< ((menu)menu).getitemcount();i++) addmenuitemlistener(((menu)menu).getitem(i));
}
private void setmenuitemfont(menucomponent menu) { menu.setfont(labelfont); if (menu instanceof menu || menu instanceof popupmenu) for (int i=0;i< ((menu)menu).getitemcount();i++) setmenuitemfont(((menu)menu).getitem(i)); }
public void addmenu(popupmenu menu,string name) { if (menu==null || name==null ||name.length()< =0) return; menubarlabel label=new menubarlabel(name); label.setfont(labelfont); label.addlistener(this); mymenubar.add(label); labelvector.addelement(label); setmenuitemfont(menu); addmenuitemlistener(menu); popupvector.addelement(menu); popuppanel.add(menu); }
public void setmenufont(font menufont) { int fontsize=menufont.getsize();
if (menufont.getsize() >25) fontsize=25; labelfont=new font(menufont.getname(), menufont.getstyle(),fontsize); setfont(labelfont); for (int i=0;i< popupvector.size();i++) setmenuitemfont(((popupmenu) popupvector.elementat(i))); repaint(); }
public void paint(graphics g) { menubarlabel label; int width=0,width1; int panelwidth=getparent().getsize().width; if (panelwidth >0) { setsize(panelwidth,getsize().height); mymenubar.setbounds(0,0,panelwidth,25); popuppanel.setbounds(0,26,panelwidth,500); } for (int i=0; i< labelvector.size();i++) { label=(menubarlabel)labelvector.elementat(i); label.setfont(labelfont); width1=g.getfontmetrics().stringwidth(label.getname()); if (width1 >width) width=width1; } if (width !=maxwidth) { maxwidth=width; for (int i=0; i< labelvector.size();i++) { label=(menubarlabel)labelvector.elementat(i); label.setbounds(i*maxwidth+(i+1)*15,0,maxwidth,25); } } }
public void processlabelclick(string labelname) { menubarlabel label=null; boolean invector=false; int i=0; while (i< labelvector.size()) { label=(menubarlabel)labelvector.elementat(i); if ((label.getname()).equals(labelname)) { invector=true; break; } i++; } if (invector) { if ((null !=previouslabel)&& (!previouslabel.equals(label))) previouslabel.paintback(); previouslabel=label; if (((popupmenu)popupvector.element at(i)).getitemcount() >0) { popuppanel.setvisible(true); ((popupmenu)popupvector.elementat(i)). show(popuppanel,i*maxwidth+ (i+1)*15,0); } } }
public void actionperformed(actionevent evt) { if(null!=listener) listener.processmymenu(evt.getsource(), evt.getactioncommand()); } }
---- 四. 应 用 举 例
---- 本 例 程 利 用 上 面 的menupanel, 在testmenu 中 实 现 了 带 两 个 下 拉 菜 单 的 菜 单。
import java.awt.*; public class testmenu extends frame implements menupanellistener { public testmenu() { setlayout(null); setsize(400,300); menupanel mypanel=new menupanel(); menupanel.addlistener(this); // 在mypanel 中 加 入listener popupmenu popupmenu1=new popupmenu("menu1"); //"menu1" 即 为 显 示 的label menu submenu1=new menu("test1"); submenu1.addmenuitem(new menuitem("item1")) submenu1.addmenuitem(new menuitem("item2")) menu submenu2=new menu("test2"); submenu2.addmenuitem(new menuitem("item3")) submenu2.addmenuitem(new menuitem("item4")) menu submenu3=new menu("test3"); submenu3.addmenuitem(new menuitem("item5")) submenu3.addmenuitem(new menuitem("item6")) popupmenu1.addmenuitem(submenu1); popupmenu1.addmenuitem(submenu2); popupmenu1.addmenuitem(submenu3); mypanel.addmenu(popupmenu1);
popupmenu popupmenu2=new popupmenu ("menu2");//"menu2" 即 为 显 示 的label menu submenu4=new menu("test4"); submenu4.addmenuitem(new menuitem("item7")) submenu4.addmenuitem(new menuitem("item8")) menu submenu5=new menu("test5"); submenu5.addmenuitem(new menuitem("item9")) submenu5.addmenuitem(new menuitem("item10")) menu submenu6=new menu("test6"); submenu6.addmenuitem(new menuitem("item11")) submenu6.addmenuitem(new menuitem("item12")) popupmenu2.addmenuitem(submenu4); popupmenu2.addmenuitem(submenu5); popupmenu2.addmenuitem(submenu6); mypanel.addmenu(popupmenu2);
mypanel.setbounds(0,0,400,26); add(menupanel); }
public void processmymenu(object source,object label) { system.out.println((string)label); }
protected void processevent(awtevent evt) { if (evt.id == event.window_destroy) system.exit(0); }
}
---- 注: 本 文 程 序 在win95 下, 用jdk1.1 调 试 通 过。
|
|