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.
Related
I have an assignment which requires me to create the layout that you see in the image as part of the development of a game. I've never worked with Java for desktop applications before so i'm a complete noob when it comes to using the Swing & AWT libraries. The image suggests that we use a JLayeredPane as our root container and then add the rest on top of it. My issue is that i've tried starting with the background image and the gridLayout but i can't seem to make anything other than the background show up. The grid doesn't show up at all (no border line, no background of the cells) and any other component i've added to it has failed. Can somebody point me in the right direction here? I've read the docs & saw some example of various layouts,containers and components but i can't seem to make all of them work together.
Here's my code so far:
public class BoardView extends JFrame{
// Constructor
public BoardView() {
JFrame window = new JFrame("Sorry Game"); // create a new Jwindow instance
ImageIcon appIcon = new ImageIcon(getClass().getClassLoader().getResource("res/icon.png")); // create the icon for the app
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // when the 'X' button is clicked, the app stops
window.setSize(new Dimension(1000, 700)); // setting the size of the window
window.setResizable(false); // Window won't be resizable
window.setIconImage(appIcon.getImage()); // set the icon for the app
window.setLayout(new BorderLayout());
JLayeredPane layeredPane = new JLayeredPane();
JLabel background = new JLabel();
background.setSize(1000,700);
background.setIcon(new ImageIcon(getClass().getClassLoader().getResource("res/background.png"))); for the JLabel
layeredPane.add(background,0);
JPanel gridPanel = new JPanel(new GridLayout(16,16));
gridPanel.setSize(650,700);
layeredPane.add(gridPanel);
for(int i = 0; i < 256; i++) {
JLabel tile = new JLabel();
tile.setBackground(Color.red);
tile.setBorder(new LineBorder(Color.black));
gridPanel.add(tile);
}
JLabel logo = new JLabel();
logo.setIcon(new ImageIcon(getClass().getClassLoader().getResource("res/sorryImage.png")));
layeredPane.add(logo);
window.add(layeredPane);
window.setLocationRelativeTo(null); // centers the window to the screen
window.setVisible(true); // make the window visible
}
}
My thought process was that i could set the JFrame's layout to a BorderLayout so that i can brake the final layout down into two parts, the West one and the East one. The West one would contain the Grid and the various JLabels and Buttons and the East one would contain the rest of the components. I've tried using the BorderLayout.WEST & EAST parameters when adding components to the JFrame but none has worked or changed a single thing. I've also tried using an index for the depth when adding components to the JLayeredPane as per the docs but again nothing changes.
P.S. Please note that i'm not looking for someone to create the layout for me. I want someone to help me understand what i'm doing wrong and what the best way of creating such layouts is.
In order to initialize the cells of the grid that i want to have images in, don't i need to add them manually in those positions?
If you use a GridLayout every cell must have a component and the components must be added in sequential order. That is as components are added they will wrap automatically to the next row as required.
So even if you don't want an image in a cell you would need to add a dummy component, lets say a JLabel with no text/icon.
An easier approach might be to use a GridBagLayout. The GridBagLayout can be configured to "reserve" space for cells that don't have components. So you can add a component to a specific cell.
import java.awt.*;
import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
public class GridBagLayoutSparse extends JPanel
{
public GridBagLayoutSparse()
{
setBorder( new LineBorder(Color.RED) );
GridBagLayout gbl = new GridBagLayout();
setLayout( gbl );
/*
// Set up a grid with 5 rows and columns.
// The minimimum width of a column is 50 pixels
// and the minimum height of a row is 20 pixels.
int[] columns = new int[5];
Arrays.fill(columns, 50);
gbl.columnWidths = columns;
int[] rows = new int[5];
Arrays.fill(rows, 20);
gbl.rowHeights = rows;
*/
// Add components to the grid at top/left and bottom/right
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
addLabel("Cell 0:0", gbc);
gbc.gridx = 3;
gbc.gridy = 4;
addLabel("Cell 3:4", gbc);
}
private void addLabel(String text, GridBagConstraints gbc)
{
JLabel label = new JLabel(text);
label.setBorder( new LineBorder(Color.BLUE) );
add(label, gbc);
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("GridBagLayoutSparse");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout( new GridBagLayout() );
frame.add(new GridBagLayoutSparse());
frame.setSize(300, 300);
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args) throws Exception
{
java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
}
}
Run the code as is and the components will be grouped together in the center.
Uncomment the block comment and run again. The components will be positioned in the appropriate cell.
This question already has answers here:
error upon assigning Layout: BoxLayout can't be shared
(4 answers)
Closed 4 years ago.
Trying to have 2 panels in a frame, one small one at the top and one filling up the rest of the frame. This code returns a "BoxLayout can't be shared" error though.
JFrame frame = new JFrame("Clients");
frame.setSize(1000,900);
JPanel sorters = new JPanel();
sorters.setSize(1000, 100);
frame.getContentPane().add(sorters);
JPanel rowPane = new JPanel();
JScrollPane scrPane = new JScrollPane(rowPane, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrPane.setSize(1000, 800);
frame.getContentPane().add(scrPane);
frame.getContentPane().setLayout(new BoxLayout(frame, BoxLayout.Y_AXIS));
A BoxLayout must have as first parameter the actual container it is applied to, in your case the container is the contentPane of the frame :
frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
I am trying to create a panel, using MigLayout, divided on three rows. The first and last row should have a pushY of some ratio (in this case, 2f) and the row in between should grow as mush as possible in order to occupy the remaining space.
However, I have some cases in which the last row, for example, which is a panel on its own, will have no components in it. In this case, I want the 2nd row to occupy all the height and I can't achieve that.
Please not that making it invisible is not possible due to other flow-dependencies.
I've attached the code here:
public class TestClass {
public static void main(String[] args) {
createPanel(true);
createPanel(false);
}
private static void createPanel(boolean removeAll) {
JFrame frame = new JFrame();
JPanel panel = new JPanel(new MigLayout(new LC().fill().gridGap("0", "0").insetsAll("0")));
panel.add(new JLabel("first row"), new CC().grow().newline().pushY(2f));
JTextArea abc = new JTextArea("abc");
abc.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
panel.add(abc, new CC().push().grow().newline());
JPanel pnl = new JPanel(new MigLayout(new LC().fill().gridGap("0", "0").insetsAll("0")));
pnl.add(new JLabel("aaa"), new CC());
pnl.add(new JLabel("bbb"), new CC().newline());
pnl.add(new JLabel("ccc"), new CC().newline());
panel.add(pnl, new CC().grow().newline().pushY(2f));
if (removeAll) {
pnl.removeAll();
}
frame.setContentPane(panel);
frame.setSize(100,800);
frame.setVisible(true);
}
}
Use dock feature for that, so top will dock in north, bottom in south, and middle row will grow between them. http://www.miglayout.com/QuickStart.pdf check the page no.5 for docking tutorial.
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)