Domanda

Ho lavorato su un programma che attira JComponents personalizzati su un jlayeredpane, tuttavia tutte le chiamate a riverniciare () sui componenti sembrano non fare nulla, ma il metodo PaintComponent viene invocato automaticamente quando la finestra è ridimensionata.

Ho seguito alcuni dei consigli forniti qui:Perché Paint ()/PaintComponent () non è mai stato chiamato?

Ma nessuna delle soluzioni sembra risolvere il mio problema, aggiornare i componenti di swing sull'EDT, impostando manualmente la dimensione dei componenti prima di chiamare Reverta (), chiamare Super.PaintComponent (G) nel PaintComponent () superata e chiamare Revalidate () dopo il fotogramma dopo il fotogramma Aggiunta di nuovi componenti (anche se questo non è chiaramente il problema in questo caso)

Qualche idea Cosa potrebbe fermare la chiamata? Grazie in anticipo :)

Ecco il codice per la vista e SvGelementContainer, View.setFile () è il punto di entrata in quanto viene invocato quando è necessario visualizzare un nuovo 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()));
    }

}
È stato utile?

Soluzione

Vedo che stai chiamando setaPaque (falso). Dal setopaque javadoc, enfasi il mio:

Se vero il componente dipinge ogni pixel all'interno dei suoi limiti. Altrimenti, Il componente potrebbe non dipingere alcuni o tutti i suoi pixel, permettendo ai pixel sottostanti di mostrare.

Che "può" essere la causa di PaintComponent () che non viene chiamata dopo la prima volta durante una chiamata di riverniciatura. Swing può decidere che il componente non è "cambiato" e quindi non ha bisogno di ridipingere.

Altri suggerimenti

Impostazione manualmente della dimensione del componente prima di chiamare Reverta (), chiamare Super.PaintComponent (G) nel PaintComponent () sovrascritto e chiamare Revalidate () sul telaio dopo aver aggiunto nuovi componenti

Il tuo codice è sbagliato su questi concetti.

a) Non invocare mai il metodo SetSize (). Questo è il lavoro del layout Manager. Dovresti fornire suggerimenti al gestore di layout mediante metodi prevalenti come getPreferredSize () per restituire la dimensione preferita del tuo componente

b) Non sovrascrivere il metodo Revalidate (). Il punto di quel suggerimento è usare il codice come:

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

Ma non so davvero cosa dovrebbe fare tutto il tuo codice, quindi non posso dire con certezza se il tuo codice abbia senso. Trovo anche strano che tu stia estendendo un jlayeredpane.

Posso vedere estenderlo JPanel Per ottenere il buffering e il delegato dell'interfaccia utente, ma l'opacità dipende da L&F. Invece, probabilmente dovresti iniziare con JComponent e implementa il EventListenerList impianto idraulico per il tuo (ipotetico) SVGEvent.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top