Проблема с Java GridLayout и добавлением кнопок - PullRequest
0 голосов
/ 14 октября 2018

Я хочу добавить 100 кнопок в GridLayout, и мой код работает, но иногда он добавляет только одну кнопку, и если я нажимаю, где остальные кнопки принадлежат, появляется кнопка, на которой я нажал.это происходит совершенно случайно, и я не понимаю.Вот мой код:

    public class GamePanel extends JPanel {
    GameUI controler;
    GridLayout gameLayout = new GridLayout(10,10);
    JButton gameButtons[] = new JButton[100];
    ImageIcon ice;
    JButton startButton;
    JButton exitButton;
    ImageIcon startIcon;
    ImageIcon exitIcon;
    URL urlIcon;
    private int i;

    public GamePanel(GameUI controler) {
        this.setLayout(gameLayout);
        this.controler = controler;
        urlIcon = this.getClass().getResource("/icons/Overlay.png");
        ice = new ImageIcon(urlIcon);
        makeButtons();
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
    }

    public void makeButtons() {
        for(i = 0; i< 100; i++) {
            gameButtons[i] = new JButton(ice);
            this.add(gameButtons[i]);
            revalidate();   
        }
        repaint();
    }
}

обновление:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.net.URL;


public class GameUI extends JFrame {

ImageIcon i;
Image jFrameBackground;
JButton startButton;
JButton exitButton;
ImageIcon startIcon; 
ImageIcon exitIcon;


public GameUI() {
    setResizable(false);
    this.setSize(1200, 800);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    this.setLayout(null);








    BackGroundPanel backGroundPanel = new BackGroundPanel();
    GamePanel panel = new GamePanel(this);
    ButtonPanel buttonPanel = new ButtonPanel();

    panel.setSize(500,500);
    panel.setLocation(100, 150);
    backGroundPanel.setSize(this.getWidth(),this.getHeight());
    backGroundPanel.setLocation(0,0);
    buttonPanel.setSize(390,50);
    buttonPanel.setLocation(100,100);
    this.add(backGroundPanel);
    this.add(panel);
    this.add(buttonPanel);




    backGroundPanel.setBackground(Color.BLACK);



}





public static void main(String[] args) throws InvocationTargetException, InterruptedException {







    javax.swing.SwingUtilities.invokeAndWait(
                new Runnable(){

                    @Override
                    public void run() {



                        GameUI ui = new GameUI();
                        ui.setVisible(true);


                    }


                }

            );




}

}

1 Ответ

0 голосов
/ 14 октября 2018

Как я уже упоминал в комментариях, вы используете пустой макет, и это источник ваших проблем.

Вы используете нулевой макет, чтобы попытаться наложить JPanels, один поверхдругое, и это не то, как это должно использоваться или для чего, ни как вы должны создавать фоны.Это имеет эффект фона, покрывающего ваши кнопки, пока ваша мышь не наведет на них курсор.

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

  • создатьJPanel, скажем, называется BackgroundPanel,
  • переопределяет свой метод paintComponent,
  • вызывает его super.paintComponent(g); в первой строке вашего метода
  • , затем рисует изображение, которое должно отображаться
  • затем дайте ему достойный менеджер компоновки
  • и добавьте к нему компоненты GUI
  • Убедитесь, что все добавленные в него JPanelsстановится прозрачным с помощью .setOpaque(false)

Другие варианты включают использование JLayeredPane, но вам действительно не нужно это просто иметь фон.

Например, следующий код производит:

enter image description here

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

public class GameUI2 {

    private static final String IMG_PATH = "https://upload.wikimedia.org/wikipedia/commons/3/3f/"
            + "Butterfly_Nebula_in_narrow_band_Sulfur%2C_Hydrogen_and_Oxygen_Stephan_Hamel.jpg";
    private static final String BTN_IMG_PATH = "https://upload.wikimedia.org/wikipedia/commons/5/54/Crystal_Project_Games_kids.png";

    private static void createAndShowGui() {
        BufferedImage bgImg = null;
        BufferedImage btnImg = null;
        try {
            URL bgImgUrl = new URL(IMG_PATH);
            URL btnImgUrl = new URL(BTN_IMG_PATH);
            bgImg = ImageIO.read(bgImgUrl);
            btnImg = ImageIO.read(btnImgUrl);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(-1);
        }


        BackgroundPanel2 mainPanel = new BackgroundPanel2(bgImg);
        mainPanel.setLayout(new GridBagLayout());
        GamePanel2 gamePanel = new GamePanel2(btnImg); 
        mainPanel.add(gamePanel);        

        JFrame frame = new JFrame("Game");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.setResizable(false);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

@SuppressWarnings("serial")
class BackgroundPanel2 extends JPanel {
    private Image backgroundImg;

    public BackgroundPanel2(Image backgroundImg) {
        this.backgroundImg = backgroundImg;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (backgroundImg != null) {
            g.drawImage(backgroundImg, 0, 0, this);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet() || backgroundImg == null) {
            return super.getPreferredSize();
        } else {
            int w = backgroundImg.getWidth(this);
            int h = backgroundImg.getHeight(this);
            return new Dimension(w, h);
        }
    }
}

@SuppressWarnings("serial")
class GamePanel2 extends JPanel {
    public static final int MAX_BUTTONS = 100;
    private static final int IMG_WIDTH = 40;
    JButton[] gameButtons = new JButton[MAX_BUTTONS];

    public GamePanel2(Image buttonImg) {
        setOpaque(false);
        if (buttonImg.getWidth(this) > IMG_WIDTH) {
            buttonImg = buttonImg.getScaledInstance(IMG_WIDTH, IMG_WIDTH, Image.SCALE_SMOOTH);
        }
        Icon icon = new ImageIcon(buttonImg);
        setLayout(new GridLayout(10, 10, 4, 4));
        for (int i = 0; i < gameButtons.length; i++) {
            int finalIndex = i;
            JButton btn = new JButton(icon);
            btn.addActionListener(e -> {
                String text = String.format("Button: %02d", finalIndex);
                System.out.println(text);
            });
            add(btn);
            gameButtons[i] = btn;            
        }
    }
}
...