Peinture en swing
-
13-11-2019 - |
Question
J'ai une classe (chronologie) qui étend JPanel. Le panneau de chronologie contient de nombreux JLabels (éléments verts et orange) qui sont positionnés manuellement ("Null-Layout"). En haut de la chronologie se trouvent quelques boutons pour basculer entre des mois. Parfois, lorsque je bascule entre les mois, le swing ne peint pas les jlabels mais peint toujours le fond de la grille.
J'ai déjà essayé de nombreuses méthodes "magiques" (repeindre, revalider, invalider, valider, updateui).
Time peint avec succès:
Peinture ratée:
Un court exemple:
public interface IDateSelectorRegistrar {
void addListener(DateSelectorListener listener);
void removeListener(DateSelectorListener listener);
}
public interface DateSelectorListener {
void dateChanged(Timestamp from, Timestamp to);
}
public interface ITimelineModel {
Timespan[] getTimespans(Timestamp from, Timestamp to);
}
public class Timespan {
private String title;
private Timestamp to;
private Timestamp from;
public Timespan(String title, Timestamp from, Timestamp to) {
this.title = title;
this.from = from;
this.to = to;
}
// setters and getters
}
public class TimelineLabel extends JLabel {
public TimelineLabel(Timespan timespan) {
super(timespan.getTitle());
}
@Override
protected void paintComponent(Graphics g) {
// paint colored background
super.paintComponent(g);
}
}
public class Timeline extends JPanel {
public Timeline(final ITimelineModel model, IDateSelectorRegistrar registrar) {
registrar.addListener(new DateSelectorListener() {
public void dateChanged(Timestamp from, Timestamp to) {
Timeline.this.removeAll();
Timespan[] timespans = model.getTimespans(from, to);
for(Timespan timespan : timespans) {
TimelineLabel label = new TimelineLabel(timespan);
Timeline.this.add(label);
// label positioning because of Timestamp object data
}
// repaint of timeline
Timeline.this.invalidate();
Timeline.this.repaint();
}
});
}
@Override
protected void paintComponent(Graphics g) {
// paint background grid
super.paintComponent(g);
}
}
La solution 2
L'appel des méthodes suivantes dans l'ordre suivant a résolu le problème:
invalidate();
repaint();
validate();
Autres conseils
En tant qu'alternative, considérez org.jfree.chart.renderer.category.GanttRenderer
, ce qui est idéal pour les graphiques de domaine temporel et admet une variété de personnalisation. Un exemple, illustré ci-dessous, peut être trouvé ici.