代码中吸取营养:GoodTechnique
2026/7/20 19:07:20 网站建设 项目流程

package com.Murphy;
/*
这个程序的作用是捕获各个区域的鼠标坐标
/
// 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; //事件的本质,其实就是一个String,这里定义的是事件组,下标对应消息类型存放一组消息。
Display() {
evnt = new String[LAST];
for(int i = 0; i < LAST; i++)
evnt[i] = new String();
}
//这里是精髓,用一个方法,输出7行信息,对应每一种事件。
public void show(Graphics g) {
for(int i = 0; i < LAST; i++)
g.drawString(evnt[i], 0, 10 * i + 10); //直接用画布输出字串
}
}
//定义一个可以接收鼠标位置信息的panel类
class EnabledPanel extends Panel {
Color c;
int id;
Display display = new Display(); //这里利用Display类,在画布中显示事件信息。

public EnabledPanel(int i, Color mc) { //用panel的ID和底色来初始化
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:
@Override
public void update(Graphics g) { //更新画布
paint(g);
}

@Override
public void paint(Graphics g) { //画布作图:颜色,宽高,填充区域,带事件字符串显示区域
g.setColor©;
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:
@Override
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(); } } //得到键盘消息,键盘的消息值e ,其实就是每个按键的ASCII码值的字符表示 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); } //鼠标消息用画布字串输入,记录当前的鼠标坐标,鼠标消息对应的就是坐标可以用e.getX()和e.getY()得到 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; //水平缩进: 按钮宽度减去字符串宽度除以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() {
//用表格模式增加3个记录事件带button的Panel,这样右下角会空出一个区域。
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);
}
}
学会用Graphics类的对象方法drawString输出文本参数列表:(strText, horizMargin, verMargin+ascent+leading)
其中:horizMargin和verMargin可以通过FontMetrics的高度,宽度算出。 而ascent和leading来自FontMetrics的
方法graphics.getFontMetrics.getAscent 或者getLeading.

在键盘按键事件中,可以得到按键ASCII码值: KeyEvent e; code = e.getKeyCode();
而ASCII码值,可以用KeyEvent类方法转为文本显示: KeyEvent.getKeyText(code); 注意,这里控制字符也能显示出来。

在鼠标按键的事件中,可以得到鼠标的当前坐标: MouseEvent e ; e.getX()和e.getY();这个坐标返回的是当前监听者的
相对坐标。 可能需要requestFocus();这个属于Component对象方法,监听者都自带。

画布要想生效的话,记得在其所在组件中,使用update(Graphics g)重写内容添加paint(g);
画刷方法paint(Graphics g)也需要重写,里面需要包含诸如drawString方法才能让新画布内容生效。还需要重写过程事件processEvent(AWTEvent e) 里面增加repaint(); super.processEvent(e);

虚拟键小程序

package UsePaint;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class VirtualKeyTest {
public static void main(String[] args) {
new KeyFrame();
}
}
class KeyFrame extends Frame{
public KeyFrame(){
setBounds(200,200,800,600);
setVisible(true);
this.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
//super.keyPressed(e);
int keycode = e.getKeyCode();
if (keycode==KeyEvent.VK_UP){ //直接VK_UP–>Goto就可以看到所有键值
System.out.println(“你按了上键”);
}else{//这里显示的是10进制值,除了Tab键其他所有键都有键值
//这种虚拟键并不支持组合键或切换键,如NumLock
System.out.println(keycode);
}
}
});
}
}
10. 用反射机制追溯控件源头
我们可以用getSuperclass来追踪每一个组件的父类源头,下面是Frame 的类源头。
class java.awt.Frame
class java.awt.Window
class java.awt.Container
class java.awt.Component
class java.lang.Object
null //Object 的父类是NULL,如果用变量引用了Null,再继续getSupercass则会: NullPointerException.
Button<–Component<–Object<–null
Canvas<–Component<–Object<–null
Checkbox<–Component<–Object<–null
CheckboxMenuItem<–MenuItem<–MenuComponent<–Object<–null
Choice<–Component<–Object<–null
Dialog<–Window<–Container<–Component<–Object<–null
FileDialog<-Dialog<–Window<–Container<–Component<–Object<–null
Label<–Component<–Object<–null
List<–Component<–Object<–null
Menu<–MenuItem<–MenuComponent<–Object<–null
MenuItem<–MenuComponent<–Object<–null
Panel<–Container<–Component<–Object<–null
PopupMenu<–Menu<–MenuItem<–MenuComponent<–Object<–null
Scrollbar<–Component<–Object<–null
ScrollPane<–Container<–Component<–Object<–null
TextArea<–TextComponent<–Component<–Object<–null
TextField<–TextComponent<–Component<–Object<–null
String<–Object<–null
Integer<–Number<–Object<–null
所有的基础数据类型类,都没有父类。而对应的方法类,如:Integer, Double,Float.都来自Number类。
Boolean,String方法类除外,它们是直接来自Object.所有数组的类,也是来自Object.
byte , short, int , long, float, double, char, boolean <–null

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询