目标:1、随鼠标点击改变LED灯颜色,2、在改变颜色的同时闪烁,3、并有提示声音。
代码运行后会实现1、随鼠标点击改变LED灯颜色,3、有提示声音,但是2却不能。
高手们帮忙分析下
public class SwitchAn extends Component implements MouseListener,
MouseMotionListener, Runnable, Serializable { /**
 *LED颜色
 */
public static Color LED_UP_COLOR = Color.green; public static Color LED_NEUTRAL_COLOR = new Color(20, 20, 20); public static Color LED_DOWN_COLOR = Color.red; protected Color m_color; /**
 * LED闪烁间隔
 *
 */
private int m_blinkInterval; public int getBlinkInterval() {
return m_blinkInterval;
} public void setBlinkInterval(int blinkInterval) {
m_blinkInterval = blinkInterval;
// notifyAll();
} /**
 * LED位置,一个很重要的函数
 *
 */
public final static int UP = 0; public final static int NEUTRAL = 1; public final static int DOWN = 2; private int m_position; public int getPosition() {
return m_position;
} public void setPosition(int newPosition) {
synchronized (this) {
m_position = newPosition;
switch (newPosition) {
case UP:
m_color = LED_UP_COLOR;
notifyAll();
break;
case NEUTRAL:
m_color = LED_NEUTRAL_COLOR;
notifyAll();
break;
case DOWN:
m_color = LED_DOWN_COLOR;
new Thread(this).start();
break;
}
}
repaintLED();
processEvent(new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
getActionCommand()));
}
/**
 * 提示状态文本
 * 
 */
private String m_label; public String getLabel() {
return m_label;
} public void setLabel(String newLabel) {
m_label = newLabel;
invalidate(); } public void mousePressed(MouseEvent evt) {
if (isEnabled()) {
int newPos = getPosition();
switch (newPos) {
case UP:
newPos = NEUTRAL;
break;
case NEUTRAL:
newPos = DOWN;
break;
case DOWN:
newPos = UP;
break;
}
setPosition(newPos); }
} /**
 * 鼠标离开,移动
 */
