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.
Related
I've added two 10x10 grids in a window but I cannot get them to appear in a smaller size. They just fill the entire window. How do I place both of them neatly in the middle in a smaller size so that there's room for some labels and buttons? I've pasted the code below for reference.
public static void main(String[] args) {
window = new JFrame();
window.setTitle("Battleship.exe");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setPreferredSize(new Dimension(600, 600));
P1_container = new JPanel(new GridLayout(10,10));
P1_container.setBorder(BorderFactory.createLineBorder(Color.black, 5));
compContainer = new JPanel(new GridLayout(10,10));
compContainer.setBorder(BorderFactory.createLineBorder(Color.black, 5));
grid = new JPanel[10][10];
for (int i =0; i< 10; i++) {
for (int j =0; j< 10; j++) {
grid[i][j] = new JPanel();
grid[i][j].setBackground(Color.white);
grid[i][j].setBorder(BorderFactory.createLineBorder(Color.blue, 2));
grid[i][j].setPreferredSize(new Dimension(25,25));
P1_container.add(grid[i][j]);
}
}
enemyGrid = new JPanel[10][10];
for (int i =0; i< 10; i++) {
for (int j =0; j< 10; j++) {
enemyGrid[i][j] = new JPanel();
enemyGrid[i][j].setBackground(Color.white);
enemyGrid[i][j].setBorder(BorderFactory.createLineBorder(Color.red, 2));
enemyGrid[i][j].setPreferredSize(new Dimension(25, 25));
compContainer.add(enemyGrid[i][j]);
}
}
GridLayout layout = new GridLayout(1, 2);
layout.setHgap(150);
mainPanel = new JPanel(layout);
mainPanel.add(P1_container);
mainPanel.add(compContainer);
window.add(mainPanel);
window.pack();
window.setVisible(true);
}
Your code had 24 compile errors. Once I fixed the compile errors, I modified one line and commented out one line to get this GUI.
Here's the complete runnable code.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class BattleshipGUI {
public static void main(String[] args) {
JFrame window = new JFrame();
window.setTitle("Battleship.exe");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// window.setPreferredSize(new Dimension(600, 600));
JPanel P1_container = new JPanel(new GridLayout(10,10));
P1_container.setBorder(BorderFactory.createLineBorder(Color.black, 5));
JPanel compContainer = new JPanel(new GridLayout(10,10));
compContainer.setBorder(BorderFactory.createLineBorder(Color.black, 5));
JPanel[][] grid = new JPanel[10][10];
for (int i =0; i< 10; i++) {
for (int j =0; j< 10; j++) {
grid[i][j] = new JPanel();
grid[i][j].setBackground(Color.white);
grid[i][j].setBorder(BorderFactory.createLineBorder(Color.blue, 2));
grid[i][j].setPreferredSize(new Dimension(25,25));
P1_container.add(grid[i][j]);
}
}
JPanel[][] enemyGrid = new JPanel[10][10];
for (int i =0; i< 10; i++) {
for (int j =0; j< 10; j++) {
enemyGrid[i][j] = new JPanel();
enemyGrid[i][j].setBackground(Color.white);
enemyGrid[i][j].setBorder(BorderFactory.createLineBorder(Color.red, 2));
enemyGrid[i][j].setPreferredSize(new Dimension(25, 25));
compContainer.add(enemyGrid[i][j]);
}
}
GridLayout layout = new GridLayout(0, 2);
layout.setHgap(150);
JPanel mainPanel = new JPanel(layout);
mainPanel.add(P1_container);
mainPanel.add(compContainer);
window.add(mainPanel);
window.pack();
window.setVisible(true);
}
}
The key to using Swing layout managers is to nest your containers.
Nest mainPanel into another JPanel, one that uses a layout that helps you achieve your goal, say a BorderLayout with mainPanel placed into the BorderLayout.CENTER position. Then add the other gui components to this same outer JPanel at other BorderLayout locations.
If you don't want the mainPanel to expand, then use a different outer layout that does not expand, such as FlowLayout.
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
}
I made a class which takes as parameters 2 dimentions ( n,m ) and a matrix ( mat ). This class makes a JFrame,fills it with buttons colored white(for 1's) or black( for 0's).
The issue is, the matrix being sent is continually changing and i want the button colors to update. If i set the mainframe game = new mainframe(n,m,mat) inside the loop im changing the matrix in,it continually spawns JFrame windows.
I read some stuff on this site that using repaint() or revalidate() could do something like this. I tried putting it in various segments of code but had no luck with it.
The main class is just a loop which calls "mainframe" and updates a matrix in a loop. Here is the class which makes the actual GUI work:
package game;
import java.awt.Color;
public class mainframe extends Jframe {
public mainframe(int n,int m,int mat[][]){
JButton[] buttons = new JButton[n*m];
setSize(600,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setLayout(new GridLayout(n,m));
for(int i = 0; i<n*m;i++) {
buttons[i] = new JButton();
}
int counter = 0;
for(int j=0;j<n;j++){
for(int k=0;k<m;k++){
if(mat[j][k]==0){
buttons[counter].setBackground(Color.BLACK);
}
add(buttons[counter]);
counter++;
}
}
}
}
Put the setVisible(true); or revalidate(); after you added your components. Better work with the frame content pane.
import javax.swing.*;
import java.awt.*;
class Scratch {
public static void main(String[] args) throws InterruptedException {
JFrame jFrame = new JFrame();
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setSize(600, 400);
jFrame.setVisible(true);
for (int i = 5; i < 10; ++i) {
jFrame.setContentPane(createPanel(i, i, new int[i][i]));
jFrame.revalidate();
Thread.sleep(1000);
}
}
public static JPanel createPanel(int n, int m, int[][] mat) {
JButton[] buttons = new JButton[n * m];
JPanel jPanel = new JPanel();
jPanel.setLayout(new GridLayout(n, m));
for (int i = 0; i < n * m; i++) {
buttons[i] = new JButton();
}
for (int j = 0; j < n; j++) {
for (int k = 0; k < m; k++) {
int index = k + k * j;
if (mat[j][k] == 0) {
buttons[index].setBackground(Color.BLACK);
}
jPanel.add(buttons[index]);
}
}
return jPanel;
}
}
I am trying to develop a Jpanel of JPanels in Java
the outer JPanel has Layout FlowLayout.LEFT and the inner JPanels have Layout FlowLayout.LEADING
i added a labels to the inner jpanels
the should add to the outer panel as a Columns and rows of lables
but that does not work the labels added to the outer panel as a one row i mean left FowLayout for all
I stored the labels in a linkedlist of linkedlist of labels called board
here is the code for filling the labels linked list
for(int i =0 ; i <7 ;i++)
{
LinkedList<JLabel> list =new LinkedList<JLabel>();
for(int j=0 ; j< 5; j++)
{
JLabel lab = new JLabel();
lab.setIcon(add_icon);
lab.addMouseListener(listener);
lab.setTransferHandler(new TransferHandler("icon"));
list.add(lab);
}
board.add(list);
}
then i added the labels to the outer jpanel called container
Here is the code
container.setLayout(new FlowLayout(FlowLayout.LEFT));
for(int i =0 ; i < board.size() ;i++)
{
panel =new JPanel();
panel.setLayout(new FlowLayout(FlowLayout.LEADING));
for(int j=0 ; j< board.get(i).size(); j++)
{
panel.add(board.get(i).get(j));
}
container.add(panel);
//
}
add(container);
validate();
repaint();
here is the output it seems that the flow-layout leading does not work
How can i do it ? What should i do to add the labels as rows and columns ?
FlowLayout can't stack components vertically. Use BoxLayout instead. Try the following code:
container.setLayout(new FlowLayout(FlowLayout.LEFT));
for(int i = 0; i < board.size(); i++){
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
for(int j = 0; j < board.get(i).size(); j++)
panel.add(board.get(i).get(j));
container.add(panel);
}
add(container);
validate();
repaint();
I found it can be done by usuing GridBagLayout
container.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill=GridBagConstraints.HORIZONTAL;
for(int i =0 ; i < board.size() ;i++)
{
panel =new JPanel();
panel.setLayout(new GridBagLayout());
GridBagConstraints c1 = new GridBagConstraints();
c1.fill=GridBagConstraints.VERTICAL;
c1.weighty=-.9;
// panel.setBounds(0, 0, 400, 300);
for(int j=0 ; j< board.get(i).size(); j++)
{
c1.gridx = j;
c1.gridy = 0;
c1.insets= new Insets(-5,0,0,-5);
panel.add(board.get(i).get(j),c1);
}
c.weightx =- 5;
c.gridx = 0;
c.gridy =i ;
c.insets=new Insets(-5,0,-5,0);
container.add(panel,c);
//
}
add(container);
validate();
repaint();
The code below produces nine individual JPanels in which are 9 buttons. The nine JPanels are arranged onto a base JPanel using GridLayout. This base JPanel is then placed onto the ContentPane using Border Layout. I'm using borders for the JButtons and each individual JPanel to clearly define their separation. The JButtons inside each JPanel look fine but there is a gap between the JPanels which is causing the appearance of a double line which is bugging the hell out of me. I've tried adding each individual JPanel onto the ContentPane directly but this does nothing. Totally stumped and wondering if anyone has any suggestions?
P.S. I know the mass of duplicate code needs re-factoring in a bad way and it will, this is just for mock-up purposes.
Thanks,
import java.awt.*;
import javax.swing.*;
import javax.swing.UIManager.*;
public class View1 extends JFrame
{
private JPanel basePanel;
private JPanel childPanel1;
private JPanel childPanel2;
private JPanel childPanel3;
private JPanel childPanel4;
private JPanel childPanel5;
private JPanel childPanel6;
private JPanel childPanel7;
private JPanel childPanel8;
private JPanel childPanel9;
private int row = 3;
private int column = 3;
private JButton[][] squares1;
private JButton[][] squares2;
private JButton[][] squares3;
private JButton[][] squares4;
private JButton[][] squares5;
private JButton[][] squares6;
private JButton[][] squares7;
private JButton[][] squares8;
private JButton[][] squares9;
private Font numberFont;
public View1()
{
setSize(400,400);
setTitle("2013");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
basePanel = new JPanel();
basePanel.setLayout(new GridLayout(row, column, 0, 0));
numberFont = new Font("sansserif", Font.BOLD, 32);
childPanel1Setup();
childPanel2Setup();
childPanel3Setup();
childPanel4Setup();
childPanel5Setup();
childPanel6Setup();
childPanel7Setup();
childPanel8Setup();
childPanel9Setup();
basePanel.add(childPanel1);
basePanel.add(childPanel2);
basePanel.add(childPanel3);
basePanel.add(childPanel4);
basePanel.add(childPanel5);
basePanel.add(childPanel6);
basePanel.add(childPanel7);
basePanel.add(childPanel8);
basePanel.add(childPanel9);
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
cp.add(basePanel, BorderLayout.CENTER);
}
public void childPanel1Setup()
{
childPanel1 = new JPanel();
childPanel1.setLayout(new GridLayout(row, column, 0, 0));
childPanel1.setBorder(BorderFactory.createLineBorder(Color.BLACK));
squares1 = new JButton[row][column];
for(int rows = 0; rows < this.row; rows++)
{
for(int cols = 0; cols < this.column; cols++)
{
squares1[rows][cols] = new JButton();
squares1[rows][cols].setSize(32, 32);
squares1[rows][cols].setBorder(BorderFactory.createLineBorder(Color.BLACK));
squares1[rows][cols].setBackground(Color.WHITE);
childPanel1.add(squares1[rows][cols]);
}
}
}
public void childPanel2Setup()
{
childPanel2 = new JPanel();
childPanel2.setLayout(new GridLayout(row, column, 0, 0));
childPanel2.setBorder(BorderFactory.createLineBorder(Color.BLACK));
squares2 = new JButton[row][column];
for(int rows = 0; rows < this.row; rows++)
{
for(int cols = 0; cols < this.column; cols++)
{
squares2[rows][cols] = new JButton();
squares2[rows][cols].setSize(32, 32);
squares2[rows][cols].setBorder(BorderFactory.createLineBorder(Color.BLACK));
squares2[rows][cols].setBackground(Color.WHITE);
childPanel2.add(squares2[rows][cols]);
}
}
}
public void childPanel3Setup()
{
childPanel3 = new JPanel();
childPanel3.setLayout(new GridLayout(row, column, 0, 0));
childPanel3.setBorder(BorderFactory.createLineBorder(Color.BLACK));
squares3 = new JButton[row][column];
for(int rows = 0; rows < this.row; rows++)
{
for(int cols = 0; cols < this.column; cols++)
{
squares3[rows][cols] = new JButton();
squares3[rows][cols].setSize(32, 32);
squares3[rows][cols].setBorder(BorderFactory.createLineBorder(Color.BLACK));
squares3[rows][cols].setBackground(Color.WHITE);
childPanel3.add(squares3[rows][cols]);
}
}
}
public void childPanel4Setup()
{
childPanel4 = new JPanel();
childPanel4.setLayout(new GridLayout(row, column, 0, 0));
childPanel4.setBorder(BorderFactory.createLineBorder(Color.BLACK));
squares4 = new JButton[row][column];
for(int rows = 0; rows < this.row; rows++)
{
for(int cols = 0; cols < this.column; cols++)
{
squares4[rows][cols] = new JButton();
squares4[rows][cols].setSize(32, 32);
squares4[rows][cols].setBorder(BorderFactory.createLineBorder(Color.BLACK));
squares4[rows][cols].setBackground(Color.WHITE);
childPanel4.add(squares4[rows][cols]);
}
}
}
public void childPanel5Setup()
{
childPanel5 = new JPanel();
childPanel5.setLayout(new GridLayout(row, column, 0, 0));
childPanel5.setBorder(BorderFactory.createLineBorder(Color.BLACK));
squares5 = new JButton[row][column];
for(int rows = 0; rows < this.row; rows++)
{
for(int cols = 0; cols < this.column; cols++)
{
squares5[rows][cols] = new JButton();
squares5[rows][cols].setSize(32, 32);
squares5[rows][cols].setBorder(BorderFactory.createLineBorder(Color.BLACK));
squares5[rows][cols].setBackground(Color.WHITE);
childPanel5.add(squares5[rows][cols]);
}
}
}
public void childPanel6Setup()
{
childPanel6 = new JPanel();
childPanel6.setLayout(new GridLayout(row, column, 0, 0));
childPanel6.setBorder(BorderFactory.createLineBorder(Color.BLACK));
squares6 = new JButton[row][column];
for(int rows = 0; rows < this.row; rows++)
{
for(int cols = 0; cols < this.column; cols++)
{
squares6[rows][cols] = new JButton();
squares6[rows][cols].setSize(32, 32);
squares6[rows][cols].setBorder(BorderFactory.createLineBorder(Color.BLACK));
squares6[rows][cols].setBackground(Color.WHITE);
childPanel6.add(squares6[rows][cols]);
}
}
}
public void childPanel7Setup()
{
childPanel7 = new JPanel();
childPanel7.setLayout(new GridLayout(row, column, 0, 0));
childPanel7.setBorder(BorderFactory.createLineBorder(Color.BLACK));
squares7 = new JButton[row][column];
for(int rows = 0; rows < this.row; rows++)
{
for(int cols = 0; cols < this.column; cols++)
{
squares7[rows][cols] = new JButton();
squares7[rows][cols].setSize(32, 32);
squares7[rows][cols].setBorder(BorderFactory.createLineBorder(Color.BLACK));
squares7[rows][cols].setBackground(Color.WHITE);
childPanel7.add(squares7[rows][cols]);
}
}
}
public void childPanel8Setup()
{
childPanel8 = new JPanel();
childPanel8.setLayout(new GridLayout(row, column, 0, 0));
childPanel8.setBorder(BorderFactory.createLineBorder(Color.BLACK));
squares8 = new JButton[row][column];
for(int rows = 0; rows < this.row; rows++)
{
for(int cols = 0; cols < this.column; cols++)
{
squares8[rows][cols] = new JButton();
squares8[rows][cols].setSize(32, 32);
squares8[rows][cols].setBorder(BorderFactory.createLineBorder(Color.BLACK));
squares8[rows][cols].setBackground(Color.WHITE);
childPanel8.add(squares8[rows][cols]);
}
}
}
public void childPanel9Setup()
{
childPanel9 = new JPanel();
childPanel9.setLayout(new GridLayout(row, column, 0, 0));
childPanel9.setBorder(BorderFactory.createLineBorder(Color.BLACK));
squares9 = new JButton[row][column];
for(int rows = 0; rows < this.row; rows++)
{
for(int cols = 0; cols < this.column; cols++)
{
squares9[rows][cols] = new JButton();
squares9[rows][cols].setSize(32, 32);
squares9[rows][cols].setBorder(BorderFactory.createLineBorder(Color.BLACK));
squares9[rows][cols].setBackground(Color.WHITE);
childPanel9.add(squares9[rows][cols]);
}
}
}
}
I believe it's because the Layout Manager for JPanels is FlowLayout which includes a margin. When you create the panels, set their layout to GridLayout which will give you 0 margin.
Also have you done setVgap(0); and setHgap(0); for the GridLayout?
GridLayout makes all component to be of the same size. If it needs to layout matrix of 3x3 components inside JPanel that it 100x100 pixels, each component will be 33x33 pixels and there will be on extra pixel at the right and at the bottom because 100 is not factor of 3. If JPanel is 101x101 pixels, there will be extra pixels at all four edges.
Consider using GridBagLayout or Box or some other layout that is smarter than GridLayout.