Java Repaint - JComponet necesita volver a pintar la clase cuando se llama a la repintación () de otra clase

StackOverflow https://stackoverflow.com//questions/20025881

Pregunta

Todavía estoy tratando de obtener un método repintado () para trabajar en una clase separada con una clase que extiende el JComponente.He colocado un par de publicaciones aquí y hasta ahora no he podido hacer que el código funcione.He conseguido un buen consejo.Estoy colocando por debajo de lo que tengo hasta ahora.

Clase principal 1:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

public class DDHGenericFrame extends JFrame {
        private static final long serialVersionUID = 1L;
        DDHGenericPanel d = new DDHGenericPanel(); /*User defined class that is above*/

        public DDHGenericFrame() {
            initUI();
        }

        public final void initUI() {
            add(d);//Adds the panel to the JFrame
            setSize(650,350);
            setTitle("Lines");
            setLocationRelativeTo(null);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        }

        public static void main(String[] args) {
            DDHGenericFrame ex = new DDHGenericFrame();
            ex.setVisible(true);
        }
}

Clase 2:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;

class DDHGenericPanel extends JPanel {
    private static final long serialVersionUID = 1L;
      public JButton aButton1;
      public JButton aButton2;
      public TestPane tPane = new TestPane();

    DDHGenericPanel(){
        System.out.println("DDH Generic JPanel");

          aButton1 = new JButton();
          aButton1.setText("Button 1");
          aButton1.addActionListener(new myButtonActionListener1());
          add(aButton1);

          aButton2 = new JButton();
          aButton2.setText("Button 2");
          aButton2.addActionListener(new myButtonActionListener2());
          add(aButton2);

          System.out.println("Before the setDraw!!!");
          tPane.setDraw(); 
          System.out.println("After the setDraw!!!");
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        System.out.println("paintComponent of DDHGenericPanel.java");
    }
}   

class myButtonActionListener1 implements ActionListener {
    public TestPane tPane = new TestPane();

    @Override
    public void actionPerformed(ActionEvent arg0) {
         System.out.println("Button 1 -- Before the setDraw!!!");
         tPane.setDraw(); 
         System.out.println("Button 1 -- After the setDraw!!!");
    }
}

class myButtonActionListener2 implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent arg0) {
          System.out.println("Button1 clicked 2");
    }
}

Clase 3: (Tuve este incrustado en los mismos archivos que la clase anterior, estará separada cuando tenga el código terminado)

/**
 * This class will draw a cricle with the repaint method
 * @author DDH
 */
class TestPane extends JComponent {
    private static final long serialVersionUID = 1L;
    private static final int LINE_THICKNESS = 4;
      private static final int LINE_GAP = 10;
    private Color lineColor = Color.red;

      /**
      * This method will draw the circle with coordinated (0,0)
      * @param none
      * @return none
      */
      public void setDraw() {
          repaint();//This should call the paintComponent() that is below and paint a circe but it does not for some reason.
      }

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

        int radius = 10;
        BufferedImage buffer = new BufferedImage(radius, radius, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = buffer.createGraphics();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHint        (RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);

        Ellipse2D circle = new Ellipse2D.Float(0, 0, radius,radius);
        Shape clip = g2d.getClip();
        g2d.setClip(circle);
        AffineTransform at = g2d.getTransform();

        g2d.setTransform(AffineTransform.getRotateInstance(
                                                    Math.toRadians(45),
                                                    radius / 2, radius / 2));

        int gap = LINE_GAP;

        g2d.setColor(Color.WHITE);
        g2d.fill(circle);

        g2d.setColor(lineColor);
        //g2d.setStroke(new BasicStroke(LINE_THICKNESS));
        for (int index = 0; index < 10; index++) {
            int x1 = index*gap-(LINE_THICKNESS/2);
            int y1 = 0;
            int x2 = index*gap+(LINE_THICKNESS/2);
            int y2 = radius;
            int width = x2 - x1;
            int height = y2 - y1;

            g2d.fillRect(x1, y1, width, height);
            //g2d.drawLine(index * gap, 0, index * gap, getRadius());
        }

        g2d.setTransform(at);
        g2d.setClip(clip);
        g2d.dispose();
        g.drawImage(buffer, 0, 0, this);
    }

}

De lo que he leído y lo que las personas han publicado esto debería funcionar.¿Hay alguna manera de forzarlo a pintar de inmediato?Volver a pintar () a veces tiene un poco de retraso.Quiero usar esto como el comienzo de un juego y debo poder crear un arraylist de círculos y luego repintarlos de inmediato. Actualmente, esto solo dibujará un círculo en las coordenadas superior (0,0).

Doug Deines Hauf

¿Fue útil?

Solución

¿Hay alguna manera de forzarlo a pintar de inmediato?

Se pintará de inmediato tan pronto como la GUI sea visible. No hay nada especial que necesites hacer. No hay necesidad de un método SetDraw (). Todos los componentes se pintarán automáticamente cuando se muestre la GUI.

      System.out.println("Before the setDraw!!!");
      tPane.setDraw(); 
      System.out.println("After the setDraw!!!");

Ese código no hace nada. La GUI no es visible, por lo que no hay nada que pintar. No hay ninguna razón para usted invoque un repintado a menos que realmente cambie una propiedad de un componente en una GUI visible.

public void setDraw() {
      repaint();
  }

No hay razón para crear un método que simplemente haga una repintación (), deshacerse de este método. Eso no es lo que sugerí en tu última publicación. Dije que crea un método para cambiar una propiedad que afectará el resultado de la pintura del componente.

Le di un ejemplo, como cuando usa SetForground (), el método cambia el color del texto a pintar, así que la repintación () se invoca automáticamente cuando se cambia el color.

Deshazte de todo el código de pintura complejo en su componente de pintura y luego intente hacer un simple

graphics.drawString();

No juegue con rotaciones y clips (incluso tengo problemas con estos conceptos y, si no se hace correctamente, es posible que no se pinte nada) hasta que obtenga algo de trabajo básico. Luego, una vez que obtiene ese trabajo, hace algo más complicado, un paso a la vez hasta que entiende lo básico. No escriba un programa complejo hasta que obtenga algo de funcionamiento simple.

Además, no sé por qué está intentando dibujar desde una imagen amortiguada. Simplemente dibuje utilizando el objeto gráficos que se pasa al método de PaintComponent (). No es necesario usar un bufferedImage, el swing ya está en tamponero doble, por lo que solo está complicando su código.

¿Has leído el pintura personalizada tutorial todavía? Contiene un ejemplo de trabajo.

Editar:

Dicho todo lo anterior que aún tiene dos problemas fundamentales:

  1. No agregas el componente al panel
  2. El componente no tiene un tamaño preferido, por lo que no hay nada que pintar. Debe anular el método GETPreferredsize () para devolver un tamaño razonable para el componente que desea pintar.
  3. Incluso estas dos soluciones no resuelven el problema de su pintura compleja, pero al menos ahora puedo obtener un simple cordón (...) para trabajar.

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