so i have a problem i cant solve i want my GUI app to be split between 3 JPanels (left, center, right). I want left panel and right panel to be of fixed size and center to be fluid. Meaning side panels expand only vertically as JFrame is expanded and center panel expands bot horizontally and vertically.
I have set minimal size for all panels to be height of 600 but they just stay in the minimal size and dont expand as JForm increases i dont know how to set bounds to JFrame borders so they expand whit it.
package ppe.view;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import net.miginfocom.swing.MigLayout;
public class UI_View extends JFrame
{
private JList browse = new JList();
private JScrollPane rightX = new JScrollPane();
private JButton btn1 = new JButton("Button 1");
private JButton btn2 = new JButton("Button 2");
private JButton btn3 = new JButton("Button 3");
private JButton btn4 = new JButton("Button 4");
public UI_View()
{
this.setTitle("Prototype MVC Arhitecture");
this.setMinimumSize(new Dimension(800, 600));
this.setExtendedState(this.MAXIMIZED_BOTH);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setLayout(new MigLayout());
JPanel content = new JPanel(new MigLayout());
content.setBackground(Color.black);
JPanel right = new JPanel(new MigLayout());
JPanel center = new JPanel(new MigLayout());
JPanel left = new JPanel(new MigLayout());
right.setBackground(Color.red);
right.setMinimumSize(new Dimension(200, 600));
right.setMaximumSize(new Dimension(200, 37500));
center.setBackground(Color.green);
center.setMinimumSize(new Dimension(400, 600));
left.setBackground(Color.blue);
left.setMinimumSize(new Dimension(200, 600));
left.setMaximumSize(new Dimension(200, 37500));
content.add(left);
content.add(center);
content.add(right);
this.setContentPane(content);
}
public static void main(String[] args)
{
new UI_View().setVisible(true);
}
}
I have tryed bounding them to another content panel and adding that panel as ContentPane to JFrame that automatically bounds it to JFrame border but the thing is still pretty much fixed.
If you're using MiGLayout why don't you configure the constraints when adding the components?
This, for example, might help (although I'm a MiGLayout beginner, too):
content.add(left, "growy");
content.add(center, "grow"); //the same as growx, growy
content.add(right, "growy");
In some cases I needed to also add a pushx but I'm not sure when this is needed. Please refer to the documentation for further information.
Edit: it seems like you always have to add push for components that should cause the column/row to grow. Otherwise grow alone would make the components as big as the column/row they are in which in turn is defined by the largest component in that column/row. If there is more space available columns/rows won't grow to fill it without the push keyword.
From the documentation:
Components will never "push" the column/row's size to be larger using the grow keyword.
Related
Im creating an application in java swing and in it Im making what I think is called an embedded Jpanel which is to my understanding a jpanel inside a jpanel. To make this simpler we will use the panel names there is content, sidebar, and content sidebar
Sidebar is just the sidebar for the application with buttons
Content is the main content of the app
Content sidebar is a side bar inside of content, I use this so my settings page has its own side bar apart from the normal side bar.
I make sidebar aligned to WEST and content CENTER
after content.add(contentSidebar, BorderLayout.WEST); it won't make content sidebar go to west and im not sure why.
this is my source code
package Assets.Settings;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Security implements ActionListener{
JFrame Security;
JPanel sideBar;
JPanel content;
//for sidebar
JButton volume;
JButton security;
JButton contactUs;
JPanel contentSidePanel;
// JButton twoStep;
// JButton changePassword;
public void security(){
Security = new JFrame();
sideBar = new JPanel();
content = new JPanel();
contentSidePanel = new JPanel();
sideBar.setPreferredSize(new Dimension(125, 700));
content.setPreferredSize(new Dimension(1000, 700));
content.setBackground(Color.YELLOW);
Security.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Security.setTitle("Anonyomail Security Settings");
Security.setSize(1152, 700);
Security.setLayout(new java.awt.BorderLayout());
contentSidePanel.setLayout( new java.awt.BorderLayout());
volume = new JButton();
security = new JButton();
contactUs = new JButton();
// twoStep = new JButton();
// changePassword = new JButton();
volume.addActionListener(this);
contactUs.addActionListener(this);
volume.setText("Volume");
security.setText("Security");
contactUs.setText("Contact Us");
// changePassword.setText("Change Password");
// twoStep.setText("2-Step");
security.setBackground(Color.decode("#24a0ed"));
contentSidePanel.setPreferredSize(new Dimension(100, 700));
contentSidePanel.setBackground(Color.BLACK);
// contentSidePanel.add(changePassword);
// contentSidePanel.add(twoStep);
content.add(contentSidePanel, BorderLayout.WEST);
sideBar.add(volume);
sideBar.add(security);
sideBar.add(contactUs);
Security.add(sideBar, BorderLayout.WEST);
Security.add(content, BorderLayout.CENTER);
Security.pack();
Security.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == volume){
//open volume
}else if(e.getSource() == contactUs){
//open contact us
}
}
}
EDIT
The issue is that I didn't give content a border layout
You call content.add(contentSidePanel, BorderLayout.WEST) however you never set content's layout manager to BorderLayout. I believe JPanel's default layout manager is FlowLayout and thus BorderLayout.WEST implies nothing.
On another note, it seems like you're only adding one thing, contentSidePanel, to content. I believe that BorderLayout will size content to the same size as contentSidePanel and that specifying BorderLayout.WEST will have no effect since there is nothing in the center or to the east. Try adding a test JPanel to content and setting it's layout to BorderLayout.CENTER to see if I'm correct.
Note: BorderLayout's position constants where updated in JDK 1.4 from compass positions (NORTH, EAST, ...) to wordier constants (PAGE_START, PAGE_END, LINE_START, LINE_END and CENTER). Therefor the use of BorderLayout.WEST should be replaced with BorderLayout.LINE_START. - from How to use BorderLayout
I am trying to add button in my GUI using Gridbagconstraints in LayoutManager in Java. The location of the button is always in the center, irrespective of the coordinates.
package StudentInfo;
import javax.swing.*;
import java.awt.*;
public class Gui {
public static void main(String[] args) {
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.add(panel);
panel.setLayout(new GridBagLayout());
frame.setSize(600,600);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
GridBagConstraints gbc = new GridBagConstraints();
JButton b = new JButton("Hello");
gbc.gridx=1;
gbc.gridy=1;
panel.add(b,gbc);
JButton v = new JButton("exit");
gbc.gridx=1;
gbc.gridx=0;
panel.add(v,gbc);
}
}
Output
Question
How to define co-ordinates of the buttons and place them at desired location?
You need to set weightx and weighty for the GridBagConstraints object.
Unless you specify at least one non-zero value for weightx or weighty, all the components clump together in the center of their container. This is because when the weight is 0.0 (the default), the GridBagLayout puts any extra space between its grid of cells and the edges of the container.
How to Use GridBagLayout
I recommend you read through this tutorial as well as the ones on the other swing layout managers if you want to continue working with GUIs in Java as they require a good deal of proficiency to use properly.
I have a JFrame and three JPanels. On the frame I used BorderLayout. At the CENTER of the frame I have put outerPanel. On my outerPanel I have used MigLayout. The two other panels are added on to the outerPanel. These two panels are of equal size and their widths add up to the width of the outerPanel - I wanted the outerPanel to be divided into two halves. Below is the code for this:
public class ControlPanel extends JFrame {
// components
public JPanel outerPanel;
public JPanel innerPanel1;
public JPanel innerPanel2;
public ControlPanel() {
this.createUI();
}
public void createUI() {
// form properties
this.setSize(new java.awt.Dimension(300, 300));
this.setVisible(true);
this.setLayout(new java.awt.BorderLayout());
this.outerPanel = new JPanel();
this.outerPanel.setPreferredSize(new java.awt.Dimension(260, 250));
this.outerPanel.setLayout(new net.miginfocom.swing.MigLayout());
this.outerPanel.setBorder(BorderFactory.createEtchedBorder());
this.add(new javax.swing.JLabel("North"), BorderLayout.NORTH);
this.add(this.outerPanel, BorderLayout.CENTER);
this.innerPanel1 = new JPanel();
this.innerPanel1.setPreferredSize(new java.awt.Dimension(130, 150));
this.innerPanel1.setLayout(new net.miginfocom.swing.MigLayout());
this.innerPanel1.setBorder(BorderFactory.createTitledBorder("Panel1"));
this.innerPanel2 = new JPanel();
this.innerPanel2.setPreferredSize(new java.awt.Dimension(130, 150));
this.innerPanel2.setLayout(new net.miginfocom.swing.MigLayout());
this.innerPanel2.setBorder(BorderFactory.createTitledBorder("Panel2"));
this.outerPanel.add(this.innerPanel1);
this.outerPanel.add(this.innerPanel2);
this.pack();
}
public static void main(String[] args) {
ControlPanel cp = new ControlPanel();
}
}
Problem: When I run my program, the GUI that appears before I resize the window is fine; but when I resize the window -enlarging it, innerPane1 and innerPanel2 remains of the same size without resizing to occupy the space available.
Question: How do we make the two panels , innerPannel1 and innerPanel2, resize at the same time with the window so that they can share equally the available space? Any particular Layout Manager that can be used to divide a panel into two equal halves that can resize at the same time with the window?
Images Showing the output.
Before resizing - the GUI looks well and the panels have correct size.
After resizing -the GUI is distorted and the panels doesn't change size.
I suggest you use new GridLayout(1, 2). This will split the panel in 1 row and 2 (equally sized) columns.
So, simply changing
this.outerPanel = new JPanel();
to
this.outerPanel = new JPanel(new GridLayout(1, 2));
should do.
I am currently trying to take the typed text in the textField 'itemName' and have it print out on the text area 'printArea.' When I have both printArea and itemName on the same JPanel (p1) it works just fine. When printArea is set to a separate JPanel (itemName on p1 and printArea on p2), nothing prints out. Two JPanels are used to make the GUI appear as it was assigned. The area i Believe to be the issue is where I added JPanel 'p1' to JPanel 'p2'.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MovieGUI extends JFrame{
JButton submit = new JButton("Submit");
JTextField itemName = new JTextField();
JTextField itemPrice = new JTextField();
JTextField itemQuantity = new JTextField();
JTextArea printArea = new JTextArea(400,400);
public MovieGUI(){
JPanel p1 = new JPanel();
p1.setLayout(new GridLayout(6, 2));
p1.add(new JLabel("Item Name"));
p1.add(itemName); //p1.add(new JTextField(8));
p1.add(new JLabel("Item Price"));
p1.add(itemPrice); // p1.add(new JTextField(8));
p1.add(new JLabel("Quantity"));
p1.add(itemQuantity); //p1.add(new JTextField(8));
p1.add(new JLabel("submit"));
p1.add(submit);
//Something is not working...
JPanel p2 = new JPanel(new BorderLayout());
p2.setLayout(new BorderLayout());
p2.add(p1, BorderLayout.NORTH);
p2.add(printArea, BorderLayout.SOUTH);
//add(p1);
add(p2);
event e = new event();
submit.addActionListener(e);
}
public class event implements ActionListener{
public void actionPerformed(ActionEvent e){
String text = itemName.getText();
printArea.setText(text); //printArea.setText("BUTTON");
}
}
public static void main(String[] args){
MovieGUI frame = new MovieGUI();
frame.setTitle("Submission");
frame.setSize(800, 500);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
Your JPanel p2 does not contain nothing on CENTER alignment, so printArea doesn't view on SOUTH alignment. To see the inputItem text on printArea change from
p2.add(printArea, BorderLayout.SOUTH);
to
p2.add(printArea, BorderLayout.CENTER);
Your text is being printed in printArea, but the first line (and more) of the printArea is hidden behind p1. This is because the south location with printArea is filling the entirety of p2, but it's z-index means it is behind p1. You can see this if you do:
p2.add(printArea, BorderLayout.SOUTH);
printArea.setBackground(Color.BLUE);
p2.setComponentZOrder(printArea, 0); // now the blue printArea hides the form elements in p1
To fix this: change printArea to CENTER instead of SOUTH.
Why?
It helps to understand how BorderLayout works to understand why. It is not splitting up the areas by percentage but it is used to arrange components around a centre panel. The order of the layout is:
North / South components will use their preferred height, and then the width of the component they're in.
I'll ignore East/West in here as you aren't using them.
Centre will use the remaining space after the N/S/E/W components have been sized
Your printArea's preferred height was "huge" (technical term!), so it was trying to use that. Once in a centre panel it is told to use the remaining space only: as p1 has a preferred height that is smaller than the p2 height, the centre panel gets the remaining height and you can still see the printArea. You can also see this effect if you reverse the addition order when using NORTH/SOUTH; you would then only see the printArea, not the p1 form.
If you take a look at the source of BorderLayout in the JDK, you can see the layoutContainer method where this all takes place.
Is it possible to have some extra space around the edges of a JFrame that uses AbsoluteLayout? When I have a button as the downwardsmost component on the JFrame, it gets positioned right up against the bottom edge of the JFrame window, and it looks bad. I would like to know if there's a way to add a little extra space between components and the edge of the JFrame while using AbsoluteLayout.
Suggestions:
When you add a component to a JFrame, you're actually adding it to the JFrame's contentPane. To give the contentPane a "buffer" border, consider giving it an EmptyBorder(...) with the parameters being int constants for the amount of border desired around the component.
Avoid using "absolute" layouts for anything, and especially for placing components at easy to place locations for the layout managers, such as at the bottom of the GUI.
For example, note in the GUI created in the code below how the center and bottom JPanel's don't go out to the edge of the GUI because of the empty border:
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.*;
public class ButtonAtBottom {
private static void createAndShowGui() {
JPanel bottomPanel = new JPanel();
bottomPanel.add(new JButton("Bottom Button"));
bottomPanel.setBorder(BorderFactory.createTitledBorder("Bottom Panel"));
JPanel centerPanel = new JPanel();
centerPanel.setBorder(BorderFactory.createTitledBorder("Center Panel"));
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.add(centerPanel, BorderLayout.CENTER);
mainPanel.add(bottomPanel, BorderLayout.PAGE_END);
// **** here I add the border to the mainPanel which I'll
// make into the contentPane
int eb = 25;
mainPanel.setBorder(BorderFactory.createEmptyBorder(eb, eb, eb, eb));
// don't set the preferredSize per Kleopatra, but am doing it
// here simply to make code shorter for this sscce
mainPanel.setPreferredSize(new Dimension(500, 400));
JFrame frame = new JFrame("ButtonAtBottom");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
You can use Box.createRigidArea(dimensions) to create an empty space that you can add below the button.
Set an empty border on your content panel where SIZE is the amount of padding you want.
JFrame frame = new JFrame();
JPanel panel = new JPanel(null);
panel.setBorder(BorderFactory.createEmptyBorder(SIZE,SIZE,SIZE,SIZE);
frame.setContentPane(panel);
//The rest
The arguments are for top, left, bottom and right padding so if you want different paddings on each edge, you can set it accordingly.