public void mouseExited(MouseEvent evt) {
if (getCursor() != null
&& getCursor().getType() != Cursor.DEFAULT_CURSOR) {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
} public void mouseMoved(MouseEvent evt) {
if (isEnabled() && getCursor() != null
&& getCursor().getType() != Cursor.HAND_CURSOR) {
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
} public void mouseClicked(MouseEvent evt) { } public void mouseReleased(MouseEvent evt) { } public void mouseEntered(MouseEvent evt) { } public void mouseDragged(MouseEvent evt) { } /**
 * 设置操作命令
 */
private String m_actionCommand; public String getActionCommand() {
return (m_actionCommand == null ? getLabel() : m_actionCommand);
} public void setActionCommand(String command) {
m_actionCommand = command;
} /**
 * 注册操作监听器
 */
private transient ActionListener m_actionListener; public synchronized void addActionListener(ActionListener l) {
m_actionListener = AWTEventMulticaster.add(m_actionListener, l);
} public synchronized void removeActionListener(ActionListener l) {
m_actionListener = AWTEventMulticaster.remove(m_actionListener, l);
} /* 
 * 调度操作事件
 */
protected void processEvent(AWTEvent e) {
if (e instanceof ActionEvent) {
processActionEvent((ActionEvent) e);
return;
}
super.processEvent(e);
} protected void processActionEvent(ActionEvent e) {
if (m_actionListener != null) {
m_actionListener.actionPerformed(e);
}
}
/*
 * 得到最佳容器大小
 */
protected final static int SHIM = 10;
private static final int LED_DIAMETER = 20;
private static final int BLINK_INTERVAL = 1000;
public Dimension getPreferredSize() {
Dimension prefSize = new Dimension();
prefSize.width = getLEDDiameter() + (3 * SHIM);
prefSize.height = getLEDDiameter();
prefSize.height += (2 * SHIM);
if (getLabel() != null) {
FontMetrics fm1 = getFontMetrics(getFont());
prefSize.width += fm1.stringWidth(getLabel()) + SHIM;
prefSize.height = Math.max(prefSize.height, (2 * SHIM)
+ fm1.getHeight());
} return prefSize; } public static int LED_DIAMENTER = 20; protected int m_ledDiam; public int getLEDDiameter() {
return m_ledDiam;
} public void setLEDDiameter(int ledDiam) {
m_ledDiam = ledDiam;
invalidate();//当修改属性时,强迫父容器重新布局
}
/**
 * 构造函数
 * 
 */
public SwitchAn(String label, int ledDiam, int blinkInterval) {
setLabel(label);
setLEDDiameter(ledDiam);
setBlinkInterval(blinkInterval);
setPosition(UP);
addMouseListener(this);
addMouseMotionListener(this); } public SwitchAn() {
this("one", LED_DIAMETER, BLINK_INTERVAL);
} /**
 * @绘图属性
 */
protected int getLEDX() {
return SHIM;
} protected int getLEDY() {
return (((getSize()).height - getLEDDiameter()) / 2);
} /* 
 * 
 * 绘图以及更新
 */
public void paint(Graphics g) {
super.paint(g);
drawLED(getLEDX(), getLEDY(), getLEDDiameter(), g, m_color);
if (getLabel() != null) {
if (isEnabled()) {
g.setColor(getForeground());
} else {
g.setColor(SystemColor.textInactiveText);
}
FontMetrics fm = g.getFontMetrics();
g.drawString(getLabel(), (getSize().height - fm.getHeight()) / 2
+ fm.getAscent(), m_blinkInterval);
}
} public void update(Graphics g) {
paint(g);
} protected void drawLED(int x, int y, int diam, Graphics g, Color c) {
int diameter = diam;
int LEDx = x;
int LEDy = y; g.setColor(Color.BLUE);
g.drawArc(LEDx, LEDy, diameter, diameter, 45, 180);
g.drawArc(LEDx, LEDy, diameter, diameter, 225, 180);
g.setColor(c);
g.fillOval(LEDx + 1, LEDy + 1, diameter - 2, diameter - 2);

g.drawArc(LEDx + (diameter / 10), LEDy + (diameter / 10),
(4 * diameter) / 5, (4 * diameter) / 5, 80, 110); g.setColor(Color.white);
g.drawArc(LEDx + (diameter / 4) + 1, LEDy + (diameter / 4) + 1,
diameter / 4, diameter / 4, 80, 110); g.drawArc(LEDx + (diameter / 4) + 2, LEDy + (diameter / 4) + 2,
(diameter) / 5, (diameter) / 5, 80, 110); g.setColor(Color.BLUE);
g.drawArc(LEDx + (diameter / 10), LEDy + (diameter / 10),
(4 * diameter) / 5, (4 * diameter) / 5, 260, 110);
} protected void repaintLED() {
repaint(getLEDX(), getLEDY(), getLEDDiameter() + SHIM, getLEDDiameter());
} /**
 *
 * 当position改变时,the audio clip  play
 */
private AudioClip m_audioClip;
public void setAudioClip(AudioClip audioClip) {
m_audioClip = audioClip;
}
public AudioClip getAudioClip() {
return m_audioClip;
} /**
 * LED闪烁线程
 */
public synchronized void run() {
try {
// 等待间隔时间,看是否需要重画颜色
wait(getBlinkInterval());
// 只有DOWN时线程运行
while (getPosition() == Switch.DOWN) {
if (m_color.equals(LED_DOWN_COLOR)) {
m_color = LED_NEUTRAL_COLOR;
} else if (m_color.equals(LED_NEUTRAL_COLOR)) {
m_color = LED_DOWN_COLOR;
}
int l_ledDiam = getLEDDiameter();
repaint(getLEDX(), getLEDY(), l_ledDiam, l_ledDiam);
wait(getBlinkInterval());
}
} catch (InterruptedException e) {
}
}
       
}还有里面的那个label,显示不出来,我也不明白它是怎么实现的?不是应该是Label类的吗?
怎么就用set函数呢?
这是一个例子,我调不出来,所以来这里寻求帮助。

解决方案 »

  1.   

    这么多代码,看着都头晕估计需要重绘,调用下repaint和updateui方法吧
      

  2.   

    看着确实头晕,拷贝了运行一下就好看多了。
    对了,我把运行的代码贴上来,直接运行就清楚很多不用头晕了。
    public class TestSwitchAn  extends Applet {

    FlowLayout flowLayout = new FlowLayout();
    SwitchAn switch1=new SwitchAn();
    SwitchAn switch2=new SwitchAn();
    SwitchAn switch3=new SwitchAn();public void init(){
    try {
    cwInit();
    } catch (Exception e) {
    // TODO 自动生成 catch 块
    e.printStackTrace();
    }

    }public  void cwInit() throws Exception {
    AudioClip audio=getAudioClip(getDocumentBase(),"mianban/alert5.wav");
    switch1.setAudioClip(audio);
    switch2.setAudioClip(audio);
    switch3.setAudioClip(audio);
    switch1.setLabel("one");
    switch1.label.setText(switch1.getLabel());

    switch2.setLabel("Disabled");
    switch2.setPosition(SwitchAn.NEUTRAL);

    switch3.setLabel("three");
    switch3.setPosition(SwitchAn.DOWN);

    setLayout(flowLayout);
    setBackground(Color.lightGray);
    add(switch1.label);
    add(switch1,null);
    add(switch2,null);
    add(switch3,null);
    switch2.setEnabled(false);
    setVisible(true);
    }
    }
      

  3.   

    要用到线程来处理闪烁状态.SwingUtilities.invokeLater(new Runnable(){ public void run() {
       ... //这里写闪烁的代码
    }
           
          });
      

  4.   

    楼上说的地方是对,是因为这个线程运行不到。
    但是按你的方法改了不行。
    case DOWN:
    m_color = LED_DOWN_COLOR;
    new Thread(this).start();   //这个this到底指的是哪里啊?反正感觉指不到
    break;                                             //闪烁线程其实一直对this的指代很迷惑,以前也看过这种贴,但是都没人说明白。
      

  5.   

    本来想帮楼主看一下,运行代码才发现代码根本就不对:
    比如:在SwithAnn中
    while (getPosition() == Switch.DOWN) {
    if (m_color.equals(LED_DOWN_COLOR)) {
    m_color = LED_NEUTRAL_COLOR;
    } else if (m_color.equals(LED_NEUTRAL_COLOR)) {
    m_color = LED_DOWN_COLOR;

    Switch.DOWN中的Switch是在哪里定义的?在TestSwitchAn中
    switch1.label.setText(switch1.getLabel()); 
    ...
    add(switch1.label); 
    中的label又是哪里来的?
    拜托,不要调戏大家的时间。
      

  6.   

    是这样的:label是在发了贴之后加的,
    “还有里面的那个label,显示不出来,我也不明白它是怎么实现的?不是应该是Label类的吗?
    怎么就用set函数呢?” 
    为了让label显示出来,在SwitchAn里加了public JLabel label=new JLabel();.
    Switch是手误,应该是SwitchAn的。
    绝不是来调戏你的时间的,别误会。
      

  7.   

    switch1.setLabel("one");
    switch1.label.setText(switch1.getLabel()); 从这行代码来看,SwitchAn中还应该有一个public Label。
      

  8.   

    不用啊
    SwitchAn里面定义了set方法了:
    public void setLabel(String newLabel) {
    m_label = newLabel;
    invalidate(); 
      

  9.   

    setLabel()操作的是String对象
    在Applet中引用的是一个Label对象
      

  10.   

    setLabel("one")以后,m_label=one;然后getLabel()返回one,
    将"one"设置给JLabel的对象label.
    这没问题啊!
    你都没看清楚。
      

  11.   

    switch1.setLabel("one");
    到这里为止没有问题switch1.label.setText(switch1.getLabel()); 
    请问switch1.label中的lable是在哪一行声明的????
      

  12.   


    要把wait(getBlinkInterval());改成Thread.sleep();
    可以达到预期目的。
    原因不清楚~~
    ??