1

So my problem is this: I have a class extending JProgressBar and basically it looks like a flashing circle(it also breaks into segments depending on the amount of tasks, assigned to that indicator and I need to use setUI each time I switch indicator to the next task, which is pretty bad, but it'll do for now). I need to position 37 of those circles on a JPanel so that they form a circle of their own. Right now I do it like this:

private void addToPane(JPanel pane){
        pane.setLayout(null);
        Insets insets = pane.getInsets();
        int width = pane.getWidth();
        int height = pane.getHeight();
        Dimension size = new Dimension(30, 30);
        //Dimension mid = new Dimension(width/2, height/2);
        Dimension mid = new Dimension(200, 250);
        int r = 210;
        double revox, revoy, angle = -Math.PI/2;
        double revangle = 2*Math.PI/37;
        for(int i=1; i<38; i++){
            FlashingIndicator templabel = new FlashingIndicator();
            templabel.setPreferredSize(size);
            templabel.setUI(new ProgressIndicator(flash, 0, false));
            templabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
            indicate.add(templabel);
            revox = r*Math.cos(angle);
            revoy = r*Math.sin(angle);
            indicate.get(i - 1).setBounds(insets.left + mid.width + (int) revox, insets.top + mid.height + (int) revoy, size.width, size.height);
            pane.add(indicate.get(i - 1));
            angle-=revangle;
        }
    }

No need to say: this is pretty bad. I wanted to locate them depending on the size of the panel, but when the function is being called in createUIComponents() (I use IntelliJ Idea's GUI builder) - the panel is not properly created yet, so getWidth() just returns 0. Using random numbers like 200 and 250 is bad for the obvious reasons. Also seems like the general consensus is: Null Layout is bad and I shouldn't use it. So here's the question:

Which LayoutManager should I use in order to locate indicators properly? All I can think of is GridLayout, but the way I do it now indicators nicely overlap a bit, using a grid will make it look rough. And if I can't use managers for this - how can I make it dependnant on the size of the panel?

Right now it looks like this:

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
graynk
  • 131
  • 1
  • 2
  • 17
  • Consider using custom painting for the entire component. – Andrew Thompson Feb 22 '15 at 12:51
  • I don't think null layout in this situation IS bad. I think it usually is bad, because it is usually being used by someone who is (1) not taking the trouble to learn layout managers and what they're for, (2) doesn't realize the amount of work it's going to take to do all the things layout managers do for you without them. But you aren't doing a normal UI layout here. As for making things dependent on the panel size, I vaguely remember that you can render your frame to memory, and then use its size. – arcy Feb 22 '15 at 12:55
  • @arcy *"But you aren't doing a normal UI layout here."* Failing 'custom painting' I would recommend a **custom layout.** After all, if there is any logic at all to the layout (and there clearly is to this one), it is better to encapsulate it in a layout manager. *Null layout is never a good idea, **ever.*** – Andrew Thompson Feb 22 '15 at 12:58

1 Answers1

4

Override the paintDeterminate() method in a custom BasicProgressBarUI to render your indicator; a related example is seen here. You can scale the rendering, as shown here, in a way that fills the component; this will obviate the need for a custom layout manager internal to your component. Override getPreferredSize(), as discussed here, so that your custom progress indicator works correctly with enclosing layouts.

image

image

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • See also this related [Q&A](http://stackoverflow.com/q/16182705/230513) suggesting a [tag:jfreechart] `DialPlot`. – trashgod Feb 22 '15 at 13:37
  • thanks @mKorbel, wound up using that with combination of the anwser(the part about getPrefferedSize()) Still looking at paintDeterminate() and get a feeling that I'll need to write custom L&F for animation eventually, not a current workaround. – graynk Feb 23 '15 at 09:36
  • @graynk: It's a trade-off. I think you can leverage some existing L&F defaults in a custom `ProgressBarUI`, as shown [here](http://stackoverflow.com/a/7137801/230513) for `JTable`. If you go with the custom layout manager, you'll have to re-invent some progress plumbing. – trashgod Feb 23 '15 at 16:50