Link to home
Start Free TrialLog in
Avatar of sanjay_thakur
sanjay_thakur

asked on

Panel getGraphics problem


Hi,

I have a tree with many nodes which represent
unused volume on the diskdrives

for example

root
--40 gb
--60 gb

I want a pie chart which will represent
the unused space on the disk


I do this
 Graphics g = panel.getGraphics();


right now I have put the code to draw piechart
in the valueChanged event of the tree because the pie chart will change as this event is fired

 public void valueChanged(TreeSelectionEvent e)
    {
      gui_drawPieChart();
    }

The pie chart is displayed correctly
but if I do anything like resizing/minimizing
the panel becomes empty I mean I cannot see the
chart if I resize the panel

I am sure this is some sort of paint problem

Is there any way to draw  pie chart before the
panel is displayed and redraw as the value changed event is fired




Any help?
Avatar of Tom7
Tom7

You have to override the panel's paintComponent() method, then the chart will be there constantly! That means you must use a subclass (for example of JPanel). Something like:

class ChartPanel extends JPanel {
  float unusedDiskSpace;
  float totalDiskSpace;
  public void paintComponent(Graphics g) {
    if (totalDiskSpace == 0.0F) return;
    // do your drawing here:
  }
}


Tom
Avatar of sanjay_thakur

ASKER

Hi, I did that but the problem is it looks bit
distorted the pie chart.I mean it looks real rough at the edges.

Is ther any way I can make it look better
without distortions.
So how did you draw the chart? Maybe you could post some code.

Tom
Hi, here is the code




public void paintComponent(Graphics g){

    gui_customize();

    int  x=0;
    int  y=0;
    int width=0,height=0;
    int ax=0,ay=0;          //For Drawing Black line from center to Peripherial
    int px=0,py=0;          //For Writing Percentage
    int radius=0;
    //width=height=Math.min((this.getSize().width - 100),(this.getSize().height - 100));
    width=height=Math.min((this.getSize().width - 15),(this.getSize().height - 15));
    //width =height = 100;

    x=y=50;

    if ( this.getSize().width > width ){
        x = (this.getSize().width - width ) /2 ;
    }


     if ( this.getSize().height > height ){
        y = (this.getSize().height - height ) /2 ;
    }



    cx = x + width/2;
    cy = y + height/2;
    radius = width/2;

    // Draw the Title of the Chart on Top of the Applet

    strWidth=fontMetrics.stringWidth(title);
    Font fnt = new java.awt.Font("Sanserif", Font.BOLD, 12);
    g.setFont(fnt);
    g.setColor(Color.red);
    //g.drawString(title,((detP.getSize().width - strWidth )/2),15);
    //g.drawString(title,((this.getSize().width - strWidth )/2),15);

    g.setFont(font);
    int initAngle=90;
    int sweepAngle=0;
    int incSweepAngle=0;
    int incLabelAngle= (int) (angle[0]/2);

    for (int i=0; i < columns; i++) {
        sweepAngle = (int) Math.round(angle[i]);
        g.setColor((Color)colors[i]);

        if (i==(columns-1)){
            sweepAngle = 360 - incSweepAngle;
            g.fillArc(x,y,width,height,initAngle,(-sweepAngle));
            g.setColor(Color.black);
            g.drawArc(x,y,width,height,initAngle,(-sweepAngle));

            if (showLabel){
                lx = (int) (cx + ( radius * Math.cos((incLabelAngle * 3.14f/180) - 3.14f/2)));
                ly = (int) (cy + ( radius * Math.sin((incLabelAngle * 3.14f/180) - 3.14f/2)));
                adjustLabel(i);
                g.drawString((String)labels[i],lx,ly);
            }
            if (showPercent){
                px = (int) (cx + ((radius*2/3) * Math.cos((incLabelAngle * 3.14f/180) - 3.14f/2)));
                py = (int) (cy + ((radius*2/3) * Math.sin((incLabelAngle * 3.14f/180) - 3.14f/2)));
                g.drawString(String.valueOf(Math.round(percent[i]))+"%",px,py);
            }
            break;
        }

        g.fillArc(x,y,width,height,initAngle,(-sweepAngle));
        g.setColor(Color.black);
        g.drawArc(x,y,width,height,initAngle,(-sweepAngle));
        incSweepAngle +=sweepAngle;

        ax = (int) (cx + ( radius * Math.cos((incSweepAngle * 3.14f/180) - 3.14f/2)));
        ay = (int) (cy + ( radius * Math.sin((incSweepAngle * 3.14f/180) - 3.14f/2)));
        g.drawLine(cx,cy,ax,ay);

        if (showLabel){
            lx = (int) (cx + ( radius * Math.cos((incLabelAngle * 3.14f/180) - 3.14f/2)));
            ly = (int) (cy + ( radius * Math.sin((incLabelAngle * 3.14f/180) - 3.14f/2)));
            adjustLabel(i);
            g.drawString((String)labels[i],lx,ly);
        }
        if (showPercent){
            px = (int) (cx + ((radius*2/3) * Math.cos((incLabelAngle * 3.14f/180) - 3.14f/2)));
            py = (int) (cy + ((radius*2/3) * Math.sin((incLabelAngle * 3.14f/180) - 3.14f/2)));
            strWidth = fontMetrics.stringWidth(Math.round(percent[i])+"%");
            g.drawString(String.valueOf(Math.round(percent[i]))+"%",(px - strWidth/2),py);
        }

        incLabelAngle = incLabelAngle + (int) (angle[i]/2 + angle[i+1]/2);
        initAngle += (-sweepAngle);
    }
    g.setColor(Color.black);
    g.drawLine(cx,cy,cx,cy-radius);
  }
