Pregunta

He estado trabajando en un programa que dibuja JComponentes personalizados en un JlayeredPane, sin embargo, todas las llamadas para repintar () en los componentes parecen no hacer nada aún, el método PaintComponent se invoca automáticamente cuando la ventana se vuelve a tamaño.

He estado siguiendo algunos de los consejos dados aquí:¿Por qué nunca se llama pintar ()/pintarComponent ()?

Pero ninguna de las soluciones parece solucionar mi problema, actualice los componentes de swing en el EDT, configurando el tamaño del componente manualmente antes de llamar a Repaint (), llamar a Super.PaintComponent (g) en el PintarComponente anulado () y llamar a Revalidate () en el marco después de Agregar nuevos componentes (aunque esto claramente no es el problema en este caso)

¿Alguna idea de qué podría detener la llamada? Gracias por adelantado :)

Aquí está el código para la vista y el SvGelementContainer, View.setFile () es el punto de entrada, ya que se invoca cuando se debe mostrar un nuevo documento.

public class View extends JLayeredPane implements SVGViewport {

    private SVGDocument document;
    //Array list of the SVGElementContainer components
    private ArrayList<SVGElementContainer> elemContainers;
    private SVGFrame frame;
    private int elemCount;
    private Border viewBorder;
    private int borderWidth = 1;

    //panels displayed on the JLayeredPane
    private JPanel backgroundPanel;

    /** Creates a new view */
    public View(SVGFrame frame) {
        super();
        this.frame = frame;
        elemCount = 0;

        elemContainers = new ArrayList<SVGElementContainer>();
        viewBorder = BorderFactory.createLineBorder(Color.BLACK, borderWidth);
    }

    public float getViewportWidth() {
        return getWidth();
    }

    public float getViewportHeight() {
        return getHeight();
    }

    // paints all elements and adds them to the JLayeredPane
    public void paintAllElements(){

        System.out.println("Painting all elements");

        // Paint document
        for (SVGElement elem : document) {
            //only paint stylable (rect, line, circle) elements
            if (elem instanceof SVGStylable){
                //create a new SVGElementContainer
                SVGElementContainer newElemCont = new SVGElementContainer();

                //add component to JLayeredPane
                elemCount++;
                this.add(newElemCont, new Integer(elemCount + 1));

                //set the current element within its container and calls repaint() on the component
                System.out.println("Painting element #" + elemCount);
                newElemCont.setElement(elem);
                newElemCont.repaint();
            }
            else {
                System.out.println("Skip painting group element!");
            }
        }
    }

    /** Gets the document currently being displayed by the view. */
    public SVGDocument getDocument() {
        return document;
    }

    /** Sets the document that the view should display.
     *
     * @param document the document to set
     */
    public void setDocument(SVGDocument document) {
        this.document = document;
        //paintBackground();
        paintAllElements();
        revalidate();
    }

    public void revalidate(){
        //calls validate() on the frame in order to display newly added components
        frame.getContentPane().validate();
    }
}

public class SVGElementContainer extends JPanel{

    private SVGElement elem;

    public SVGElementContainer(){
        super();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        System.out.println("PAINT METHOD CALLED!");
        paint2D((Graphics2D) g);
    }

    //paint the element onto this JComponent
    public void paint2D(Graphics2D g){
        if (!(elem instanceof SVGStylable)){
            System.out.println("Skipping non-stylable element!");
            return;
        }

        setOpaque(false);

        Shape shape = elem.createShape();

        // get fill stroke and width properties
        SVGStylable style = (SVGStylable) elem;
        SVGPaint fillPaint = style.getFill();
        SVGPaint strokePaint = style.getStroke();
        SVGLength strokeWidth = style.getStrokeWidth();

        // Fill the interior of the shape
        if (fillPaint.getPaintType() == SVGPaint.SVG_PAINTTYPE_RGBCOLOR) {
            g.setPaint(fillPaint.getRGBColor());
            g.fill(shape);
        }

        // Stroke the outline of the shape
        if (strokePaint.getPaintType() == SVGPaint.SVG_PAINTTYPE_RGBCOLOR) {
            Stroke stroke = new BasicStroke(strokeWidth.getValue());
            g.setStroke(stroke);
            g.setColor(strokePaint.getRGBColor());
            g.draw(shape);
        }
    }

    public void setElement(SVGElement elem){
        this.elem = elem;
        setComponentSize();
    }

    private void setComponentSize(){

        //this.setPreferredSize(new Dimension(
        //  (int)elem.getDocument().getWidth().getValue(),
        //  (int)elem.getDocument().getHeight().getValue()));

        this.setSize(new Dimension(
                (int)elem.getDocument().getWidth().getValue(),
                (int)elem.getDocument().getHeight().getValue()));
    }

}
¿Fue útil?

Solución

Veo que estás llamando a SetOpaque (falso). Del setopaco javadoc, énfasis mía:

Si es cierto, el componente pinta cada píxel dentro de sus límites. De lo contrario, El componente no puede pintar algunos o todos sus píxeles, permitiendo que los píxeles subyacentes se muestren.

Que "puede" ser la causa de pintarComponent () que no se llama después de la primera vez durante una llamada de repintado (). Swing puede decidir que el componente no ha "cambiado" y, por lo tanto, no necesita volver a pintar.

Otros consejos

Configuración del tamaño del componente manualmente antes de llamar a Repaint (), llamar a Super.PaintComponent (g) en el anulación de pintura de pintura () y llamar a Revalidate () en el marco después de agregar nuevos componentes

Su código está mal en estos conceptos.

a) Nunca invoque el método setSize (). Ese es el trabajo del gerente de diseño. Debe proporcionar sugerencias al Administrador de diseño anulando métodos como GetPreferredSize () para devolver el tamaño preferido de su componente

b) No anule el método Revalidate (). El punto de ese consejo es usar código como:

panel.add( .... );
panel.revalidate();
panel.repaint();

Pero realmente no sé qué se supone que debe hacer todo su código, por lo que no puedo decir con certeza si su código tiene sentido. También me resulta extraño que estés extendiendo un JlayeredPane.

Puedo ver extenderse JPanel Para obtener el buffering y el delegado de la interfaz de usuario, pero la opacidad depende de L&F. En cambio, probablemente deberías comenzar con JComponent e implementar el EventListenerList Plomería para su (hipotético) SVGEvent.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top