Search code examples
javaswingrepaintjcomponent

Moving draw on Jcomponent


I want to draw a moving cursor (in green) in my 2D plan view (in red) . I use a joystick to command it.

To access to the red panel I have to get components of components from the controller following this scheme : JPanel => JScrollPane => JViewPort => PlanComponent (extends JComponent)

My cursor coordinates are continuously updated by reading a socket. When the coordinates are changed, it calls the drawCross fonction.

My cursor is perfectly moved by the joystick but the red area blinks and the cursor blinks over more.

Coloured program screenshot

 public ThreadGestionObjetImu(Home home, HomeController homeController) {
    _sweetHome3dHomeControllerVar = homeController;
    _jComponentLayer1 = (MultipleLevelsPlanPanel) _sweetHome3dHomeControllerVar.getPlanController().getView();
    _jComponentLayer2 = (JPanel) _jComponentLayer1.getComponent(1);
    _jComponentLayer3 = (JScrollPane) _jComponentLayer2.getComponent(0);
    _jComponentLayer4 = (JViewport) _jComponentLayer3.getComponent(0);
    _planComponent = (PlanComponent) _jComponentLayer4.getComponent(0);
}


public void update(Observable o, Object arg) {
    //parsing socket signal
    switch(XImuPlugin.state){
        case PLAN:
            drawCross();
            break;
    }
}



public void drawCross() {
    _planComponent.getGraphics().drawLine(_crossPositionX + _intImuValueX, _crossPositionY + 25 + _intImuValueY, _crossPositionX + 50 + _intImuValueX, _crossPositionY + 25 + _intImuValueY);
    _planComponent.getGraphics().drawLine(_crossPositionX + 25 + _intImuValueX, _crossPositionY + _intImuValueY, _crossPositionX + 25 + _intImuValueX, _crossPositionY + 50 + _intImuValueY);

    if (_intImuValueX > 1 || _intImuValueX < -1 || _intImuValueY > 1 || _intImuValueY < -1) {
        _planComponent.update(_planComponent.getGraphics());
        // I tried update, repaint, updateUI and all the possible functions
    }
}

EDIT: I forgot to precise that I was stuck in only using the sweetHome3D Api because I'm creating a plug-in, I can't modify the original code.

Problem solved by using _planComponent.add(MyComponent); I created a JComponent with an override of paintComponent.


Solution

  • This is a know problem, if you draw in a component already in the UI the result is this blinking (the component drawing his background color and then drawing the image).

    To avoid that, you can use a "double buffer", drawing the new image in a hide image and then, when it is ready replace directly in your UI.

    A nice explanation can be found in oracle doc page

    And an example here in stackoverflow: double buffering in java SWING