Вопрос

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!

Это было полезно?

Решение

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top