Buttons not fully loading in GridLayout - java

Im trying to make a 17 by 17 GridLayout board, but when i run the code the board that i generated is messed up and looks like this instead of a 17 by 17 button board:
So my question is why is the board displaying weird like this, and how do i get it to display the 17 by 17 button board that i want?
here is the code i am using:
public class TheJFrame {
public static final char[][] board = new char[17][17];
public static class TheJFramez {
JFrame boardz = new JFrame("Game of Life");
JPanel panel = new JPanel();
public TheJFramez(){
int r = 0,c;
boardz.setLayout(new GridLayout(board.length,board[r].length,1,1));
for(r=0;r<board.length;r++){
for(c = 0;c<board[r].length;c++){
JButton tats = new JButton(" " + board[r][c] + " ");
panel.add(tats);
}
}
boardz.add(panel);
boardz.setVisible(true);
boardz.setSize(1200, 700);
boardz.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
}
public static void main(String[] args) {
new TheJFramez();
}
}

In this code, You have set the Layout of 'boardz' to GridLayout while you are adding the buttons to 'panel' who's layout is not specified so, it is taking default layout , when you add the panel to 'boardz', the panel will be arranged in grid layout, While the components of 'panel' would still be in the default layout.
So, you want to add the JButton to boardz and there is no use of panel.
Here is the correct code :-
import java.awt.*;
import javax.swing.*;
public class TheJFrame {
public static final char[][] board = new char[17][17];
public static class TheJFramez {
JFrame boardz = new JFrame("Game of Life");
JPanel panel = new JPanel();
public TheJFramez(){
int r = 0,c;
boardz.setLayout(new GridLayout(board.length,board[r].length));
for(r=0;r<17;r++){
for(c = 0;c<17;c++){
JButton tats = new JButton(" " + board[r][c] + " ");
boardz.add(tats);
System.out.print(board[r][c]);
}
System.out.println();
}
boardz.setVisible(true);
boardz.setSize(1200, 700);
boardz.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
}
public static void main(String[] args) {
new TheJFramez();
}
}

shubham you are right but the frame take default layout which is flowlayout. So they are arrange in linear way.so u can just set layout as gridlayout.

Related

How to generate GUI with multiple buttons and incrementing labels on them?

I am trying to generate a GUI using swing that creates a frame with 100 buttons and every button has a "label" on it from on 1 to a 100.
What I have tried:
import javax.swing.*;
import java.awt.*;
public class ButtonScreen extends JFrame{
JFrame frame = new JFrame();
int rows=10;
int cols=10;
JButton[][] button = new JButton[rows][cols];
JTextArea screen = new JTextArea();
JPanel bpanel = new JPanel();
public static void main(String[] args) {
ButtonScreen bs = new ButtonScreen();
bs.setVisible(true);
}// end of main
public ButtonScreen(){
super("Welcome to the ButtonScreen Program!");
setDefaultCloseOperation(EXIT_ON_CLOSE);
bpanel.setLayout(new GridLayout(rows,cols));
for(int i=0;i<button.length;i++){
for(int j=0;j<button.length;j++){
button[i][j]=new JButton(""+i+j);
bpanel.add(button[i][j]);
}
}
add(bpanel);
}//end of constructor
}//end of class
This works just fine, but it creates buttons with "labels" (meaning string parameters at line 26) and also these labels, are not one string or one integer but it is a dillusion of the of i right next to j counter. So my second attempt, after some corrections, was:
import java.awt.*;
import javax.swing.*;
public class LabArr extends JFrame{
JFrame frame = new JFrame();
int rows=10;
int cols= 10;
int i=0;
JButton[][] button = new JButton[rows][cols];
JLabel[] label = new JLabel[100];
public static void main(String[] args) {
LabArr la = new LabArr();
la.setVisible(true);
}//end of main
public LabArr(){
super("title");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new GridLayout(rows,cols));
for(i=0;i<label.length;i++){
label[i]= new JLabel(toString(i));
}
for(int i=0;i<button.length;i++){
for(int j=0;j<button.length;j++){
button[i][j]= new JButton(""+label[j]);
add(button[i][j]);
}
}
}//end of constructor
public String toString(int k){
k=i;
String s;
s=""+k;
return s;
}
}//end of class
My goal using that was to create an array of JLabel objects and then match every JLabel element to one from the JButton array.
So, first of all I would like to know to which object the methods setLayout and setDefaultCloseOperation refer to.
Second, "Does the toString method need to refer to an object at the line I am using it?". And finally, what am I missing?
This will create a single frame with buttons from 1 to 100.
import javax.swing.*;
import java.awt.GridLayout;
public class HundredButtonGrid{
public static void main(String[] args){
JFrame frame = new JFrame("100 buttons");
frame.setLayout(new GridLayout(10, 10));
for(int i = 0; i<100; i++){
frame.add( new JButton( "" + (i + 1) ) );
}
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
I've addressed a few things.
I just use 1 index because the GridLayout takes care of the x/y values.
I used parenthesis to add the index to 1 so that it doesn't end up concatenating them by string.
I've set the default close operation to exit, you can have it do other things too. Like JFrame.DISPOSE_ON_CLOSE so the window will go away, but not terminate the application.
I didn't extend JFrame, I created a separate instance. In your case you have extended JFrame, so when you call setLayout it is being called on the instance you're creating. An alternative way to say it is this.setLayout same with setDefaultCloseOperation.
Hope this will help you with your problem, kindly see the code below:
public class LabArr extends JFrame{
JFrame frame = new JFrame();
int rows=10;
int cols= 10;
int counter = 0;
JButton[][] button = new JButton[rows][cols];
JLabel[] label = new JLabel[rows*cols];
public static void main(String[] args) {
DemoApplication la = new DemoApplication();
la.setVisible(true);
}//end of main
public LabArr(){
super("title");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(new GridLayout(rows,cols));
for(int i=0;i<label.length;i++){
label[i]= new JLabel(toString(i));
}
for(int i=0;i<button.length;i++){
for(int j=0;j<button.length;j++){
button[i][j]= new JButton(counter + "");
add(button[i][j]);
counter++;
}
}
}//end of constructor
public String toString(int k){
String s;
s=""+k;
return s;
}
}
You've been creating the buttons with the label toString() method name.

Java GUI - How to center a single button

I'm very new to java (I'm used to python).
NOTE: I do want the position to stay in the center even when the gui is resized.
I was wondering how I can center a single button? At the moment, the button is at the top of the gui.
public class main_gui extends JFrame{
public static void main(String[] args) {
// Initial window
JFrame start_frame = new JFrame("P.D");
start_frame.setSize(1200, 800);
start_frame.setVisible(true);
start_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Panel to hold our buttons
JPanel start_panel = new JPanel();
start_frame.add(start_panel);
// Button to initialize everything
JButton start_button = new JButton("Start");
// Take out the border around the text
start_button.setFocusable(false);
start_panel.add(start_button);
}
}
Here is what is currently looks like, I just want this button down a bit, to the center.
There is no need for the panel. Just add the button directly to the frame.
The easiest way is to use a GridBagLayout:
frame.setLayout( new GridBagLayout() );
frame.add(startButton, new GridBagConstraints());
By default the component will be centered horizontally and vertically within the GridBagLayout.
A quick solution would be to set the vertical gap between components of your FlowLayout to half the size of your JFrame:
public class MainGUI {
static java.awt.Dimension bd;
public static void main(String[] args) {
// Initial window
JFrame start_frame = new JFrame("P.D");
start_frame.setSize(1200, 800);
start_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Button to initialize everything
JButton start_button = new JButton("Start");
bd = start_button.getPreferredSize();
// Take out the border around the text
start_button.setFocusable(false);
// Panel to hold our buttons
java.awt.Dimension d = start_frame.getSize();
JPanel start_panel = new JPanel(new java.awt.FlowLayout(FlowLayout.CENTER, 0, d.height / 2 - bd.height / 2));
start_panel.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent evt) {
JPanel c = (JPanel) evt.getSource();
c.setLayout(new java.awt.FlowLayout(FlowLayout.CENTER, 0, c.getSize().height / 2 - bd.height / 2));
}
});
start_panel.add(start_button);
start_frame.add(start_panel);
start_frame.setVisible(true);
}
}
When the size of your JFrame is changed, the ComponentAdapter recalculates the new height and places the button to the new center.
In order to place the button to the vertical center, we calculate the height of your button and subtract its half from the vertical gap.
The horizontal center is automatically applied by the layout.
Your class should not extend JFrame if you instantiate another JFrame inside it and use it.
Class names should be nouns, in mixed case with the first letter of each internal word capitalized.
It is recommended to make your JFrame visible after you have added all widgets to it.
In order to use the SwingUtilities invoker and make your application code cleaner, let your class extend JFrame, write a constructor and call it this way:
public class MainGUIJFrame extends JFrame {
public MainGUIJFrame() {
initComponents();
}
private void initComponents() {
setTitle("P.D");
setSize(1200, 800);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
start_button = new JButton("Start");
bd = start_button.getPreferredSize();
// Take out the border around the text
start_button.setFocusable(false);
java.awt.Dimension d = getSize();
start_panel = new JPanel(new java.awt.FlowLayout(FlowLayout.CENTER, 0, d.height / 2 - bd.height / 2));
start_panel.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent evt) {
JPanel c = (JPanel) evt.getSource();
c.setLayout(new java.awt.FlowLayout(FlowLayout.CENTER, 0, c.getSize().height / 2 - bd.height / 2));
}
});
start_panel.add(start_button);
add(start_panel);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new MainGUIJFrame().setVisible(true);
}
});
}
private JButton start_button;
private JPanel start_panel;
private java.awt.Dimension bd;
}
You keep main simple and small this way, and bd does not have to be static anymore.
You can use a layout manager like BorderLayout if you want to put the button in the center so that it occupies the whole space in the frame. So, your code will look something like this:
public class main_gui extends JFrame{
public static void main(String[] args) {
// Initial window
JFrame start_frame = new JFrame("P.D");
start_frame.setSize(1200, 800);
start_frame.setVisible(true);
start_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Panel to hold our buttons
JPanel start_panel = new JPanel();
start_panel.setLayout(new BorderLayout());
start_frame.add(start_panel);
// Button to initialize everything
JButton start_button = new JButton("Start");
// Take out the border around the text
start_button.setFocusable(false);
start_panel.add(start_button, BorderLayout.CENTER);
}
}
You may go without using a layout manager. It's a bad practice but it should work. This code will put a small button in the center of the frame:
public class MainGUI {
public static void main(String[] args) {
JFrame start_frame = new JFrame("P.D");
int width = 1200;
int height = 800;
start_frame.setSize(width, height);
start_frame.setVisible(true);
start_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Panel to hold our buttons
JPanel start_panel = new JPanel();
start_panel.setLayout(null);
start_frame.add(start_panel);
// Button to initialize everything
JButton start_button = new JButton("Start");
buttonWidth = 80;
buttonHeight = 20;
start_button.setBounds(new Rectangle((width - buttonWidth)/2, (height - buttonHeight)/2, buttonWidth, buttonHeight));
start_button.setSize(new Dimension(buttonWidth, buttonHeight));
start_button.setFocusable(false);
start_panel.add(start_button);
}
}
The best way to do it is to use a Layout of your choice and try to make it work using that.
However, if you are sure your window won't be getting resized, or you're happy to deal with such events yourself, you could attempt working without a layout and position the button manually, e.g.:
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.Dimension;
public class main_gui {
public static void main(String[] args) {
// Initial window
JFrame start_frame = new JFrame("P.D");
int FrameWidth = 1200, FrameHeight = 800;
start_frame.setSize(FrameWidth, FrameHeight);
start_frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Panel to hold our buttons
JPanel start_panel = new JPanel();
start_panel.setLayout(null); // Now working without a layout manager
// i.e, can position things manually.
start_frame.add(start_panel);
// Button to initialize everything
JButton start_button = new JButton("Start");
start_button.setFocusable(false); // Take out the border around the text
Dimension size = start_button.getPreferredSize();
start_button.setBounds( FrameWidth/2 - size.width/2,
FrameHeight/2 - size.height/2,
size.width, size.height);
start_panel.add(start_button);
// Display the Layout after all components have been added.
// (adding components after the frame has been set to visible
// may result in components not showing up reliably!)
start_frame.setVisible(true);
}
}

