How to show matrix in a JFrame with JLabels - java

I want to show a matrix in Java in a JFrame, I know how to do it, but I have this problem now, and I don´t know how to solve it. I've tried a lot of things, but nothing has worked.
The problem are these empty places marked in the picture.
code:
public class VentanaConsulta extends javax.swing.JFrame {
JLabel[] arreglo = new JLabel[16];
public VentanaConsulta(Sistema sistema, VentanaInicial ventanaInicial) {
this.modelo = sistema;
this.ventanaInicial = ventanaInicial;
initComponents();
IniciarComponentes();
}
private void IniciarComponentes() {
int[][] campo = {{1,2,3,4}, {0,0,0,0} , {0,0,0,0}, {0,0,0,0}};
setLayout(new GridLayout(4, 4));
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
arreglo[i] = new JLabel(Integer.toString(campo[i][j]));
arreglo[i].setHorizontalAlignment(SwingConstants.CENTER);
add(arreglo[i]);
}
}
}

Your image shows that while you're setting the layout of your container to a 4x4 grid, you are adding more than 16 items to this container, and this is likely due to your setting the layout of the wrong container. You are probably setting the layout of the main JFrame's contentPane, adding your JLabels to it, and adding other things to it as well, messing up the size of the grid.
I suggest that you create a new JPanel, one to hold your JLabel grid, give it a 4x4 grid layout, add the JLabels, and then add this JPanel to the main GUI (the JFrame), or to a container that is displayed within the JFrame.
And yes, your arreglo array indices use is wrong, since you are trying to add a whole row to a single array item. e.g. something like:
private void IniciarComponentes() {
int[][] campo = {{1,2,3,4}, {0,0,0,0} , {0,0,0,0}, {0,0,0,0}};
JPanel gridPanel = new JPanel(new GridLayout(4, 4));
// setLayout(new GridLayout(4, 4));
for (int i = 0; i < campo.length; i++) { // avoid using "magic" numbers
for (int j = 0; j < campo[i].length; j++) {
JLabel label new JLabel(Integer.toString(campo[i][j]));
label.setHorizontalAlignment(SwingConstants.CENTER);
arreglo[4 * i + j] = label
gridPanel.add(label);
}
}
// here add gridPanel to the main GUI
}

Related

FlowLayout not going to new line

