Berechnung der Ecken von einem RoundRect

javaprogger1987

Erfahrenes Mitglied
Hallo!

Ich habe folgendes Problem, ich bin dabei mir eine eigene ProgressBar zu basteln, das meiste funktioniert auch schon, nur bei den Details hapert es etwas..
So wie auf dem ersten angehängten Bild sieht die ProgressBar bis jetzt aus, erstmal eigentlich ganz ok..
Das Problem ist nun wenn man genauer hinguckt bzw. eine andere Hintergrundfarbe nimmt (Bild2). Der Border ist ein eigener (einfach 2 RoundRects - eins für Schatten eins für den Border).
Mein erstes Problem ist nun, das der Schatten zwar ungefähr richtig ist, aber nicht so wie er eigentlich sein sollte (Liegt vermutlich daran das ich es mir mit dem Zeichnen ein wenig einfach gemacht habe ;)) - gibt es eine andere Möglichkeit so einen Schatten zu zeichnen?
Java:
    g.drawRoundRect( x, y, width-1, height-1, arc, arc );
    g.setColor( Color.BLACK );
    g.drawRoundRect( x, y, width-2, height-2, arc-1, arc-1 );


Das andere Problem erkennt man auch auf Bild 2 - die weißen überstehenden Teile der ProgressBar Füllung. Da ich einen Verlauf verwende wüsste ich nicht wie ich fillRoundRect verwenden könnte um das zu verhindern, denn mein Zeichnungsschleife sieht so aus:
Java:
      for ( int i = 0; i < amountFull; i++ )
      {
        g2.setColor( getFadeFromWhite( base, progressBar.getWidth(), i ) );
        g2.fillRect( i, 0, 1, progressBar.getHeight() - 1 );
      }

Kann ich irgendwie aus dem Durchmesser der Ecken (arc) berechnen wie breit und hoch die Ecken letztendlich sind?

Danke schonmal :)

Gruß
 

Anhänge

  • 24542attachment.jpg
    24542attachment.jpg
    2 KB · Aufrufe: 24
  • 24543attachment.jpg
    24543attachment.jpg
    1,4 KB · Aufrufe: 138
Falls noch mal jemand das gleiche Problem haben sollte (unwahrscheinlich aber was solls :)) :
Das mit den Schatten hab ich so gelassen, sieht ok aus.
Das andere hab ich folgendermaßen gelöst:
1. Ein leeres BufferedImage erstellen
2. mit fillRoundRect ein schwarzes (0,0,0) rundes Rechteck zeichnen, das die Größe des Randes hat
3. jeden Pixel einzeln durchgehen und gucken ob er gemalt werden muss (wenn aktuelle Farbe schwarz ist)

Das muss nur einmal gemacht werden, danach reicht es immer einen Ausschnitt des BufferedImage zu zeichnen..
Code:
Java:
      Color base = new Color( 250, 125, 0 );
      g2.setColor( base );

      if ( fill == null )
      {
        fill = new BufferedImage( barRectWidth,
                                  barRectHeight,
                                  BufferedImage.TYPE_INT_ARGB );
        Graphics2D gFill = fill.createGraphics();
        gFill.setColor( progressBar.getBackground() );
        gFill.fillRect( 0, 0, barRectWidth, barRectHeight );
        gFill.setColor( new Color( 0, 0, 0 ) );
        gFill.fillRoundRect( 0, 0, barRectWidth, barRectHeight, arc-1, arc-1 );
    
        for ( int x = 0; x < fill.getWidth(); x++ )
        {
          gFill.setColor( getFadeFromWhite( base, progressBar.getWidth()-1, x ) );
    
          for ( int y = 0; y < fill.getHeight(); y++ )
          {
            if( fill.getData().getPixel( x, y, (int[])null )[0] == 0 &&
                fill.getData().getPixel( x, y, (int[])null )[1] == 0 &&
                fill.getData().getPixel( x, y, (int[])null )[2] == 0 )
              gFill.fillRect( x, y, 1, 1 );
          }
        }
      }
      g2.drawImage( fill, 0, 0, amountFull, barRectHeight, 0, 0, amountFull, barRectHeight, null );

Gruß
 
Hallo!

Weshalb hast du denn da nicht einfach ein RoundRectangle als Clipping Area auf dem Graphics Kontext gesetzt?

Gruß Tom
 
Ähh.. ein was auf den was gesetzt?
Ich weiß nicht was das ist - das wird der Hauptgrund gewesen sein *GGG*
Ist das sowas wie ne Maske?

Gruß
 
Hallo!

Java:
/**
 * 
 */
package de.tutorials;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.geom.RoundRectangle2D;

import javax.swing.JFrame;

/**
 * @author Tom
 *
 */
public class RoundRectangleClipAreaExample extends JFrame{

    public RoundRectangleClipAreaExample(){
        super("RoundRectangleClipAreaExample");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        
        setSize(400,300);
        setVisible(true);
    }
    
    /**
     * @param args
     */
    public static void main(String[] args) {
        new RoundRectangleClipAreaExample();
    }
    
    public void paint(Graphics g) {
        g.setColor(Color.RED);
//        Mach mal die Kommentare weg ;-)
//        RoundRectangle2D roundRectangle2D = new RoundRectangle2D.Double(50,50,300,200,20,20);
//        g.setClip(roundRectangle2D);
        g.fillRect(0,0,400,300);
    }
}

Gruß Tom
 
Ok, das ist ja mal echt praktisch ;)
Ist vermutlich auch wesentlich performanter :)
Vielen vielen Dank Tom :D

Gruß

P.S. Wieso zur Hölle kopiert der die Zeilennummern mit wenn ich den Quellcode markiere und kopiere xD? Sehr unpraktisch ;)
 
Hallo Javaprogger,

javaprogger1987 hat gesagt.:
P.S. Wieso zur Hölle kopiert der die Zeilennummern mit wenn ich den Quellcode markiere und kopiere xD? Sehr unpraktisch ;)

Wenn du auf zitieren klickst, wirst du denn Quellcode auch ohne Zeilennummern wiederfinden.

Vg Erdal
 
Öhm.. Also bei Toms Beitrag auf zitieren? Da sind die Zeilennummern beim kopieren des Quellcodes aber immer noch vorhanden :confused:

Gruß
 
Hallo Javaprogger,

wenn du auf zitieren klickst, ist der Quellcode in deinem Antwortfeld ohne Nummern vorhanden. Den sollst du kopieren, und nicht die aus der Vorschau.


Vg Erdal
 
Zurück