tutorials.de Buch-Aktion 05/2012
  • JRatingBar (Bewertungs-Panel) selbst Programmieren



    In Swing gibt es leider keine JRatingBar, damit meine ich eine Komponente mit der der Benutzer eine Art Bewertung abgeben kann. So etwas wie die 5 Sterne bei iTunes zum bewerten der Lieder.

    Darum will ich euch heute zeigen wie man sich das ganze selbst Programmieren kann.

    Die Anforderungen:
    • Geht der Benutzer mit der Maus hin und her, so verändert sich die Bewertung
    • Durch Maus-Klick verliert oder gewinnt die RatingBar den Fokus
    • Programmgesteuert kann der aktuelle Wert sowie die Farbe der Sterne abgefragt und geändert werden

    Die Umsetzung:
    • Wir verwenden keine Bilder sondern zeichnen einfache goldene Sterne einzeln auf JPanel mit der Methode fillPolygon() von Graphics
    • Sie werden wiederum auf einem JPanel mit Hilfe des GridBagLayouts angeordnet
    • Die Sterne bekommen Id's zugeordnet, die jeweils höchste ID eines goldenen Sterns ist die aktuelle Punktzahl
    • In der Methode setPoints() werden alle Sterne mit ID's <= der gewünschten Punktzahl golden gemacht

    Der Quellcode:

    Die Klasse Star:
    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    
    import java.awt.Graphics;
    import java.awt.Color;
    import java.awt.event.MouseListener;
    import java.awt.event.MouseEvent;
    import javax.swing.JPanel;
     
    public class Star extends JPanel implements MouseListener{
     
        private JRatingBar parent;
        private byte id;
        // Koordinaten der Eckpunkte der Sterne
        private int[]   x = {60, 72, 108, 79, 90, 60, 30, 41, 12, 48},
                        y = {10, 44, 45, 66, 100, 80, 100, 66, 45, 44};
        private int size = 120;
        private Color color;
     
        // Konstruktor und Start-Zeichnung
     
        public Star(JRatingBar me, int id){
            parent = me;
            this.id = (byte)id;
            // nachträgliche Anpassung der Koordinaten
            for(int i=0; i<x.length; ++i){
                // Verkleinerung
                x[i] -= 5;
                y[i] -= 5;
                // runden
                x[i] = (x[i]%6>=3 ? x[i]/6+1 : x[i]/6);
                y[i] = (y[i]%6>=3 ? y[i]/6+1 : y[i]/6);
            }
            addMouseListener(this);
            // Verkleinerung
            size =- 10;
            // runden
            size = (size%6>=3 ? size/6+1 : size/6);
            setSize(size, size);
        }
     
        @Override
        public void paint(Graphics g){
            g.setColor(Color.gray);
            g.fillPolygon(x, y, x.length);
        }
     
        // Getter-/ Setter-Methoden
     
        public void setColor(Color c){
            color = c;
        }
     
        public Color getColor(){
            return color;
        }
     
        public byte getID(){
            return id;
        }
        
        // Nicht enablete Stars sollen Grau werden, enablete dagegen Gold
        @Override
        public void setEnabled(boolean aFlag){
            Graphics graphics = getGraphics();
            if(aFlag){
                graphics.setColor(color);
                graphics.fillPolygon(x, y, x.length);
            }
            else{
                graphics.setColor(Color.gray);
                graphics.fillPolygon(x, y, x.length);
            }
        }
     
        // MouseListener-Schnittstelle
     
        @Override
        public void mouseEntered(MouseEvent e){
            parent.setPoints(id);
        }
        
        // Wenn die Maus die Stern-Fläche verlässt, wird er Grau
     
        @Override
        public void mouseExited(MouseEvent e){
            // parent.isActive() bedeutet, dass das Benutzer die RatingBar durch KLICK hinein aktiviert hat
            if(id == 1 && parent.isActive()){
                setEnabled(false);
            }
        }
     
        @Override
        public void mousePressed(MouseEvent e){
        }
     
        @Override
        public void mouseReleased(MouseEvent e){
        }
     
        @Override
        public void mouseClicked(MouseEvent e){
            // Ein Klick bedeutet, dass die RatingBar aktiviert wird, wenn sie zuvor nicht aktiv war und umgekehrt
            parent.toggleEnabled();
            parent.setPoints(id);
        }
     
    }

    Die Klasse JRatingBar:
    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    
    import javax.swing.JPanel;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
     
    public class JRatingBar extends JPanel{
     
        private Star[] star = new Star[5];
        private GridBagLayout gbl;
        private GridBagConstraints gbc;
        private Color color;
        private boolean active;
        private byte points;
     
        // Konstruktor und Start-Zeichnung
     
        public JRatingBar(){
            super();
            // Positionierung der Einzelnen Stern-Panels durch das GridBagLayout
            gbl = new GridBagLayout();
            setLayout(gbl);
            gbc = new GridBagConstraints();
            gbc.anchor = GridBagConstraints.CENTER;
            gbc.fill = GridBagConstraints.NONE;
            gbc.gridwidth = 1;
            gbc.gridheight = 1;
            gbc.weightx = 0.2;
            gbc.weighty = 1;
            gbc.gridy = 0;
            gbc.ipadx = 20;
            gbc.ipady = 20;
            color = new Color(205, 149, 12);
            for(int i=0; i<star.length; ++i){
                gbc.gridx = i;
                // Jeder Stern bekommt eine ID (Ist er der an weitesten rechts selektiert, ist seine ID gleichzeitig die aktuelle Punktzahl
                star[i] = new Star(this, i+1);
                star[i].setColor(color);
                gbl.setConstraints(star[i], gbc);
                add(star[i]);
            }
            // Die RatingBar muss zu Anfang erst mal durch Mausklick fokussiert werden
            active = false;
        }
     
        @Override
        public void repaint(){
            // Die Sterne werden z.B. nach Maximieren des Fenstern wieder wie vorher angezeigt
            setPoints(points);
            super.repaint();
        }
     
        // Getter-/ Setter-Methoden
     
        // die Farbe jedes einzelnen Sterns wird verändert
        public void setColor(Color c){
            color = c;
            for(int i=0; i<star.length; ++i){
                star[i].setColor(color);
            }
        }
     
        public Color getColor(){
            return color;
        }
     
        // Gesamtgröße der JRatingBar
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(70, 20);
        }
     
        // Aufruf bei MouseEvents
     
        public void setPoints(byte p){
            if(active){
                points = p;
                // Von links aus werden so viele Sterne Gold wie Punkte angezeigt werden sollen
                for(int i=0; i<star.length; ++i){
                    if(star[i].getID() > p){
                        star[i].setEnabled(false);
                    }
                    else{
                        star[i].setEnabled(true);
                    }
                }
            }
        }
     
        public byte getPoints(){
            return points;
        }
     
        public boolean isActive(){
            return active;
        }
     
        // Umschalten (Klick von User auf beliebigen Stern => Fokussierung der RatingBar oder Verlust des Fokusses)
        protected void toggleEnabled(){
            active = (!active ? true : false);
        }
     
    }

    Testen:

    Nun willst du die JRatingBar bestimmt gleich ausprobieren, dazu hier eine Main-Class, die sich von JFrame ableitet.

    Die Klasse Main:
    Code java:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    import javax.swing.JFrame;
     
    public class Main extends JFrame{
     
        public Main(){
            super("JRatingBar Test");
            JRatingBar rb = new JRatingBar();
            add(rb);
        }
     
        public static void main(String[] args) {
            Main m = new Main();
            m.pack();
            m.setResizable(false);
            m.setLocation(50, 50);
            m.setVisible(true);
        }
     
    }

    Wer mag kann sich jetzt noch das fertige JAR und/oder den Source-Folder aus dem Anhang herunterladen.
    Viel Spaß beim ausprobieren und weiterentwickeln wünscht,
    javaDeveloper2011
    Bratkartoffel, HonniCilest, zer0 und 1 weitere bedanken sich. 
    Angehängte Grafiken Angehängte Grafiken  
    Angehängte Dateien Angehängte Dateien


    Kommentare 3 Kommentare
    1. Avatar von zer0
      zer0 -
      Schönes Tutorials! =)

      Man könnte vielleicht noch mittels Anti-Aliasing die Kantenglättung aktivieren. So würden die Sterne noch besser aussehen!

      Code :
      1
      2
      3
      
      Graphics2D g2 = (Graphics2D)g;
      RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g2.setRenderingHints(rh);
    1. Avatar von SE
      SE -
      Top Tutorial !
      Den Verwendungsmöglichkeiten sind fast keine grenzen gesetzt.
      Ich könnte mir das gut für mein aktuelles Projekt vorstellen ... falls ichs übernehme werd ich dich natürlich im Listing erwähnen ... deine Arbeit soll nicht ungeachtet bleiben.
    1. Avatar von javaDeveloper2011
      javaDeveloper2011 -
      @zer0: Danke für den Tipp, habs jetzt so gemacht:
      Code java:
      1
      
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    Kommentare Kommentar schreiben

    Klicke hier, um dich anzumelden

    Welche Farbe hat eine reife Zitrone?