I'm trying to add a variable number of JPanels (each one containst 2 Label) inside another JPanel using the FlowLayout.
When there's too many panels added instead of going to the new row they disappear out of the border
I've tried many types of Layouts, setting sizes, maximussizes but nothing changes.
public class AlbumView extends javax.swing.JFrame
{
private Album A;
public AlbumView()
{
initComponents();
A = new Album();
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
int w = this.getSize().width;
int h = this.getSize().height;
int x = (dim.width-w)/2;
int y = (dim.height-h)/2;
this.setLocation(x, y);
pnlCategorie.setLayout(new FlowLayout(FlowLayout.TRAILING, 10, 10));
/*
Insert of many elements in the Album
*/
aggiornaAlbum();
}
public void aggiornaAlbum()
{
for(int i = 0; i < A.getDim(); i++)
{
Categoria c = A.getCategoria(i);
JPanel pnl = new JPanel();
pnl.setName(c.getNome());
JLabel lb1, lb2;
ImageIcon img = new ImageIcon(c.getPhoto(0).getImg(95, 95)); //da cambiare lo 0 con un numero casuale tra le foto disponibili
lb1 = new JLabel(img, JLabel.CENTER);
lb2 = new JLabel(c.getNome(), JLabel.CENTER);
pnl.setLayout(new BoxLayout(pnl, BoxLayout.Y_AXIS));
pnl.setBorder(BorderFactory.createLineBorder(Color.black));
pnl.add(lb1);
pnl.add(lb2);
//pnl.revalidate();
//pnl.repaint();
pnlCategorie.add(pnl);
}
//ADDED AFTER COMMENT, NOTHING CHANGED (but probably it's because i didn't get exaclty what to do
pnlCategorie.revalidate();
pnlCategorie.repaint();
}
pnlCategorie is created using NetBeans swing.
I expect that after the number of jpanels that fits the bigger jPanel the next one goes to a new line
Example of what is appearing (I'm using some exaple image, don't judge) :

Sudoku Gui Issues

I am required to create a Suduku Game Board that looks like this:
Here are the requirements I need for this assignment, but am having some issues.
Use two for loops to draw the text fields instead of brute-force of listing 81 text fields. You should do something like:
for (int k = 1; k <= 9; k++)
{
JPanel level2 = new JPanel();
….
for (int i = 1; i <= 9; i++)
{
JTextField text = new JTextField();
…
}
gridPanel.add(level2);
}
I need 2 classes in
an application class named TestSudoku and a work class named SudokuLayout.
Implement the following visual gadgets and write listeners for them. These gadgets have the following behaviors:
Button “Reset”---when the button is clicked, the program will clear the text area, then output the string “Reset button clicked!” to the text area.
Button “Hint”---when the button is clicked, the program will clear the text area, then output the string “Hint button clicked!” to the text area.
Combobox “Difficulty”---when an item is selected, the program will clear the text area, then output the selected item name to the text area.
implement the listeners using loosely coupled methods (private listener class or private adapter class).
This is what I currently have..
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
public class SudokuLayout extends JFrame {
public SudokuLayout() {
JPanel board = new JPanel(new GridLayout(9, 9));
add(board);
JPanel[][] squares = new JPanel[9][9];
Border border = BorderFactory.createLineBorder(Color.BLACK);
for (int row = 1; row < 9; row++) {
for (int col = 1; col < 9; col++) {
squares[row][col] = new JPanel();
board.add(squares[row][col]);
}
}
JPanel menu = new JPanel();
menu.add(new JButton("Reset"));
menu.add(new JButton("Hint"));
menu.add(new JButton("Solve"));
menu.add(new JButton("New Puzzle"));
add(menu);
}
public static void main(String[] args) {
/** Create a frame and set its properties*/
JFrame frame = new SudokuLayout();
frame.setTitle("Sudoku");
frame.setSize(600, 600);
frame.setLocationRelativeTo(null); //Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
The problem is that, with my current version, the right menu shows horizontally and I cannot see the grid. Moreover, I don't know how to add the output area.
When facing this kind of frames with Swing you need to divide the frame in sections and treat them separately. I mean, by looking at the image you can easily identify the Sudoku, the menu, and the output. Thus, your answer should try to first create each of them separately and then join them.
Considering this, you must notice:
There are 3 main components: sudoku, menu, and output
The 3 main components may use a BorderLayout since they are probably at WEST, EAST and SOUTH
The sudoku component is a 3x3 grid of 3x3 smaller grids (so you can change the black-border).
The menu component is a 5x1 grid with buttons in each position
The output component is a single text frame
So, you may need to change something to get the exact behaviour (button sizes and margins, options on the difficulty ComboBox) but your solution should look like this:
public class SudokuLayout extends JFrame {
public SudokuLayout() {
// Create panel for Sudoku
JPanel board = new JPanel();
board.setLayout(new GridLayout(3, 3));
board.setBorder(BorderFactory.createLineBorder(Color.BLACK));
for (int row = 0; row < 3; ++row) {
for (int col = 0; col < 3; ++col) {
JPanel box = new JPanel(new GridLayout(3, 3));
box.setBorder(BorderFactory.createLineBorder(Color.BLACK));
for (int cell = 0; cell < 9; ++cell) {
box.add(new JTextField(2));
}
board.add(box);
}
}
// Create difficulty combo box
JComboBox<String> difficultyChoices = new JComboBox<>(new String[] { "Hard", "Easy" });
difficultyChoices.setSelectedIndex(0);
// Create menu panel
JPanel menu = new JPanel();
menu.setLayout(new GridBagLayout());
GridBagConstraints menuConstraints = new GridBagConstraints();
menuConstraints.anchor = GridBagConstraints.WEST;
menuConstraints.weightx = 0.5;
menuConstraints.weighty = 0.5;
menuConstraints.gridwidth = 2;
menuConstraints.gridx = 2;
menuConstraints.gridy = 0;
menu.add(new JButton("Reset"), menuConstraints);
menuConstraints.gridx = 2;
menuConstraints.gridy = 1;
menu.add(new JButton("Hint"), menuConstraints);
menuConstraints.gridx = 2;
menuConstraints.gridy = 2;
menu.add(new JButton("Solve"), menuConstraints);
menuConstraints.gridx = 2;
menuConstraints.gridy = 3;
menu.add(new JButton("New Puzzle"), menuConstraints);
menuConstraints.weighty = 1.0;
menuConstraints.gridx = 2;
menuConstraints.gridy = 4;
menu.add(new JLabel("Difficulty:"), menuConstraints);
menuConstraints.fill = GridBagConstraints.HORIZONTAL;
menuConstraints.weightx = 0.5;
menuConstraints.weighty = 0.5;
menuConstraints.gridwidth = 2;
menuConstraints.gridx = 0;
menuConstraints.gridy = 5;
menu.add(difficultyChoices, menuConstraints);
// Create output panel
JTextArea output = new JTextArea(5, 20);
output.setEditable(false);
output.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.BLUE), "Output Area"));
// Join the 3 panels on the frame
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
cp.add(board, BorderLayout.WEST);
cp.add(menu, BorderLayout.EAST);
cp.add(output, BorderLayout.SOUTH);
}
public static void main(String[] args) {
// Create a frame and set its properties
JFrame frame = new SudokuLayout();
frame.setTitle("TestSudoku");
frame.setSize(600, 600);
frame.setLocationRelativeTo(null); // Center the frame
// Setup the window
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
UPDATE: I update my answer with a GridBagLayout for the menu and a TextArea with border for the output.

Improper sizing using GridBagLayout

I am trying to use a GridBagLayout to have a JFrame that contains a JPanel that has a grid layout and a JPanel with just a large button. I want the rows to all be the same size, and the JPanel with the JButton to be the same size as one row. However, the button panel, which is currently empty, is about 1/3 of the JFrame. I'm not quite sure what's happening, but it is pretty important to me that I maintain this structure because the rest of my code uses this. Any help is appreciated, and thank you in advance.
This is my code:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class Minesweeper extends JPanel {
private final int SIZE = 7;
public void startGame(){
JFrame holder = new JFrame();
JPanel window = new JPanel();
JPanel pan = new JPanel();
holder.setLayout(new GridBagLayout());
GridBagConstraints con = new GridBagConstraints();
con.weightx = 1;
con.weighty = 1;
con.gridx = 0;
con.gridy = 0;
con.fill = GridBagConstraints.BOTH;
con.gridheight = SIZE;
con.gridwidth = SIZE;
holder.getContentPane().setBackground(Color.darkGray);
holder.setSize(450, 450);
holder.setResizable(false);
holder.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBackground(Color.darkGray);
window.setLayout(new GridLayout(SIZE, SIZE));
for (int c=0; c<(SIZE*SIZE); c++){
int row = (c/SIZE);
int col = (c%SIZE);
JPanel p = new JPanel();
p.setBackground(Color.gray);
Border b = BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
p.setBorder(b);
window.add(p);
}
holder.add(window, con);
con.gridx = 0;
con.gridy = SIZE+1;
con.gridheight = 0;
con.gridwidth = SIZE;
holder.add(pan, con);
holder.setVisible(true);
}
public static void main(String[] args){
Minesweeper start = new Minesweeper();
start.startGame();
}
}
This is what is being shown:
con.gridy = SIZE+1;
You can't specify a gridy value of 8. There are only two components added to the grid. The grid doesn't know that one of your panels happens to contain 7 rows of components. So the value should be 1.
This won't solve the problem but should clear up a misunderstanding of how GridBagLayout works.
holder.setSize(450, 450);
You are manually setting a size to the frame. Each component is originally sized at its preferred size. When there is extra space in the frame the space is distributed equally between the two components.
You should NOT be setting the size. Each component should determine its own size and then you should use pack(). So you need to use custom components that override the getPreferredSize() method to return the appropriate size for each component so pack() can do its job.
Also, the pack() is done just before the setVisible().

Creating Grid on my Image

I am currently trying to create a moving character in a Map using AWT and Swings.
I need help on trying to create a GridLayout on my Image. I have tried using setLayout(new GridLayout()) and it just doesn't work.
If possible, I would also like to incorporate a KeyListener to this.
Currently, Here's my Code for the Image:
public class GUI extends JFrame{
GUI(){
setLayout(new FlowLayout());
ImageIcon image1 = new ImageIcon("path-to-backgroundImage");
JLabel label1 = new JLabel(image1);
add(label1);
}
public static void main(String[] args) {
GUI gui = new GUI();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.setVisible(true);
gui.pack();
gui.setTitle("Map");
}
}
And Here's the GridLayout I had with the code, but it doesn't work:
setLayout(new GridLayout(ROWS, COLS));
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
JLabel label = new JLabel(cellIcon);
add(label);
}
}
Help is always highly appreciated!
JLabel label1 = new JLabel(image1);
add(label1);
You add the label to the frame, which is reasonable:
setLayout(new GridLayout(ROWS, COLS));
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
JLabel label = new JLabel(cellIcon);
add(label);
}
}
But then you change the layout of the frame and add more labels to the frame. Your code doesn't make sense. If you want to add the grid of labels to the background image then the code should be:
label1.setLayout(new GridLayout(ROWS, COLS));
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
JLabel label = new JLabel(cellIcon);
label1.add(label);
}
}
If you need more help then poste a proper SSCCE that demonstrates the problem. The random lines of code don't tell us the context of how the code is used.

