Обновите метку Java-апплета с помощью потоков

У меня есть следующий класс апплета:

public class Marquee extends Applet {
    Label label1 = new Label("Testing");

    public void pushUpdate( String text ) {
        System.out.println( "receiving: " + text );
        label1.setText( text );
        repaint();
    }

    public void init() {
        ScrollText_2 scrollObj = new ScrollText_2( "Applet test" );
        scrollObj.setApplet(this);
        add( label1 );
        scrollObj.run();
    }
}

Класс ScrollText2 реализует Runnable и имеет метод scroll(). Прямо сейчас все, что делает метод прокрутки, это возвращает строку, содержащуюся в объекте. Метод run() этого класса выглядит так:

while(true) {
    try {
        marquee.pushUpdate( scroll() );
        Thread.sleep( 2000 );
    }
    catch (InterruptedException e) {}
}

Проблема в том, что когда я запускаю апплет, если я вызываю метод .run(), то метка в бегущей строке никогда не отображается. Я пробовал repaint(), просто label.setText(), updateUI() и redraw(), чтобы попытаться заставить апплет отображать обновления, но это не сработало.

Любые предложения будут ценны.

Спасибо!


person Mike Caputo    schedule 11.12.2011    source источник
comment
делает получение:... распечатать в консоли? Если это не так, проблема может заключаться в том, что вы переводите Thread в спящий режим, прежде чем он сможет обновить пользовательский интерфейс. В таком случае попробуйте удалить Thread.sleep(2000).   -  person Jon Egeland    schedule 11.12.2011
comment
Да, принимающая println распечатывает, просто пользовательский интерфейс не обновляется.   -  person Mike Caputo    schedule 11.12.2011
comment
Вы пытались удалить Thread.sleep в любом случае?   -  person Jon Egeland    schedule 11.12.2011
comment
1) Чтобы быстрее получить помощь, опубликуйте SSCCE. 2) Как упоминалось в вопросе HFOE, используйте Swing в этом тысячелетии, а не AWT. 3) Есть простые способы добиться этого с помощью Swing Timer, который вызывает repaint().   -  person Andrew Thompson    schedule 12.12.2011


Ответы (3)


Вы не вызываете run() из Thread или Runnable. Вы вызываете start() в потоке или в потоке, содержащем Runnable. Кроме того, вам нужно будет позаботиться об обновлении компонентов графического интерфейса в потоке графического интерфейса. Для Swing это означает использование SwingUtilities.invokeLater(someRunnable), и я подозреваю, что это можно сделать аналогичным образом с AWT.

Кстати, а почему AWT, а не Swing?

person Hovercraft Full Of Eels    schedule 11.12.2011
comment
+1 за рассмотрение invokeLater. Многопоточность может быть совершенно коварной. - person Allen Z.; 12.12.2011

Вы не создаете новый Thread для запуска scrollObj. Когда вы вызываете scrollObj.run() в Marquee.init(), scrollObj перехватывает поток вашего апплета. Это означает, что ваш основной цикл обновления Marquee, который включает paint(), никогда не будет достигнут. Вызов repaint() также не гарантирует, что будет вызван paint(). Таким образом, ваш Marquee никогда не красится.

Ваш код отлично работает, когда вы заменяете scrollObj.run(); на

new Thread(scrollObj).start();
person Allen Z.    schedule 11.12.2011
comment
Прочитав ответ Hovercraft, я понял, что вместо этого было бы правильнее вызывать EventQueue.invokeLater(scrollObj) - это настраивает графический интерфейс вашего апплета до запуска scrollObj. - person Allen Z.; 12.12.2011
comment
Нет, ты прав. Он должен вызвать start() в потоке, который содержит вышеприведенный Runnable, но затем внутри приведенного выше кода исходный автор должен поместить вызов marquee.pushUpdate( scroll() ); в Runnable, а затем поставить Runnable в очередь в потоке событий, используя invokeLater(...). Проголосовали и спасибо. - person Hovercraft Full Of Eels; 12.12.2011

пример выделения в апплете для потока, например перемещения чего-либо

import java.applet.*;
import java.awt.*;
/**<applet code="Marquee" height=768 width=1024></applet>*/
public class Marquee extends Applet implements Runnable {
  Color clr[] = { Color.red, Color.green, Color.cyan, Color.blue, Color.orange };
  int xx = 0;
  int x = 100;
  int a = 200;
  Thread t = new Thread(this);

  public void start() {
    t.start();
  }

  public void paint(Graphics g) {
    g.setFont(new Font("Times New Roman", Font.BOLD, 28));
    xx++;
    if (xx == 3) {
      xx = 0;
    }
    g.setColor(clr[xx]);
    g.fillOval(200, 200, x, a);
    g.drawString("Vinay", x, 200);
    g.drawString("Mayur", a, 300);
    x += 1;
    a -= 1;
  }

  public void run() {
    try {
      System.out.println("sdd");
      for (int i = 0; i < 200; i++) {
        Thread.sleep(10);
        repaint();
      }
    } catch (Exception e) {
      System.out.println("Error:-->" + e);
    }
  }
}
person Mayur Chudasama    schedule 09.02.2014