不使用JLabel调整图像大小

时间:2016-05-24 18:00:48

标签: java swing

我正在编写一个River-Raid-Like游戏,所有图像都是用g.drawImage(...)绘制的。 我的问题是:当有人调整JFrame的大小时,如何保持内容宽高比,并缩放内容以适应新的窗口大小?

有这样的选择吗?我可以在不使用JLabel和布局的情况下执行此操作吗?如果没有,如何以其他方式做到这一点?

我在JPanel上绘制内容的代码

 private void doDrawing(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        drawStrings(g2);
        mapa.drawMap(g2);
        ArrayList ms = craft.getMissiles();

        for (Object m1 : ms) {
            Missile m = (Missile) m1;
            g2.drawImage(m.getImage(), m.getX(), m.getY(), this);
        }
        g2.drawImage(craft.getImage(), craft.getX(), craft.getY(), this);
        for (EnemyJet enemy : enemies) {
            g2.drawImage(enemy.getImage(), enemy.getX(), enemy.getY(), this);
        }
        for (Fuel fuel : fuels) {
            g2.drawImage(fuel.getImage(), fuel.getX(), fuel.getY(), fuel.getHeight(), fuel.getHeight(), this);
        }
        for (Obstacle o : obst) {
            g2.drawImage(o.getImage(), o.getX(), o.getY(), this);
        }
        drawStrings(g2);
    }

也是Jpanel构造函数:

  private void initBoard() {
        addKeyListener(new TAdapter());
        setFocusable(true);
        setBackground(Color.WHITE);
        setLayout(new GridBagLayout());
        craft = new Craft(ICRAFT_X, ICRAFT_Y);
        mapa = new Mapa();
        setMinimumSize(new Dimension(WIDTH, HEIGHT));
        initEnemiesAndAddThem();
        czas = new Timer(delay, this);
        czas.start();
    }

JFrame构造函数:

 private void initGame()
    {
        add(new Plansza());
        setTitle("Reeevah Raaid");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(WIDTH, HEIGHT);
        setPreferredSize(new Dimension(WIDTH, HEIGHT));
        setLocationRelativeTo(null);
        pack();
        setVisible(true);
        //setExtendedState(JFrame.MAXIMIZED_BOTH);
        //setResizable(false);
    }

2 个答案:

答案 0 :(得分:1)

你可以扩展整个事物:

private void doDrawing(Graphics g) {
    Graphics2D g2 = (Graphics2D) g;

    AffineTransform originalTransform = g2.getTransform();
    g2.scale(getWidth() / (double) WIDTH, getHeight() / (double) HEIGHT);

    // Do all drawing here

    g2.setTransform(originalTransform);
}

一些注意事项:

  • 最后g2.setTransform(originalTransform)很重要。 Graphics对象不属于您 - 它可能用于绘制其他组件,因此您需要将其保留为给它时的状态。
  • WIDTH和HEIGHT需要转换为double,因为在Java中,如果除法运算的任何操作数是double,结果是double,但如果它们都是int,则执行整数除法,这绝对不是什么你要。 (例如,3 / (double) 2为1.5,但3 / 2正好为1。)

答案 1 :(得分:0)

需要按如下方式绘制任何图像:

  double fct=1.0*image.getWidth()/getWidth();
  double fct2=1.0*image.getHeight()/getHeight();
  if(fct2>fct) fct=fct2;
  g2.drawImage(image, x, y, (int)(1.0*image.getWidth()/fct), (int)(1.0*image.getHeight()/fct), this);

这会留下很多空白区域 - 但是如果你想保持宽高比的话。

-

要使图像居中,请执行以下操作:

int newWidth=(int)(1.0*image.getWidth()/fct);
int newHeight=(int)(1.0*image.getHeight()/fct);
g2.drawImage(image, getWidth()/2-newWidth()/2, getHeight()/2-newHeight()/2, newWidth, newHeight, this);