Как добавить кнопку в Canvas без изменения размера кнопки?

Я работаю на экране входа в мою игру. У меня есть два изображения. Один скриншот заставки, а другой фоновое изображение. Я использую BufferedImages для рендеринга изображений на экран.

Проблема, которую я получаю, заключается в том, что когда я добавляю стандартную кнопку в Canvas, кнопка занимает все окно, и, очевидно, я этого не хочу.

Я бы опубликовал фотографию, но, увы, у меня нет "достаточно репутации", чтобы сделать это. Вот посмотрите на мой код:

import java.awt.Button;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.TextField;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;

import javax.swing.JFrame;
import javax.swing.UIManager;

public class Login extends Canvas implements Runnable {

private static final long serialVersionUID = 1L;

private static final int WIDTH = 495;
private static final int HEIGHT = 307;
private static final int SCALE = 2;
private final Dimension size = new Dimension(WIDTH * SCALE, HEIGHT * SCALE);

private BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
public int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();

private BufferedImage splash = new BufferedImage(315, 177, BufferedImage.TYPE_INT_RGB);
public int[] splashPixels = ((DataBufferInt) splash.getRaster().getDataBuffer()).getData();

private Thread thread;
public static boolean isRunning = false;

JFrame frame;
MainMenu menu;
Splash splashscreen;

Button login;
Button register;
TextField username;

private Login() {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception exc) {
        exc.printStackTrace();
    }

    frame = new JFrame("Game Login");
    menu = new MainMenu(WIDTH, HEIGHT, "/login/login_screen.png");
    splashscreen = new Splash(315, 177, "/login/splash.png");

    frame.setSize(size);
    frame.setVisible(true);
    frame.setResizable(false);
    frame.setLocationRelativeTo(null);

    setPreferredSize(size);
    frame.add(this);

    login = new Button("Login");
    login.setBounds(0, 0, getWidth(), getHeight());

    frame.add(login);

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

private void begin() {
    createBufferStrategy(2);
    thread = new Thread(this);
    thread.start();
    isRunning = true;
}

private void finish() throws InterruptedException {
    isRunning = false;
    thread.join();
}

private void updateLogin() {
    for (int a = 0; a < pixels.length; a++) {
        pixels[a] = menu.pixels[a];
    }
}

private void renderLogin() {
    BufferStrategy buffer = getBufferStrategy();
    Graphics gfx = buffer.getDrawGraphics();

    for (int a = 0; a < splashPixels.length; a++) {
        splashPixels[a] = splashscreen.splashPixels[a];
    }

    gfx.drawImage(image, 0, 0, getWidth(), getHeight(), null);
    gfx.drawImage(splash, 320, 37, 625, 340, null);

    gfx.setColor(Color.WHITE);
    gfx.drawString("Game Co © 2013", 3, (getHeight() - 4));
    gfx.drawString("\"Game\" is a trademark of Blah-Blah-Blah.", (getWidth() - 268), (getHeight() - 3));

    gfx.dispose();
    buffer.show();
}

public void run() {
    while (isRunning == true) {
        updateLogin();
        renderLogin();
    }

    try {
        finish();
    } catch (InterruptedException exc) {
        exc.printStackTrace();
    }
}

public static void main(String[] args) {
    Login login = new Login();
    login.begin();
}
}

Еще раз, моя единственная проблема в том, что я продолжаю получать увеличенную кнопку.

Спасибо заранее, я знаю, что вы, ребята, заняты, и еще много чего, и я благодарен, что нашел время посмотреть и помочь ответить на мои вопросы.

PS Кто-нибудь знает, как сделать поле пароля с AWT? Мне тоже это нужно.;)

2 ответа

Решение

Решение: сначала добавьте свой JButton (снова используйте компоненты Swing) в JPanel (который по умолчанию использует FlowLayout), а затем добавьте его в окно верхнего уровня.

Вы можете просто изменить менеджер макета для своего фрейма на FlowLayout, чтобы он вел себя как JPanel.

frame.setLayout(new FlowLayout());

Вы заявляете:

Проблема, которую я получаю, заключается в том, что когда я добавляю стандартную кнопку в Canvas, кнопка занимает все окно, и, очевидно, я этого не хочу.

Вы пытаетесь добавить компонент непосредственно в контейнер, который использует BorderLayout, вероятно, в contentPane окна верхнего уровня, и поэтому по умолчанию добавляется BorderLayout.CENTER и заполняет контейнер.

Решение: сначала добавьте свой JButton (снова используйте компоненты Swing) в JPanel (который по умолчанию использует FlowLayout), а затем добавьте его в окно верхнего уровня.

Опять же, нет необходимости смешивать компоненты AWT и Swing, и на самом деле есть веские аргументы не делать этого. Я предлагаю вам придерживаться всех компонентов Swing для вашего графического интерфейса.


Кто-нибудь знает, как сделать поле пароля с AWT? Мне тоже это нужно.;)

Опять же, не используйте AWT, а вместо этого используйте Swing JPasswordField.

Другие вопросы по тегам