Hey,
Ich habe eine Klasse geschrieben welche einen Lauftext in Java realisiert, sie erweitert JComponent und das zeichnen wird in der paintComponent Methode realisiert. Ich benutze einen SwingTimer für das Aufrufen von repaint() in einem vorgegebenen Intervall um so die Geschwindigkeit des Textes zu beinflussen. Das Programm um das es geht ist schon recht groß und es kommt zu folgendem Problem:
Wenn ich z.B. nun dass "Einstellungs-Fenster" meines Programms öffne, stockt der Text für einen winzigen Moment, es ist nicht sonderlich viel, aber sichtbar. Das Ganze tritt mehr oder weniger stark bei noch anderen "größeren" Aktionen auf. Ich habe schon versucht durch Optimierungen, wie alle größeren Aufgaben in SwingWorker Klassen auszulagern, oder überall dort wo es möglich ist durch die Beachtung vom Clip des GraphicsContext, die Probleme in den Griff zu bekommen. Es ist dadurch auch bedeutend besser geworden, aber leider gibt es bei bestimmten Aktionen immer noch leichte, aber leider sichtbare Ruckler.
Da Swing mit dem EDT ja ein Single-Threaded-Model umsetzt, hab ich leider nun keine Idee mehr was ich da noch machen kann.
Ich hoffe jemand von euch hat hier ein paar Tips oder Tricks wie ich das ganze besser in den Griff bekomme.
Hier mal der Code der entsprechenden Komponente.
Vielen Dank schonmal.
Grüße,
sMau
Ich habe eine Klasse geschrieben welche einen Lauftext in Java realisiert, sie erweitert JComponent und das zeichnen wird in der paintComponent Methode realisiert. Ich benutze einen SwingTimer für das Aufrufen von repaint() in einem vorgegebenen Intervall um so die Geschwindigkeit des Textes zu beinflussen. Das Programm um das es geht ist schon recht groß und es kommt zu folgendem Problem:
Wenn ich z.B. nun dass "Einstellungs-Fenster" meines Programms öffne, stockt der Text für einen winzigen Moment, es ist nicht sonderlich viel, aber sichtbar. Das Ganze tritt mehr oder weniger stark bei noch anderen "größeren" Aktionen auf. Ich habe schon versucht durch Optimierungen, wie alle größeren Aufgaben in SwingWorker Klassen auszulagern, oder überall dort wo es möglich ist durch die Beachtung vom Clip des GraphicsContext, die Probleme in den Griff zu bekommen. Es ist dadurch auch bedeutend besser geworden, aber leider gibt es bei bestimmten Aktionen immer noch leichte, aber leider sichtbare Ruckler.
Da Swing mit dem EDT ja ein Single-Threaded-Model umsetzt, hab ich leider nun keine Idee mehr was ich da noch machen kann.
Ich hoffe jemand von euch hat hier ein paar Tips oder Tricks wie ich das ganze besser in den Griff bekomme.
Hier mal der Code der entsprechenden Komponente.
Java:
public class TickerComponent extends JComponent {
private String tickerString;
private int posOfString1;
private int posOfString2;
private int toDrawStringWidth;
private int tickerSpeed;
private String toDraw1;
private String toDraw2;
private Timer liveTickerTimer;
public TickerComponent() {
super();
posOfString1 = getWidth();
posOfString2 = getWidth();
try {
tickerSpeed = Integer.parseInt(PreferencesHandler.getInstance().getProperties().getProperty(Constants.PROP_TICKER_SPEED));
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
startLiveTicker();
}
/**
* creates a new Swing Timer with the given update interval and starts the timer.
* The timer refreshes the ticker component every x milliseconds.
*/
public void startLiveTicker() {
liveTickerTimer = new Timer(tickerSpeed, new ActionListener() {
public void actionPerformed(ActionEvent e) {
repaint(0, 0, getWidth(), getHeight());
}
});
liveTickerTimer.start();
}
/**
* stops the timer
*/
public void stopLiveTicker() {
liveTickerTimer.stop();
}
/**
* Set the ticker string to draw on the component.
* A GUI update is invoked automatically after setting the new string.
* @param tickerString
*/
public void setTickerString(String tickerString) {
this.tickerString = tickerString;
if(tickerString != null && !tickerString.equals("")) {
generateDrawingStrings();
} else if(tickerString != null) {
toDraw1 = " ";
toDraw2 = " ";
stopLiveTicker();
} else {
stopLiveTicker();
}
}
/**
* needs to be invoked after resizing the tickerComponent, e.g. after entering the fullscreen
*/
public void refreshStringGeneration() {
generateDrawingStrings();
}
/**
* generates the two strings needed for a gapless ticker run.
*/
private void generateDrawingStrings() {
int tickerStringWidth = getFontMetrics(getFont()).stringWidth(tickerString);
toDraw1 = tickerString;
toDrawStringWidth = tickerStringWidth;
while(toDrawStringWidth < getWidth()) {
toDrawStringWidth = toDrawStringWidth + tickerStringWidth;
toDraw1 = toDraw1 + tickerString;
}
toDraw2 = toDraw1;
posOfString2 = posOfString1 + toDrawStringWidth;
}
@Override
protected void paintComponent(Graphics g) {
if (toDraw1 != null && toDraw2 != null && !toDraw1.equals("") && !toDraw2.equals("")) {
posOfString1--;
posOfString2--;
//if last char of the string is not visible anymore
if(posOfString1 + toDrawStringWidth < 0 ) {
posOfString1 = posOfString2 + toDrawStringWidth;
}
//if last char of the string is not visible anymore
if(posOfString2 + toDrawStringWidth < 0 ) {
posOfString2 = posOfString1 + toDrawStringWidth;
}
Graphics2D tmpG2D = (Graphics2D) g.create();
tmpG2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
tmpG2D.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
tmpG2D.drawString(toDraw1, posOfString1, 55);
tmpG2D.drawString(toDraw2, posOfString2, 55);
tmpG2D.dispose();
} else {
stopLiveTicker();
}
}
}
Vielen Dank schonmal.
Grüße,
sMau
Zuletzt bearbeitet: