- /**
- * <p>Copyright: Copyright (c) 2002-2004</p>
- * <p>Company: JavaResearch(http://www.javaresearch.org)</p>
- * <p>最后更新日期:2003年4月30日
- * @author cherami
- */
- package org.jr.swing;
-
- import javax.swing.*;
- import java.awt.*;
- import java.awt.event.*;
- import java.util.ArrayList;
- import org.jr.util.*;
- /**
- * 多行走马灯。
- * 垂直方向滚动显示多行文本。
- * 每行文本的颜色、显示对齐方式以及字体都可以不同。
- * @since 0.6
- */
-
- public class MultiLineHorseLight
- extends JLabel {
- ArrayList texts=new ArrayList(); //文本行数组
- int interval; //刷新间隔
- int startLine=0; //开始显示的行
- int endLine; //最后显示的行
- int showLines=1; //一屏显示的行数
- int lineIndex=1;//开始行的位置
- Timer timer;
- private static final int INTERVAL=1000;
- /**
- * 构造一个空的MultiLineHorseLight。
- */
- public MultiLineHorseLight() {
- interval = INTERVAL;
- init();
- }
- /**
- * 以指定的文本数组构造一个MultiLineHorseLight。
- * @param texts 文本
- */
- public MultiLineHorseLight(String texts[]) {
- this(texts, INTERVAL);
- }
- /**
- * 以指定的文本数组构造一个MultiLineHorseLight。
- * @param texts 具有属性的文本
- */
- public MultiLineHorseLight(TextLine texts[]) {
- this(texts, INTERVAL);
- }
- /**
- * 以指定的文本数组以及时间间隔构造一个MultiLineHorseLight。
- * @param texts 文本
- * @param interval 时间间隔
- */
- public MultiLineHorseLight(String texts[], int interval) {
- for (int i=0;i<texts.length ;i++ ) {
- TextLine text=new TextLine(texts[i]);
- this.texts.add(text);
- }
- if (interval > 0) {
- this.interval = interval;
- }
- else {
- interval = INTERVAL;
- }
- init();
- }
- /**
- * 以指定的文本数组以及时间间隔构造一个MultiLineHorseLight。
- * @param texts 具有属性的文本
- * @param interval 时间间隔
- */
- public MultiLineHorseLight(TextLine texts[], int interval) {
- ListUtil.addArrayToList(texts,this.texts);
- if (interval > 0) {
- this.interval = interval;
- }
- else {
- interval = INTERVAL;
- }
- init();
- }
- /**
- * 初始化。生成定时器以及监听组件大小改变事件。
- */
- private void init() {
- timer = new Timer(interval, new ActionListener() {
- public void actionPerformed(ActionEvent e) {
- repaint();
- }
- });
- timer.start();
- addComponentListener(new ComponentAdapter() {
- public void componentResized(ComponentEvent e) {
- startLine=0;
- lineIndex=1;
- showLines=1;
- }
- });
- }
-
-
- /**
- * 在走马灯后面附加一个新行。
- * @param text 文本
- */
- public void appendText(String text) {
- texts.add(new TextLine(text));
- }
- /**
- * 在走马灯后面附加一个新行。
- * @param text 具有属性的文本
- */
- public void appendText(TextLine text) {
- texts.add(text);
- }
-
- /**
- * 添加一个空行。
- */
- public void addSpaceLine() {
- appendText(" ");
- }
-
- /**
- * 设置刷新间隔。
- * @param interval 刷新间隔
- */
-
- public void setInterval(int interval) {
- if (interval > 0) {
- this.interval = interval;
- timer.setDelay(interval);
- }
- }
-
-
-
- /**
- * 得到组件的最佳大小。
- * 最佳宽度为文本中的最大字符串长度加10,最佳高度为文字高度的三倍。
- * @return 组件的最佳大小
- */
- public Dimension getPreferredSize() {
- Graphics g = getGraphics();
- FontMetrics fontMetrics = g.getFontMetrics();
- int height = fontMetrics.getHeight();
- int maxTextWidth=0;
- for (int i=0;i<texts.size() ;i++ ) {
- int width=fontMetrics.stringWidth(((TextLine)texts.get(i)).text);
- if (width>maxTextWidth) {
- maxTextWidth=width;
- }
- }
- return new Dimension(maxTextWidth+10,height*3);
-
- }
-
- /**
- * 重新绘制组件。
- * @param g 图形设备
- */
- protected void paintComponent(Graphics g) {
- FontMetrics fontMetrics = g.getFontMetrics();
- int fontheight = fontMetrics.getHeight();
- int height = getSize().height;
- int lines = height / fontheight;
- int positionY;
- if (lines>=texts.size()) {
- endLine = startLine + showLines;
- positionY = height - lineIndex * fontheight+10;
- for (int i=startLine;i<endLine ;i++ ) {
- TextLine line=(TextLine)texts.get(i);
- drawLine(line,positionY,g,fontMetrics);
- positionY+=fontheight;
- }
- if (lineIndex<lines) {
- showLines++;
- }
- if (showLines>texts.size()) {
- showLines=texts.size();
- }
- lineIndex++;
- if (lineIndex>lines) {
- lineIndex=lines;
- startLine++;
- showLines--;
- if (startLine==texts.size()) {
- startLine=0;
- lineIndex=1;
- showLines=1;
- }
- }
- }
- else {
- endLine = startLine + showLines;
- positionY = height - lineIndex * fontheight+10;
- for (int i=startLine;i<endLine ;i++ ) {
- TextLine line=(TextLine)texts.get(i);
- drawLine(line,positionY,g,fontMetrics);
- positionY+=fontheight;
- }
- showLines++;
- lineIndex++;
- if (lineIndex>lines) {
- lineIndex=lines;
- startLine++;
- showLines--;
- if (startLine+showLines>texts.size()) {
- showLines--;
- }
- if (startLine==texts.size()) {
- startLine=0;
- lineIndex=1;
- showLines=1;
- }
- }
- }
- }
- /**
- * 绘制一行文本。
- * @param text 具有属性的文本。
- * @param positionY 绘制的垂直坐标
- * @param g 图形设备
- * @param fontMetrics 字体信息
- */
- private void drawLine(TextLine text,int positionY,Graphics g,FontMetrics fontMetrics) {
- int width = getSize().width;
- int positionX;
- g.setColor(text.color);
- g.setFont(text.font);
- switch (text.align) {
- case TextLine.LEFT:
- positionX=0;
- break;
- case TextLine.CENTER:
- positionX = (width - fontMetrics.stringWidth(text.text)) / 2;
- break;
- case TextLine.RIGHT:
- positionX = (width - fontMetrics.stringWidth(text.text));
- break;
- default:
- positionX=0;
- break;
- }
- g.drawString(text.text, positionX, positionY);
- }
-
- /**
- * 重新开始运动显示。
- */
- public void start() {
- startLine=0;
- lineIndex=1;
- showLines=1;
- timer.start();
- }
-
- /**
- * 停止运动。
- */
- public void stop() {
- timer.stop();
- }
- }