显示文本的文本横幅小程序反转 [英] Text Banner applet reverses that displayes text

查看:21
本文介绍了显示文本的文本横幅小程序反转的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理水平显示移动横幅的小程序,当此文本横幅到达小程序窗口的右边界它应该从左边界的开始出现反转,我编写了以下类来完成这项工作,问题是当文本横幅到达右横幅时它崩溃了,小程序转到无限循环:

i'm working on applet that displays a moving banner horizontally and when this text banner reaches the right boundary of the applet window it should be appear reversed from the start of the left boundary, i write the following class to do the work, the problem is that when the text banner reaches the right banner it crashes, the applet goes to infinite loop:

    import java.applet.*;
    import java.awt.*;
    import java.net.*;
    import java.io.*;
    import javax.swing.*;

    /*
    <applet code="banner" width=300 height=50>
    </applet>
    */
    public class TextBanner extends Applet implements Runnable 
    {
        String msg = "Islam Hamdy", temp="";
        Thread t = null;
        int state;
        boolean stopFlag;
        int x;
        String[] revMsg;
        int msgWidth;
        boolean isReached;

         public void init() 
        {

            setBackground(Color.BLACK);
            setForeground(Color.YELLOW);
        }

        // Start thread

        public void start() 
        {

            t = new Thread(this);
            stopFlag = false;
            t.start();
        }

        // Entry point for the thread that runs the banner.

        public void run() 
        {

            // Display banner
            while(true) 
            {
                try 
                {
                    repaint();
                    Thread.sleep(550);
                    if(stopFlag)
                        break;
                } catch(InterruptedException e) {}
            }
        }

        // Pause the banner.

        public void stop() 
        {
            stopFlag = true;
            t = null;
        }

        // Display the banner.

        public void paint(Graphics g) 
        {
        String temp2="";
        System.out.println("Temp-->"+temp);
        int result=x+msgWidth; 
        FontMetrics fm = g.getFontMetrics();
        msgWidth=fm.stringWidth(msg);
        g.setFont(new Font("ALGERIAN", Font.PLAIN, 30));        
        g.drawString(msg, x, 40);
        x+=10;
        if(x>bounds().width){
        x=0;
    }
        if(result+130>bounds().width){
         x=0;
        while((x<=bounds().width)){
        for(int i=msg.length()-1;i>0;i--){
        temp2=Character.toString(msg.charAt(i));
        temp=temp2+temp;
                    // it crashes here
        System.out.println("Before draw");
            g.drawString(temp, x, 40);
        System.out.println("After draw");
        repaint();
               }
            x++;
            }       // end while
         }          //end if

      }

     }

推荐答案

让我们从...开始

  • 使用 Swing over AWT 组件(JApplet 而不是 Applet)
  • 不要覆盖顶级容器的 paint 方法.原因有很多,影响您的主要因素是顶级容器不是双缓冲的.
  • 永远不要从事件分派线程以外的任何线程更新 UI,事实上,对于您要执行的操作,线程 简直是完蛋了.
  • 不要使用 paint 方法更新动画状态.您已经尝试在 paint 方法中执行所有动画,这不是 paint 的工作方式.将 paint 视为电影中的一个帧,由线程决定(在您的情况下)确定哪个帧到达哪里,实际上,它应该准备应该绘制的内容.
  • 您无法控制油漆系统.repaint 是对绘制子系统执行更新的请求".重绘管理器将决定实际重绘何时发生.这使得执行更新有点棘手......
  • Use Swing over AWT components (JApplet instead of Applet)
  • Don't override the paint methods of top level containers. There are lots of reasons, the major one that is going to effect you is top level containers are not double buffered.
  • DO NOT, EVER, update the UI from any thread other the Event Dispatching Thread, in fact, for what you are trying to do, a Thread is simply over kill.
  • DO NOT update animation states with the paint method. You've tried to perform ALL you animation within the paint method, this is not how paint works. Think of paint as a frame in film, it is up to (in your case) the thread to determine what frame where up to, and in fact, it should be preparing what should painted.
  • You do not control the paint system. repaint is a "request" to the paint sub system to perform an update. The repaint manager will decide when the actual repaint will occur. This makes performing updates a little tricky...

更新示例

public class Reverse extends JApplet {

