Laufschrift-Hänger mit Java 8

wolf-itc

Mitglied
Hallo Java-Profis,
habe kleines Problem: Ich habe eine ziemlich einfache Laufschrift mit einem JLabel realisiert, welche langsam von rechts nach links unten über den Bildschirm läuft. Mittels Timer-Event setze ich dazu alle 20ms ein setBounds(...) mit x=x-1
Bis Java 7 hatte ich keine Probleme, jetzt habe ich einen neuen Rechner mit Java 8 aufgesetzt -> auf einmal ruckelt die Laufschrift total. Es wir nur alle 10 oder 20 Aufrufe mal ein Update angezeigt. Ist aber unregelmäßig.
Ich habe jetzt - als Workaround - das JLabel aus dem GridBag rausgenommen und auf die LayeredPane gelegt. Lustig hier: Solange ich mit der Maus über der Java-Anwendung schwebe, läuft es akkurat, sobald ich die Maus weg-bewege, ruckelt es wieder.
Ich habe als Gegentest mal Java 7 installiert -> einwandfrei, keine Ruckler.
Was wurde von Java 7 auf 8 geändert, das diese Auswirkungen haben kann?

Hier noch ein Code-Schnipsel:

Java:
  gTimrMarqee= new Timer();
  gTTskMarqee= new TimerTask()
  {
    public void run() 
    {
      Dimension d= gView.gLablMessage.getPreferredSize();
      gView.gLablMessage.setBounds( new Rectangle( gXPos, 3, d.width, d.height ));
      gView.revalidate(); // neu eingefügt, damit ist es besser, solange ich mit der Maus im Fenster bin
      gXPos-= 1;
      if ( gXPos <= gXEnd )
      {
        gXPos= getBounds().width;
      }
    }
  };
  gTimrMarqee.schedule( gTTskMarqee, 0, 20 );

Cheers
Martin
 
Zuletzt bearbeitet von einem Moderator:
Hallo Thallius,
vielen Dank für Deine schnelle Antwort 🙂
Hmm, dachte mir, dass das sauberer wäre als selbst was zu zeichnen. Ist aber ein ein guter Tipp, werde ich mal versuchen. Danke!
 
Hallo Thallius,
ich habe das jetzt entsprechend umgebaut ... aber leider: Gleiches Verhalten. Solange ich mit der Maus über der Applikation bin, ist ok. Geh ich rau, hakelt es.
Noch eine Idee?
Cheers
Martin

Der Code:
-> Der View:
...
Java:
  public class CScrollLabel extends JPanel
  {
    public String gText= "-NO TEXT GIVEN-";
    public int  gXPos= 0;
    public int  gYPos= 0;
 
    public void setXPos( int pX )
    {
      gXPos= pX;
    }
 
    public void setYPos( int pY )
    {
      gYPos= pY;
    }
 
    @Override public void paintComponent( Graphics g )
    {
      super.paintComponent( g );
      g.setColor( Color.WHITE );
      g.drawString( gText, gXPos, gYPos );
    }
  } // CScrollLabel

-> Der Controller:
Java:
public class CAnnouncement extends JDialog implements Runnable
{
  ...
  @Override
  public void run()
  {
    try
    {
      while ( true )
      {
        Thread.sleep( 25 );
        gYPos-= 3;
        if ( gYPos > 0 )
        {
          gView.gLablNextSingerList.setYPos( gYPos );
        }
        if ( gYPos <= 30 )
        {
          gYPos= gView.gLablNextSingerList.getBounds().height;
        }
      } 
    }
  } // run

