I am new to java swing, I wrote a startup program to formart text, but i am confused with the layout,
the result is below:
I want the combobox and the button are placed middle of the ctrlPanel, and the combobox should not be stretched
public class MainFrame extends JFrame {
private static final long serialVersionUID = 7553142908344084288L;
private static String[] formats = new String[] {
"JSON",
"XML",
"YAML"
};
public MainFrame() {
super("jValidator");
Panel mainPanel = new Panel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.X_AXIS));
setContentPane(mainPanel);
JTextArea fromTextArea = new JTextArea(20, 40);
JScrollPane fromTextAreaScrollPanel = new JScrollPane(fromTextArea);
fromTextAreaScrollPanel.setPreferredSize(new Dimension(300, 300));
fromTextAreaScrollPanel.setBorder(BorderFactory.createEmptyBorder(15, 5, 15, 5));
mainPanel.add(fromTextAreaScrollPanel);
JButton fmtButton = new JButton("Format >>");
JComboBox jComboBox = new JComboBox(formats);
jComboBox.setBorder(BorderFactory.createTitledBorder("Text Format"));
JPanel ctrPanel = new JPanel();
ctrPanel.setLayout(new BoxLayout(ctrPanel, BoxLayout.Y_AXIS));
ctrPanel.setAlignmentY(Component.CENTER_ALIGNMENT);
ctrPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
ctrPanel.add(jComboBox);
ctrPanel.add(Box.createRigidArea(new Dimension(50, 15)));
ctrPanel.add(fmtButton);
mainPanel.add(ctrPanel);
JTextArea toTextArea = new JTextArea(20, 40);
JScrollPane toTextAreaScrollPanel = new JScrollPane(toTextArea);
toTextAreaScrollPanel.setPreferredSize(new Dimension(300, 300));
toTextAreaScrollPanel.setBorder(BorderFactory.createEmptyBorder(15, 5, 15, 5));
mainPanel.add(toTextAreaScrollPanel);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public static void main(String[] args) {
new MainFrame();
}
}
You could use a GridBagLayout instead of a BoxLayout...
JPanel ctrPanel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
ctrPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
gbc.fill = GridBagConstraints.HORIZONTAL;
ctrPanel.add(jComboBox, gbc);
ctrPanel.add(Box.createRigidArea(new Dimension(50, 15)), gbc);
gbc.fill = GridBagConstraints.NONE;
ctrPanel.add(fmtButton, gbc);
Take a look at Laying Out Components Within a Container for more details
For that purposes I recommend you to use another LayoutManager, for example GridBagLayout change creation of ctrPanel like next :
JButton fmtButton = new JButton("Format >>");
JComboBox jComboBox = new JComboBox(formats);
jComboBox.setBorder(BorderFactory.createTitledBorder("Text Format"));
JPanel ctrPanel = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.gridx=0;
c.gridy=1;
ctrPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
ctrPanel.add(fmtButton,c);
c.gridy=0;
c.fill = GridBagConstraints.HORIZONTAL;
ctrPanel.add(jComboBox,c);
mainPanel.add(ctrPanel);
And it looks like:
Related
I am writing my first Swing app and I'm having some trouble stacking labels in code.
I have the following right now
I would like "Enter the name of the repo and the name of the" to be above "owner of that repo to search for open issues." so the window isn't so wide.
Here's my code:
public class MainFrame extends JFrame {
private Boolean submitted = false;
public MainFrame(String title) {
super(title);
// Set layout manager
setLayout(new BorderLayout());
// Create components
JPanel panOuter = new JPanel(new BorderLayout());
JPanel panLeft = new JPanel(new BorderLayout());
panLeft.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JPanel panRight = new JPanel(new BorderLayout());
panRight.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JPanel panBottom = new JPanel();
panBottom.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JPanel panTop = new JPanel();
panTop.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JPanel panTopTop = new JPanel();
panTopTop.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
JPanel panTopBottom = new JPanel();
panTopBottom.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
// Add components to content panel
panOuter.add(panLeft, BorderLayout.WEST);
panOuter.add(panRight, BorderLayout.EAST);
panOuter.add(panBottom, BorderLayout.SOUTH);
panOuter.add(panTop, BorderLayout.NORTH);
JLabel lblTop1 = new JLabel("Enter the name of the repo and the name of the\n", JLabel.CENTER);
JLabel lblTop2 = new JLabel("owner of that repo to search for open issues.\n", JLabel.CENTER);
JLabel lblLeft = new JLabel("Repo", JLabel.CENTER);
JLabel lblRight = new JLabel("Owner", JLabel.CENTER);
JTextField txtLeft = new JTextField("Hello", 10);
JTextField txtRight = new JTextField("World", 10);
JButton btnBottom = new JButton("Submit!");
panLeft.add(lblLeft, BorderLayout.NORTH);
panLeft.add(txtLeft, BorderLayout.CENTER);
panRight.add(lblRight, BorderLayout.NORTH);
panRight.add(txtRight, BorderLayout.CENTER);
panBottom.add(btnBottom);
panTopTop.add(lblTop1);
panTopBottom.add(lblTop2);
panTop.add(panTopTop, BorderLayout.NORTH);
panTop.add(panTopBottom, BorderLayout.SOUTH);
this.setContentPane(panOuter);
this.pack();
btnBottom.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(!submitted)
btnBottom.setText(txtLeft.getText());
else
btnBottom.setText(txtRight.getText());
submitted = !submitted;
}
});
}
}
I tried to make a panel that has a NORTH and SOUTH component of labels, but it didn't work.
Does anyone have suggestions?
Thanks,
erip
You could try using a GridBagLayout...
JPanel panTop = new JPanel(new GridBagLayout());
panTop.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
//JPanel panTopTop = new JPanel();
//panTopTop.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
//JPanel panTopBottom = new JPanel();
//panTopBottom.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
//...
//panTopTop.add(lblTop1);
//panTopBottom.add(lblTop2);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
panTop.add(lblTop1, gbc);
panTop.add(lblTop2, gbc);
//panTop.add(panTopBottom, BorderLayout.SOUTH);
See How to Use GridBagLayout for more details
Now, you could get really sneaky and use a JTextArea...
JTextArea ta = new JTextArea(1, 20);
ta.setText("Enter the name of the repo and the name of the owner of that repo to search for open issues.");
ta.setWrapStyleWord(true);
ta.setLineWrap(true);
ta.setBorder(null);
ta.setFont(UIManager.getFont("Label.font"));
ta.setOpaque(false);
ta.setFocusable(false);
ta.setEditable(false);
//JLabel lblTop1 = new JLabel("<html>Enter the name of the repo and the name of the owner of that repo to search for open issues", JLabel.CENTER);
//JLabel lblTop2 = new JLabel("owner of that repo to search for open issues.\n", JLabel.CENTER);
//...
//panTopTop.add(lblTop1);
//panTopBottom.add(lblTop2);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
panTop.add(ta, gbc);
Or even just use Swing's HTML support...
JLabel lblTop1 = new JLabel("<html><p align='center'>Enter the name of the repo and the name of the owner of that repo to search for open issues</p>", JLabel.CENTER);
panOuter.add(lblTop1, BorderLayout.NORTH);
I am having trouble adding a scroll pane to a nested panel. Here is what I have:
public class board {
public static void addComponentsToPane(Container pane) {
pane.setLayout(new GridLayout(1, 0));
JPanel left = new JPanel();
pane.add(left);
left.setLayout(new BoxLayout(left, BoxLayout.Y_AXIS));
JPanel leftTop = new JPanel();
leftTop.setPreferredSize(new Dimension(266, 300));
leftTop.setBackground(Color.black);
left.add(leftTop);
JScrollPane scrollPane = new JScrollPane(leftTop); //problem is here
left.add(scrollPane);
JButton jb = new JButton();
jb.setPreferredSize(new Dimension(250,50));
leftTop.add(jb);
JButton jb1 = new JButton();
jb1.setPreferredSize(new Dimension(250,50));
leftTop.add(jb1);
JButton jb2 = new JButton();
jb2.setPreferredSize(new Dimension(250,50));
leftTop.add(jb2);
JButton jb3 = new JButton();
jb3.setPreferredSize(new Dimension(250,50));
leftTop.add(jb3);
JButton jb4 = new JButton();
jb4.setPreferredSize(new Dimension(250,50));
leftTop.add(jb4);
JButton jb5 = new JButton();
jb5.setPreferredSize(new Dimension(250,50));
leftTop.add(jb5);
JButton jb6 = new JButton();
jb6.setPreferredSize(new Dimension(250,50));
leftTop.add(jb6);
JPanel leftBottom = new JPanel();
leftBottom.setPreferredSize(new Dimension(266, 300));
leftBottom.setBackground(Color.red);
left.add(leftBottom);
JPanel middle = new JPanel();
pane.add(middle);
middle.setLayout(new BoxLayout(middle, BoxLayout.Y_AXIS));
JPanel middleTop = new JPanel();
middleTop.setPreferredSize(new Dimension(266, 200));
middleTop.setBackground(Color.green);
middle.add(middleTop);
JPanel middleBottom = new JPanel();
middleBottom.setPreferredSize(new Dimension(266, 400));
middleBottom.setBackground(Color.yellow);
middle.add(middleBottom);
JPanel right = new JPanel();
right.setPreferredSize(new Dimension(266, 600));
right.setBackground(Color.blue);
pane.add(right);
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("GridBagLayoutDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addComponentsToPane(frame.getContentPane());
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGUI();
}
});
}
}
I am just messing around with JPanels and I cannot seem to add scrolling to the left top pane. I think i initialized scrollPane right, but am I adding it to the wrong pane?
Your initial problem is here
leftTop.setPreferredSize(new Dimension(266, 300));
This is overriding what the layout manager (FlowLayout in this case) would otherwise provide to the JScrollPane in order for it to know how to manage the view (when to show the scrollbars for instance)
The next problem you will have is, FlowLayout won't do what you want it to. Instead you might want to use GridLayout or maybe GridBagLayout instead
JPanel leftTop = new JPanel(new GridBagLayout());
//leftTop.setPreferredSize(new Dimension(266, 300));
leftTop.setBackground(Color.black);
JScrollPane scrollPane = new JScrollPane(leftTop); //problem is here
left.add(scrollPane);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
gbc.insets = new Insets(5, 10, 5, 10);
JButton jb = new JButton();
jb.setPreferredSize(new Dimension(250, 50));
leftTop.add(jb, gbc);
JButton jb1 = new JButton();
jb1.setPreferredSize(new Dimension(250, 50));
leftTop.add(jb1, gbc);
JButton jb2 = new JButton();
jb2.setPreferredSize(new Dimension(250, 50));
leftTop.add(jb2, gbc);
JButton jb3 = new JButton();
jb3.setPreferredSize(new Dimension(250, 50));
leftTop.add(jb3, gbc);
JButton jb4 = new JButton();
jb4.setPreferredSize(new Dimension(250, 50));
leftTop.add(jb4, gbc);
JButton jb5 = new JButton();
jb5.setPreferredSize(new Dimension(250, 50));
leftTop.add(jb5, gbc);
JButton jb6 = new JButton();
jb6.setPreferredSize(new Dimension(250, 50));
leftTop.add(jb6, gbc);
Know, if that's not meeting your needs, you will need to create a custom component which implements Scrollable, which will allow you to specify PreferredScrollableViewportSize which will tell the JScrollPane what the preferred size of the viewable area should be, rather then using the preferredSize of the view
Here is some Java Code that I have that works that uses GridBagConstraints:
public AuctionClient() {
JFrame guiFrame = new JFrame();
JPanel guiPanel = new JPanel(new GridBagLayout());
JLabel userNameLabel = new JLabel("UserName:");
JTextField userNameTextField = new JTextField(30);
JButton loginButton = new JButton("Login");
JButton registerButton = new JButton("Register");
JLabel passwordLabel = new JLabel("Password:");
JTextField passwordTextField = new JPasswordField(30);
guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiFrame.setTitle("Auction Client");
guiFrame.setSize(500, 250);
guiFrame.setLocationRelativeTo(null);
GridBagConstraints labelGBC = new GridBagConstraints();
labelGBC.insets = new Insets(3, 3, 3, 3);
GridBagConstraints fieldGBC = new GridBagConstraints();
fieldGBC.insets = new Insets(3, 3, 3, 3);
fieldGBC.gridwidth = GridBagConstraints.REMAINDER;
guiPanel.add(userNameLabel, labelGBC);
guiPanel.add(userNameTextField, fieldGBC);
guiPanel.add(passwordLabel, labelGBC);
guiPanel.add(passwordTextField, fieldGBC);
GridBagConstraints loginButtonGBC = new GridBagConstraints();
loginButtonGBC.insets = new Insets(3, 3, 3, 3);
GridBagConstraints registerButtonGBC = new GridBagConstraints();
registerButtonGBC.insets = new Insets(3, 3, 3, 3);
registerButtonGBC.gridwidth = GridBagConstraints.REMAINDER;
guiPanel.add(loginButton, loginButtonGBC);
guiPanel.add(registerButton, registerButtonGBC);
guiFrame.add(guiPanel, BorderLayout.NORTH);
guiFrame.setVisible(true);
}
I have had a look online for some explanation of how the GridBagConstraints work in relation to placing controls on a panel. I could not understand exactly how it works so am asking a question here on this forum.
Here is a screenshot of the above code when running:
Can I please have some help to position the Login and Register buttons in the middle of the panel, side by side.
EDIT
Here is my current working code:
public AuctionClientLogon() {
JFrame guiFrame = new JFrame();
JPanel guiFieldsPanel = new JPanel(new GridBagLayout());
JPanel guiButtonsPanel = new JPanel(new GridBagLayout());
JLabel userNameLabel = new JLabel("UserName:");
JTextField userNameTextField = new JTextField(30);
JButton loginButton = new JButton("Login");
JButton registerButton = new JButton("Register");
JLabel passwordLabel = new JLabel("Password:");
JTextField passwordTextField = new JPasswordField(30);
guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiFrame.setTitle("Auction Client");
guiFrame.setSize(500, 250);
guiFrame.setLocationRelativeTo(null);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.CENTER;
guiFieldsPanel.add(userNameLabel, gbc);
gbc.gridx++;
guiFieldsPanel.add(userNameTextField, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
guiFieldsPanel.add(passwordLabel, gbc);
gbc.gridx++;
guiFieldsPanel.add(passwordTextField, gbc);
gbc.anchor = GridBagConstraints.CENTER;
gbc.gridx = 0;
gbc.gridy = 1;
guiButtonsPanel.add(loginButton, gbc);
gbc.gridx++;
guiButtonsPanel.add(registerButton, gbc);
guiFrame.add(guiFieldsPanel, BorderLayout.NORTH);
guiFrame.add(guiButtonsPanel, BorderLayout.CENTER);
guiFrame.setVisible(true);
}
Here is an image:
http://canning.co.nz/Java/Positioning_Image2.png
Is it possible to place the Labels and TextFields in the Center as well as the buttons, but not on top of each other? I would like everything in the Center if possible, but the buttons to be a little bit lower than the Labels and TextFields. Is this possible?
Start by taking a look at your forms requirements. You have two sections. The fields and the buttons. Each of these sections have a (slightly) different layout requirement.
Start by separating the layout to best meet these requirements.
Create a JPanel to hold the fields and a JPanel for the buttons. These panels could have different layouts if required, but the example I've included uses GridBagLayout for each.
Then layout your components accordingly (on there individual panels).
Then bring it all together...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class GridBagLayout01 {
public static void main(String[] args) {
new GridBagLayout01();
}
public GridBagLayout01() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame guiFrame = new JFrame();
JPanel guiPanel = new JPanel(new GridBagLayout());
JLabel userNameLabel = new JLabel("UserName:");
JTextField userNameTextField = new JTextField(30);
JButton loginButton = new JButton("Login");
JButton registerButton = new JButton("Register");
JLabel passwordLabel = new JLabel("Password:");
JTextField passwordTextField = new JPasswordField(30);
guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiFrame.setTitle("Auction Client");
guiFrame.setSize(500, 250);
guiFrame.setLocationRelativeTo(null);
JPanel fields = new JPanel(new GridBagLayout());
GridBagConstraints labelGBC = new GridBagConstraints();
labelGBC.insets = new Insets(3, 3, 3, 3);
GridBagConstraints fieldGBC = new GridBagConstraints();
fieldGBC.insets = new Insets(3, 3, 3, 3);
fieldGBC.gridwidth = GridBagConstraints.REMAINDER;
fields.add(userNameLabel, labelGBC);
fields.add(userNameTextField, fieldGBC);
fields.add(passwordLabel, labelGBC);
fields.add(passwordTextField, fieldGBC);
JPanel buttons = new JPanel(new GridBagLayout());
GridBagConstraints loginButtonGBC = new GridBagConstraints();
loginButtonGBC.insets = new Insets(3, 3, 3, 3);
GridBagConstraints registerButtonGBC = new GridBagConstraints();
registerButtonGBC.insets = new Insets(3, 3, 3, 3);
registerButtonGBC.gridwidth = GridBagConstraints.REMAINDER;
buttons.add(loginButton, loginButtonGBC);
buttons.add(registerButton, registerButtonGBC);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
guiPanel.add(fields, gbc);
guiPanel.add(buttons, gbc);
guiFrame.add(guiPanel, BorderLayout.NORTH);
guiFrame.setVisible(true);
}
});
}
}
Use a FlowLayout to keep this kind of line of buttons.Then you can easily place the button position where ever you want inline.
Have a look at how to use flow layout
I've attached a screenshot for which the following Border legend applies:
Yellow = JPanel with BorderLayout
Blue = JPanel with GridBagLayout
Fuchsia = JPanel with FlowLayout
There are two panels not blocked out in colors that warrant mentioning:
1) The title panel where the word "Primary" is displayed; this panel is at BorderLayout.NORTH in "Yellow" panel.
2) The image panel where the image of the device is located; this panel is a sibling to "Fuchsia"
"Blue" is at BorderLayout.CENTER in "Yellow" while "Fuchsia" and the image panel are given the following constraints:
GridBagConstraints c = new GridBagConstraints();
c.weightx = 1.0;
c.weighty = 1.0;
c.gridx = 0;
c.gridy = 0;
c.anchor = GridBagConstraints.NORTHWEST;
c.insets = new Insets(0, 10, 0, 0);
c.fill = GridBagConstraints.BOTH;
//"Blue".add(imagePanel, c);
c.weighty = 0.80;
c.gridy = 1;
c.fill = GridBagConstraints.HORIZONTAL;
//"Blue".add("Fuchsia", c);
As you can probably tell from the image, I'm trying to get rid of the "wasted" space in "Blue" right below "Fuchsia". I don't seem to be able to do it with GridBagConstraints, so am I just using the wrong LayoutManager? It looks to me like "Blue", who is at CENTER in the BorderLayout is just giving each child JPanel half of the available space and reserving the remainder space instead of contracting upward. What am I missing here? Is this simply a matter of setting a preferred or maximum size on "Fuchsia"? it doesn't seem like that will get me where I want to be, since the border around "Fuchsia" (which is covered by my color coding) is where I want the end of the component to be.
Have a look at this output, from this code example :
import java.awt.*;
import javax.swing.*;
public class LayoutTest
{
private void displayGUI()
{
JFrame frame = new JFrame("Layout Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setOpaque(true);
contentPane.setBackground(Color.YELLOW);
contentPane.setLayout(new BorderLayout(2, 2));
JPanel topPanel = new JPanel();
topPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
JLabel headingLabel = new JLabel("Primary");
topPanel.add(headingLabel);
contentPane.add(topPanel, BorderLayout.PAGE_START);
JPanel centerPanel = new JPanel();
centerPanel.setOpaque(true);
centerPanel.setBackground(Color.BLUE);
centerPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1.0;
gbc.weighty = 0.2;
gbc.gridx = 0;
gbc.gridy = 0;
JPanel imagePanel = new JPanel();
JLabel imageLabel = null;
try
{
imageLabel = new JLabel(
new ImageIcon(
new java.net.URL(
"http://pscode.org/"
+ "tame/screenshot/"
+ "landscape/slider1.gif")));
}
catch(Exception e)
{
e.printStackTrace();
}
imagePanel.add(imageLabel);
centerPanel.add(imagePanel, gbc);
JPanel detailsPanel = new JPanel();
detailsPanel.setOpaque(true);
detailsPanel.setBackground(Color.WHITE);
detailsPanel.setBorder(
BorderFactory.createEmptyBorder(
5, 5, 5, 5));
detailsPanel.setLayout(new GridLayout(0, 1, 5, 5));
JLabel statusLabel = new JLabel("Chassis Status : ");
JLabel usageLabel = new JLabel("Bandwidth Usage : ");
JLabel fanLabel = new JLabel("Fan Status : ");
detailsPanel.add(statusLabel);
detailsPanel.add(usageLabel);
detailsPanel.add(fanLabel);
gbc.fill = GridBagConstraints.BOTH;
gbc.weighty = 0.8;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridheight = 3;
centerPanel.add(detailsPanel, gbc);
contentPane.add(centerPanel, BorderLayout.CENTER);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new LayoutTest().displayGUI();
}
});
}
}
Without using GridBagLayout could be
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
public class NestedLayout {
private JFrame frame = new JFrame();
private JPanel yellowNorthPanel = new JPanel();
private JPanel yellowPanel = new JPanel();
private JPanel bluePanel = new JPanel();
private JPanel fuchsiaTopPanel = new JPanel();
private JPanel fuchsiaBottonPanel = new JPanel();
public NestedLayout() {
yellowNorthPanel.setBorder(new LineBorder(Color.yellow, 5));
yellowPanel.setLayout(new BorderLayout());
yellowPanel.setBorder(new LineBorder(Color.yellow, 5));
bluePanel.setLayout(new BorderLayout(5, 5));
bluePanel.setBorder(new LineBorder(Color.blue, 5));
fuchsiaTopPanel.setBorder(new LineBorder(Color.cyan, 5));
fuchsiaBottonPanel.setBorder(new LineBorder(Color.cyan, 5));
bluePanel.add(fuchsiaTopPanel, BorderLayout.NORTH);
bluePanel.add(fuchsiaBottonPanel);
yellowPanel.add(bluePanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(yellowNorthPanel, BorderLayout.NORTH);
frame.add(yellowPanel);
//frame.pack();
frame.setSize(400, 300);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new NestedLayout();
}
});
}
}
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I'm trying to hand-code a Java GUI using Swing and AWT. I'm using various layouts to try and achieve or something similar to the GUI posted below (it's a mock layout made with Pencil):
What I got so far is this, but can't seem to make it more "polite", appealing and user-friendly as possible.
This is the code I have done so far:
import java.awt.*;
import javax.swing.*;
import javax.swing.JTable;
public class GUI extends JFrame {
public void buildGui() {
JFrame frame = new JFrame("Hotel TV Scheduler");
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout(0,0));
JPanel chPanel = new JPanel();
chPanel.setLayout(new GridLayout(3,2));
JPanel listPanel = new JPanel();
listPanel.setLayout(new GridLayout(3,2));
JPanel infoPanel = new JPanel();
infoPanel.setLayout(new GridLayout(0,2));
JPanel addPanel = new JPanel();
addPanel.setLayout(new GridLayout(0,3));
mainPanel.add(chPanel, BorderLayout.LINE_START);
mainPanel.add(listPanel, BorderLayout.CENTER);
mainPanel.add(infoPanel, BorderLayout.LINE_END);
JTable chOneTable = new JTable();
JTable chTwoTable = new JTable();
JTable listTable = new JTable();
JLabel ch1Label = new JLabel("Channel 1");
JLabel ch2Label = new JLabel("Channel 2");
JLabel listLabel = new JLabel("List");
JButton rmvChOneButton = new JButton("Remove Channel");
JButton rmvChTwoButton = new JButton("Remove Channel");
chPanel.add(ch1Label);
chPanel.add(ch2Label);
chPanel.add(chOneTable);
chPanel.add(chTwoTable);
chPanel.add(rmvChOneButton);
chPanel.add(rmvChTwoButton);
listPanel.add(listLabel);
listPanel.add(listTable);
JLabel titleLabel = new JLabel("Title");
JLabel genreLabel = new JLabel("Genre");
JLabel durationLabel = new JLabel("Duration");
JLabel actorLabel = new JLabel("Actor");
JLabel directorLabel = new JLabel("Director");
JLabel rentableLabel = new JLabel("Rentable");
JLabel synLabel = new JLabel("Synopsis");
JTextField txtTitle = new JTextField();
JTextField txtGenre = new JTextField();
JTextField txtDuration = new JTextField();
JTextField txtActor = new JTextField();
JTextField txtDirector = new JTextField();
JTextField txtSynopsis = new JTextField();
JCheckBox rentCB = new JCheckBox();
JButton btnAddProg = new JButton("Add Program");
JList channelList = new JList();
JList timeList = new JList();
infoPanel.add(titleLabel);
infoPanel.add(txtTitle);
infoPanel.add(genreLabel);
infoPanel.add(txtGenre);
infoPanel.add(durationLabel);
infoPanel.add(txtDuration);
infoPanel.add(actorLabel);
infoPanel.add(txtActor);
infoPanel.add(directorLabel);
infoPanel.add(txtDirector);
infoPanel.add(rentableLabel);
infoPanel.add(rentCB);
infoPanel.add(synLabel);
infoPanel.add(txtSynopsis);
infoPanel.add(btnAddProg);
infoPanel.add(channelList);
infoPanel.add(timeList);
frame.add(mainPanel);
frame.setVisible(true);
}
}
It doesn't have to be exactly as the mock layout shown above but as much as possible similar or at least more user-friendly.
I want to use anything but GridBagLayout and SwingLayout.
Any ideas on how to improve the code and make it look more similar?
Any help is appreciated.
Brian
Have a look at the MigLayout. It's licensing is very inclusive:
MigLayout is free to use for commercial and non-commercial projects and the source code is provided. It is licensed under the very free BSD or GPL license, whichever you prefer
The JNLP demo application should show up great examples and corresponding source.
Also, try to avoid nesting logically unrelated components. Getting alignment, borders and padding becomes quite painful as you increase the degree of nesting.
What that GUI mostly needs is:
White space between components. Two common ways to provide that are:
Layout padding provided in the constructor of the layout.
Adding an EmptyBorder to components or containers. In the case of many components that already have borders, it is best to wrap them in a JPanel and add the border to the panel.
Constraining panels. E.G. If it is desired to have a group of components in the WEST of a BorderLayout to be 'shoved to the top', add them inside another panel with a BorderLayout.NORTH layout/constraint 1st. Here is an example of what I mean.
Use Eclipse and WindowBuilder. You can go back and "hand code" specific parts later and still return to WindowBuilder if you like.
Have a look at this sample program, will this do to satisfy your needs :-)
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;
public class TVSchedule
{
private static final int GAP = 5;
private static TVSchedule tvSchedule;
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("HOTEL TV SCHEDULE");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setLocationByPlatform(true);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout());
JPanel centerPanel = new JPanel();
//centerPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
centerPanel.setLayout(new GridLayout(0, 4, 5, 5));
centerPanel.add(createChannelOnePanel());
centerPanel.add(createChannelTwoPanel());
centerPanel.add(createListPanel());
centerPanel.add(createInformationPanel());
JPanel bottomPanel = new JPanel();
bottomPanel.setOpaque(true);
bottomPanel.setBackground(Color.RED.darker());
bottomPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));
JButton exitButton = new JButton("EXIT");
bottomPanel.add(exitButton);
contentPane.add(centerPanel, BorderLayout.CENTER);
contentPane.add(bottomPanel, BorderLayout.PAGE_END);
frame.setContentPane(contentPane);
frame.pack();
frame.setVisible(true);
}
private JPanel createChannelOnePanel()
{
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
panel.setOpaque(true);
panel.setBackground(Color.DARK_GRAY);
panel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
GridBagConstraints gbc = new GridBagConstraints();
String[] columnNames = {
"Time",
"Title"
};
Object[][] data = {
{"01:00","Cowboy and Alchemist."}
};
DefaultTableModel model = new DefaultTableModel(data, columnNames);
JTable table = new JTable( model )
{
// Returning the Class of each column will allow different
// renderers to be used based on Class
public Class getColumnClass(int column)
{
return getValueAt(0, column).getClass();
}
};
table.setPreferredScrollableViewportSize(new Dimension(200, 200));
table.setFillsViewportHeight(true);
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(Color.BLACK, 1)
, "Channel 1"
, TitledBorder.CENTER
, TitledBorder.DEFAULT_POSITION));
gbc.weightx = 1.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
panel.add(scrollPane, gbc);
JButton removeButton = new JButton("Remove Selected");
gbc.weightx = 1.0;
gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 2;
panel.add(removeButton, gbc);
return panel;
}
private JPanel createChannelTwoPanel()
{
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
panel.setOpaque(true);
panel.setBackground(Color.WHITE);
panel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
GridBagConstraints gbc = new GridBagConstraints();
String[] columnNames = {
"Time",
"Title"
};
Object[][] data = {
{"02:00","Grey's Anatomy"}
};
DefaultTableModel model = new DefaultTableModel(data, columnNames);
JTable table = new JTable( model )
{
// Returning the Class of each column will allow different
// renderers to be used based on Class
public Class getColumnClass(int column)
{
return getValueAt(0, column).getClass();
}
};
table.setPreferredScrollableViewportSize(new Dimension(200, 200));
table.setFillsViewportHeight(true);
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(Color.BLACK, 1)
, "Channel 2"
, TitledBorder.CENTER
, TitledBorder.DEFAULT_POSITION));
gbc.weightx = 1.0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
panel.add(scrollPane, gbc);
JButton removeButton = new JButton("Remove Selected");
gbc.weightx = 1.0;
gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 2;
panel.add(removeButton, gbc);
return panel;
}
private JPanel createListPanel()
{
JPanel panel = new JPanel();
panel.setLayout(new GridBagLayout());
panel.setOpaque(true);
panel.setBackground(Color.DARK_GRAY);
panel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
GridBagConstraints gbc = new GridBagConstraints();
String[] columnNames = {
"Genre",
"Title",
"Duration (Hours)"
};
Object[][] data = {
{"Comedy","C & A", "1.5"}
};
DefaultTableModel model = new DefaultTableModel(data, columnNames);
JTable table = new JTable( model )
{
// Returning the Class of each column will allow different
// renderers to be used based on Class
public Class getColumnClass(int column)
{
return getValueAt(0, column).getClass();
}
};
table.setPreferredScrollableViewportSize(new Dimension(200, 200));
table.setFillsViewportHeight(true);
JScrollPane scrollPane = new JScrollPane(table);
scrollPane.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(Color.BLACK, 1)
, "List"
, TitledBorder.CENTER
, TitledBorder.DEFAULT_POSITION));
gbc.weightx = 1.0;
gbc.anchor = GridBagConstraints.PAGE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
panel.add(scrollPane, gbc);
gbc.weightx = 1.0;
gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 2;
panel.add(Box.createRigidArea(new Dimension(100, 30)), gbc);
return panel;
}
private JPanel createInformationPanel()
{
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new GridLayout(0, 1, 2, 2));
bottomPanel.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createLineBorder(Color.BLACK, 1)
, "Information"
, TitledBorder.LEFT
, TitledBorder.DEFAULT_POSITION));
JPanel panel = new JPanel();
panel.setOpaque(true);
panel.setBackground(Color.WHITE);
panel.setLayout(new GridBagLayout());
panel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
GridBagConstraints gbc = new GridBagConstraints();
JLabel titleLabel = new JLabel("TITLE : ");
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 0;
panel.add(titleLabel, gbc);
JTextField titleField = new JTextField(10);
gbc.gridx = 1;
panel.add(titleField, gbc);
JLabel genreLabel = new JLabel("GENRE : ");
gbc.gridx = 0;
gbc.gridy = 1;
panel.add(genreLabel, gbc);
JTextField genreField = new JTextField(10);
gbc.gridx = 1;
panel.add(genreField, gbc);
JLabel durationLabel = new JLabel("DURATION : ");
gbc.gridx = 0;
gbc.gridy = 2;
panel.add(durationLabel, gbc);
JTextField durationField = new JTextField(10);
gbc.gridx = 1;
panel.add(durationField, gbc);
JLabel actorLabel = new JLabel("ACTOR : ");
gbc.gridx = 0;
gbc.gridy = 3;
panel.add(actorLabel, gbc);
JTextField actorField = new JTextField(10);
gbc.gridx = 1;
panel.add(actorField, gbc);
JLabel directorLabel = new JLabel("DIRECTOR : ");
gbc.gridx = 0;
gbc.gridy = 4;
panel.add(directorLabel, gbc);
JTextField directorField = new JTextField(10);
gbc.gridx = 1;
panel.add(directorField, gbc);
JLabel rentLabel = new JLabel("RENTABLE : ");
gbc.gridx = 0;
gbc.gridy = 5;
panel.add(rentLabel, gbc);
JCheckBox rentCBox = new JCheckBox(" ", false);
rentCBox.setOpaque(true);
rentCBox.setBackground(Color.WHITE);
rentCBox.setHorizontalTextPosition(SwingConstants.LEFT);
gbc.gridx = 1;
panel.add(rentCBox, gbc);
JLabel synopsisLabel = new JLabel("SYNOPSIS : ");
gbc.gridx = 0;
gbc.gridy = 6;
panel.add(synopsisLabel, gbc);
JTextArea synopsisArea = new JTextArea(10, 5);
synopsisArea.setBackground(Color.BLUE.darker());
synopsisArea.setForeground(Color.WHITE);
synopsisArea.setCaretColor(Color.WHITE);
gbc.gridx = 1;
gbc.gridwidth = 2;
gbc.gridheight = 2;
panel.add(synopsisArea, gbc);
JButton addProgramButton = new JButton("Add Program");
gbc.gridx = 0;
gbc.gridy = 8;
gbc.insets = new Insets(5, 5, 5, 5);
gbc.anchor = GridBagConstraints.PAGE_END;
gbc.gridwidth = 1;
gbc.gridheight = 1;
panel.add(addProgramButton, gbc);
JSpinner spinner = new JSpinner(new SpinnerNumberModel(00.15, 00.15, 60.00, 00.15));
gbc.gridx = 2;
gbc.gridy = 8;
panel.add(spinner, gbc);
bottomPanel.add(panel);
return bottomPanel;
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
tvSchedule = new TVSchedule();
tvSchedule.createAndDisplayGUI();
}
});
}
}
I really don't know what you using between JButton and 'JSpinner', that's why never added anything there, hope you can do that yourself.
Here is the output for the same :