How to control the size of the panels - java

I'm learning swing gui and I get this result when I use the following code:-
The code I use :-
private void initUI() {
JTextArea visualize=new JTextArea();
visualize.setEditable(false);
//DEFINE BUTTONS....
JButton[] buttons1={addition,subtraction,division,multiplication};
JButton [] buttons2={expr,date,conversion};
JPanel numerical=new JPanel(new FlowLayout());
numerical.setPreferredSize(new Dimension(350, 50));
for(int i=0;i<buttons1.length;i++){
numerical.add(buttons1[i]);
}
numerical.setBorder(new TitledBorder("Numerical Operations"));
JPanel nonnum=new JPanel(new FlowLayout());
nonnum.setPreferredSize(new Dimension(500, 50));
for(int i=0;i<buttons2.length;i++){
nonnum.add(buttons2[i]);
}
nonnum.setBorder(new TitledBorder("Non-numerical Operations"));
JPanel operations = new JPanel(new BorderLayout(2,2));
operations.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
operations.setSize(800, 100);
operations.add(numerical,BorderLayout.WEST);
operations.add(nonnum,BorderLayout.EAST);
JTable sheet = new JTable(10,5);
add(visualize, BorderLayout.NORTH);
add(sheet,BorderLayout.SOUTH);
add(operations,BorderLayout.CENTER);
pack();
setSize(1000, 700);
setTitle("Spreadsheet Application");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
But what I really want is this:-
My questions :-
Why is the operations panel too long?
How can I change it's height?
Doesn't "operations.setSize(..)" work?

Try using GroupLayout.
I'm also new to swing gui and had similar problems - GroupLayout saved the day
JPanel complete=new JPanel();
GroupLayout gl=new GroupLayout(complete);
complete.setLayout(gl);
gl.setAutoCreateContainerGaps(true);
gl.setHorizontalGroup(gl.createParallelGroup() //this is parallel bcz you need components vertically
.addComponent(visualize) //you MUST add components to both horizontal and vertical groups
.addComponent(operations)
.addComponent(sheet)
);
gl.setVerticalGroup(gl.createSequentialGroup() //NOTE that this is sequential
.addComponent(visualize)
.addComponent(operations)
.addGap(50) //you can add gaps if you want
.addComponent(sheet)
);
add(complete);

Because that's how BorderLayout works, take a closer look at How to Use BorderLayout. The CENTRE position will occupy all the remaining space of the frame, where as the NORTH and SOUTH positions will try and honour the preferred sizes of the components.
You could use a GridBagLayout, which will allow you more control over the layout or use a series of compound layouts.
Something like...
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.BOTH;
add(visualize, gbc);
add(operations, gbc);
gbc.gridy = 1;
add(sheet, gbc);
It is generally discouraged to extend from a top level container like JFrame, instead you should use something like JPanel to define your UIs and then add them to the containers you want. This increases there re-usability and makes it easier to use on different containers
You may also like to take a look at How to Use Scroll Panes

SOME of us find GridBagLayout to be a royal pain, and you may not have to use it to do what you want to do.
The idea behind a layout manager is to let the layout manager control the size and position of its components so that you don't have to futz with them. MP is right, GridBag allows you a lot of control, but that also means you have to get a lot of things right to have it do what you want it to do.
So, an alternative: Make a JPanel to hold the visualize and operations panels; give this new panel a BoxLayout with a Y_AXIS orientation, then add them in the order you want them to appear, top-to-bottom.
Then put sheet in the BorderLayout.CENTER of the JFrame. In fact, I think you'll want to take MP's advice and go through a tutorial on JScrollPane; as best I remember, you create the panel, then create the JScrollPane instance with the panel as a construction parameter, then add the scrollpane instance to the JFrame (in the CENTER, in your case).
Being in the center, it will then expand and contract as the user changes window size.
Good luck. Swing takes some getting used to.

Related

Align to the limit Components in a JPanel Swing

I need to totally align components to the JTextArea components, I am currently using a BoxLayout and I already used the setAlignmentX and setHorizontalAlignment to LEFT but it's not working. Here I upload an image to make clearer what I mean. For example look at "+ Pla PLAMARC" it's clearly not aligned with the text area component.
By the moment this is the code:
//Declarations
private JLabel nomPla;
private JTextArea infoPla;
private JScrollPane textAreaScroll;
//Inside the constructor
nomPla = new JLabel();
infoPla = new JTextArea(2, 50);
textAreaScroll = new JScrollPane(infoPla);
this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
nomPla.setAlignmentX(Component.LEFT_ALIGNMENT);
nomPla.setHorizontalAlignment(nomPla.LEFT);
textAreaScroll.setAlignmentX(Component.CENTER_ALIGNMENT);
this.setBorder(new EmptyBorder(new Insets(25, 25, 25, 25)));
this.add(nomPla, BorderLayout.NORTH);
this.add(textAreaScroll, BorderLayout.NORTH); //Orientacions
I am clearly telling nomPla to be on the leftside, but this is not the same as the JTextArea.
How is this done then?
I already used the setAlignmentX and
The setAlignmentX(...) needs to be applied to all the components you add to the BoxLayout if you want all to be left aligned with respect to the BoxLayout.
Edit:
I just want the labels to be on the left side, not the JTextArea components..
Then you need to use a wrapper panel for the BoxLayout Panel.
For example:
JPanel wrapper = new JPanel( new FlowLayout(FlowLayout.CENTER) );
wrapper.add(yourBoxLayoutPanel);
frame.add(wrapper);
Now all the components in the BoxLayout will be left aligned and the BoxLayout panel will be center aligned in the wrapper panel.
Layout management is about nesting panels with different layout manager to achieve you desired effect.

I want my JTable at the centre

I want my JTable at the centre of my JFrame and for this purpose i have used setbounds method but it's not doing anything and i don't want to use layout managers.I just want to know that why it's not doing anything?
Here is my code:
tabel=new JTable(data,columnNames);
tabel.setLayout(null);
tabel.setPreferredScrollableViewportSize(new Dimension(500,50));
tabel.setFillsViewportHeight(true);
JScrollPane pane=new JScrollPane(tabel);
pane.setBounds(100,700,200,200);
add(pane);
It's better to use layout managers but if you insist,that you want to move JTable in JFrame by setting layout to null,then you should try the following option:
(1)Make a JPanel in JFrame and add that table to JPanel in this way
JPanel panel=new JPanel();
panel.setBounds(20,300,700,300);
add(panel);
tabel=new JTable(data,columnNames);
tabel.setBounds(100,20,700,400);
tabel.setPreferredScrollableViewportSize(new Dimension(500,50));
tabel.setFillsViewportHeight(true);
JScrollPane pane=new JScrollPane(tabel);
panel.add(pane);
You should add everything to a JPanel, and then set the layout of the JPanel to a border layout. Add the table to the JPanel and then position it at the center. This is the easiest way to do it. Layouts may seem complicated and inconvenient at first but once you learn them, you quickly realise they are a million times easier that setting bounds and null layouts. Here is a link to learn about border layout: https://docs.oracle.com/javase/tutorial/uiswing/layout/border.html
You are adding JTable to a JFrame(Top level component).This may get you going
JPanel tablePanel = new JPanel(new GridBagLayout());
GridBagConstraints layout= new GridBagConstraints();
JTable jtable = new JTable();
jtable.setPreferredScrollableViewportSize(new Dimension(500,50));
jtable.setFillsViewportHeight(true);
layout.fill = GridBagConstraints.BOTH;
layout.weightx = 1;
layout.weighty = 1;
layout.gridx = 0;
layout.insets = new Insets(10,10,10,10);
tablePanel.add(new JScrollPane(jtable), layout)
You may want to set layout dimensions and insets according to your jtable.

How to fill Cells of GridbagLayout with the controls in Swing?

I need to design a swing GUI which has a JFrame with a Menu on top and another main panel having three more panels in center and a separate panel in the bottom of the panel. The required design of the UI is as below
But when I run my swing application I get the output like this (all the panels are packed in the center of the window)
Below is my code
import java.awt.*;
import javax.swing.*;
public class FrontEndView {
private JFrame mainFrame;
private JPanel mainPanel,subPanelUp,subPanelDown,panelLeft,panelRight,panelCenter,panelDown;
private JScrollPane scrollPane;
private JList logViewList;
private JPanel panel1;
public FrontEndView(){
this.prepareGUI();
}
public void prepareGUI(){
mainFrame=new JFrame("GUI");
Toolkit tk = Toolkit.getDefaultToolkit();
int xSize = ((int) tk.getScreenSize().getWidth());
int ySize = ((int) tk.getScreenSize().getHeight());
mainFrame.setSize(xSize,ySize);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setResizable(true);
mainFrame.setLayout(new BorderLayout());
mainPanel=new JPanel();
mainPanel.setLayout(new GridBagLayout());
mainPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
GridBagConstraints gridbagConstMain = new GridBagConstraints();
GridBagConstraints gridbagConstSub = new GridBagConstraints();
subPanelUp=new JPanel();
subPanelUp.setLayout(new GridBagLayout());
subPanelUp.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
panelLeft=new JPanel();
panelLeft.setBorder(BorderFactory.createTitledBorder("Message Defs"));
gridbagConstSub.fill = GridBagConstraints.HORIZONTAL;
gridbagConstSub.weightx = 0.5;
gridbagConstSub.gridx = 0;
gridbagConstSub.gridy = 0;
subPanelUp.add(panelLeft, gridbagConstSub);
panelCenter=new JPanel();
panelCenter.setBorder(BorderFactory.createTitledBorder("Main Workspace"));
gridbagConstSub.fill = GridBagConstraints.HORIZONTAL;
gridbagConstSub.weightx = 0.5;
gridbagConstSub.gridx = 1;
gridbagConstSub.gridy = 0;
subPanelUp.add(panelCenter, gridbagConstSub);
panelRight=new JPanel();
panelRight.setBorder(BorderFactory.createTitledBorder("Script Viewer"));
gridbagConstSub.fill = GridBagConstraints.HORIZONTAL;
gridbagConstSub.weightx = 0.5;
gridbagConstSub.gridx = 2;
gridbagConstSub.gridy = 0;
subPanelUp.add(panelRight, gridbagConstSub);
mainPanel.add(subPanelUp,gridbagConstMain);
subPanelDown=new JPanel();
subPanelDown.setLayout(new BorderLayout());
panelDown=new JPanel();
panelDown.setBorder(BorderFactory.createTitledBorder("Log View"));
logViewList= new JList();
panelDown.add(logViewList);
gridbagConstSub.fill = GridBagConstraints.HORIZONTAL;
//gridbagConst.ipady=20;
//gridbagConst.weightx = 0.0;
gridbagConstSub.gridwidth = 5;
gridbagConstSub.gridx = 0;
gridbagConstSub.gridy = 0;
subPanelDown.add(panelDown,BorderLayout.PAGE_END);
mainPanel.add(subPanelDown, gridbagConstSub);
scrollPane=new JScrollPane(mainPanel,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
mainFrame.add(scrollPane);
mainFrame.setVisible(true);
}
public static void main(String[] args){
FrontEndView frontEnd = new FrontEndView();
}
}
I want to fill the GridBagLayout's cells with the relevant panel/control it holds as shown in the design and also each panel should have its controls filled inside (I need to add a JList inside the panelDown whose size should be the size of the panelDown JPanel).Simply I don't need any extra space visible in my JFrame. Please guide me on what is missing in my code.
I would suggest you can use nested panels with different layout managers to solve the problem.
The default layout of a frame is a BorderLayout.
So you could create a panel and add it to the PAGE_END so it displays the entire width at the bottom.
Then you can create another panel that uses a GridLayout. You can then add 3 child panels to this panel and each panel can use its own layout. Then you add this panel to the CENTER of the frame. As the frame size changes the extra spaces will be allocated to the CENTER so the panels will dynamically grow.
Edit:
Too many panels for me to take the time to understand what is happening
I was suggesting a structure like this:
frame (which by default uses a BorderLayout)
--- CENTER
panel using GrigBagLayout
childPanel1
childPanel2
childPanel3
---- PAGE_END
JScrollPane containing the JList
When you create the JList the basic code would be:
JList list = new JList(...);
list.setVisibleRowCount(5);
JScrollPane scrollPane = new JScrollPane( list );
There is no need to create a panel just to add the list to another panel. The point of setting the visible row count is to give the JList a fixed height. Scrollbars will then appear in the scroll pane as needed.
Now that the PAGE_END has a fixed height component all the reset of the space will go to the component that you add to the CENTER of the frame.
all the panels are packed in the center of the window)
The panels are displayed at their preferred sizes when you use the GridBagLayout. If the total size of all the panels is less than the size of the scrollpane then they will be in the center. If you want the panels to fill the space available, then I believe you need to use the weightx/y constraints. Read the section from the Swing tutorial on How to Use GridBagLayout which describes all the constraints.
That is why I suggested a GridLayout instead. It will make all the panels the same size and will fill the viewport of the scroll pane without playing with constraints.
mainFrame.add(menubar,BorderLayout.NORTH);
That is not how you add a menubar to the frame.
You should be using:
mainFrame.setJMenuBar(menuBar);
You were told this in your last question. Why did you not listen to the advice??? Why should we take the time to help when you don't pay attention to what is suggested.
Based on your instructions I changed my design in a way all of the outer panels are used with Border Layout and the inner most ones with more controls were used with Grid, GridBag and FlowLayouts based on the requirement. In that way the entire design could be done nicely.
Also if a particular panel within a cell of a layout needs to be expanded, I used the setPreferredSize(new Dimension(int,int)) whenever required.

Position of buttons in rows, in a JPanel based 'menu bar'

I'm trying Swing programming but I can't do what I want.
I would like to place a top bar button with 2 lines of button but I just have 1 line in my case.
Here is my code:
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
setMinimumSize(new Dimension(1000,500));
setMaximumSize(new Dimension(1000,500));
JPanel panelButton = new JPanel();
JPanel panelTopButton = new JPanel();
JPanel panelBottomButton = new JPanel();
panelTopButton.add(dashboard);
panelTopButton.add(journal);
panelTopButton.add(myPlans);
panelTopButton.add(myFavorites);
panelTopButton.add(shoppingCart);
panelBottomButton.add(profile);
panelBottomButton.add(notifications);
panelButton.add(panelTopButton, BorderLayout.NORTH);
panelButton.add(panelBottomButton, BorderLayout.SOUTH);
contentPane.add(panelButton,BorderLayout.NORTH);
//Display
setSize(400,120);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
I have this
And I want this
Can somebody help me?
You need one panel for each line.
Try to do this:
JPanel panelButtonsL1 = new JPanel();
JPanel panelButtonsL2 = new JPanel();
panelButtonsL1.add(dashboard);
panelButtonsL1.add(journal);
panelButtonsL1.add(myPlans);
panelButtonsL1.add(myFavorites);
panelButtonsL1.add(shoppingCart);
panelButtonsL2.add(profile);
panelButtonsL2.add(notifications);
The default layour of JPanel is FlowLayout. Bear in mind that layout is very important to work with swing component disposition.
Define the bottom panel as GridLayout.
JPanel panelButton = new JPanel(new GridLayout(2, 1)); // 2 rows x 1 column
panelButton.add(panelButtonsL1);
panelButton.add(panelButtonsL2);
Details of GridLayout you can find on API.
You can achieve that using a GridLayout: assign a GridLayout to panelButton with two rows and one column, and then add the two panels to it.
According to what you want there is a simpler alternative by continue using the default FlowLayout from the panel. It is more appropriate than using GridLayout since you wanted the last 2 buttons to move to the next row and center itself.
If you use GridLayout, the buttons at the next row are likely going to be directly below one of the buttons above. Here are 2 ways to get what you want.
Method 1. Reduce the width of the main panel holding your buttons:
Dosing so, you will have to add the main panel using BorderLayout.CENTER.
Method 2. Add the buttons to a sub-panel of smaller width and add it to the main panel. All your buttons will be added to the smaller sub-panel:

JScrollPane not getting larger when JLabels are added to panel

my problem is that although the scroll bar is appearing on the specific panel I want it to it's not extending as labels are added. I would like it to extend when the labels start going off the panel that they are being added to.
I have a main JPanel 'panel' which uses GridBagLayout, within that I have 5 other panels, the ones that needs a scroll bar is boardPanel which has null value for setLayout()
panel = new JPanel();
panel.setLayout(new GridBagLayout());
...
1Panel = new JPanel();
1Panel.setPreferredSize(new Dimension(480, 800));
1Panel.setLayout(null);
scrollPanel = new JScrollPanel(1Panel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
...
c.weighty = 1.0;
c.weightx = 0.6;
c.gridx = 0;
c.gridy = 0;
c.gridheight = 3;
panel.add(scrollPanel, c);
...
I hope this is enough information, thank you so much for your help in advance.
Don't use a null layout!!!
Don't use setPreferredSize()!!!
Scrollbars will appear when the preferred size of the component is greater than the size of the scroll pane. By hardcoding a size you break this functionality.
Use a layout manager and the preferred size will change dynamically as you add components to the panel.
Read the Swing tutorial on Layout Managers

Categories

Resources