Swing gui not displaying, but no errors?

I am working on a java program that solves sudoku puzzles. So far all I have coded is a class that draws the board with swing, and another class that calls the gui class.
When I try and run the program nothing happens. No error messages are shown, but the gui doesn't show either. It immediately terminates.
Here is my code so far:
Gui class:
package sudoku;
import java.awt.*;
import javax.swing.*;
public class Gui {
Gui gui;
JPanel board;
JPanel subBoard[][];
GridLayout layout;
JLabel square[][];
public void load() {
gui = new Gui();
gui.setUp();
gui.buildBoard();
}
private void setUp() {
layout = new GridLayout(3, 3);
board = new JPanel(layout);
subBoard = new JPanel[3][3];
square = new JLabel[9][9];
}
private void buildBoard() {
// set up board
board.setSize(800, 600);
board.setVisible(true);
int mod = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
// add subBoards to board
subBoard[i][j] = new JPanel();
board.add(subBoard[i][j]);
subBoard[i][j].setLayout(layout);
subBoard[i][j].setVisible(true);
// add textfields to each subBoard
square[i + mod][j + mod] = new JLabel();
subBoard[i][j].add(square[i + mod][j + mod]);
square[i + mod][j + mod].setVisible(true);
}
mod += 3;
}
}
}
main class:
package sudoku;
public class SudokuSolver {
public static void main(String[] args) {
Gui gui = new Gui();
gui.load();
}
}
I tried running it in both eclipse and netbeans but got the same result both times. Why does this not work?
There is no displayable window such as a JFrame being used in the application.
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("New GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Gui gui = new Gui();
gui.load();
frame.add(gui.getBoard()); // add getBoard getter
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
Remove the class member variable gui within Gui. This is shadowing variables in the outer class Gui so use the latter instead. Also override getPreferredSize to give the board a size when frame.pack() is invoked.
Make GUI extend JFrame firstly. Then in your main method call gui.setVisible(true);.
public class Gui extends JFrame { }
Then in main.
Gui gui = new Gui();
gui.load();
gui.setVisible(true);
You can not show directly Jpanel. for show gui you must use JFrame or any other Window class(JDialog, JWindow...) and after that set visible property true.
setVisible(true);
public class Gui extends JFrame {
Gui(){
...
setVisible(true);
setSize(300,400);
}
...
}

How to embed a grid layout inside a border layout in java

I have a border layout and I want to add a grid layout to the center section. However, I can't declare a grid and then add my center border. How can I do this?
public Liability_Calculator(String s)
{
super(s);
setSize(325,200);
c = getContentPane();
c.setLayout(new BorderLayout());
//the top label
total = new JLabel("Total monthly liabilities ", JLabel.CENTER);
c.add(total, BorderLayout.NORTH);
//the grid
GridLayout grid = new GridLayout(2,2);
text_field1 = new JTextField(7);
//I GET AN ERROR HERE!!!!!!!
grid.add(text_field1);
//AND ERROR HERE!!!!!!!!!!!!!
c.add(grid, BorderLayout.CENTER);
setVisible(true);
}
You're trying to add a component to a layout, and that simply cannot be done. Instead use a JPanel, give it a GridLayout, and then add the component to the JPanel (acting as the "container" here).
In general, you will want to nest JPanels with each using the best layout for the GUI, here the inner JPanel using GridLayout and the outer one using BorderLayout. Then you simply add the inner JPanel to the outer one (here your contentPane) in the BorderLayout.CENTER position.
Providing code visualization derived from Hovercraft's answer:
Display class:
public class Display extends JFrame {
JPanel gridHolder = new JPanel(); // panel to store the grid
private GridLayout buttonsGrid; // space containing a buttons
private JButton myButtons[]; // grid is to be filled with these buttons
private BorderLayout mainGUILayout; // main gui layout
private Container mainGuiContainer;
public Display() {
mainGUILayout = new BorderLayout(5,5); // Border layout option
mainGuiContainer = getContentPane(); // getting content pane
mainGuiContainer.setLayout(mainFrameLayout); // setting main layout
buttonsGrid = new GridLayout(4, 1, 5, 5); // 4 buttons one over the other
myButtons = new JButton[4]; // player's hand represented with buttons
gridHolder.setLayout(buttonsGrid);
for (int x = 0; x < 4; x++) {
myButtons[x] = new JButton (" ");
gridHolder.add(myButtons[x]); }
add(gridHolder, BorderLayout.WEST);
setVisible(true); } }
MainGUILaunch class:
public class MainGUILaunch {
public static void main (String args[]) {
Display myApplication = new Display();
myApplication.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myApplication.setSize(1024, 1024);
myApplication.setVisible(true); // displaying application }
} // End of MainGUILaunch

Problem with setVisible (true)

The two examples shown below are same. Both are supposed to produce same result e.g. generate the coordinates of images displayed on JPanel.
Example 1, works perfectly (print the coordinates of images), however example 2 returning 0 for the coordinate.
I was wondering why because, I have put the setvisible (true) after adding the panel, in both examples. The only difference is that example 1 used extends JPanel and example 2 extends JFrame
EXAMPLE 1:
public class Grid extends JPanel{
public static void main(String[] args){
JFrame jf=new JFrame();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
final Grid grid = new Grid();
jf.add(grid);
jf.pack();
Component[] components = grid.getComponents();
for (Component component : components) {
System.out.println("Coordinate: "+ component.getBounds());
}
jf.setVisible(true);
}
}
EXAMPLE 2:
public class Grid extends JFrame {
public Grid () {
setLayout(new GridBagLayout());
GridBagLayout m = new GridBagLayout();
Container c = getContentPane();
c.setLayout (m);
GridBagConstraints con = new GridBagConstraints();
//construct the JPanel
pDraw = new JPanel();
...
m.setConstraints(pDraw, con);
pDraw.add (new GetCoordinate ()); // call new class to generate the coordinate
c.add(pDraw);
pack();
setVisible(true);
}
public static void main(String[] args) {
new Grid();
}
}
The problem is that in the second example, you are trying to print out the bounds of a component before the component has been added to its container (by calling add()) and before the frame's contents have been laid out (by calling pack()).
Here is my attempt to reproduce Example 1. ...
Here is my attempt to reproduce Example 2. I added the SwingUtilities call to put things in the right thread, and I filled in the contents of the GetCoordiates constructor with help from your comments:
class GetCoordinate extends JLabel {
public GetCoordinate() {
setText("Foo!");
System.out.println("Coordinate: " + this.getBounds());
}
}
public class Grid extends JFrame {
public Grid() {
setLayout(new GridBagLayout());
GridBagLayout m = new GridBagLayout();
Container c = getContentPane();
c.setLayout(m);
GridBagConstraints con = new GridBagConstraints();
// construct the JPanel
final JPanel pDraw = new JPanel();
m.setConstraints(pDraw, con);
pDraw.add(new GetCoordinate()); // call new class to generate the
// coordinate
c.add(pDraw);
pack();
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Grid();
}
});
}
}
Just as you described, it prints out a size of zero:
Coordinate: java.awt.Rectangle[x=0,y=0,width=0,height=0]
However, if you print out the size after the component has been added and the frame has been packed, it should work. Here is a modified version of my Example 2, where I added a method GetCoordinate.printBounds() and call that method everything has been added and laid out:
class GetCoordinate extends JLabel {
public GetCoordinate() {
setText("Foo!");
// Let's not try to do this here anymore...
// System.out.println("Coordinate: " + this.getBounds());
}
public void printBounds() // <-- Added this method
{
System.out.println("Coordinate: " + this.getBounds());
}
}
public class Grid extends JFrame {
public Grid() {
setLayout(new GridBagLayout());
GridBagLayout m = new GridBagLayout();
Container c = getContentPane();
c.setLayout(m);
GridBagConstraints con = new GridBagConstraints();
// construct the JPanel
final JPanel pDraw = new JPanel();
m.setConstraints(pDraw, con);
final GetCoordinate content = new GetCoordinate();
pDraw.add(content);
c.add(pDraw);
pack();
setVisible(true);
content.printBounds(); // <-- Added this
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Grid();
}
});
}
}
With these changes, I get the following console output, including a nonzero size for my content:
Coordinate: java.awt.Rectangle[x=5,y=5,width=23,height=16]
A common cause of such anomalies is failing to start on the EDT. In this case, I can't tell from your code what is different: in particular, it's not clear where the second example prints.
contoh
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* #author LENOVO G40
*/
public class Main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
new FrmMenuUTama().setVisible(true);
}
}

Categories