简体   繁体   中英

Java - adding JButton array to JFrame

I am trying to add a 2D JButton array to a JFrame, I don't get any errors, just the JButtons don't show up.

Creating the JButtons:

public class TTTGrid {
private static JFrame frame;
private static int[][] coords;
private static int width, height;
public TTTGrid(JFrame frame,int[][] coords, int width, int height){
    this.frame = frame;
    this.coords = coords;
    this.width = width;
    this.height = height;
}
static JButton map[][] = new JButton[3][3];

public void Draw(){
    for(int i = 0; i<coords.length; i++){
        for(int j = 0; j<coords[i].length; j++){
            map[i][j] = new JButton();
            map[i][j].setBounds(i*100, j*100, width, height);
            frame.add(map[i][j]);

        }
    }
}

}

Where the draw method is called:

public class TTTthread extends TTT implements Runnable {
int[][] map = new int[3][3];
TTTGrid grid = new TTTGrid(frame, map, 100, 100);

@Override
public void run() {
    try {
        while (true) {
            grid.Draw();

            Thread.sleep(20);

        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

If your code is running like I think it's running, you appear to be trying to add 9 JButtons to your GUI 50 times a second! That's a heck of a lot of buttons -- are you sure that this is what you want to be doing? Your code also runs far afoul of Swing threading rules by making Swing calls (a lot of Swing calls!) off of the Swing event thread.

Your main solution is likely to

  • Add your 9 JButtons to a JPanel that uses a GridLayout(3, 3)
  • Do this only once not 50 times a second
  • Then add that JPanel to your GUI, BorderLayout.CENTER and to be sure not to use null layouts.
  • Not try to set the bounds, size or locations of these JButtons, but rather to let the layout managers to the work
  • Get rid of that while loop and instead change your code to be more event-driven using Swing's event driven model.
  • Strive to use mostly non-static variables and methods so that your classes become true OOPS-compliant classes, allowing them to take advantage of the benefits of OOPS programming, including reducing program complexity and interconnectedness (reduce coupling).

For example

import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.*;
import javax.swing.*;

public class MyTttFoo extends JPanel {
   // it's OK for constants to be static
   private static final long serialVersionUID = 1L;
   private static final int ROWS = 3;

   // use a larger Font to make buttons larger
   private static final Font BTN_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 60);
   private static final String BLANK = "   ";
   private static final String X = "X";
   private static final String O = "O";

   // but not most variables
   private JButton[][] buttonGrid = new JButton[ROWS][ROWS];

   public MyTttFoo() {
      setBackground(Color.black);

      // use layout managers to help you create your GUI
      setLayout(new GridLayout(ROWS, ROWS, 1, 1));
      ActionListener btnListener = new ButtonListener();
      // create your buttons and add them only **once**
      for (int row = 0; row < buttonGrid.length; row++) {
         for (int col = 0; col < buttonGrid[row].length; col++) {
            JButton button = new JButton(BLANK);
            button.setFont(BTN_FONT);
            button.addActionListener(btnListener);
            add(button);  // add button to a gridlayout using component
            buttonGrid[row][col] = button; // and assign into the array
         }
      }
   }

   private class ButtonListener implements ActionListener {
      private boolean xTurn = true;

      @Override
      public void actionPerformed(ActionEvent e) {
         AbstractButton btn = (AbstractButton) e.getSource();
         String txt = btn.getText();
         if (txt.equals(BLANK)) {
            if (xTurn) {
               btn.setText(X);
            } else {
               btn.setText(O);               
            }
            xTurn = !xTurn;
         } 
      }
   }

   private static void createAndShowGui() {
      MyTttFoo mainPanel = new MyTttFoo();

      JFrame frame = new JFrame("MyTttFoo");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM