Java Canvas不会画画

时间:2014-04-01 00:22:45

标签: java swing canvas awt mixing

我希望我的程序显示在开始时重新绘制一次的画布,然后在之后进行更改时。我以为我的所有内容都编码正确,但由于某些原因,画布上的任何内容都没有显示(我知道它正在重新绘制,我测试过了)。

以下是代码段:

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;
}

目前画布应该绘制的区域只是Java GUI的常规灰色。谢谢你的帮助!

1 个答案:

答案 0 :(得分:3)

你似乎将Swing与AWT组件混合在一起,并以一种非常奇怪的方式绘制,这是我以前从未见过的(而且我已经看过很多)。为什么不使用JVM提供的Graphics对象在JPanel的paintComponent(Graphics g)方法中简单地绘制图形,就像您在Swing图形教程中找到的那样,以及在此站点上98%的Swing图形答案?另外,对于我的钱,我避免使用Canvas或尝试将重量和重量轻的组件混合在一起。坚持使用Swing,事情应该更加顺利。

我很乐意为您提供更具体的建议,如果您可以创建并发布minimal example program,可能会有一些建议。如果您需要更多信息,请查看链接并告知我们。


例如:

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();
         }
      });
   }
}

我发现Swing教程是一项很好的资产,并打赌你也会这样做。请看看它们。


修改
你问:

  

嗯,所以显然我的缓冲图像的图形对象两次没有导致任何实际被绘制...我必须获取图形对象,将其分配给变量,然后绘制。

我不会这么说。我说你获取Graphics对象的方式应该与我的相同,但是你的方法不安全,因为以这种方式获得的Graphics对象不能被处理,你可能会耗尽资源。我认为您的图片没有显示出来,因为您尝试显示图片的方式非常复杂且不常见。。你重写repaint(),在其中放入一些奇怪的代码,告诉JVM 忽略 重绘调用,永远不要在你的覆盖内部调用重绘超级方法,所以这种重画确实没有。我不得不怀疑 - 你从哪里获得这段代码?是从教程?如果是这样,请在此处分享链接。并且再也不会从该网站获得建议。