Using empty gridLayout, but will hold ImageIcon and store information later. Can i modify the size?

Below is my code, which is meant to create a grid on the left hand side, which is does, however the two grids are made very long and thin, and even when later on i add the image to it it remains the same size!
I dont know whether there's some way of changing it, and i tried to use the gridBagLayout but I've never used it before and i wasn't sure how i could apply my current code to it!
I'm not quite sure how to explain it, as i'm a beginner in java and have only just been learning it at uni for a short while. If you need more information I'm happy to provide it.
I know that the grid means everything is the same size, but is there any way of actually setting that size of controlling the size of it?
public static int ROWS = 3;
public static int ROWS1 = 1;
public static int COLUMNS = 4;
pnlLorry = new JPanel();
pnlLorry.setLayout(new GridLayout(ROWS1, COLUMNS));
pnlLorry.setSize(100, 400);
pnlLorry.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
pnlLorry.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
for (int row = 0; row < largeVehicle.length; row++) {
for (int column = 0; column < largeVehicle[row].length; column++) {
ImagePanel pnlLorryImage = new ImagePanel();
pnlLorryImage.addMouseListener(new MyMouseListener(row, column));
pnlLorryImage.setBorder(BorderFactory.createLineBorder(Color.BLACK));
pnlLorry.add(pnlLorryImage, row * (largeVehicle.length - 1) + column);
}
}
pnlCars = new JPanel();
pnlCars.setSize(400, 400);
pnlCars.setLayout(new GridLayout(ROWS, COLUMNS));
pnlCars.applyComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
pnlCars.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
for (int row = 0; row < carVehicle.length; row++) {
for (int column = 0; column < carVehicle[row].length; column++) {
ImagePanel pnlCarImage = new ImagePanel();
pnlCarImage.addMouseListener(new MyMouseListener(row, column));
pnlCarImage.setBorder(BorderFactory.createLineBorder(Color.BLACK));
pnlCars.add(pnlCarImage, row * (carVehicle.length - 1) + column);
}
}
GridLayout = new GridLayout(2, 1);
vehicleMain.setLayout(GridLayout);
vehicleMain.add(pnlLorry);
vehicleMain.add(pnlCars);
the two grids are made very long and thin
I am surprised why It's not working with GridLayout because by default GridLayout assigns equal size for all the components in percentage.
Whenever you uses Layout Manager then there is no need to call setSize(). Just leave it for Layout Manager to set the size.
Just remove the setSize() method calls.
i tried to use the gridBagLayout but I've never used it before and i wasn't sure how i could apply my current code to it!
In below sample code I have changed the last part that might help you to solve it.
Change:
GridLayout = new GridLayout(2, 1);
vehicleMain.setLayout(GridLayout);
vehicleMain.add(pnlLorry);
vehicleMain.add(pnlCars);
To:
GridBagLayout gridBagLayout = new GridBagLayout();
vehicleMain.setLayout(gridBagLayout);
GridBagConstraints gc = new GridBagConstraints();
gc.fill = GridBagConstraints.BOTH;// set VERTICAL/HORIZONTAL as per need
gc.weightx=1; // 100% horizontally
gc.weighty=1; // 100% vertically
gc.gridx = 0; // first column
gc.gridy = 0; // first row
vehicleMain.add(pnlLorry, gc);// notice second parameter
gc.gridx = 0; // first column
gc.gridy = 1; // second row
vehicleMain.add(pnlCars, gc);// notice second parameter
It's better explained under Swing Tutorial on How to Use GridBagLayout with detail example.

Categories