FlowLayout takes up too much vertical space, change height - java

I have JFrame that uses FlowLayout for buttons and BoxLayout for the JFrame and looks like this:
I need it to look like this:
For some reason the JPanel of the buttons (green) takes up too much space, while the labels on the red panel are all on the same row, instead of each on a different row.
My code is as follows:
import javax.swing.*;
import java.awt.*;
public class ButtonsTest extends JFrame {
private JButton button1 = new JButton("Button1");
private JButton button2 = new JButton("Button2");
private JButton button3 = new JButton("Button3");
private JButton button4 = new JButton("Button4");
private JPanel panel = new JPanel(new FlowLayout());
private JPanel otherPanel = new JPanel();
public ButtonsTest() {
setPreferredSize(new Dimension(200, 200));
setMinimumSize(new Dimension(200, 200));
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
panel.add(button1);
panel.add(button2);
panel.add(button3);
panel.add(button4);
panel.setBackground(Color.GREEN);
add(panel);
setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
otherPanel.add(new Label("1"));
otherPanel.add(new Label("2"));
otherPanel.add(new Label("3"));
otherPanel.setBackground(Color.RED);
add(otherPanel);
pack();
}
public static void main(String[] args) {
ButtonsTest test = new ButtonsTest();
}
}
What is my mistake?

For some reason the JPanel of the buttons (green) takes up too much space
When using a BoxLayout, the components will grow up to the maximum size when extra space is available. So extra space is allocated to both the red and green panels.
Don't set the layout of the content pane to use a BoxLayout.
while the labels on the red panel are all on the same row, instead of each on a different row.
By default a JPanel uses a Flow layout.
The solution is to use the default BorderLayout of the JFrame.
Then you add the green panel to the frame using:
add(panel, BorderLayout.PAGE_START);
Then for the "otherPanel" you can use the BoxLayout:
otherPanel.setLayout( new BoxLayout(otherPanel, BoxLayout.Y_AXIS) );
Then you add the "otherPanel" to the frame using:
add(otherPanel, BorderLayout.CENTER);
Also, components should be added to the frame BEFORE the frame is visible. So the setVisible(...) statement should be the last statement in the constructor.

Related

Why does Java pack does not size frame properly when textarea is used with other components?

