0

I have a class (Timeline) which extends JPanel. The Timeline Panel contains many JLabels (green and orange elements) which are positioned manually ("null-Layout"). On top of the Timeline are some buttons for switching between months. Sometimes when i switch between months swing won't paint the JLabels but always paints the grid background.

I've already tried many of the "magic" methods(repaint, revalidate, invalidate, validate, updateUI).

Successfully painted Timeline:

Timeline succesful

Failed painting:

Timeline failed

A short example:

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);
   }
}
Jonas
  • 121,568
  • 97
  • 310
  • 388
endian
  • 4,761
  • 7
  • 32
  • 54
  • When the painting fails, have you checked whether your relevant paint/paintComponent method is called ? – ARRG Jan 24 '12 at 14:39
  • @endian I never saw that, did you place those JLabels to the JPanel by implements Insets ???, – mKorbel Jan 24 '12 at 14:44
  • The paintComponent method of the JLabels aren't called. – endian Jan 24 '12 at 14:44
  • @mKorbel no, i use no layout manager and position the labels manually – endian Jan 24 '12 at 14:45
  • @endian > Then you'll have to show us how you build your components and how you dispatch your paint/repaint calls. – ARRG Jan 24 '12 at 14:46
  • 1) no layout manager is AbsoluteLayout or NullLayout, 2) Container returns Insets 3) for switching betweens view is there CardLayout or you place JLabels manually for every view (on Runtime) – mKorbel Jan 24 '12 at 14:51
  • 2
    For better help sooner, post an [SSCCE](http://sscce.org/). For the sake of sanity, wrap the positioning logic in a (custom) `TimeLineLayout`. – Andrew Thompson Jan 24 '12 at 14:52
  • @ARRG The only moment when i repaint manually is if a button click (when selecting another month) triggers – endian Jan 24 '12 at 14:57
  • astonished that you _do_ see the labels occasionally ;-) In the snippet, you don't size nor locate them when adding. Which is your responsibility if you insist on not using a LayoutManager. Which is **WRONG** in Swing. – kleopatra Jan 25 '12 at 10:58
  • i added a comment where positioning of labels happens – endian Jan 25 '12 at 11:35

2 Answers2

2

As an alternative, consider org.jfree.chart.renderer.category.GanttRenderer, which is ideal for time domain charts and admits a variety of customization. An example, illustrated below, may be found here.

Gantt Subtasks

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
0

Calling following methods in the following order fixed the problem:

invalidate();
repaint();
validate();
endian
  • 4,761
  • 7
  • 32
  • 54