I want to make with swing this interface:
And when I resise it I want all the subpanels and buttons to be resized like this:
Not only main window to be resized. I am using GridBagLayout. And I dont know how to stick the borders of the panel with GridBagLayout to the borders of the Frame in that way, when I am resizing the frame the panel also to be resized.
I normally use nested layouts for this.
Use a JPanel with a BorderLayout as the base.
Store your central components in a JPanel, and add this to the CENTER of the BorderLayout.
Store your bottom components in two separate JPanels.
Create another JPanel with a GridLayout of 1 row and 2 columns.
Add the two JPanels to it in the correct order.
Add this JPanel to the SOUTH of the BorderLayout.
The property to achieve this, i.e. when JFrame is resized the JPanel should also resize itself, will be GridBagConstraints.BOTH. It appears to me that your Left JButton is a bit smaller than the Right JButton. If you really wanted to achieve this with GridBagLayout, here I have crafted a small sample code for your help, have a look and ask any question that may arise :
import java.awt.*;
import javax.swing.*;
public class GridBagExample
{
private JPanel contentPane;
private void displayGUI()
{
JFrame frame = new JFrame("GridBag Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = new JPanel();
contentPane.setLayout(new GridBagLayout());
JPanel centerPanel = new JPanel();
centerPanel.setOpaque(true);
centerPanel.setBackground(Color.CYAN);
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.weightx = 1.0;
gbc.weighty = 0.9;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
gbc.fill = GridBagConstraints.BOTH; // appears to me this is what you wanted
contentPane.add(centerPanel, gbc);
JButton leftButton = new JButton("Left");
JButton rightButton = new JButton("Right");
gbc.gridwidth = 1;
gbc.gridy = 1;
gbc.weightx = 0.3;
gbc.weighty = 0.1;
contentPane.add(leftButton, gbc);
gbc.gridx = 1;
gbc.weightx = 0.7;
gbc.weighty = 0.1;
contentPane.add(rightButton, gbc);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
new GridBagExample().displayGUI();
}
});
}
}
Related
I am having issue where my JPanel is not setting up the size. I am not sure if is something to do with my JTab or JFrame. I am using GridBagLayout layout management. And for some reason are not able to set the size.
Here is a dummy code, following the same logic to my original source code:
FirstPanel.java
import javax.swing.*;
import java.awt.*;
public class FirstPanel extends JPanel {
private JLabel label1 = new JLabel("Label 1");
private JTextField textField1 = new JTextField();
private GridBagConstraints c = new GridBagConstraints();
public FirstPanel() {
//Size is not overriding
Dimension size = getPreferredSize();
size.width = 100;
setPreferredSize(size);
setBorder(BorderFactory.createTitleBorder("Border Title");
setLayout(new GridBagLayout());
addComponents();
}
private void addComponents() {
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.NORTHWEST;
c.insets = new Insets(5, 0, 0, 0);
add(label1, c);
c.gridx = 1;
add(textField1, c);
c.weightx = 1;
c.weighty = 1;
add(new JLabel(""), c);
}
}
MainPanel.java
import javax.swing.*;
import java.awt.*;
public class MainPanel {
private JFrame frame = new JFrame("App");
private JPanel panel1 = new JPanel(new GridBagLayout());
private GridBagConstraints c = new GridBagConstraints();
private JTabbedPane tabPane = new JTabbedPane();
public MainPanel() {
addComponents();
frame.add(tabPane);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 350);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
}
private void addComponents() {
tabPane.addTab("Tab 1", new FirstPanel());
}
}
Main.java
public class Main {
public static void main(String[] args) {
new MainPanel();
}
}
Or at least have two JPanels,
Exactly.
Frist you create a main panel using a BorderLayout that you add to the tabbed pane.
Then you have a second panel for your labels and text fields (using whatever layout manager you want). Then you add this panel to the BorderLayout.LINE_START.
Then you add your scrollpane containing the JTable to the BorderLayout.CENTER of the main panel.
Read the tutorial on Layout Manager. Nest panels with different layout managers as required.
want to have JTable taking 50% of the other side.
Picking a random number like 50% is not the way to design a GUI. What happens if the frame is made smaller/larger. What happens to the space? Design the layout with flexibility in mind, just like your browser window is designed. There are always fixed areas where the size is determined by the components added and there is a flexible area that grows/shrinks as desired.
I am trying to make a login page but unfortunately my formPanel's border is so out of bounds. Here in the pic you can see the titled border is way out. I need it to be more around my panel with login form:
I see that when creating this formPanel it is that big and the border just surround it. I tried with setPrefferedSize but its not working. How can I fix it?
Here is my code:
public class LoginPanel extends JPanel {
private JLabel title;
public LoginPanel() {
this.setBackground(new Color(0, 128, 43));
this.setBorder(new EmptyBorder(10, 10, 10, 10));
this.setLayout(new BorderLayout());
//adding the title
title = new JLabel("<html><h1><strong><i>Krisko Beatz Quiz</i></strong></h1><hr></html>");
title.setForeground(Color.BLACK);
JPanel titlePanel = new JPanel();
titlePanel.setBackground(new Color(0, 128, 43));
titlePanel.add(title);
this.add(titlePanel, BorderLayout.PAGE_START);
//creating the login form
JPanel formPanel = new JPanel(new GridBagLayout());
formPanel.setBackground(new Color(0, 128, 43));
//gbc
GridBagConstraints gbc = new GridBagConstraints();
//gbc for username
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(5, 0, 0, 0);
JLabel username = new JLabel("Username: ");
username.setForeground(Color.BLACK);
formPanel.add(username, gbc);
//gbc for textfield
gbc.gridx = 1;
gbc.gridy = 0;
JTextField usernameField = new JTextField(10);
formPanel.add(usernameField, gbc);
//gbc for pass
gbc.gridx = 0;
gbc.gridy = 1;
JLabel password = new JLabel("Password: ");
password.setForeground(Color.BLACK);
formPanel.add(password, gbc);
//gbc for pass field
gbc.gridx = 1;
gbc.gridy = 1;
JPasswordField passField = new JPasswordField(10);
formPanel.add(passField, gbc);
//gbc for button
gbc.gridx = 1;
gbc.gridy = 2;
gbc.gridwidth = 2;
gbc.anchor = GridBagConstraints.PAGE_END;
JButton loginButton = new JButton("Login");
formPanel.add(loginButton, gbc);
//add border to the form panel
TitledBorder title = BorderFactory.createTitledBorder("Login");
formPanel.setBorder(title);
this.add(formPanel, BorderLayout.CENTER);
}
}
I tried with setPrefferedSize but its not working.
Don't try to manage the preferredSize of a component.
I would guess the problem is that you are using setSize(...) instead of pack().
You should be using pack() AFTER all the components have been added to the frame. Then all the components will be displayed at their preferred size.
Edit:
I originally misread your question and changed my original answer. The point in my original answer of using the "wrapper" panel is to give extra space to the wrapper panel, while keeping the "formPanel" at a fixed size. This way the titled border will remain around the formPanel even as the frame size is changed.
So again the basic approach for this type of solution is:
JPanel wrapper = new JPanel( new GridBagLayout() );
wrapper.add(formPanel, new GridBagConstraints());
this.add(wrapper, BorderLayout.CENTER);
//this.add(formPanel, BorderLayout.CENTER);
I took your LoginPanel class as is, and wrote a Main class around it to start the GUI.
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new LoginPanel());
frame.pack();
frame.setVisible(true);
});
}
}
Especially note, I did no explicit setting of the size, only a pack() call which resizes everything to its preferred size according to your layout.
The resulting layout looks perfectly fine to me.
So the conclusion is: Your LoginPanel is fine, but probably there is something wrong in your other code which you didn't post here.
I am a beginner in Java Swing and I am trying to put a multiple JPanels in a JScrollPanel. The matter is, the JSCrollPannel (named jp in the code) should not fill all the JFrame but it does even if I fix a size with setSize() and a maximal size with setMaximalSize(). What is the trouble? How can I make the JSCrollPane smaller than the JFrame?
package GUI;
import java.awt.*;
import javax.swing.*;
public class MultiPanels {
private JScrollPane getContent() {
Dimension d = new Dimension(300,200);
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc= new GridBagConstraints();
gbc.weightx = 1.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER;
panel.add(getPanel(d, 6, Color.red), gbc);
panel.add(getPanel(d, 4, Color.green.darker()), gbc);
panel.add(getPanel(d, 4, Color.orange), gbc);
panel.add(getPanel(d, 12, Color.blue), gbc);
panel.add(getEmptyPanel(d), gbc);
return new JScrollPane(panel);
}
private JScrollPane getPanel(Dimension d, int rows, Color color) {
JPanel panel = new JPanel(new GridBagLayout());
panel.setBackground(color);
GridBagConstraints gbc= new GridBagConstraints();
gbc.insets = new Insets(10,5,10,5);
gbc.weightx = 1.0;
for(int i = 0, j = 1; i < rows; i++) {
gbc.gridwidth = GridBagConstraints.RELATIVE;
panel.add(new JButton(String.valueOf(j++)), gbc);
gbc.gridwidth = GridBagConstraints.REMAINDER;
panel.add(new JButton(String.valueOf(j++)), gbc);
}
JScrollPane scrollPane = new JScrollPane(panel);
scrollPane.setPreferredSize(d);
return scrollPane;
}
private JScrollPane getEmptyPanel(Dimension d) {
JPanel panel = new JPanel() {
protected void paintComponent(Graphics g) {
int w = getWidth();
int h = getHeight();
GradientPaint gp = new GradientPaint(0,0,Color.red,
0,h,Color.cyan);
((Graphics2D)g).setPaint(gp);
g.fillRect(0,0,w,h);
}
};
panel.setPreferredSize(new Dimension(300,400));
JScrollPane scrollPane = new JScrollPane(panel);
scrollPane.setPreferredSize(d);
return scrollPane;
}
public static void main(String[] args) {
JFrame f = new JFrame();
JScrollPane jp = new MultiPanels().getContent();
jp.setSize(new Dimension(200, 200));
jp.setMaximumSize(new Dimension(200,200));
jp.setPreferredSize(new Dimension(200,200));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(jp);
f.setSize(400,400);
f.setLocation(200,200);
f.setResizable(false);
f.setVisible(true);
}
}
Any time things don't size or arrange correctly, you have to look into Layouts.
Generally, spend more time on:
http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
To be specific, the default layout of a JPanel and JFrame is BorderLayout which is a very simple layout manager indeed. When you add to a component managed by BorderLayout without saying where, it is automatically added to the center and fills to use all available space:
http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html#border
It is possible to use "none" (Absolute Positioning) as the layout, but this is almost always a bad idea and you want to think about what you really want to do with the rest of the space in the JFrame: perhaps by letting new child components, with their own size demands, take up some of the space that the main panel is now swallowing up.
I have tried to boil this down as far as I can in code. I have been using GridBagLayout for a long time and for some reason I have never run into this situation.
JDialog dialog = new JDialog();
dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
dialog.setResizeable(true);
JPanel guiHolder = new JPanel();
guiHolder.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.PAGE_START;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
guiHolder.add(new JLabel("my test"), gbc);
dialog.add(guiHolder);
dialog.setSize(new Dimension(320, 240);
dialog.setSize(true);
The JLabel ends up square in the center of the screen. How can I get it to go to the top? I have looked at How To Use GridBagLayout. I am stumped...
Had you fixed your compile errors and wrapped your code into a runnable demo, you'd see that GridBagLayout works as advertised:
import java.awt.*;
import javax.swing.*;
public class Test implements Runnable
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Test());
}
public void run()
{
JDialog dialog = new JDialog();
dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
dialog.setResizable(true); // fixed mispelling here
JPanel guiHolder = new JPanel();
guiHolder.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.PAGE_START;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
guiHolder.add(new JLabel("my test"), gbc);
dialog.add(guiHolder);
dialog.setSize(new Dimension(320, 240));
dialog.setVisible(true); // fixed wrong method name here
}
}
My goal is to have my components resize according to my GridBagConstraints, but for some reason, when my applet is run, the components appear, but do not fill the entire applet like I expected. here is my code:
ServerPanel:
public class ServerPanel extends JPanel{
public ServerPanel(){
setLayout(new GridBagLayout()); //use gridbag layout
GridBagConstraints gbc = new GridBagConstraints();
JButton reverse = new JButton("Reverse text");
JButton send = new JButton("Send text");
JButton clear = new JButton("Clear text");
JTextField text = new JTextField("Test");
JScrollPane scrollPane = new JScrollPane(text, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
//Reverse button
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = gbc.HORIZONTAL;
add(reverse, gbc);
//send button
gbc.gridy = 1;
add(send, gbc);
//clear button
gbc.gridy = 2;
add(clear,gbc);
//text field
gbc.gridy = 3;
gbc.ipadx = 20;
gbc.ipady = 20;
gbc.fill = gbc.BOTH;
add(scrollPane, gbc);
}
}
the relevant code from ServerApplet which extends JApplet:
public void init(){
//dim = getSize();
//create the GUI in the EDT
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run(){
//System.out.println(dim);
setLayout(new BorderLayout());
add(new ServerPanel(), BorderLayout.CENTER);
}
});
}
What happens is that the right components get created, and the panel is centered in the applet, but it does not expand to fill the entire applet. Any help is appreciated. Thanks!
When I see this:
but for some reason, when my applet is run, the components appear, but do not fill the entire applet like I expected....
used in conjunction with GridBagLayout, I look to see if the weightx and weighty fields are being set on the GridBagConstraints, because a symptom of them being left at their default values of 0 is that the components all bunch up in the center.
Solution: set these fields where and when needed. If a component should expand in the x direction, then give it a + weightx, perhaps 1.0, and likewise for weighty.