Q:

java swing - paint jcomponent

i am try to make chorded keyboard simulation.
I cannot resolve why KeyboardButtons in Keyboard are not painting. I have more KeyboardButtons in Keyboard. Mouse is listened properly, but polygons are not painted.
When i call paint to each KeyboardButton in the Keyboard's paintComponent(), polygons are painted, but not changing color on mousePressed.
Keyboard.java
package keyboard;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JComponent;
import javax.swing.JPanel;

public class Keyboard extends JPanel implements MouseListener{

    Point[] leftFingers;
    Point leftCenter = new Point(300, 600);
    KeyboardButton[] buttons;

    public Keyboard(Point left1, Point left2, Point left3, Point left4, Point left5) {
    leftFingers = new Point[5];
    leftFingers[0] = left1;
    leftFingers[1] = left2;
    leftFingers[2] = left3;
    leftFingers[3] = left4;
    leftFingers[4] = left5;
    buttons = registerKeys();
    addMouseListener(this);
    }

    public KeyboardButton[] registerKeys() {
    Polygon[] polygons = generateKeyPolygons(calculateBordersOfKeys(leftFingers));
    KeyboardButton[] buttons = new KeyboardButton[5];
    for (int i = 0; i < polygons.length; i++) {
        buttons[i] = new KeyboardButton(polygons[i]);

    }
    return buttons;
    }

    private Point[] calculateBordersOfKeys(Point[] fingers) {
    Point[] centers = calculateCentersBetweenEachTwoFingers(fingers);
    Point[] result = new Point[6];

    result[0] = calculateCentralSymmetry(centers[0], fingers[0]);
    System.arraycopy(centers, 0, result, 1, centers.length);
    result[5] = calculateCentralSymmetry(centers[3], fingers[4]);
    return result;
    }

    @Override
    protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.red);
    g.drawOval(leftCenter.x - 25, leftCenter.y - 25, 50, 50);

    for (int i = 0; i < leftFingers.length; i++) {
        g.drawOval(leftFingers[i].x, leftFingers[i].y, 10, 10);

    }
    }

    private Polygon[] generateKeyPolygons(Point[] borders) {
    Polygon[] polygons = new Polygon[5];
    for (int i = 0; i < borders.length - 1; i++) {
        Polygon p = new Polygon();
        p.addPoint(leftCenter.x, leftCenter.y);
        p.addPoint(borders[i].x, borders[i].y);
        p.addPoint(borders[i + 1].x, borders[i + 1].y);
        polygons[i] = p;
    }

    return polygons;
    }

    private Point[] calculateCentersBetweenEachTwoFingers(Point[] fingers) {
    Point[] centers = new Point[4];
    for (int i = 0; i < fingers.length - 1; i++) {
        centers[i] = new Point(((fingers[i].x + fingers[i + 1].x) / 2), ((fingers[i].y + fingers[i + 1].y) / 2));
    }
    return centers;
    }

    private Point calculateCentralSymmetry(Point toReflected, Point center) {
    Point reflection = new Point();

    if (toReflected.x > center.x) {
        reflection.x = center.x - Math.abs(center.x - toReflected.x);
    } else {
        reflection.x = center.x + Math.abs(center.x - toReflected.x);
    }

    if (toReflected.y > center.y) {
        reflection.y = center.y - Math.abs(center.y - toReflected.y);
    } else {
        reflection.y = center.y + Math.abs(center.y - toReflected.y);
    }

    return reflection;
    }

    public void mouseClicked(MouseEvent e) {

    }

    public void mousePressed(MouseEvent e) {
    for (KeyboardButton button : buttons) {
        button.checkMousePosition(e);
    }
    }

    public void mouseReleased(MouseEvent e) {
    for (KeyboardButton button : buttons) {
        button.checkMousePosition(e);
    }   
    }

    public void mouseEntered(MouseEvent e) {

    }

    public void mouseExited(MouseEvent e) {

    }

}

KeyboardButton.java
package keyboard;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.event.*;
import javax.swing.JComponent;
import javax.swing.JPanel;

public class KeyboardButton extends JComponent {

    Polygon polygon;
    boolean isActive;
    final Color ACTIVE_COLOR = Color.red;
    final Color INACTIVE_COLOR = Color.blue;

    public KeyboardButton(Polygon p) {
    polygon = p;
    }

    public void checkMousePosition(MouseEvent e) {
    if (polygon.contains(e.getX(), e.getY())) {
        setState(true);
    }
    }

    @Override
    protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(isActive ? ACTIVE_COLOR : INACTIVE_COLOR);
    g.drawPolygon(polygon);
    }

    void setState(boolean state) {
    isActive = state;
    System.out.println(this.hashCode());
    repaint();

    }
}

A:

As far as I can tell, the KeyboardButton components are never added to the Keyboard. So, when they call repaint(), it has no effect because they are not part of the view hierarchy.

