Question

I am still trying to get a repaint() method to work in a separate class with a class that extends the JComponent. I have placed a couple of post on here and so far I haven't been able to get the code to work. I have gotten some good advice. I am placing below what I have so far.

Main Class 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);
        }
}

Class 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");
    }
}

Class 3: (I had this one embedded in the same files as the class above -- it will be separate when I have the finished code)

/**
 * 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);
    }

}

Frome what I have read and what people have posted this should work. Is there a way to force it to paint right away. Repaint() sometimes has a little bit of a delay. I want to use this as the start of a game and I have to be able to create an ArrayList of Circles and then repaint them immediately. Currently this will only draw one circle in the top (0,0) coordinates.

Doug Deines Hauf

Was it helpful?

Solution

Is there a way to force it to paint right away.

It will paint right away as soon as the GUI is visible. There is nothing special that you need to do. There is no need for a setDraw() method. All components will automatically be painted when the GUI is displayed.

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

That code does nothing. The GUI isn't visible yet so there is nothing to paint. There is no reason for you do invoke a repaint unless you actually change a property of a component on a visible GUI.

public void setDraw() {
      repaint();
  }

There is no reason to create a method that simply does a repaint(), get rid of this method. That is NOT what I suggested in your last posting. I said you create a method to change a property that will affect the outcome of the painting of the component.

I gave you an example, like when you use setForeground(), the method changes the Color of the text to be painted, so repaint() is automatically invoked when the color is changed.

Get rid of all the complex painting code in your paint component and then try to do a simple

graphics.drawString();

Don't be playing with rotations and clips (even I have problem with these concepts and if not done correctly you may not get anything painted) until you get something basic working. Then once you get that working you do something more complicated, one step at a time until you understand the basics. Don't write a complex program until you get something simple working.

Also, I don't know why you are attempting to draw from a buffered image. Just draw using the Graphics object that is passed into the paintComponent() method. There is no need to use a BufferedImage, Swing is already double buffered so you are just complicating your code.

Have you read the Custom Painting tutorial yet? It contains a working example.

Edit:

Having said all the above you still have two fundamental problems:

  1. you don't add the component to the panel
  2. the component doesn't have a preferred size so there is nothing to paint. You need to override the getPreferredSize() method to return a reasonable size for the component that you want to paint.

Even these two fixes don't solve the problem of your complex painting, but at least now I can get a simple drawstring(...) to work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top