I am creating a GUI using GridLayout to arrange multiple panels that are using FlowLayout. I am using pack to determine the size of the frame. If I have only a TextArea then it sizes correctly. If I have only other components it sizes correctly. But if I use both p1 and p2 in the code below the panel with the buttons does not size properly. The test code I am using is below. If I use only p1 or p2 it sizes properly, but not with both: Here is the image I am getting. I don't want all that extra space between the buttons and the textarea.
If I do textarea alone it sizes properly.:
public class GUIPractice extends JFrame
{
//declare GUI objects
JPanel panel;
JPanel p1, p2;
JButton btnAdd, btnShow;
JScrollPane js;
JTextArea taOutput;
//constructor
public GUIPractice()
{
//give frame a title
setTitle("GUI Practice");
panel =new JPanel(new GridLayout(0, 1));
btnAdd = new JButton("Add");
btnShow = new JButton("Show");
taOutput = new JTextArea(10, 20);
js = new JScrollPane(taOutput, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
p1 = new JPanel();
p1.add(btnAdd);
p1.add(btnShow);
p2 = new JPanel();
p2.add(js);
panel.add(p1);
panel.add(p2);
//add the panel to the frame
add(panel);
}
public static void main(String[] args)
{
GUIPractice frame = new GUIPractice();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
It sizes correctly. The GridLayout means that all cells will be the same size. Since the text area is bigger than the buttons, you see extra space in the panel containing the buttons.
I would suggest you just use the default BorderLayout of the frame.
There is no need for your "panel" using the GridLayout.
You just use:
add(p1, BorderLayout.PAGE_START);
add(p2, BorderLayout.CENTER);
Now the p1 and p2 will be the proper height.
Also, there really is no need for "p2". You can just add the scroll pane directly to the frame.

How to set position to JComponent in BoxLayout?

I want to use 2 JPanel as panel and panel_1.
I want to add image automatically to panel using JLabel
and also add JButton to panel_1.
How can I resize button according to the image which is above the button?
public class Testing extends JFrame {
public Testing() {
this.setSize(590, 327);
this.setTitle("JFrame");
getContentPane().setLayout(null);
JPanel panel = new JPanel();
panel.setBounds(118, 136, 321, 89);
getContentPane().add(panel);
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
JLabel lblImage = new JLabel("image for button1");
panel.add(lblImage);
JLabel lblImage_1 = new JLabel("image for button2");
panel.add(lblImage_1);
JLabel lblImage_2 = new JLabel("image for button3");
panel.add(lblImage_2);
JPanel panel_1 = new JPanel();
panel_1.setBounds(118, 30, 321, 77);
getContentPane().add(panel_1);
panel_1.setLayout(new BoxLayout(panel_1, BoxLayout.X_AXIS));
JButton btnNewButton = new JButton("New button 1");
panel_1.add(btnNewButton);
JButton btnNewButton_1 = new JButton("New button 2");
panel_1.add(btnNewButton_1);
JButton btnNewButton_2 = new JButton("New button 3");
panel_1.add(btnNewButton_2);
}
public static void main(String[] args) throws Exception {
Testing frame = new Testing();
frame.setVisible(true);
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
}
}
If your goal is to have the button above the image, and have the button's width expand with the image, then:
Get rid of your use of null layouts and .setBounds(...) (this is just good general advice)
Put the JLabel with the image into a JPanel that uses BorderLayout with the JLabel in the BorderLayout.CENTER position
Put the button above the JLabel in the same JPanel using the BorderLayout.PAGE_START position.
Then put that JPanel wherever it is needed in the GUI, nesting JPanels, each using their own layout manager.
The BorderLayout will allow the center component to fill that position, and will expand the PAGE_START and PAGE_END positions to fill the width necessary. If the top and bottom components are wider, then this will also expand the width of the container.

Trying to add ScrollPane in Jpanel with null layout inside BorderLayout

I am trying to add a scrollbar in jpanel with null layout.
I want to create a form. This should should display few buttons at the bottom at all times.Any content inside form should maintain it's size and ratio even if the parent container is resized.
Here is what I've come with. I have a panel with borderlayout and added buttons at the south of border. Then created another jpanel to contain form that is added at the center of parent jpanel. Since I want form to maintain it's ratio I went with null layout for inner panel. But I want it to display scrollbar when content is not fully visible. enter image description here
Now adding inner jpanel into scrollpane and adding scrollpanel into parent panel (.add(scrollpane, BorderLayout.CENTER)) doesn't give desired format.
Is there any thing that I can do to get desired format?
Here is code Sample:
public static void main(String[] args) {
JFrame jFrame = new JFrame();
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.setSize(new Dimension(1000, 700));
Container c = jFrame.getContentPane();
c.setLayout(new BorderLayout());
bottomPanel(c);
centerPanel(c); //scrollbar should go in this panel
jFrame.setVisible(true);
}
private static void centerPanel(Container c) {
JPanel centerPanel = new JPanel();
centerPanel.setLayout(null);
JButton button = new JButton("This jObject should not resize when window resizes and also should maintain relative position.");
button.setBounds(new Rectangle(10, 10, 600, 50));
JButton button1 = new JButton("Just like it works in this code. Just Add ScrollPane to centerPanel That is in green backround");
button1.setBounds(new Rectangle(10, 70, 600, 50));
JButton button2 = new JButton("For clearity");
button2.setBounds(new Rectangle(10, 130, 600, 50));
centerPanel.add(button);
centerPanel.add(button1);
centerPanel.add(button2);
centerPanel.setBackground(Color.GREEN);
c.add(centerPanel, BorderLayout.CENTER);
}
private static void bottomPanel(Container c) {
JPanel bottomPanel = new JPanel(); //Buttons that goes at the bottom of screen will go in here
JPanel bottomInnerPanel = new JPanel();
bottomInnerPanel.setLayout(new BorderLayout());
bottomPanel.setLayout(new GridLayout());
bottomInnerPanel.add(new JButton("Add"), BorderLayout.WEST);
bottomInnerPanel.add(new JButton("Search"), BorderLayout.EAST);
bottomPanel.add(bottomInnerPanel);
bottomPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
c.add(bottomPanel, BorderLayout.SOUTH);
}

How to change width size of Jpanels in BorderLayout?

I have main JPanel which is Borderlayout with added 4 JPANELS: NORTH(Green), WEST(Red), CENTER(Gray), SOUTH(Blue). I want to reduce width size of WEST(Red) Jpanel, or increase width size of Center(Grey) Jpanel.
Screenshot:
Here is my code:
frame = new JFrame("FreshPos baza podataka");
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
// Main paneel
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.setBorder( BorderFactory.createEmptyBorder(10,10,10,10) );
frame.getContentPane().add(panel);
//West panel;
JPanel panelWest = new JPanel(new GridLayout(14,0,0,2));
panelWest.setPreferredSize(new Dimension(300, 300));
panelWest.setBorder( BorderFactory.createEmptyBorder(100,0,0,0) );
panel.add(panelWest, BorderLayout.WEST);
panelWest.setBackground(Color.red);
for (int i = 0; i < MAX_TABLES; i++) {
buttonsTables[i] = new JButton(tables[i]);
buttonsTables[i].setMaximumSize(new Dimension(Integer.MAX_VALUE, buttonsTables[i].getMinimumSize().height));
panelWest.add(buttonsTables[i]);
panelWest.add(Box.createVerticalStrut(10));
}
//South panel;
JPanel southPanel = new JPanel(); // Donji layout za dugmice
southPanel.setBorder( BorderFactory.createEmptyBorder(20,0,0,0) );
panel.add(southPanel, BorderLayout.SOUTH);
southPanel.setBackground(Color.BLUE);
JButton buttonDodaj = new JButton("Dodaj");
southPanel.add(buttonDodaj);
JButton buttonIzmeni = new JButton("Izmeni");
southPanel.add(buttonIzmeni);
JButton butonObrisi = new JButton("Obrisi");
southPanel.add(butonObrisi);
//North panel;
JPanel northPanel = new JPanel(); // Donji layout za dugmice
northPanel.setBorder( BorderFactory.createEmptyBorder(0,10,0,0) );
panel.add(northPanel, BorderLayout.NORTH);
northPanel.setBackground(Color.green);
JButton buttonImport = new JButton("Importuj fajl");
buttonImport.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
importActionPerformed(evt);
}
});
northPanel.add(buttonImport, BorderLayout.WEST);
JButton ButtonRecord = new JButton("Snimi fajl");
northPanel.add(ButtonRecord, BorderLayout.WEST);
// Central panel
JPanel centerPanel = new JPanel(new BorderLayout());
centerPanel.setBackground(Color.GRAY);
panel.add(centerPanel, BorderLayout.CENTER);
I want to reduce width size of WEST(Red) Jpanel
panelWest.setBorder( BorderFactory.createEmptyBorder(100,0,0,0) );
So why is the width of your Border so large?
A Border is for "extra" space around the components.
So the width of your panel is the width of the buttons plus the width of the border.
Edit:
panelWest.setPreferredSize(new Dimension(300, 300));
Don't hardcode a preferred size. The layout manager will calculate the size based on the above logic. Get rid of that statement.
Edit 2:
// buttonsTables[i].setMaximumSize(new Dimension(Integer.MAX_VALUE, buttonsTables[i].getMinimumSize().height));
Get rid of any logic that attempts to control the size of a component. The point of using layout managers is to let the layout manager do the size calcualtions.
So for your buttons panel you need to nest panels to prevent the buttons from taking all the space.
You can do something like:
JPanel wrapper = new JPanel();
wrapper.add(buttonsPanel);
...
//panel.add(panelWest, BorderLayout.WEST);
panel.add(wrapper, BorderLayout.WEST);
By default a JPanel uses a FlowLayout which will respect the preferred size of any component added to it.
Another option is to use a GridBagLayout with the wrapper panel. By default the panel will then be displayed in the "center" of the available space. So it will be vertically centered and you won't need the EmptyBorder.

