【问题标题】:Java AWT Heavyweight CanvasJava AWT 重量级画布
【发布时间】:2011-04-23 11:49:30
【问题描述】:

我有一个小应用程序,我通过覆盖paint() 方法在其中绘制东西,并在小应用程序中添加了一个画布,它将占据整个屏幕。这个画布似乎是在我的paint()ing 之后绘制的,所以我的applet 的paint()ed 东西是不可见的。关于如何在我的小程序上的绘制方法之前强制绘制画布的任何想法?

编辑:

public void paint(Graphics g) {
    super.paint(g);
    if (DEBUG) {
        g.setColor(Color.red);
        g.drawString("Memory free: " + ((Runtime.getRuntime().freeMemory()
            / 1024) / 1024) + "MB", 5, 20);
        g.drawString("Memory total: " + ((Runtime.getRuntime().totalMemory()
            / 1024) / 1024) + "MB", 5, 35);
        g.drawString("Memory used: " + (((Runtime.getRuntime().totalMemory()
            - Runtime.getRuntime().freeMemory()) / 1024) / 1024) + "MB", 5, 50);
    }
}

【问题讨论】:

  • 重新格式化的代码;如果不正确,请恢复。
  • 您的paint() 方法是否覆盖AppletCanvas 的方法。

标签: java canvas awt paint


【解决方案1】:

即使您必须使用 AWT,您也应该能够为 GL 内容和内存状态使用单独的Panel

import java.awt.*;
import java.awt.event.*;

public class AWTPaintTest {

    public static void main(String[] args) {
        Frame frame = new Frame();
        // frame.add(new AWTGLCanvas(), BorderLayout.CENTER);
        frame.add(new MemoryPanel(), BorderLayout.SOUTH);
        frame.addWindowListener(new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        frame.pack();
        frame.setVisible(true);
    }

    private static class MemoryPanel extends Panel {

        private final Runtime r = Runtime.getRuntime();

        public MemoryPanel() {
            this.setPreferredSize(new Dimension(240, 120));
            this.setForeground(Color.blue);
            this.setFont(new Font("Monospaced", Font.BOLD, 16));
            this.addMouseListener(new MouseAdapter() {

                @Override
                public void mousePressed(MouseEvent e) {
                    r.gc();
                    MemoryPanel.this.repaint();
                }
            });
        }

        @Override
        public void paint(Graphics g) {
            super.paint(g);
            long m = r.maxMemory();
            long t = r.totalMemory();
            long f = r.freeMemory();
            int y = g.getFontMetrics().getHeight() + 4;
            g.drawString("Memory max:   " + toMB(m), 5, 1 * y);
            g.drawString("Memory total: " + toMB(t), 5, 2 * y);
            g.drawString("Memory free:  " + toMB(f), 5, 3 * y);
            g.drawString("Memory used:  " + toMB(t - f), 5, 4 * y);
            g.drawString("Click to update.", 5, 5 * y);
        }

        private String toMB(long bytes) {
            return (bytes / 1024) / 1024 + " MB";
        }
    }
}

【讨论】:

  • 谢谢,它消除了一些混乱,它现在可以工作了(无论如何对我来说)
【解决方案2】:

没有看到您的代码,很难猜出您做了什么。

paint() 方法中的通用代码大概应该是:

super.paint(g); // this will paint the children components added to the applet
// add your custom painting here

另外,最好花时间学习 Swing 而不是 AWT,因为在 Swing 中绘画有些不同,您不妨花时间学习更新的 GUI 解决方案。

如果您需要更多帮助,请发布您的 SSCCE

【讨论】:

  • 准确地说,我使用的是 AWTGLCanvas(使用 LWJGL),所以 Swing 并没有真正的帮助。我的paint() 方法是: public void paint(Graphics g) { super.paint(g); if (DEBUG) { g.setColor(Color.red); g.drawString("内存空闲:" + ((Runtime.getRuntime().freeMemory() / 1024) / 1024) + "MB", 5, 20); g.drawString("内存总量:" + ((Runtime.getRuntime().totalMemory() / 1024) / 1024) + "MB", 5, 35); g.drawString("使用的内存:" + (((Runtime.getRuntime().totalMemory() - 运行时.getRuntime().freeMemory()) / 1024) / 1024) + "MB", 5, 50); } }
【解决方案3】:

如果您打算通过覆盖其容器的paint() 来在该画布组件上绘制一些东西,它不会起作用。问题是,AWT 容器不会绘制它们的子级。顺便说一句,即使对于 Swing 容器也是如此。如果您需要在画布组件上绘制一些东西,请定义您的自定义组件子类并将您的绘图代码放在它的 paint() 方法中。然后通过 setGlassPane() 方法将该组件设置到您的小程序中。或者,更好的是,只需覆盖 Canvas(而不是其容器)的 paint() 并在调用 super.paint(g) 后进行绘画

【讨论】:

  • 对于在 AWTGLCanvas 上绘画,glassPane 方法可能可行。覆盖 opengl 上下文时,覆盖paint方法可能会引入闪烁或其他不需要的效果
  • 我认为 Swing paint() 调用 paintChildren(): java.sun.com/products/jfc/tsc/articles/painting/index.html
  • 我同意,但我的意思是,当某些子组件排队等待重绘时,重绘管理器并不总是遍历整个层次结构。它直接进入该组件并调用其绘制方法而不调用其父组件的绘制。因此,即使您的 paint() 被覆盖以不执行任何操作,子组件也会偶尔偷看(由于有人在这些子组件上调用 repaint())
猜你喜欢
  • 2012-04-23
  • 1970-01-01
  • 2015-11-10
  • 2015-04-14
  • 2011-08-31
  • 1970-01-01
  • 1970-01-01
  • 2022-01-25
  • 2021-06-26
相关资源
最近更新 更多