3

我有一个带有 Canvas 的 jFrame。当我在 Windows XP/Vista 中运行我的程序并调整窗口大小时,画布会与窗口一起按比例调整大小。

但是,在 Ubuntu linux 中,当我编译相同的 java 应用程序并调整窗口大小时,Canvas 的大小保持不变。

在 Windows 和 Linux 中,我需要做什么才能使 Canvas 与我的窗口一起调整大小?与差异有什么关系?

主.java

public class Main {
    public static void main(String[] args)
    {
        JFrame frame = new JFrame("BallBounce");
        frame.setDefaultCloseOperation(Jframe.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(),BoxLayout.Y_AXIS));

        BallCanvas ballCanvas = new BallCanvas();

        frame.getContentPane().add(ballCanvas);
        frame.getContentPane().add(controlPanel);
        frame.pack();
        frame.setVisible(true);
    }
}

BallCanvas.java

public class BallCavnas extends Canvas {
    public BallCanvas()
    {
        setPreferredSize(new Dimension(640, 400));
        setIgnoreRepaint(true);

        ... various gui controls are wired up here
    }
    ... rest of canvas code
}

编辑:我的源代码被压缩在这里以防有人想看看:
http ://www.filedropper.com/ballbounce

我已经完成了 Dave Ray 的建议,但它仍然没有调整 Canvas 的大小?请记住,当我编译这个 java 程序并在 Windows 中运行它时,它可以很好地调整大小。只有在 linux 中它才会对我这样做。如果重要的话,我也在运行 Java 6 Sun 1.6.0.10 JVM。

替代文字 http://img158.imageshack.us/img158/7642/screenshotww0.png

也许我的画布正在通过我的BufferStrategy/Graphics不调整大小来调整大小?

编辑 2:从截图来看,它肯定设置为 CENTER:

frame.getContentPane().add(ballCanvas, BorderLayout.CENTER);
frame.getContentPane().add(controlPanel, BorderLayout.SOUTH);

解决

显然“画布”正在调整大小,但我用它的缓冲策略做了一些奇怪的事情,它不允许调整 IT 的大小。我修好了它。感谢大家!

4

4 回答 4

3

也许,布局管理器只是试图尊重您的首选尺寸。

我会:

A)删除首选只是为了看看会发生什么(无论如何都不是一个好主意)

或者

B)首先不使用画布,而是使用 JComponent。毕竟 Canvas 是 AWT 组件,我不太确定它们现在是如何工作的。JComponent 是一个轻量级组件,并且由于您使用 JComponent 作为容器,它们会... mmhhh 一起工作得更好?

哎呀..我现在正在给巫毒编程建议。最好去上班。

C) 一直对我有用的东西。通过在我的代码中逐步添加内容来做一个小的概念证明。从空画布开始,然后添加首选大小,然后等等等等。机会是,错误在绘制方法上:P

祝你好运。

:)

于 2009-01-22T05:47:16.030 回答
2

改用边框布局:

frame.getContentPane().setLayout(new BorderLayout());
BallCanvas ballCanvas = new BallCanvas();
frame.getContentPane().add(ballCanvas, BorderLayout.CENTER);            
frame.getContentPane().add(controlPanel, BorderLayout.SOUTH);

也摆脱 setPreferredSize() 支持 frame.setSize() 来设置显示的初始大小。

于 2009-01-22T04:48:14.373 回答
2

另一个好的解决方案是将画布放入 JPanel 中,就像我做的那样

    panel.add(new JPanel() {

        @Override
        public void paint(Graphics g) {
          // do not paint
        }

    }.add(capture));

在画布功能中类似于

@Override
public void paint(Graphics g) {
    Dimension currentSize = getParent().getSize();
    int width = currentSize.width;
    int height = currentSize.height;
    if (offscreenImage == null || !currentSize.equals(offscreenDimension)) {
        // call the 'java.awt.Component.createImage(...)' method to get an
        // image
        offscreenImage = createImage(width, height);
        offscreenGraphics = offscreenImage.getGraphics();
        offscreenDimension = currentSize;
    }

    if (image != null) {
        offscreenGraphics.drawImage(image, 0, 0, width, height, null);
    } else {
        offscreenGraphics.setColor(Color.BLACK);
        offscreenGraphics.fillRect(0, 0, width, height);
    }
    //scratch image
    g.drawImage(offscreenImage, 0, 0, this);
}

例如。这使它非常简单。带上父面板以满足您的需求。

于 2011-12-29T00:29:17.633 回答
1

如果你听从了戴夫的建议,尤其是。将 ballCanvas 放在 CENTER 中,那么您必须为 ballCanvas 设置最大尺寸。

于 2009-01-22T05:38:57.967 回答