Java - JFrame, JPanel, Layout и Clipping - PullRequest
       40

Java - JFrame, JPanel, Layout и Clipping

4 голосов
/ 04 октября 2010

У меня три вопроса / проблемы.(ПРИМЕЧАНИЕ. У меня недостаточно репутации, чтобы публиковать фотографии, поэтому я связал их. И мне нужно было их запутать ...)

1) Я создал панель с графикой игры (область игрока).Предполагается, что панель имеет размер 800x800 и обрезает все, что находится внизу и справа.Но когда я добавляю графическую панель в JFrame, она не обрезается.Таким образом, изображения идут справа и слева.Это картина о том, как начинается игра.В идеале графика должна начинаться в этом прямоугольнике все время:

Изображение №1: http://i.stack.imgur.com/idL8f.png

Теперь вот что происходит, когда я нажимаю кнопку воспроизведения, чтобы начать.

Изображение № 2: http://i.stack.imgur.com/dxtbe.png

Как настроить панель / рамку таким образом, чтобы графика занимала только 800x800 (как на первом изображении), а все остальное обрезалось?1014 * 2) Я немного озадачен тем, как я могу настроить JFrame.Вот как я хочу, чтобы он был выложен:

Рисунок №3: http://i.stack.imgur.com/ZyJS5.png

Как бы вы выложили JFrame / Panels?Я думал о BorderLayout, но я не уверен, что это сработает.

3) В этой игре мой класс, который расширяет JFrame, также содержит main ().Это плохая практика? ** Вы не должны распространять JFrame на основной класс?

1 Ответ

3 голосов
/ 04 октября 2010

1) Самый простой способ получить панель 800x800 - это использовать setPreferredSize(), а затем pack() JFrame, который содержит. Удобно, pack() "Приводит размер Window к предпочтительному размеру и расположению его подкомпонентов."

2). См. Визуальное руководство для менеджеров по макету для предложений по компоновке. Вы можете использовать вложенные панели для достижения желаемого макета.

3). В расширении JFrame нет ничего неправильного , но нет никакого смысла, если вы не изменяете поведение из JFrame. Напротив, JPanel - это удобный контейнер для группировки компонентов; он был разработан для расширения. Вы можете изучить этот пример в этом отношении.

Добавление:

Я не хочу, чтобы на панели отображалось что-либо, кроме 800 пикселей в направлении x и y.

Вы можете переопределить paintComponent() и скопировать любую часть изображения. В приведенном ниже примере g.drawImage(img, 0, 0, null) рисует верхние левые 800 пикселей изображения, а g.drawImage(img, 0, 0, getWidth(), getHeight(), null) масштабирует изображение до размера панели. Обратите внимание, что f.setResizable(false) предотвращает изменение размера окна.

Добавление: вы также можете копировать произвольные части исходного изображения в произвольные области панель назначения, как показано ниже.

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

/** @see http://stackoverflow.com/q/3851847 */
public class MyPanel extends JPanel {

    private BufferedImage img;

    public MyPanel() {
        this.setPreferredSize(new Dimension(800, 800));
        try {
            img = ImageIO.read(new File("../scratch/image.png"));
        } catch (IOException ex) {
            ex.printStackTrace(System.err);
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
//        g.drawImage(img, 0, 0, 800, 800, null);
//        g.drawImage(img, 0, 0, getWidth(), getHeight(), null);
        g.drawImage(img, 0, 0, 800, 800, 0, 0, 800, 800, this);
    }

    private void display() {
        JFrame f = new JFrame("MyPanel");
//        f.setResizable(false);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new MyPanel().display();
            }
        });
    }
}
...