    // Set colors and initialize thread.
    public void init() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }
                setBackground(Color.BLACK);
                setForeground(Color.YELLOW);
                setLayout(new BorderLayout());
                add(new TextPane());
            }
        });
    }

    // Start thread
    public void start() {
    }

    // Pause the banner.
    public void stop() {
    }

    public class TextPane extends JPanel {

        int state;
        boolean stopFlag;
        char ch;
        int xPos;
        String masterMsg = "Islam Hamdy", temp = "";
        String msg = masterMsg;
        String revMsg;
        int msgWidth;

        private int direction = 10;

        public TextPane() {
            setOpaque(false);
            setBackground(Color.BLACK);
            setForeground(Color.YELLOW);

            setFont(new Font("ALGERIAN", Font.PLAIN, 30));

            // This only needs to be done one...
            StringBuilder sb = new StringBuilder(masterMsg.length());
            for (int index = 0; index < masterMsg.length(); index++) {
                sb.append(masterMsg.charAt((masterMsg.length() - index) - 1));
            }
            revMsg = sb.toString();

            // Main animation engine.  This is responsible for making
            // the decisions on where the animation is up to and how
            // to react to the edge cases...
            Timer timer = new Timer(100, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    xPos += direction;
                    FontMetrics fm = getFontMetrics(getFont());
                    if (xPos > getWidth()) { // this condition fires when the text banner reaches the right banner
                        direction *= -1;
                        msg = revMsg;
                    } else if (xPos < -fm.stringWidth(masterMsg)) {
                        direction *= -1;
                        msg = masterMsg;
                    }
                    repaint();
                }
            });
            timer.setRepeats(true);
            timer.setCoalesce(true);
            timer.start();

        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            System.out.println(xPos);
            FontMetrics fm = g.getFontMetrics();
            msgWidth = fm.stringWidth(msg);
            g.drawString(msg, xPos, 40);
        }
    }
}

更新了其他示例

现在,如果你想变得更聪明一点......你可以利用负缩放过程,它会为你反转图形......

Now, if you want to be a little extra clever...you could take advantage of a negative scaling process, which will reverse the graphics for you...

更新计时器...

            Timer timer = new Timer(100, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    xPos += direction;
                    FontMetrics fm = getFontMetrics(getFont());
                    System.out.println(xPos + "; " + scale);
                    if (scale > 0 && xPos > getWidth()) { // this condition fires when the text banner reaches the right banner
                        xPos = -(getWidth() + fm.stringWidth(msg));
                        scale = -1;
                    } else if (scale < 0 && xPos >= 0) {
                        xPos = -fm.stringWidth(msg);
                        scale = 1;
                    }
                    repaint();
                }
            });

和更新的绘制方法...

And the updated paint method...

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.scale(scale, 1);
            FontMetrics fm = g2d.getFontMetrics();
            msgWidth = fm.stringWidth(msg);
            g2d.drawString(msg, xPos, 40);
            g2d.dispose();
        }

更新为弹跳"...

这将替换上一个示例中的 TextPane

This replaces the TextPane from the previous example

当文本超出右边界时,它会反转"方向并移回左侧,直到超出该边界,它会再次反转"...

As the text moves beyond the right boundary, it will "reverse" direction and move back to the left, until it passes beyond that boundary, where it will "reverse" again...

public class TextPane    public class TextPane extends JPanel {

    int state;
    boolean stopFlag;
    char ch;
    int xPos;
    String msg = "Islam Hamdy";
    int msgWidth;

    private int direction = 10;

    public TextPane() {
        setBackground(Color.BLACK);
        setForeground(Color.YELLOW);

        setFont(new Font("ALGERIAN", Font.PLAIN, 30));

        Timer timer = new Timer(100, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                xPos += direction;
                FontMetrics fm = getFontMetrics(getFont());
                if (xPos > getWidth()) {
                    direction *= -1;
                } else if (xPos < -fm.stringWidth(msg)) {
                    direction *= -1;
                }
                repaint();
            }
        });
        timer.setRepeats(true);
        timer.setCoalesce(true);
        timer.start();

    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g.create();
        FontMetrics fm = g2d.getFontMetrics();
        msgWidth = fm.stringWidth(msg);
        g2d.drawString(msg, xPos, 40);
        g2d.dispose();
    }
}

这篇关于显示文本的文本横幅小程序反转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