  public void paintNextSingerList()
  {
    gView.repaint();
  } // paintNextSingerList

In der Hauptklasse:
Java:
public class CKaraMain extends JFrame ...
{
  gTimrUpdate= new javax.swing.Timer( 10, this );
  gTimrUpdate.start();
  ...
  public void actionPerformed( ActionEvent e )
  {
    ...
    if ( e.getSource() == gTimrUpdate )
    {
      gDlogAnnouncement.paintNextSingerList();
    }
 
Zuletzt bearbeitet von einem Moderator:
Sorry, sorry! War mir auch unangenehm, das so einzufügen. Wusste aber nicht, wie es besser geht -> Hab's rausgefunden ;-):
-> Der View:
Java:
...
public class CScrollLabel extends JPanel
{
  public String gText= "-NO TEXT GIVEN-";
  public int gXPos= 0;
  public int gYPos= 0;

  public void setXPos( int pX )
  {
    gXPos= pX;
  }

  public void setYPos( int pY )
  {
    gYPos= pY;
  }

  @Override public void paintComponent( Graphics g )
  {
    super.paintComponent( g );
    g.setColor( Color.WHITE );
    g.drawString( gText, gXPos, gYPos );
  }
} // CScrollLabel

-> Der Controller:
Java:
public class CAnnouncement extends JDialog implements Runnable
{
  ...
  @Override public void run()
  {
    try
    {
      while ( true )
      {
        Thread.sleep( 25 );
        gYPos-= 3;
        if ( gYPos > 0 )
        {
          gView.gLablNextSingerList.setYPos( gYPos );
        }
        if ( gYPos <= 30 )
        {
          gYPos= gView.gLablNextSingerList.getBounds().height;
        }
      }
    }
  } // run

  public void paintNextSingerList()
  {
    gView.repaint();
  } // paintNextSingerList

In der Hauptklasse:
Java:
public class CKaraMain extends JFrame ...
{
  gTimrUpdate= new javax.swing.Timer( 10, this );
  gTimrUpdate.start();
  ...
  public void actionPerformed( ActionEvent e )
  {
    ...
    if ( e.getSource() == gTimrUpdate )
    {
       gDlogAnnouncement.paintNextSingerList();
    }
 
Zuletzt bearbeitet von einem Moderator:
Hallo Thallius,
fällt Dir dazu noch was ein? Ich habe die Hänger nicht wegbekommen. Würde jetzt halt wieder Java 7 installieren, dann ist gut.
LG
Martin
 
Habe den Thread jetzt nur überflogen was mir zu dem Thema noch einfallen würde wäre folgendes:

1) Wenn du mit der "draw" fertig bist, dann versuch mal
Java:
  /*
    * Synchronizes this toolkit's graphics state. Some window systems may do buffering of graphics events
    * This method ensures that the display is up-to-date. It is useful for animation
    */
 frame.getDefaultToolKit().sync();
aufzurufen.

Sollte das dein Problem nicht lösen, gibt es noch ein nettes Workaround, was bei einigen dieses Problem schon behoben haben soll:
Du könntest über einen Robot Inputs generieren lassen, was ja quasi den selben Effekt hat, wie als wenn du über dein Marquee hoverst / eine Taste drückst. Das sollte dann das ruckeln beseitigen.
(PS: Nur in JavaFX getestet - bei Swing bin ich mir unsicher!)

Als Ansatz vllt so in der Art:

Java:
finalRobot robot =newRobot();
Timer timer =new (initialDelay,newActionListener()
{
    publicvoid actionPerformed(ActionEvent e)
    {
        // update Text

        robot.keyPress(62);
     }
});

Gruß
Robert
 
Mensch, Robert,
Du bist ja genial ... works like a charm!
Unglaublich. Wie kommt man auf so eine Lösung?
Vielen Dank!
Aber auch noch mal an Dich, Thallius, dass Du Dich mit meinem Problem beschäftigt hast.
LG
Martin
 
Mit welcher Lsg. hast du es denn nun letztendlich gemeistert?
Poste sie bitte mal, damit andere mit dem gleichen Problem gleich einen Ansatz haben 🙂

Wie kommt man auf so eine Lösung?

Naja habe mir dein Problem mal angeschaut und hab überlegt wie man das umgehen könnte, irgendwann kam mir dann die Idee dass man einfach Events generieren könnte um das zu umgehen. Irgendwann kam mir dann die Robot-Klasse in den Sinn.^^ hat sicherlich auch was mit Erfahrung zu tun 😛
 

Zurück
Oben