Custom JPanel objects overlap when added to JFrame

I'm trying to create a custom timer that will record cumulative time passage separated by days. I have a custom JPanel that does all of the timer work for me. I would like to have a GUI interace with this JPanel represented 7 times. However, when I add more than one custom JPanel to either a JPanel or a JFrame, they don't show up. I've tried setting the layout and setting them to everything I can think of, but nothing works.
This is the basic setup of the Panel:
public class TimerPane extends JPanel{
private static JButton button = new JButton("Start");
private static JLabel label = new JLabel("Time elapsed:");
private static JLabel tLabel = new JLabel("0:0:0");
private static JLabel title = new JLabel("Timer");
public TimerPane(){
button.addActionListener(new ButtonListener());
this.add(title);
this.add(label);
this.add(tLabel);
this.add(button);
this.setOpaque(false);
this.setPreferredSize(new Dimension(100,100));
this.setMaximumSize(new Dimension(100,100));
}
}
This is my latest attempt at getting the JPanel to display multiple times (just twice here):
public static void main(String[] args){
JFrame frame = new JFrame("Timer");
JPanel panel = new JPanel();
frame.setPreferredSize(new Dimension(700,110));
panel.setLayout(new BorderLayout());
panel.add(new TimerPane(), BorderLayout.EAST);
panel.add(new TimerPane(), BorderLayout.WEST);
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
The GUI that executes after this is 700x110 of which only 100x100 on the far left is used for exactly one of my TimerPane panels. I have also tried GridLayout on the same code, but then only the TimerPane in the second "spot" shows up. Any suggestions?
First of all, please remove the static from the member variables: button, label, tLabel and title. Otherwise, having them static, it means they are shared by all the TimerPane instances.
You will see 2 timer panels now.
Next, you can change the BorderLayout to a FlowLayout for instance and add several instances of TimerPane.
panel.setLayout(new FlowLayout(FlowLayout.LEFT));
panel.add(new TimerPane());
panel.add(new TimerPane());

Categories