在Java中调整大小时,绘制的内容不可见

时间:2010-08-21 15:46:00

标签: java graphics resize window minimize

请注意我还没有在Mac机器上的Windows机器上测试过。我不太确定这是否也出现在Windows机器上......

当我调整Java应用程序的大小时,内容是不可见的。我已经找到了一种方法来修复它调整大小之后,而不是,而用户正在调整窗口大小。

我没有使用Swing或其他东西,因为它使我的二进制文件变得如此缓慢(在我看来)。

结构是这样的:

  • Frame 我的主窗口
    • Containe main-window的内容视图
      • Container 的子视图,包括paint(Graphics g) - 方法

我已将所有听众添加到 My main-window ,现在我可以在调整大小后重绘内容视图 窗口。

public void componentResized(ComponentEvent e) {
    this.contentView.paint(this.contentView.getGraphics());
}

我要注意使用paint(getGraphics())方法这一事实并不是一个非常好的方法,但由于repaint() - 方法根本没有做任何事情,所以它是唯一的工作的可能性。

在调整大小时,所有绘制的内容都变得不可见。但是,当我向 Button 添加Content-view - 实例并调整 Main-window 的大小时,该按钮不会隐藏

能够追踪'live'-resize事件:

public void componentMoved(ComponentEvent e) {
    System.out.println("Live-resize");
}
  1. 当我开始调整大小时,不会调用此方法。
  2. 在调整大小时,我会在每个像素的日志中生成“实时调整大小”,并调整窗口大小。
  3. 当我停止调整大小时,没有调用此方法,componentResized-method会这样做。
  4. 当我将repaint-method(或官方重绘方法)添加到像这样的'live'-resize事件时,我仍然得到输出,但是,它不是重新绘制或者是什么

    public void componentMoved(ComponentEvent e) {
        System.out.println("Live-resize");
        this.contentView.paint(this.contentView.getGraphics());
    }
    

    或者

    public void componentMoved(ComponentEvent e) {
        System.out.println("Live-resize");
        this.contentView.repaint();
    }
    

    当我最小化我的应用程序到Dock并再次最大化应用程序时,同样的事情发生了,我想需要相同的代码来解决这个问题。

    我没有使用Graphics2D或其他内容,只是Graphics

    请您解释一下我如何重新制作观点?

    提前致谢, 添

3 个答案:

答案 0 :(得分:6)

供参考,这是使用Swing的相同程序。因为JPanel是双缓冲的,所以在调整大小后释放鼠标时它不会闪烁。

import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;

public class SwingPaint {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new CirclePanel());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

    private static class CirclePanel extends JPanel {

        private static final Random r = new Random();

        public CirclePanel() {
            this.setPreferredSize(new Dimension(320, 240));
            this.setForeground(new Color(r.nextInt()));
            this.addMouseListener(new MouseAdapter() {

                @Override
                public void mousePressed(MouseEvent e) {
                    CirclePanel.this.update();
                }
            });
        }

        public void update() {
            this.setForeground(new Color(r.nextInt()));
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Dimension size = this.getSize();
            int d = Math.min(size.width, size.height) - 10;
            int x = (size.width - d) / 2;
            int y = (size.height - d) / 2;
            g.fillOval(x, y, d, d);
            g.setColor(Color.blue);
            g.drawOval(x, y, d, d);
        }
    }
}

答案 1 :(得分:5)

我对Swing更熟悉,但文章Painting in AWT and Swing区分了系统和应用程序触发的绘画。下面的示例显示了系统在调整窗口大小时调用paint()的方式,而应用程序调用{​​{1}}来调用repaint()以响应鼠标事件。这种行为是跨平台的。

update()

答案 2 :(得分:0)

好的,我终于修好了。

不是每次在paint(Graphics g) - 方法中重新绘制它,而是需要缓冲输出并仅重绘该图像(我希望Java已经这样做了,就像Obj-C一样)。

public BufferedImage buffer;

public void redraw() {
    buffer = new BufferedImage(
            200, // height
            300, // width
            BufferedImage.TYPE_4BYTE_ABGR); // ABGR = RGBA, 4-byte (r, g, b, a) per pixel
    Graphics g = buffer.getGraphics();
    // do your drawing here
    if (this.getGraphics()) {
        // 'this' is already shown, so it needs a redraw
        this.paint(this.getGraphics()); // little hack
    }
}

public void update(Graphics g) {
    this.paint(g);
}

public void paint(Graphics g) {
    g.drawImage(buffer, 0, 0, this);
}

现在,当你最小化窗口并再次最大化时,画面仍然存在。只是,窗口的闪烁现在持续了0.1秒左右,但我并不在乎。