日期:2011-03-22 16:16:00 来源:本站整理
保举编码办法(java)[Java编程]
本文“保举编码办法(java)[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
内部类是新的事件模子,并且事实上旧的事件模子连同新库的特点都被它好的支持,依靠老式的编程办法无疑增添了一个新的混乱的因素.目前有更多差别的办法为我们编写讨厌的代码.刚巧的是,这种代码显目前本书中和程序样本中,并且乃至在文件和程序样本中同SUN公司辨别开来.在这一节中,我们将看到一些关于我们会和不会运行新AWT的争论,并由向我们展示除了可以谅解的情形,我们可以随时利用接纳器类去办理我们的事件处理需求来完毕.因为这种办法一样是最简单和最清楚的办法,它将会对我们学习它构成有效的帮忙.
在看到任何事从前,我们知道固然Java 1.1向后兼容Java 1.0(也就是说,我们可以在1.1中编译和运行1.0的程序),但我们并不能在同一个程序里混合事件模子.换言之,当我们试图集成老的代码到一个新的程序中时,我们不能利用老式的action()办法在同一个程序中,因此我们必须决意能否对新程序利用老的,难以保护的办法大概进级老的代码.这不会有太多的竞争因为新的办法对老的办法而言是如此的优异.
1. 原则:运行它的好办法
为了给我们一些事物来举行对比,这儿有一个程序例子演示向我们举荐的办法.到目前它会变得相当的熟习和舒服.
//: GoodIdea.java // The best way to design classes using the new // Java 1.1 event model: use an inner class for // each different event. This maximizes // flexibility and modularity. import java.awt.*; import java.awt.event.*; import java.util.*; public class GoodIdea extends Frame { Button b1 = new Button("Button 1"), b2 = new Button("Button 2"); public GoodIdea() { setLayout(new FlowLayout()); b1.addActionListener(new B1L()); b2.addActionListener(new B2L()); add(b1); add(b2); } public class B1L implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("Button 1 pressed"); } } public class B2L implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("Button 2 pressed"); } } public static void main(String[] args) { Frame f = new GoodIdea(); f.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e){ System.out.println("Window Closing"); System.exit(0); } }); f.setSize(300,200); f.setVisible(true); } } ///:~
这是颇有点微不足道的:每个按钮有它自己的印出一些事物到掌握台的接纳器.但请注意在整个程序中这不是一个条件语句,大概是一些表示“我想要知道怎样使事件发生”的语句.每块代码都与运行有关,而不是范例查验.也就是说,这是最好的编写我们的代码的办法;不但仅是它更易使我们理解概念,至少是使我们更易阅读和保护.剪切和粘贴到新的程序是一样如此的简单.
2. 将主类作为接纳器实现
第一个坏主张是一个普通的和举荐的办法.这使得主类(有代表性的是程序片或帧,但它能变成一些类)履行各种差别的接纳器.下面是一个例子:
//: BadIdea1.java // Some literature recommends this approach, // but it's missing the point of the new event // model in Java 1.1 import java.awt.*; import java.awt.event.*; import java.util.*; public class BadIdea1 extends Frame implements ActionListener, WindowListener { Button b1 = new Button("Button 1"), b2 = new Button("Button 2"); public BadIdea1() { setLayout(new FlowLayout()); addWindowListener(this); b1.addActionListener(this); b2.addActionListener(this); add(b1); add(b2); } public void actionPerformed(ActionEvent e) { Object source = e.getSource(); if(source == b1) System.out.println("Button 1 pressed"); else if(source == b2) System.out.println("Button 2 pressed"); else System.out.println("Something else"); } public void windowClosing(WindowEvent e) { System.out.println("Window Closing"); System.exit(0); } public void windowClosed(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} public void windowIconified(WindowEvent e) {} public void windowActivated(WindowEvent e) {} public void windowDeactivated(WindowEvent e) {} public void windowOpened(WindowEvent e) {} public static void main(String[] args) { Frame f = new BadIdea1(); f.setSize(300,200); f.setVisible(true); } } ///:~
这样做的用处显示在下述三行里:
addWindowListener(this);
b1.addActionListener(this);
b2.addActionListener(this);
因为Badidea1履行行动接纳器和窗中接纳器,这些程序行当然可以承受,并且假如我们一向保持设法使少量的类去削减服务器检索期间的程序片载入的作法,它看起来变成一个不错的主张.但是:
(1) Java 1.1版支持JAR文件,因此全部我们的文件可以被安排到一个单一的压缩的JAR文件中,只需求一次服务器检索.我们不再需求为Internet效率而削减类的数目.
(2) 上面的代码的组件越发的少,因此它难以抓住和粘贴.注意我们必须不但要履行各种各样的接口为我们的主类,但在actionPerformed()办法中,我们操纵一串条件语句测试哪个行动被完成了.不但仅是这个状况倒退,远离接纳器模子,除此之外,我们不能简单地反复利用actionPerformed()办法因为它是指定为这个特别的利用程序利用的.将这个程序例子与GoodIdea.java举行对比,我们可以恰好捕捉一个接纳器类并粘贴它和最小的焦虑到任何地方.别的我们可认为一个单独的事件注册多个接纳器类,答应乃至更多的模块在每个接纳器类在每个接纳器中运行.
3. 办法的混合
第二个bad idea混合了两种办法:利用内嵌接纳器类,但一样履行一个或更多的接纳器接口以作为主类的一部份.这种办法无需在书中和文件中举行注释,并且我可以臆测到Java开辟者认为他们必须为差别的目的而采纳差别的办法.但我们却没必要——在我们编程时,我们大概大概会偏向于利用内嵌接纳器类.
//: BadIdea2.java // An improvement over BadIdea1.java, since it // uses the WindowAdapter as an inner class // instead of implementing all the methods of // WindowListener, but still misses the // valuable modularity of inner classes import java.awt.*; import java.awt.event.*; import java.util.*; public class BadIdea2 extends Frame implements ActionListener { Button b1 = new Button("Button 1"), b2 = new Button("Button 2"); public BadIdea2() { setLayout(new FlowLayout()); addWindowListener(new WL()); b1.addActionListener(this); b2.addActionListener(this); add(b1); add(b2); } public void actionPerformed(ActionEvent e) { Object source = e.getSource(); if(source == b1) System.out.println("Button 1 pressed"); else if(source == b2) System.out.println("Button 2 pressed"); else System.out.println("Something else"); } class WL extends WindowAdapter { public void windowClosing(WindowEvent e) { System.out.println("Window Closing"); System.exit(0); } } public static void main(String[] args) { Frame f = new BadIdea2(); f.setSize(300,200); f.setVisible(true); } } ///:~
因为actionPerformed()行动完成办法同主类精密地结合,所以难以复用代码.它的代码读起来一样是缭乱和令人讨厌的,远远超越了内部类办法.不公道的是,我们不得不在Java 1.1版中为事件利用那些老的思绪.
4. 担当一个组件
成立一个新范例的组件时,在运行事件的老办法中,我们会常常看到差别的地方发生了改变.这里有一个程序例子来演示这种新的工作办法:
//: GoodTechnique.java // Your first choice when overriding components // should be to install listeners. The code is // much safer, more modular and maintainable. import java.awt.*; import java.awt.event.*; class Display { public static final int EVENT = 0, COMPONENT = 1, MOUSE = 2, MOUSE_MOVE = 3, FOCUS = 4, KEY = 5, ACTION = 6, LAST = 7; public String[] evnt; Display() { evnt = new String[LAST]; for(int i = 0; i < LAST; i++) evnt[i] = new String(); } public void show(Graphics g) { for(int i = 0; i < LAST; i++) g.drawString(evnt[i], 0, 10 * i + 10); } } class EnabledPanel extends Panel { Color c; int id; Display display = new Display(); public EnabledPanel(int i, Color mc) { id = i; c = mc; setLayout(new BorderLayout()); add(new MyButton(), BorderLayout.SOUTH); addComponentListener(new CL()); addFocusListener(new FL()); addKeyListener(new KL()); addMouseListener(new ML()); addMouseMotionListener(new MML()); } // To eliminate flicker: public void update(Graphics g) { paint(g); } public void paint(Graphics g) { g.setColor(c); Dimension s = getSize(); g.fillRect(0, 0, s.width, s.height); g.setColor(Color.black); display.show(g); } // Don't need to enable anything for this: public void processEvent(AWTEvent e) { display.evnt[Display.EVENT]= e.toString(); repaint(); super.processEvent(e); } class CL implements ComponentListener { public void componentMoved(ComponentEvent e){ display.evnt[Display.COMPONENT] = "Component moved"; repaint(); } public void componentResized(ComponentEvent e) { display.evnt[Display.COMPONENT] = "Component resized"; repaint(); } public void componentHidden(ComponentEvent e) { display.evnt[Display.COMPONENT] = "Component hidden"; repaint(); } public void componentShown(ComponentEvent e){ display.evnt[Display.COMPONENT] = "Component shown"; repaint(); } } class FL implements FocusListener { public void focusGained(FocusEvent e) { display.evnt[Display.FOCUS] = "FOCUS gained"; repaint(); } public void focusLost(FocusEvent e) { display.evnt[Display.FOCUS] = "FOCUS lost"; repaint(); } } class KL implements KeyListener { public void keyPressed(KeyEvent e) { display.evnt[Display.KEY] = "KEY pressed: "; showCode(e); } public void keyReleased(KeyEvent e) { display.evnt[Display.KEY] = "KEY released: "; showCode(e); } public void keyTyped(KeyEvent e) { display.evnt[Display.KEY] = "KEY typed: "; showCode(e); } void showCode(KeyEvent e) { int code = e.getKeyCode(); display.evnt[Display.KEY] += KeyEvent.getKeyText(code); repaint(); } } class ML implements MouseListener { public void mouseClicked(MouseEvent e) { requestFocus(); // Get FOCUS on click display.evnt[Display.MOUSE] = "MOUSE clicked"; showMouse(e); } public void mousePressed(MouseEvent e) { display.evnt[Display.MOUSE] = "MOUSE pressed"; showMouse(e); } public void mouseReleased(MouseEvent e) { display.evnt[Display.MOUSE] = "MOUSE released"; showMouse(e); } public void mouseEntered(MouseEvent e) { display.evnt[Display.MOUSE] = "MOUSE entered"; showMouse(e); } public void mouseExited(MouseEvent e) { display.evnt[Display.MOUSE] = "MOUSE exited"; showMouse(e); } void showMouse(MouseEvent e) { display.evnt[Display.MOUSE] += ", x = " + e.getX() + ", y = " + e.getY(); repaint(); } } class MML implements MouseMotionListener { public void mouseDragged(MouseEvent e) { display.evnt[Display.MOUSE_MOVE] = "MOUSE dragged"; showMouse(e); } public void mouseMoved(MouseEvent e) { display.evnt[Display.MOUSE_MOVE] = "MOUSE moved"; showMouse(e); } void showMouse(MouseEvent e) { display.evnt[Display.MOUSE_MOVE] += ", x = " + e.getX() + ", y = " + e.getY(); repaint(); } } } class MyButton extends Button { int clickCounter; String label = ""; public MyButton() { addActionListener(new AL()); } public void paint(Graphics g) { g.setColor(Color.green); Dimension s = getSize(); g.fillRect(0, 0, s.width, s.height); g.setColor(Color.black); g.drawRect(0, 0, s.width - 1, s.height - 1); drawLabel(g); } private void drawLabel(Graphics g) { FontMetrics fm = g.getFontMetrics(); int width = fm.stringWidth(label); int height = fm.getHeight(); int ascent = fm.getAscent(); int leading = fm.getLeading(); int horizMargin = (getSize().width - width)/2; int verMargin = (getSize().height - height)/2; g.setColor(Color.red); g.drawString(label, horizMargin, verMargin + ascent + leading); } class AL implements ActionListener { public void actionPerformed(ActionEvent e) { clickCounter++; label = "click #" + clickCounter + " " + e.toString(); repaint(); } } } public class GoodTechnique extends Frame { GoodTechnique() { setLayout(new GridLayout(2,2)); add(new EnabledPanel(1, Color.cyan)); add(new EnabledPanel(2, Color.lightGray)); add(new EnabledPanel(3, Color.yellow)); } public static void main(String[] args) { Frame f = new GoodTechnique(); f.setTitle("Good Technique"); f.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e){ System.out.println(e); System.out.println("Window Closing"); System.exit(0); } }); f.setSize(700,700); f.setVisible(true); } } ///:~
这个程序例子一样证明了各种各样的发现和显示关于它们的信息的事件.这种显示是一种集合显示信息的办法.一组字符串去获得关于每种范例的事件的信息,并且show()办法对任何图象对象都设置了一个句柄,我们采取并直接地写在外观代码上.这种计划是有意的被某种事件反复利用.
激活面板代表了这种新型的组件.它是一个底部有一个按钮的彩色的面板,并且它由操纵接纳器类为每一个单独的事件来引发捕捉全部发生在它之上的事件,除了那些在激活面板过载的老式的processEvent()办法(注意它应当一样调用super.processEvent()).操纵这种办法的唯一来由是它捕捉发生的每一个事件,因此我们可以察看持续发生的每一事件.processEvent()办法没有更多的展示代表每个事件的字符串,不然它会不得不利用一串条件语句去探求事件.在别的方面,内嵌接纳类早已清楚地知道被发现的事件.(假定我们注册它们到组件,我们不需求任何的控件的逻辑,这将成为我们的目的.)因此,它们不会去查抄任何事件;这些事件恰好做它们的原质料.
每个接纳器改正显示字符串和它的指定事件,并且调用重画办法repaint()因此将显示这个字符串.我们一样能注意到一个普通能消除闪耀的诀窍:
public void update(Graphics g) {
paint(g);
}
我们不会始终需求过载update(),但假如我们写下一些闪耀的程序,并运行它.默许的最新版本的排除后台然后调用paint()办法重新画出一些图画.这个排除行动普通会产生闪耀,但是不必要的,因为paint()重画了整个的外观.
我们可以看到很多的接纳器——但是,对接纳器输入查抄指令,但我们却不能接纳任何组件不支持的事件.(不像BadTechnuque.java那样我们能不时刻刻看到).
试验这个程序是非常的有教诲意义的,因为我们学习了很多的关于在Java中事件发生的办法.一则它展示了大大都开窗口的系统中计划上的瑕疵:它相当的难以去单击和释放鼠标,除非移动它,并且当我们实际上正试图用鼠标单击在某物体上时开窗口的会常常认为我们是在拖动.一个办理这个问题的筹划是利用mousePressed()鼠标按下办法和mouseReleased()鼠标释放办法去替换mouseClicked()鼠标单击办法,然后判断能否去调用我们自己的以时间和4个像素的鼠标滞后作用的“mouseReallyClicked()真实的鼠标单击”办法.
5. 蹩脚的组件担当
另一种做法是调用enableEvent()办法,并将与但愿掌握的事件对应的模子传送给它(很多参考书中都曾说起这种做法).这样做会造成那些事件被发送至老式办法(固然它们对Java 1.1来说是新的),并采取象processFocusEvent()这样的名字.也必必要记着调用底子类版本.下面是它看起来的模样.
//: BadTechnique.java // It's possible to override components this way, // but the listener approach is much better, so // why would you? import java.awt.*; import java.awt.event.*; class Display { public static final int EVENT = 0, COMPONENT = 1, MOUSE = 2, MOUSE_MOVE = 3, FOCUS = 4, KEY = 5, ACTION = 6, LAST = 7; public String[] evnt; Display() { evnt = new String[LAST]; for(int i = 0; i < LAST; i++) evnt[i] = new String(); } public void show(Graphics g) { for(int i = 0; i < LAST; i++) g.drawString(evnt[i], 0, 10 * i + 10); } } class EnabledPanel extends Panel { Color c; int id; Display display = new Display(); public EnabledPanel(int i, Color mc) { id = i; c = mc; setLayout(new BorderLayout()); add(new MyButton(), BorderLayout.SOUTH); // Type checking is lost. You can enable and // process events that the component doesn't // capture: enableEvents( // Panel doesn't handle these: AWTEvent.ACTION_EVENT_MASK | AWTEvent.ADJUSTMENT_EVENT_MASK | AWTEvent.ITEM_EVENT_MASK | AWTEvent.TEXT_EVENT_MASK | AWTEvent.WINDOW_EVENT_MASK | // Panel can handle these: AWTEvent.COMPONENT_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK | AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK | AWTEvent.CONTAINER_EVENT_MASK); // You can enable an event without // overriding its process method. } // To eliminate flicker: public void update(Graphics g) { paint(g); } public void paint(Graphics g) { g.setColor(c); Dimension s = getSize(); g.fillRect(0, 0, s.width, s.height); g.setColor(Color.black); display.show(g); } public void processEvent(AWTEvent e) { display.evnt[Display.EVENT]= e.toString(); repaint(); super.processEvent(e); } public void processComponentEvent(ComponentEvent e) { switch(e.getID()) { case ComponentEvent.COMPONENT_MOVED: display.evnt[Display.COMPONENT] = "Component moved"; break; case ComponentEvent.COMPONENT_RESIZED: display.evnt[Display.COMPONENT] = "Component resized"; break; case ComponentEvent.COMPONENT_HIDDEN: display.evnt[Display.COMPONENT] = "Component hidden"; break; case ComponentEvent.COMPONENT_SHOWN: display.evnt[Display.COMPONENT] = "Component shown"; break; default: } repaint(); // Must always remember to call the "super" // version of whatever you override: super.processComponentEvent(e); } public void processFocusEvent(FocusEvent e) { switch(e.getID()) { case FocusEvent.FOCUS_GAINED: display.evnt[Display.FOCUS] = "FOCUS gained"; break; case FocusEvent.FOCUS_LOST: display.evnt[Display.FOCUS] = "FOCUS lost"; break; default: } repaint(); super.processFocusEvent(e); } public void processKeyEvent(KeyEvent e) { switch(e.getID()) { case KeyEvent.KEY_PRESSED: display.evnt[Display.KEY] = "KEY pressed: "; break; case KeyEvent.KEY_RELEASED: display.evnt[Display.KEY] = "KEY released: "; break; case KeyEvent.KEY_TYPED: display.evnt[Display.KEY] = "KEY typed: "; break; default: } int code = e.getKeyCode(); display.evnt[Display.KEY] += KeyEvent.getKeyText(code); repaint(); super.processKeyEvent(e); } public void processMouseEvent(MouseEvent e) { switch(e.getID()) { case MouseEvent.MOUSE_CLICKED: requestFocus(); // Get FOCUS on click display.evnt[Display.MOUSE] = "MOUSE clicked"; break; case MouseEvent.MOUSE_PRESSED: display.evnt[Display.MOUSE] = "MOUSE pressed"; break; case MouseEvent.MOUSE_RELEASED: display.evnt[Display.MOUSE] = "MOUSE released"; break; case MouseEvent.MOUSE_ENTERED: display.evnt[Display.MOUSE] = "MOUSE entered"; break; case MouseEvent.MOUSE_EXITED: display.evnt[Display.MOUSE] = "MOUSE exited"; break; default: } display.evnt[Display.MOUSE] += ", x = " + e.getX() + ", y = " + e.getY(); repaint(); super.processMouseEvent(e); } public void processMouseMotionEvent(MouseEvent e) { switch(e.getID()) { case MouseEvent.MOUSE_DRAGGED: display.evnt[Display.MOUSE_MOVE] = "MOUSE dragged"; break; case MouseEvent.MOUSE_MOVED: display.evnt[Display.MOUSE_MOVE] = "MOUSE moved"; break; default: } display.evnt[Display.MOUSE_MOVE] += ", x = " + e.getX() + ", y = " + e.getY(); repaint(); super.processMouseMotionEvent(e); } } class MyButton extends Button { int clickCounter; String label = ""; public MyButton() { enableEvents(AWTEvent.ACTION_EVENT_MASK); } public void paint(Graphics g) { g.setColor(Color.green); Dimension s = getSize(); g.fillRect(0, 0, s.width, s.height); g.setColor(Color.black); g.drawRect(0, 0, s.width - 1, s.height - 1); drawLabel(g); } private void drawLabel(Graphics g) { FontMetrics fm = g.getFontMetrics(); int width = fm.stringWidth(label); int height = fm.getHeight(); int ascent = fm.getAscent(); int leading = fm.getLeading(); int horizMargin = (getSize().width - width)/2; int verMargin = (getSize().height - height)/2; g.setColor(Color.red); g.drawString(label, horizMargin, verMargin + ascent + leading); } public void processActionEvent(ActionEvent e) { clickCounter++; label = "click #" + clickCounter + " " + e.toString(); repaint(); super.processActionEvent(e); } } public class BadTechnique extends Frame { BadTechnique() { setLayout(new GridLayout(2,2)); add(new EnabledPanel(1, Color.cyan)); add(new EnabledPanel(2, Color.lightGray)); add(new EnabledPanel(3, Color.yellow)); // You can also do it for Windows: enableEvents(AWTEvent.WINDOW_EVENT_MASK); } public void processWindowEvent(WindowEvent e) { System.out.println(e); if(e.getID() == WindowEvent.WINDOW_CLOSING) { System.out.println("Window Closing"); System.exit(0); } } public static void main(String[] args) { Frame f = new BadTechnique(); f.setTitle("Bad Technique"); f.setSize(700,700); f.setVisible(true); } } ///:~
的确,它可以工作.但却实在太蹩脚,并且很难编写、阅读、调试、保护以及再生.既然如此,为什么还不利用内部接纳器类呢?
以上是“保举编码办法(java)[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |
评论内容只代表网友观点,与本站立场无关!
评论摘要(共 0 条,得分 0 分,平均 0 分)
查看完整评论