1

I want my program to display the canvas that is repainted once at the start and then whenever a change is made afterwards. I thought I had everything coded correctly, but for some reason nothing that is painted onto the canvas actually shows (I know it's repainting, I tested that).

Here are the code segments:

public TileMapCreator()
{
    currentView = new BufferedImage(640, 640, BufferedImage.TYPE_INT_ARGB);
    currentView.getGraphics().setFont(new Font("Arial", Font.BOLD, 100));
    currentView.getGraphics().drawString("No Map Yet Open", currentView.getWidth()/2, currentView.getHeight()/2);

    this.setJMenuBar(createMenuBar());
    this.setContentPane(createMapPanel());
}
private JPanel createMapPanel()
{
    JPanel p = new JPanel();
    p.add(setUpCanvas());
    p.setVisible(true);

    return p;
}
private Canvas setUpCanvas()
{
    mapCanvas = new Canvas(){
        private static final long serialVersionUID = 1L;
        public void repaint()
        {
            mapCanvas.getGraphics().drawImage(currentView, 0, 0, this);
        }
    };
    mapCanvas.setIgnoreRepaint(true);
    Dimension size = new Dimension(currentView.getWidth(), currentView.getHeight());
    mapCanvas.setSize(size);
    mapCanvas.setPreferredSize(size);
    mapCanvas.setMaximumSize(size);
    mapCanvas.setMinimumSize(size);
    mapCanvas.setFocusable(true);
    mapCanvas.addMouseListener(this);
    mapCanvas.addMouseMotionListener(this);
    mapCanvas.setVisible(true);

    return mapCanvas;
}

Currently the area where the canvas should be painting is just the regular grey color of the Java GUI. Thanks for your help!

mKorbel
  • 109,525
  • 20
  • 134
  • 319
StrongJoshua
  • 975
  • 10
  • 24

1 Answers1

3

You appear to be mixing Swing with AWT components, and drawing in a very strange way, one that I've honestly never seen before (and I've seen a lot). Why not simply do your drawings in the paintComponent(Graphics g) method of a JPanel using the Graphics object given by the JVM, like you'll find in the Swing graphics tutorials and 98% of the Swing graphics answers on this site? Also for my money, I'd avoid using Canvas or trying to mix heavy and light weight components together. Stick with Swing all the way, and things should go more smoothly.

I'd be happy to give you more specific advice and perhaps some if you could create and post a minimal example program. Please have a look at the link and let us know if you need more information.


For example:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;

import javax.swing.*;

public class TestImagePanel extends JPanel {
   private static final int BI_WIDTH = 640;
   BufferedImage currentView = new BufferedImage(BI_WIDTH, BI_WIDTH, BufferedImage.TYPE_INT_ARGB);

   public TestImagePanel() {
      Graphics g = currentView.getGraphics();
      Graphics2D g2 = (Graphics2D) g;
      g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
      g.setColor(Color.black);
      g.setFont(new Font("Arial", Font.BOLD, 60));
      g.drawString("No Map Yet Open", 20, currentView.getHeight()/2);
      g.dispose();
   }

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      if (currentView != null) {
         g.drawImage(currentView, 0, 0, this);
      }
   }

   @Override
   public Dimension getPreferredSize() {
      if (currentView != null) {
         return new Dimension(BI_WIDTH, BI_WIDTH);
      }
      return super.getPreferredSize();
   }

   private static void createAndShowGui() {
      TestImagePanel mainPanel = new TestImagePanel();

      JFrame frame = new JFrame("TestImagePanel");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

I've found the Swing tutorials to be a great asset, and bet you would too. Please have a look at them.


Edit
You ask:

Hmm, so apparently getting the graphics object of my buffered image twice did not result in anything actually being painted... I had to get the graphics object, assign it to a variable, and then paint.

I wouldn't say that. I'd say that your way of getting the Graphics object should work the same as mine, but yours is not safe since the Graphics objects obtained in this way cannot be disposed of, and you risk running out of resources. I think that your image didn't show up due to your very convoluted and unusual way of trying to display your image. You override repaint(), put some weird code inside of it, tell the JVM to ignore repaint calls, never call the repaint super method inside of your override, so that repaint does in fact nothing. I have to wonder -- where did you get this code? Was it from a tutorial? If so, please share the link here. And never get advice from that site again.

Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Hmm, so apparently getting the graphics object of my buffered image twice did not result in anything actually being painted... I had to get the graphics object, assign it to a variable, and then paint. But thanks for posting that code example, it made me try different things until I found that error! – StrongJoshua Apr 01 '14 at 00:53
  • Well, I wrote it myself without any help except programs I had made previously that used solely a Canvas as the display with no other GUI components involved. Now the reasoning to what I did initially: I had always used a Canvas and it had never failed me before, repaint is what is always called to "repaint" the canvas (although in retrospect I should have overridden paint), and I set ignore repaint to true because I only wanted the canvas to repaint when I told it to. Now that I removed the canvas and am painting directly to the panel and changed how I drew the currentView, it works :3 – StrongJoshua Apr 01 '14 at 01:20