Search code examples
javaswinggraphicspaintcomponentrepaint

Java Graphics - repaint() doesn't work when I click -> all before works


I have a new problem with the repaint methode. There is a frame in which I paint several graphics together. When I click in a specific range of coordinates, it should change the status of one graphic and then repaint this specific range. But this repaint doesn't work... This is the method that initialize the graphics (the declaration of the graphics isn't shown):

private void initComponents() {

    Painter painter = new Painter();

    setExtendedState(MAXIMIZED_BOTH);
    int width = (int) getContentPane().getBounds().getWidth();
    int height = (int) getContentPane().getBounds().getHeight();
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    g0 = new Gleis(25, 1, 4, 0, 0);
    g1 = new Gleis(26, 1, 0, 1, 0);
    k0 = new KnopfRot(26, 1, 0, false);
    g2 = new Gleis(27, 1, 0, 2, 0);
    g3 = new Gleis(28, 1, 0, 3, 0);
    g4 = new Gleis(29, 1, 0, 4, 0);
    g5 = new Gleis(30, 1, 0, 5, 0);
    g6 = new Gleis(31, 1, 0, 6, 0);
    g7 = new Gleis(32, 1, 0, 7, 0);
    g8 = new Gleis(33, 1, 0, 8, 0);
    g9 = new Gleis(34, 1, 0, 9, 0);
    g10 = new Gleis(35, 1, 0, 10, 0);
    g11 = new Gleis(36, 1, 0, 11, 0);
    g12 = new Gleis(37, 1, 0, 12, 0);
    g13 = new Gleis(38, 1, 0, 13, 0);
    k1 = new KnopfRot(38, 1, 1, false);

    painter.addGleis(g0);
    painter.addGleis(g1);
    painter.addKnopfRot(k0);
    painter.addGleis(g2);
    painter.addGleis(g3);
    painter.addGleis(g4);
    painter.addGleis(g5);
    painter.addGleis(g6);
    painter.addGleis(g7);
    painter.addGleis(g8);
    painter.addGleis(g9);
    painter.addGleis(g10);
    painter.addGleis(g11);
    painter.addGleis(g12);
    painter.addGleis(g13);
    painter.addKnopfRot(k1);

    this.addMouseListener(new MouseListener() {

        @Override
        public void mouseClicked(MouseEvent e) {
            double x = e.getX();
            double y = e.getY();
            frameMouseClicked(x, y);    
        }
    });

    this.getContentPane().add(painter);

    this.setVisible(true);
}

public void frameMouseClicked(double x, double y) {

    if(x >= 306 && x <= 314 && y >= 55 && y <= 63){     //x+11 y+32
        Painter painter = new Painter();
        painter.updateKnopfRot(k0, 26, 1, 306, 55);
        repaint();
    }
    else{}

}

Then my class KnopfRot:

public class KnopfRot {

    int xposition;
    int yposition;
    int type;
    int id;
    boolean status;

    //Konstruktor
    public KnopfRot(int xpos, int ypos, int id, boolean status){

        this.xposition = xpos * 11 + 12;
        this.yposition = ypos * 11 + 12;
        this.id = id;                       //zur eindeutigen Bezeichnung der Gleiselemente
        this.status = status;
    }

    public void draw(Graphics2D g) {

        if (!status) {
            Ellipse2D.Double aussen = new Ellipse2D.Double(xposition, yposition, 8, 8);
            Ellipse2D.Double innen = new Ellipse2D.Double(xposition + 1, yposition + 1, 6, 6);

            g.setColor(Color.black);
            g.fill(aussen);
            g.setColor(Color.red);
            g.fill(innen);
        }
        else if (status){
            Ellipse2D.Double aussen = new Ellipse2D.Double(xposition, yposition, 7, 7);
            Ellipse2D.Double innen = new Ellipse2D.Double(xposition + 1, yposition + 1, 5, 5);

            g.setColor(Color.black);
            g.fill(aussen);
            g.setColor(Color.red);
            g.fill(innen);
        }
        else {}

    }

}

And the Painter-Class with the method updateKnopfRot which is callen in the MouseEvent:

public class Painter extends JPanel {
        private List<Gleis> gleisList = new ArrayList<>();
        private List<KnopfRot> knopfList = new ArrayList<>();

        //fügt ein neues Element der Liste gleisList hinzu
        public void addGleis(Gleis gleis) {
            gleisList.add(gleis);
        }

        public void addKnopfRot(KnopfRot knopf) {
            knopfList.add(knopf);
        }

        public void updateKnopfRot(KnopfRot knopf, int x, int y, int xpos, int ypos) {
            knopfList.remove(knopf);

            addKnopfRot(new KnopfRot(x, y, 0, true));
        }


        //paint-Methode geht jedes Element der Liste gleisList durch und führt die draw-Methode in Gleis.java aus
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2 = (Graphics2D) g;
            for (Gleis gleis : gleisList) {
                gleis.draw(g2);
            }
            for (KnopfRot knopf : knopfList) {
                knopf.draw(g2);
            }
       }
 }

Sorry for so much code but I can't reduce it to explain/show the problem. Can somebody help?


Solution

  • You're creating a new Painter(...) object within your frameMouseClicked(...) method, and then changing the state of this object, but this will have no effect on the completely different visualized Painter object. Your solution -- don't create a new Painter object, but rather use a reference to the original, and then try to change its state.

    Regarding:

    Sorry for so much code but I can't reduce it to explain/show the problem.

    If this answer doesn't solve your problem, then yes, you can reduce this code and make it runnable as we've discussed in the past. Yes it will take some effort on your part to create and post a valid MCVE, but it's worth it.