Hi

I get some junk values in the panel in which I have the
Pie chart.

If I minimize the screen and load it again
then it looks fine

I know its repaint() problem
If I try to put this code in PaintComponent()
method the mouse keeps flickering continuously

this.invalidate();
this.validate();
this.repaint();


where should I do to solve this repaint problem
 


Avatar of stimpyjcat
repaint() sets a flag to tell the gui to redraw itself at the next available opportunity.

invalidate() sets a flag to tell the gui to redo the component's layout.

validate() redoes the layout.

You shouldn't need to call either of invalidate or validate if your component neither has children nor changes its own size.  It's likely the call to validate() that is causing the flicker, unless you are calling repaint() from within the paintComponent method, in which case that'd probably cause flicker.

What values in the panel are "junk"?
Sounds like your doing painting outside of the paintComponent method.
You should limit your paint calls to within the paintComponent() method.
Actually

I have a JSplitpane witch two panel components,horizontal divider.
The top component of the splitpane has
Jtree and textfield

The bottom component has this pie chart panel

When the pie chart gets displayed it shows some components of the top panel.

I mean I can see the tree and the textfield of
the top component in the background of
the pie chart(no the entire tree just a part of it)

If I minimize the screen everything looks fine.

thanks.





Hi I get the same problem when I select any of the nodes
of the tree in the top panel.

The pie chart has to change according to the
selected node.

It changes fine but displays some part of the tree in the background.

If I minimize and get it back again then it looks fine

Sounds like your doing painting outside of the paintComponent method.
You should limit your paint calls to within the paintComponent() method.
HI

Please let me know any solution to this.
it's bit urgent for me

Thanks in advance
for objects

I have removed

this.invalidate();
this.validate();
this.repaint();

from the paintComponent method.

It is same problem.

Where should I call invalidate so that the panel will
paint itself before it is displayed on the screen?


I didn't say anything about invalidate.
It has nothing really to do with painting.
Hi

My problem is that as the node selected in the tree
changes I have to change the values
in the pie chart.

To do this

I set the values and then I call
piechart.invalidate()
piechart.validate()
piechart.repaint()

This redraws the pie chart with proper values
but shows the same junk in the background





Well, I don't see in your paint routine anywhere you clear or otherwise paint the background.

Try a rectangular fill of the background to a background color prior to drawing the rest of your chart.
Still doesn't explain why your calling invalidate() and validate(). Though I wouldn't think they'd create a problem.
The repeated calls to validate() might induce cursor flicker, since it potentially recalculates the layout and updates the cursor.
Hi filling the rectangle solves the problem
But is there any way to make this rectangle invisible

I am using windows look and feel hence
I either need to fill it with the default color
of the windows since that is the color for the
entire application or I have to make the
rectangle invisible.

Please let me know.

currently
this is what I am doing in paint component

 g.setColor(Color.lightGray);
    g.fillRect(0, 0 , this.getSize().width , this.getSize().height);

How do I get the system default color
or make the filled rectangle invisible




 

ASKER CERTIFIED SOLUTION
Avatar of stimpyjcat
stimpyjcat

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks a ton!