Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I've made two grids and added them to a window using nested panels. The only issue is that I can't move the grid in the center and can't get the labels under their respective grids. Tried using setBounds but that's not working. Any advice? I've added an image of the current state. I want to display the player and opponent label under the first and second grid respectively.
public static void main(String[] args) {
window = new JFrame();
window.setTitle("Battleship.exe");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setPreferredSize(new Dimension(800, 800));
P1_container = new JPanel(new GridLayout(10,10));
P1_container.setPreferredSize(new Dimension(400, 400));
P1_container.setBorder(BorderFactory.createLineBorder(Color.black, 5));
compContainer = new JPanel(new GridLayout(10,10));
compContainer.setPreferredSize(new Dimension(400, 400));
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(35,35));
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.lightGray);
enemyGrid[i][j].setBorder(BorderFactory.createLineBorder(Color.red, 2));
enemyGrid[i][j].setPreferredSize(new Dimension(35, 35));
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);
player = new JLabel("PLAYER");
player.setBounds(100, 410, 5, 5);
opponent = new JLabel("OPPONENT");
opponent.setBounds(100, 410, 5, 5);
panel = new JPanel();
panel.setPreferredSize(new Dimension(100, 100));
panel.add(mainPanel, BorderLayout.CENTER);
panel.add(player, BorderLayout.WEST);
panel.add(opponent, BorderLayout.WEST);
window.add(panel, BorderLayout.CENTER);
window.pack();
window.setVisible(true);
}
Please mark your previous questions as solved if they are. People have taken the time to help you out and it's the least you can do. Read here for more information on What should I do when someone answers my question?
You are STILL calling setPreferredSize you should instead override getPreferredSize and ONLY where necessary. If your grid JPanels are sized via getPreferredSize there is no need to call setPreferredSize on their respective containers or the JFrame also you are still not creating your Swing components on the EDT.
As others have mentioned, you cannot use setBounds when using a LayoutManager. To achieve what you want, you need to nest layouts, as you have been told before.
So you probably want to create two JPanels with a BorderLayout. These two new containers will hold each grid and its label respectively:
JPanel p1Container = new JPanel(new BorderLayout());
p1Container.add(P1_container, BorderLayout.CENTER);
p1Container.add(player, BorderLayout.SOUTH);
JPanel opponentContainer = new JPanel(new BorderLayout());
opponentContainer.add(compContainer, BorderLayout.CENTER);
opponentContainer.add(opponent, BorderLayout.SOUTH);
...
panel.add(p1Container);
panel.add(opponentContainer);
Also the below code makes no sense:
panel = new JPanel();
panel.setPreferredSize(new Dimension(100, 100));
panel.add(mainPanel, BorderLayout.CENTER);
panel.add(player, BorderLayout.WEST);
panel.add(opponent, BorderLayout.WEST);
By default, a JPanel uses FlowLayout so BorderLayout.XXX means nothing here.
Again take the time to read A Visual Guide to Layout Managers but the code I showed corrects this by not passing in any extra parameters to add()
Related
I'm trying practice my GUI and I am having troubles putting gap between component and the frame.
The picture above is what I have so far. But I really want to put a gap between the left side of the frame and "label1".
private void initialize() {
frame = new JFrame();
frame.setTitle("WINDOW");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 300);
panel = new JPanel();
panel.setLayout(new BorderLayout());
bottomPanel = new JPanel();
bottomPanel.setLayout(new GridLayout(1, 5));
l1 = new JLabel("Label1");
l2 = new JLabel("Label2");
l3 = new JLabel("Label3");
l4 = new JLabel("Label4");
l5 = new JLabel("Label5");
bottomPanel.add(l1);
bottomPanel.add(l2);
bottomPanel.add(l3);
bottomPanel.add(l4);
bottomPanel.add(l5);
panel.add(bottomPanel, BorderLayout.SOUTH);
frame.add(panel);
}
Above is part my code. I tried doing:
bottomPanel.setLayout(new GridLayout(1, 5, -20, 0));
to put some horizontal gap but that only added gap between the components. That didn't move "label1" away from the frame at all. Is there any other way of doing this? I am very new to Java so I don't really know much of the other tricks. I would appreciate any help! Thank you!
The other answers are fudges that won't achieve the desired effect when the GUI is resized. Instead use:
JLabel.setHorizontalAlignment(SwingConstants.CENTER);
By centering the text within the JLabel, combined with GridLayout stretching the components to the full width of the cell, each label will have as much space either side as the GUI can allow. E.G. here is the effect when the GUI is at minimum size.
And when stretched wider:
(The red border is added to show the bounds of each label.)
Add a Border to the panel:
bottomPanel = new JPanel();
bottomPanel.setBorder( new EmptyBorder(0, 10, 0, 0) );
Read the section from the Swing tutorial on How to Use Borders for more information about the different borders you can create.
Try the following:
bottomPanel.add(javax.swing.Box.createHorizontalStrut(10));
This question already has answers here:
Java: vertical alignment within JPanel
(3 answers)
Closed 4 years ago.
the task i am trying to do is simple. I want to add JButtons to a panel in a vertical way, but using a loop to adding it, i tried to do it using .setBounds() and .setLocation() mehtod, but i dont have any results.
In a simple way, i want to do this but adding the buttons vertically and keeping the JScroll bar...:
public class NewMain {
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.setLayout(null);
for (int i = 0; i < 10; i++) {
JButton asd=new JButton("HOLA "+i);
asd.setLocation(i+20, i+20);
panel.add(asd);
}
JScrollPane scrollPane = new JScrollPane(panel);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.setBounds(50, 30, 300, 50);
JPanel contentPane = new JPanel(null);
contentPane.setPreferredSize(new Dimension(500, 400));
contentPane.add(scrollPane);
frame.setContentPane(contentPane);
frame.pack();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setVisible(true);
}
Give the JPanel that holds the JButtons an appropriate layout manager that adds components in a vertical manner. A GridLayout(0, 1) would work, the parameters referring to 0 rows -- meaning variable number of rows, and 1 column. This will add the JButtons into a vertical grid, column of one
Other possible solutions include BoxLayout and GridBagLayout, both of which are a little more complex than the GridLayout.
Also avoid using null layouts as you're doing as this leads to inflexible GUI's painful debugging and changes.
I am writing a chess program. For displaying the chessboard I am using two JPanels:
chessboard: This panel displays an image of an empty chessboard
chessmen: This panel displays an array of JLabels with chessmen images
So for this I need the two panels on top of each other. Therefore I am presently using a JLayeredPane. But the problem is I can only view only one of the layers at once.
My present code for the constructor is:
public ChessBoard(){
setLayout(new FlowLayout());
gamescreen = new JLayeredPane();
gamescreen.setPreferredSize(new Dimension(200,200));
chessboard = new JPanel(new GridBagLayout());
chessmen = new JPanel(new GridBagLayout());
//chessboard.setLocation(0, 0);
//chessmen.setLocation(0,0);
chessboardImage = new ImageIcon(getClass().getResource("chessboard.jpg"));
chessboardDisplay = new JLabel(chessboardImage);
chessboard.add(chessboardDisplay);
GridBagConstraints constraint = new GridBagConstraints();
for(int i=0;i<2;i++){
for(int j=0;j<2;j++){
imageSet[i][j] = new ImageIcon(getClass().getResource(""+i+(j+1)+".png"));
image = imageSet[i][j].getImage().getScaledInstance(100, 100, Image.SCALE_SMOOTH);
imageSet[i][j]= new ImageIcon(image);
}
}
for(int i=0;i<2;i++){
constraint.gridy=i+3000;
for(int j=0;j<2;j++){
chessmenPos[i][j] = new JLabel(imageSet[i][j]);
constraint.gridx=j;
chessmen.add(chessmenPos[i][j],constraint);
}
chessboard.setBounds(0, 0, 200, 200);
chessmen.setBounds(0, 0, 200, 200);
gamescreen.add(chessboard, 1);
gamescreen.add(chessmen, 0);
gamescreen.setOpaque(false);
chessboard.setVisible(true);
chessmen.setVisible(true);
add(gamescreen);
}
EventHandling eventHandler = new EventHandling();
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
chessmenPos[i][j].addMouseListener(eventHandler);
}
Where am I going wrong and what changes can I make?
But the problem is I can only view only one of the layers at once.
The top layer needs to be transparent. So you would need:
chessmen.setOpaque( false );
You can check out: Asking for some clarification in java about jlabel and parent for an example of a simple chessboard. It uses a slightly different approach. Each square is a component.
I'm looking at the How To Use BoxLayout documentation, which clearly says that
What if none of the components has a maximum width? In this case, if
all the components have identical X alignment, then all components are
made as wide as their container.
Let's assume we're adding a lot of JButton instances to a JPanel. If the maximum width of these buttons are none AND we invoke setAlignmentX(Component.LEFT_ALIGNMENT) on all of these buttons - then each of these buttons should stretch across its entire row. The documentation even illustrates this using the below picture.
I can't get this to work!
I've tried doing setMaximumSize(null) and setMaximumSize(new Dimension(-1,-1)) and setMaximumSize(new Dimension(0,0)) on the buttons but nothing gives me the described behaviour.
What excactly does the documentation mean when it says :
What if none of the components has a maximum width?
What is a maximum width of none?
The best I've been able to produce is the below. Reading the documentation I would expect that the buttons should be able to stretch across their entire rows. I know I can use other layout managers as well for this, but I would like to achieve this with BoxLayout (granted the documentation is right / I've understood the documentation right).
public class CustomList extends JPanel {
private final Box box = Box.createVerticalBox();
public CustomList() {
for (int i = 0; i < 10; i++) {
JButton b = new JButton("Button item" + i);
//b.setMaximumSize(new Dimension(0,0));
b.setAlignmentX(Component.LEFT_ALIGNMENT);
box.add(b);
}
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(box, BorderLayout.CENTER);
}
public static void main(String[] args) {
CustomList l = new CustomList();
l.setSize(200, 200);
l.setBackground(Color.red);
JFrame frame = new JFrame("Vertical Box");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(l, BorderLayout.CENTER);
frame.setSize(300, 200);
frame.setVisible(true);
}
}
Your buttons actually have a maximum width.
What you can do is create JPanel objects with BorderLayout in your loop, add each button to each panel (to BorderLayout.CENTER, which is the default anyway).
BorderLayout.CENTER doesn't care about the maximum size of its child Component, so you end up with a JPanel whose whole content is filled by a JButton.
Since the JPanel itself has a huge default maximum size of new Dimension(Short.MAX_VALUE, Short.MAX_VALUE) (this is width=32767,height=32767 !!) which is the default maximum size of Component, you will get the expected result :
public CustomList() {
for (int i = 0; i < 10; i++) {
JPanel panel = new JPanel(new BorderLayout());
JButton b = new JButton("Button item" + i);
//b.setMaximumSize(new Dimension(0,0));
b.setAlignmentX(Component.LEFT_ALIGNMENT);
panel.add(b);
box.add(panel);
}
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
add(box, BorderLayout.CENTER);
}
This question already has answers here:
How to add JTable in JPanel with null layout?
(11 answers)
Closed 6 years ago.
Can any one help me?
Hello,How can i add two panels in one frame?
public class test{
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setSize(400, 400);
frame.setLayout(null);
JPanel panel = new JPanel();
panel.setLayout(null);
panel.setBounds(5, 5, 300, 300);
JPanel panel2 = new JPanel();
panel2.setLayout(null);
panel2.setBounds(1,200,300,300);
JLabel label2 = new JLabel("asddas");
label2.setBounds(30,30,20,20);
panel2.add(label2);
JLabel label[] = new JLabel[10];
int count = 1;
for(int i = 0; i < 10; i++){
label[i] = new JLabel("ds");
label[i].setBounds(1,count,20,20);
count +=20;
panel.add(label[i]);
}
frame.add(panel,panel2);
frame.setVisible(true);
}
}
You can think of the JPanel as one big panel that contains the all of the other elements. So you can have a main JPanel and then put others inside it. You should set a layout that fits your needs to the main panel. A good introduction to layouts can be found here http://docs.oracle.com/javase/tutorial/uiswing/layout/index.html
Also see this answer
How to layout multiple panels on a jFrame? (java)