It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
So basically I want to create this sort of a GUI, but because of my inexperience with Java GUIs, I cannot figure out which Layout Manager to use. I've tried Flow, Border, Grid, but none of them allow me to create this sort of a GUI without messing up the alignments somewhere.
Any suggestions? How should I decide on a layout manager in the future, or is it something which will come with experience?
I'd prefer to use a simple to use layout, as this is a very basic GUI and I don't think something like MiGLayout should be necessary.
I'd use a combination of compound panels and layouts. Apart from making easier to get the layout to work, you could also isolate areas of responsibility within their own class.
public class TestLayout13 {
public static void main(String[] args) {
new TestLayout13();
}
public TestLayout13() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new FormPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class FormPane extends JPanel {
public FormPane() {
setBorder(new EmptyBorder(8, 8, 8, 8));
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
NamePane namePane = new NamePane();
namePane.setBorder(new CompoundBorder(new TitledBorder("Name"), new EmptyBorder(4, 4, 4, 4)));
add(namePane, gbc);
gbc.gridy++;
EMailPane emailPane = new EMailPane();
emailPane.setBorder(new CompoundBorder(new TitledBorder("E-Mail"), new EmptyBorder(4, 4, 4, 4)));
add(emailPane, gbc);
}
}
public class NamePane extends JPanel {
public NamePane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.EAST;
add(new JLabel("First Name:"), gbc);
gbc.gridx += 2;
add(new JLabel("Last Name:"), gbc);
gbc.gridy++;
gbc.gridx = 0;
add(new JLabel("Title:"), gbc);
gbc.gridx += 2;
add(new JLabel("Nickname:"), gbc);
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = GridBagConstraints.WEST;
gbc.weightx = 0.5;
add(new JTextField(10), gbc);
gbc.gridx += 2;
add(new JTextField(10), gbc);
gbc.gridy++;
gbc.gridx = 1;
add(new JTextField(10), gbc);
gbc.gridx += 2;
add(new JTextField(10), gbc);
gbc.gridx = 0;
gbc.gridy++;
gbc.anchor = GridBagConstraints.EAST;
gbc.weightx = 0;
gbc.fill = GridBagConstraints.NONE;
add(new JLabel("Format:"), gbc);
gbc.anchor = GridBagConstraints.WEST;
gbc.gridx++;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JComboBox(), gbc);
}
}
protected class EMailPane extends JPanel {
public EMailPane() {
JPanel detailsPane = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.EAST;
detailsPane.add(new JLabel("E-Mail Address:"), gbc);
gbc.gridx++;
gbc.anchor = GridBagConstraints.WEST;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
detailsPane.add(new JTextField(10), gbc);
gbc.gridy++;
gbc.gridx = 0;
gbc.fill = GridBagConstraints.BOTH;
gbc.weighty = 1;
gbc.gridwidth = GridBagConstraints.REMAINDER;
detailsPane.add(new JScrollPane(new JList()), gbc);
JPanel buttonsPane = new JPanel(new GridBagLayout());
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
buttonsPane.add(new JButton("Add"), gbc);
gbc.gridy++;
buttonsPane.add(new JButton("Edit"), gbc);
gbc.gridy++;
buttonsPane.add(new JButton("Delete"), gbc);
gbc.gridy++;
gbc.weighty = 1;
gbc.anchor = GridBagConstraints.NORTH;
buttonsPane.add(new JButton("As Default"), gbc);
JPanel formatPane = new JPanel(new FlowLayout(FlowLayout.LEFT));
formatPane.setBorder(new TitledBorder(new EmptyBorder(1, 1, 1, 1), "Mail Format:"));
formatPane.add(new JRadioButton("HTML"));
formatPane.add(new JRadioButton("Plain"));
formatPane.add(new JRadioButton("Custom"));
setLayout(new BorderLayout());
add(detailsPane);
add(buttonsPane, BorderLayout.LINE_END);
add(formatPane, BorderLayout.PAGE_END);
}
}
}
My preference is MigLayout because it is the most complete and well documented layout manager for Swing. In addition to Swing, it also supports SWT and JavaFX, so the time you spend learning it may pay back more than once. It supports maven, refer to http://www.miglayout.com for details, which is a big plus. Also it has a very useful debug feature. You can add "debug 1" in the constructor, and you will se how the layout was created. Example:
emailButtonPanel.setLayout(new MigLayout("wrap, fill, insets 20 10 0 10, debug 1"));
Another feature that I find very useful from time to time, is the hidemode, which allows you that a component does not take part in the layout if not visible (or several other strategies).
Here is one possible approach for the image you posted, using MigLayout:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import net.miginfocom.layout.CC;
import net.miginfocom.swing.MigLayout;
/**
*/
public class LayoutApproach {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Contact information");
frame.getContentPane().add(new ContactPanel());
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setMinimumSize(new Dimension(800, 450));
frame.setLocationRelativeTo(null); // Center
frame.pack();
frame.setVisible(true);
}
});
}
static class ContactPanel extends JPanel {
private JPanel namePanel;
private TitledBorder nameTitledBorder;
private JLabel firstNameLabel;
private JTextField firstNameTextField;
private JLabel lastNameLabel;
private JTextField lastNameTextField;
private JLabel titleLabel;
private JTextField titleTextField;
private JLabel nicknameLabel;
private JTextField nickNameTextField;
private JLabel formatLabel;
private JComboBox<String> formatComboBox;
private JPanel emailPanel;
private TitledBorder emailTitledBorder;
private JLabel emailLabel;
private JTextField emailTextField;
private JList<String> emailItemsList;
private JLabel mailFormatLabel;
private JPanel emailButtonPanel;
private JButton addButton;
private JButton editButton;
private JButton removeButton;
private JButton asDefaultButton;
private JRadioButton htmlRadioButton;
private JRadioButton plainTextRadioButton;
private JRadioButton customTextRadioButton;
private JPanel buttonPanel;
private JButton okButton;
private JButton cancelButton;
public ContactPanel() {
createComponents();
makeLayout();
createHandlers();
registerHandlers();
initComponent();
i18n();
}
/**
* Create GUI components, but contains no layout.
*/
public void createComponents() {
namePanel = new JPanel();
nameTitledBorder = new TitledBorder("");
firstNameLabel = new JLabel();
firstNameTextField = new JTextField();
lastNameLabel = new JLabel();
lastNameTextField = new JTextField();
titleLabel = new JLabel();
titleTextField = new JTextField();
nicknameLabel = new JLabel();
nickNameTextField = new JTextField();
formatLabel = new JLabel();
formatComboBox = new JComboBox<>();
emailPanel = new JPanel();
emailTitledBorder = new TitledBorder("");
emailLabel = new JLabel();
emailTextField = new JTextField();
emailItemsList = new JList<>();
mailFormatLabel = new JLabel();
emailButtonPanel = new JPanel();
addButton = new JButton();
editButton = new JButton();
removeButton = new JButton();
asDefaultButton = new JButton();
htmlRadioButton = new JRadioButton();
plainTextRadioButton = new JRadioButton();
customTextRadioButton = new JRadioButton();
buttonPanel = new JPanel();
okButton = new JButton();
cancelButton = new JButton("Cancel");
}
/**
* Create listeners/handlers
*/
public void createHandlers() {
}
/**
* Registers/adds listeners/handlers.
*/
public void registerHandlers() {
}
public void makeLayout() {
layoutNamePanel();
layoutEmailPanel();
layoutButtonPanel();
MigLayout migLayout = new MigLayout("fill, insets 20");
setLayout(migLayout);
add(namePanel, "dock north");
add(emailPanel, "dock north");
add(buttonPanel, "dock south");
}
private void layoutButtonPanel() {
buttonPanel.setLayout(new MigLayout("alignX right"));
buttonPanel.add(okButton, "tag ok");
buttonPanel.add(cancelButton, "tag cancel");
}
private void layoutNamePanel() {
MigLayout nameLayout = new MigLayout("fill, wrap 4", // Layout Constraints
"15[]15[grow]15[]15[grow]", // Column constraints
""); // Row constraints
// -- Layout all components with name
namePanel.setLayout(nameLayout);
// Create this border here since I use it for layout
Border nameBorder = BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(10, 6, 10, 6), nameTitledBorder);
namePanel.setBorder(nameBorder);
namePanel.add(firstNameLabel, "alignX right");
namePanel.add(firstNameTextField, "grow");
namePanel.add(lastNameLabel, "alignX right");
namePanel.add(lastNameTextField, "grow");
namePanel.add(titleLabel, "alignX right");
namePanel.add(titleTextField, "grow");
namePanel.add(nicknameLabel, "alignX right");
namePanel.add(nickNameTextField, "grow");
namePanel.add(formatLabel, "alignX right");
namePanel.add(formatComboBox, new CC().grow().span(3)); // Alternative to using plain text'
}
private void layoutEmailPanel() {
MigLayout emailLayout = new MigLayout("fill",// Layout Constraints
"", // Column constraints
""); // Row constraints
// -- Layout all components with name
emailPanel.setLayout(emailLayout);
// Create this border here since I use it for layout
Border emailBorder = BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(10, 6, 10, 6), emailTitledBorder);
emailPanel.setBorder(emailBorder);
emailButtonPanel.setLayout(new MigLayout("wrap, fill, insets 20 10 0 10"));
emailButtonPanel.add(addButton, "growx");
emailButtonPanel.add(editButton, "growx");
emailButtonPanel.add(removeButton, "growx");
emailButtonPanel.add(asDefaultButton, "growx");
JPanel emailAndItems = new JPanel(new MigLayout("fill"));
emailAndItems.add(emailLabel, "split 2");
emailAndItems.add(emailTextField, "span, growx, wrap");
emailAndItems.add(emailItemsList, "span, grow");
JPanel radioButtons = new JPanel(new MigLayout());
radioButtons.add(htmlRadioButton);
radioButtons.add(plainTextRadioButton);
radioButtons.add(customTextRadioButton);
emailPanel.add(radioButtons, "dock south");
emailPanel.add(mailFormatLabel, "dock south, gapleft 15");
emailPanel.add(emailAndItems, "dock west, growx, push");
emailPanel.add(emailButtonPanel, "dock east, shrink");
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(htmlRadioButton);
buttonGroup.add(plainTextRadioButton);
buttonGroup.add(customTextRadioButton);
}
/**
* Sets initial values for component.
*/
public void initComponent() {
formatComboBox.addItem("Item 1");
formatComboBox.addItem("Item 2");
formatComboBox.addItem("Item 3");
formatComboBox.addItem("Item 4");
DefaultListModel<String> model = new DefaultListModel<>();
emailItemsList.setModel(model);
model.insertElementAt("Item 1", 0);
model.insertElementAt("Item 2", 1);
model.insertElementAt("Item 3", 2);
model.insertElementAt("Item 4", 3);
customTextRadioButton.setSelected(true);
}
public void i18n() {
nameTitledBorder.setTitle("Name:");
firstNameLabel.setText("First Name:");
lastNameLabel.setText("Last Name:");
titleLabel.setText("Title:");
nicknameLabel.setText("Nickname:");
formatLabel.setText("Format:");
emailTitledBorder.setTitle("E-mail");
emailLabel.setText("E-mail address:");
mailFormatLabel.setText("Mail Format:");
addButton.setText("Add");
editButton.setText("Edit");
removeButton.setText("Remove");
asDefaultButton.setText("As Default");
htmlRadioButton.setText("HTML");
plainTextRadioButton.setText("Plain Text");
customTextRadioButton.setText("Custom");
okButton.setText("OK");
cancelButton.setText("Cancel");
}
}
}
The code was written in Java 7. A maven pom.xml file to go with it could be something like this:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>stackoverflow</groupId>
<artifactId>stackoverflow</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>com.miglayout</groupId>
<artifactId>miglayout-core</artifactId>
<version>4.2</version>
</dependency>
<dependency>
<groupId>com.miglayout</groupId>
<artifactId>miglayout-swing</artifactId>
<version>4.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
I'd say border layout will work alright for you if you are looking for Java library layout managers. A more advanced one would be MiG Layout. You can google it for the info.
You do know that you can nest layout managers right? As in, one JPanel has one layoutmanager and another has a different one. So one could have border layout and another flow layout.
You can try NetBeans if you want a simple Swing designer, but IMHO Miglayout is the shortest way to get your UI's done as you intended. After the initial learning curve of course...
Try to visualize your screen in grids, and then you can use both gridbag and miglayout.
Related
I am trying to create a GUI that runs a guessing game, but have gotten stuck using GridBagLayout. The problem is with the sizing of the JPanel within my JFrame.
I have already written a similar program that works just fine, and do not understand why one works and the other does not.
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.util.*;
public class GuessGame {
private static JTextField inputBox;
GuessGame(){}
public static void main(String[] args) {
createWindow();
}
private static void createWindow() {
JFrame frame = new JFrame("GuessingGame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
createUI(frame);
frame.setSize(600, 600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static void createUI(JFrame frame) {
JPanel panel = new JPanel();
GridBagLayout layout = new GridBagLayout();
panel.setLayout(layout);
GuessGame guessingGame = new GuessGame();
GridBagConstraints gbc = new GridBagConstraints();
inputBox = new JTextField(10);
inputBox.setEditable(false);
JLabel title = new JLabel("FUN FUN Guessing Game");
JLabel entryBoxLabel = new JLabel("Entry Box: ");
JLabel statsOptions = new JLabel("Statistics Options");
JLabel message = new JLabel("HAVE FUN!!!");
JButton startGame = new JButton("START");
JButton clearDisplay = new JButton("CLEAR");
JButton displayStats = new JButton("STATS");
JCheckBox bestTime = new JCheckBox("Best Time");
JCheckBox bestPlays = new JCheckBox("Best # of Plays");
JCheckBox bestPlayer = new JCheckBox("Best Player");
JTextArea displayArea = new JTextArea(300, 300);
JScrollPane scrollWrap = new JScrollPane(displayArea);
gbc.anchor = GridBagConstraints.ABOVE_BASELINE;
gbc.gridx = 0; gbc.gridy = 0; panel.add(title, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0; gbc.gridy = 1; panel.add(startGame, gbc);
gbc.fill = GridBagConstraints.WEST;
gbc.gridx = 1; gbc.gridy = 1; panel.add(entryBoxLabel, gbc);
gbc.fill = GridBagConstraints.LINE_END;
gbc.gridx = 1; gbc.gridy = 1; panel.add(inputBox, gbc);
gbc.fill = GridBagConstraints.NONE;
gbc.gridx = 0; gbc.gridy = 2; panel.add(displayArea, gbc);
gbc.gridx = 1; gbc.gridy = 2; panel.add(scrollWrap, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0; gbc.gridy = 3; panel.add(clearDisplay, gbc);
gbc.anchor = GridBagConstraints.NORTH;
gbc.gridx = 1; gbc.gridy = 3; panel.add(statsOptions, gbc);
gbc.anchor = GridBagConstraints.SOUTHWEST;
gbc.gridx = 1; gbc.gridy = 3; panel.add(bestTime, gbc);
gbc.anchor = GridBagConstraints.SOUTH;
gbc.gridx = 1; gbc.gridy = 3; panel.add(bestPlays, gbc);
gbc.anchor = GridBagConstraints.SOUTHEAST;
gbc.gridx = 1; gbc.gridy = 3; panel.add(bestPlayer, gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0; gbc.gridy = 4; panel.add(displayStats, gbc);
gbc.gridx = 1; gbc.gridy = 4; panel.add(message, gbc);
frame.getContentPane().add(panel, BorderLayout.CENTER);
}
}
I was expecting something that looks like this:
!https://imgur.com/20HVSxR
But what I got was this:
!https://imgur.com/AnMJtt7
HALP
Instad of using GridBad, I prefer using BoxLayout. Here is my approach to your problem. This is the closest you can get to the image you posted using Swing.
import java.awt.*;
import javax.swing.*;
public class Test {
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JFrame frame = new JFrame();
JPanel north = createNorthPanel();
JPanel center = createCenterPanel();
JPanel south = createSouthPanel();
frame.add(north, BorderLayout.NORTH);
frame.add(center, BorderLayout.CENTER);
frame.add(south, BorderLayout.SOUTH);
frame.setLocationByPlatform(true);
frame.pack();
frame.setVisible(true);
}
private static JPanel createNorthPanel() {
JPanel northPanel = new JPanel();
BoxLayout northPanelLayout = new BoxLayout(northPanel, BoxLayout.Y_AXIS);
northPanel.setLayout(northPanelLayout);
JPanel upperPanel = new JPanel();
JLabel funFunGuessingGameLabel = new JLabel("FUN FUN Guessing Game");
funFunGuessingGameLabel.setFont(funFunGuessingGameLabel.getFont().deriveFont(Font.ITALIC));
upperPanel.add(funFunGuessingGameLabel);
upperPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
JPanel lowerPanel = new JPanel();
BoxLayout lowerPanelLayout = new BoxLayout(lowerPanel, BoxLayout.X_AXIS);
lowerPanel.setLayout(lowerPanelLayout);
JButton startButton = new JButton("START");
startButton.setPreferredSize(new Dimension(175,(int)startButton.getPreferredSize().getHeight()));
JLabel entryBoxLabel = new JLabel("Entry Box: ");
JTextField entryBoxTextField = new JTextField();
lowerPanel.add(startButton);
lowerPanel.add(Box.createHorizontalStrut(10));
lowerPanel.add(entryBoxLabel);
lowerPanel.add(entryBoxTextField);
lowerPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
northPanel.add(upperPanel);
northPanel.add(lowerPanel);
return northPanel;
}
private static JPanel createCenterPanel() {
JPanel centerPanel = new JPanel();
BoxLayout centerPanelLayout = new BoxLayout(centerPanel, BoxLayout.Y_AXIS);
centerPanel.setLayout(centerPanelLayout);
JLabel l1 = new JLabel("Guesses and statistics are shown in this display as a scrollable list, e.g.: ");
JLabel l2 = new JLabel("(1,3,5)é(0,0)");
JLabel l3 = new JLabel("(2,4,6)é(0,0)");
JLabel l4 = new JLabel("(7,8,9)é(0,0)");
Box space = Box.createVerticalBox();
centerPanel.add(Box.createHorizontalStrut(10));
centerPanel.add(l1);
centerPanel.add(Box.createVerticalStrut(10));
centerPanel.add(l2);
centerPanel.add(Box.createVerticalStrut(5));
centerPanel.add(l3);
centerPanel.add(Box.createVerticalStrut(5));
centerPanel.add(l4);
centerPanel.add(Box.createVerticalStrut(40));
centerPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
return centerPanel;
}
private static JPanel createSouthPanel() {
JPanel southPanel = new JPanel();
BoxLayout southPanelLayout = new BoxLayout(southPanel, BoxLayout.Y_AXIS);
southPanel.setLayout(southPanelLayout);
JPanel upperPanel = new JPanel();
BoxLayout upperPanelLayout = new BoxLayout(upperPanel, BoxLayout.X_AXIS);
upperPanel.setLayout(upperPanelLayout);
JPanel clearButtonPanel = new JPanel(new BorderLayout(0, 0));
JButton clearButton = new JButton("CLEAR");
clearButton.setPreferredSize(new Dimension(175, (int) clearButton.getPreferredSize().getHeight()));
clearButtonPanel.add(clearButton);
JPanel innerPanel = new JPanel();
BoxLayout innerPanelLayout = new BoxLayout(innerPanel, BoxLayout.Y_AXIS);
innerPanel.setLayout(innerPanelLayout);
JPanel statisticsOptionsLabelPanel = new JPanel();
JLabel statisticsOptionsLabel = new JLabel("Statistics Options");
statisticsOptionsLabelPanel.add(statisticsOptionsLabel);
JPanel checkBoxPanel = new JPanel();
BoxLayout checkBoxPanelLayout = new BoxLayout(checkBoxPanel, BoxLayout.X_AXIS);
checkBoxPanel.setLayout(checkBoxPanelLayout);
JCheckBox bestTimeCheckBox = new JCheckBox("Best Time");
JCheckBox bestNumOfPlaysCheckBox = new JCheckBox("Best # of plays");
JCheckBox topPlayerCheckBox = new JCheckBox("Top Player");
checkBoxPanel.add(bestTimeCheckBox);
checkBoxPanel.add(bestNumOfPlaysCheckBox);
checkBoxPanel.add(topPlayerCheckBox);
innerPanel.add(statisticsOptionsLabelPanel);
upperPanel.add(Box.createVerticalGlue());
innerPanel.add(checkBoxPanel);
upperPanel.add(clearButtonPanel);
upperPanel.add(Box.createHorizontalStrut(14));
upperPanel.add(innerPanel);
upperPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
JPanel lowerPanel = new JPanel();
BoxLayout lowerPanelLayout = new BoxLayout(lowerPanel, BoxLayout.X_AXIS);
lowerPanel.setLayout(lowerPanelLayout);
JButton statsButton = new JButton("STATS");
statsButton.setPreferredSize(new Dimension(175,(int)statsButton.getPreferredSize().getHeight()));
JLabel haveFunLabel = new JLabel("Have Fun!!!");
lowerPanel.add(statsButton);
lowerPanel.add(Box.createHorizontalGlue());
lowerPanel.add(haveFunLabel);
lowerPanel.add(Box.createHorizontalGlue());
lowerPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
southPanel.add(upperPanel);
southPanel.add(lowerPanel);
return southPanel;
}
}
I'd like to decorate a JPanel with a JLayer, but am failing to understand why doing so messes up this panel being laid out inside a JScrollPane. The decorated component is supposed to act as a drop in replacement, but it does not appear to work in this case.
The following code creates two equivalent JPanels and puts them into another panel with CardLayout (so you may switch between them using the buttons). The only difference is that in one case the panel is decorated with a JLayer.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.LayerUI;
public class JLayerScroll extends JFrame {
public JLayerScroll() {
setTitle("Jumpy border");
setLayout(new BorderLayout());
setDefaultCloseOperation(EXIT_ON_CLOSE);
createGui();
setSize(400, 200);
setLocationRelativeTo(null);
}
private void createGui() {
JPanel mainPanel = new JPanel(new CardLayout());
// two panels ("label panels"), first one decorated, second one not
mainPanel.add(createSingleScrolledComponent(new JLayer<JPanel>(createLabelPanel(), new LayerUI<JPanel>())), WITH_JLAYER);
mainPanel.add(createSingleScrolledComponent(createLabelPanel()), WITHOUT_JLAYER);
add(mainPanel);
createButtons(mainPanel);
}
private JPanel createSingleScrolledComponent(Component component) {
GridBagConstraints gbc;
JScrollPane scroll;
JPanel panel = new JPanel(new GridBagLayout());
scroll = new JScrollPane(component);
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1.0d;
gbc.weighty = 1.0d;
panel.add(scroll, gbc);
return panel;
}
private JPanel createLabelPanel() {
GridBagConstraints gbc;
JPanel panel = new JPanel(new GridBagLayout());
JPanel entry = new JPanel(new GridBagLayout());
entry.setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.red));
JLabel label = new JLabel("Some input:");
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
entry.add(label, gbc);
JTextField field = new JTextField(20);
field.setMinimumSize(new Dimension(field.getPreferredSize().width, field.getMinimumSize().height));
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
entry.add(field, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 2;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0d;
entry.add(Box.createHorizontalGlue(), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0d;
panel.add(entry, gbc);
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.VERTICAL;
gbc.weighty = 1.0d;
panel.add(Box.createVerticalGlue(), gbc);
return panel;
}
private static final String WITH_JLAYER = "with-jlayer";
private static final String WITHOUT_JLAYER = "no-jlayer";
private void createButtons(final JPanel mainPanel) {
GridBagConstraints gbc;
JButton button;
JPanel actionsPanel = new JPanel(new GridBagLayout());
gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1.0d;
actionsPanel.add(Box.createHorizontalGlue(), gbc);
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
button = new JButton("With JLayer");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
CardLayout layout = (CardLayout) mainPanel.getLayout();
layout.show(mainPanel, WITH_JLAYER);
}
});
actionsPanel.add(button, gbc);
gbc.gridx = 2;
gbc.gridy = 0;
button = new JButton("Without JLayer");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
CardLayout layout = (CardLayout) mainPanel.getLayout();
layout.show(mainPanel, WITHOUT_JLAYER);
}
});
actionsPanel.add(button, gbc);
add(actionsPanel, BorderLayout.SOUTH);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new JLayerScroll().setVisible(true);
}
});
}
}
If you pay attention to the red border in the two cases, you will notice that in one case it spans the whole available horizontal space (as expected), while in the other case, it only spans around visible components (label and text field).
Why is this happening and how do I achieve the same behavior as in the undecorated case (spanning through all available horizontal space)?
The only difference is that in one case the panel is decorated with a JLayer.
A difference between a JPanel and a JLayer is that the JLayer implements the Scrollable interface but a JPanel does not.
The getScrollableTracksViewportWidth() method controls whether the component added to the viewport should be displayed at its preferred size or the width of the viewport. The JLayer delegates to the JPanel, but since JPanel doesn't implement the Scrollable interface the JLayer implementation will return "false" which means the component should be displayed at its preferred width.
So a way to get around this is to use a wrapper panel for the JLayer:
//scroll = new JScrollPane(component);
JPanel wrapper = new JPanel( new BorderLayout() );
wrapper.add( component );
scroll = new JScrollPane(wrapper);
Now the component added to the viewport of the scrollpane is a JPanel in both cases, so they should behave the same way.
I am new to JFrame and I am having problems with the layout in NetBean, how to solve this layout problem? I tried to resize, but the position of the elements will become mess. I am trying to display each detail to the specified text areas .
Am i using the wrong layout or my coding are having problems? help...><
This is my output now
And this is the output i want
These are my codings :
public class PokemonJournal extends JFrame
implements ActionListener {
JTextArea FirstName = new JTextArea(1, 10);
JTextArea LastName = new JTextArea(1, 10);
JTextArea Level = new JTextArea(1, 10);
JTextArea Gender = new JTextArea(1, 10);
JButton showPokemon = new JButton("Show");
JButton showRaid = new JButton("Show");
JButton showPokestop = new JButton("Show");
DBHandler db = new DBHandler();
ImageIcon image = new ImageIcon("p1.jpg");
JLabel imageLabel = new JLabel(image);
public static void main(String[] args) {
PokemonJournal jf = new PokemonJournal();
}
public PokemonJournal() {
setLayout(new FlowLayout());
setSize(300, 600);
setTitle(" Pokemon Journal ");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setLocationRelativeTo(null);
setResizable(false);
JPanel top = new JPanel();
add("north", top);
top.add(new Label("Pokemon Journal"));
JPanel side = new JPanel();
add("West", side);
side.setLayout(new GridLayout());
side.add(imageLabel);
JPanel line1 = new JPanel();
add("center", line1);
line1.setLayout(new GridLayout());
line1.add(new Label("First Name :"));
line1.add(FirstName);
JPanel line2 = new JPanel();
add("Center", line2);
FirstName.setEditable(false);
line2.setLayout(new GridLayout());
line2.add(new Label("Last Name :"));
line2.add(LastName);
LastName.setEditable(false);
JPanel line3 = new JPanel();
add("Center", line3);
line3.setLayout(new GridLayout());
line3.add(new Label("Level :"));
line3.add(Level);
Level.setEditable(false);
JPanel line4 = new JPanel();
add("Center", line4);
line4.setLayout(new GridLayout());
line4.add(new Label("Gender : "));
line4.add(Gender);
Gender.setEditable(false);
JPanel line5 = new JPanel();
add("Center", line5);
line5.setLayout(new GridLayout());
line5.add(new Label("Pokemon Caught:"));
line5.add(showPokemon);
JPanel line6 = new JPanel();
add("Center", line6);
line6.setLayout(new GridLayout());
line6.add(new Label("Raid Won:"));
line6.add(showRaid);
JPanel line7 = new JPanel();
add("Center", line7);
line7.setLayout(new GridLayout());
line7.add(new Label("Pokestop visited:"));
line7.add(showPokestop);
}
Am i using the wrong layout or my coding are having problems?
Well, yes, a little, but it has more to do with the size of your JFrame, never call setSize() on them, instead call pack(). However if you change it for pack(), the default orientation of the FlowLayout is FlowLayout.HORIZONTAL and thus all your components will go to the right of each other.
Then, you have 2 options:
Keep the JFrame's layout as FlowLayout but make two JPanels, one for the image and one for the data, the image might have the default FlowLayout as well but the other one might have GridLayout.
Use GridBagLayout for all your components, letting the image JLabel to have a height of 7 cells and all the others a height of 1.
For the following example I will be using the GridBagLayout option, and I recommend you to try to make the multipanel option (option 1).
However, before starting I must mention your other problems in your code:
You're not following the Java naming conventions: firstWordLowerCaseVariable, firstWordLowerCaseMethods(), FirstWordUpperCaseClasses, ALL_WORDS_UPPER_CASE_CONSTANTS, this will make your code easier to read and understand for you and for us.
You're not changing the behavior of the JFrame so, there's no need to inherit from it: See Extends JFrame vs. creating it inside the program for more information.
Related to the above point, it's wise to build your GUI towards JPanels instead of JFrames, see: The Use of Multiple JFrames: Good or Bad Practice? as well, as I think you might end up in similar problems in the future.
You're not placing your program on the Event Dispatch Thread (EDT), see this related answer to see how to solve this problem.
You're calling setSize(...) method, and as I said before, it's always better to call pack() method instead, leaving the calculations for the GUI size to the layout manager.
You're calling setVisible before adding all your components to the GUI, this could lead you to blank or black screens, it should be the last line in your program.
Related to the above point, I always like to start doing the GUI from inside out and adding the items that way, instead of outside in.
Why are you using JTextAreas instead of JTextFields for the user information?
Now, the code that follows the above recommendations using the 2nd option I gave you is this:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class PokemonJournal {
private JFrame frame;
private JPanel pane;
private GridBagConstraints gbc;
private JLabel imageLabel;
private JLabel firstName;
private JLabel lastName;
private JLabel level;
private JLabel gender;
private JLabel pokemonCaught;
private JLabel raidWon;
private JLabel pokestopVisited;
private JTextField nameField;
private JTextField lastNameField;
private JTextField levelField;
private JTextField genderField;
private JButton pokemonCaughtButton;
private JButton raidWonButton;
private JButton pokestopVisitedButton;
public static void main(String[] args) {
SwingUtilities.invokeLater(new PokemonJournal()::createAndShowGui);
}
private void createAndShowGui() {
frame = new JFrame(getClass().getSimpleName());
pane = new JPanel();
pane.setLayout(new GridBagLayout());
gbc = new GridBagConstraints();
imageLabel = new JLabel();
try {
imageLabel.setIcon(new ImageIcon(
new URL("http://pm1.narvii.com/6535/1b362404d09091a335ce53fa68506827418890a3_128.jpg")));
} catch (MalformedURLException e) {
e.printStackTrace();
}
firstName = new JLabel("First Name: ");
lastName = new JLabel("Last Name: ");
level = new JLabel("Level: ");
gender = new JLabel("Gender: ");
pokemonCaught = new JLabel("Pokemon Caught: ");
raidWon = new JLabel("Raid Won: ");
pokestopVisited = new JLabel("Pokestop Visited: ");
nameField = new JTextField(10);
lastNameField = new JTextField(10);
levelField = new JTextField(10);
genderField = new JTextField(10);
pokemonCaughtButton = new JButton("Show");
raidWonButton = new JButton("Show");
pokestopVisitedButton = new JButton("Show");
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridheight = 7;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(5, 5, 5, 5);
pane.add(imageLabel, gbc);
gbc.gridx = 1;
gbc.gridheight = 1;
pane.add(firstName, gbc);
gbc.gridx = 2;
pane.add(nameField, gbc);
gbc.gridx = 1;
gbc.gridheight = 1;
gbc.gridy++;
pane.add(lastName, gbc);
gbc.gridx = 2;
pane.add(lastNameField, gbc);
gbc.gridx = 1;
gbc.gridheight = 1;
gbc.gridy++;
pane.add(level, gbc);
gbc.gridx = 2;
pane.add(levelField, gbc);
gbc.gridx = 1;
gbc.gridheight = 1;
gbc.gridy++;
pane.add(gender, gbc);
gbc.gridx = 2;
pane.add(genderField, gbc);
gbc.gridx = 1;
gbc.gridheight = 1;
gbc.gridy++;
pane.add(pokemonCaught, gbc);
gbc.gridx = 2;
pane.add(pokemonCaughtButton, gbc);
gbc.gridx = 1;
gbc.gridheight = 1;
gbc.gridy++;
pane.add(raidWon, gbc);
gbc.gridx = 2;
pane.add(raidWonButton, gbc);
gbc.gridx = 1;
gbc.gridheight = 1;
gbc.gridy++;
pane.add(pokestopVisited, gbc);
gbc.gridx = 2;
pane.add(pokestopVisitedButton, gbc);
frame.add(pane);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
And it produces a GUI similar to this one:
I have a Swing Form that contains a JScrollPane(activityScrollPane) for a JPanel(activityPanel). The panel contains a JTextField and a JButton (that is used to add more fields to the Panel). Now the problem is that the elements start from the center of the panel as in the image below (with the borders marking the activityScrollPane boundary)
Following is the code I am currently using to make the scroll pane and associated components.
//part of the code for creating the ScrollPane
final JPanel activityPanel = new JPanel(new GridBagLayout());
gbc.gridx=0;
gbc.gridy=0;
JScrollPane activityScrollPane = new JScrollPane(activityPanel);
//adding activity fields
activityFields = new ArrayList<JTextField>();
fieldIndex = 0;
activityFields.add(new JTextField(30));
final GridBagConstraints activityGBC = new GridBagConstraints();
activityGBC.gridx=0;
activityGBC.gridy=0;
activityGBC.anchor = GridBagConstraints.FIRST_LINE_START;
activityPanel.add(activityFields.get(fieldIndex),activityGBC);
fieldIndex++;
JButton btn_more = (new JButton("more"));
activityGBC.gridx=1;
activityPanel.add(btn_more,activityGBC);
How can I make the JTextField and the JButton or for that matter any component to appear on the top left corner of the JScrollPane. I have already tried using
activityConstraints.anchor = GridBagConstraints.NORTHWEST;
as pointed in the SO post, but it does not at all seem to work.
You simply forgot to provide any weightx/weighty values, atleast one having a non-zero value will do. have a look at this code example :
import java.awt.*;
import javax.swing.*;
public class GridBagLayoutDemo
{
private JTextField tfield1;
private JButton button1;
private void displayGUI()
{
JFrame frame = new JFrame("GridBagLayout Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new GridBagLayout());
tfield1 = new JTextField(10);
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
contentPane.add(tfield1, gbc);
button1 = new JButton("More");
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.NONE;
contentPane.add(button1, gbc);
frame.setContentPane(contentPane);
frame.pack();
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new GridBagLayoutDemo().displayGUI();
}
});
}
}
Latest EDIT : No spacing along Y-Axis
import java.awt.*;
import javax.swing.*;
public class GridBagLayoutDemo
{
private JTextField tfield1;
private JButton button1;
private JTextField tfield2;
private JButton button2;
private void displayGUI()
{
JFrame frame = new JFrame("GridBagLayout Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new GridBagLayout());
tfield1 = new JTextField(10);
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.FIRST_LINE_START;
gbc.weightx = 1.0;
//gbc.weighty = 0.2;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
contentPane.add(tfield1, gbc);
button1 = new JButton("More");
gbc.gridx = 1;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.NONE;
contentPane.add(button1, gbc);
tfield2 = new JTextField(10);
gbc.weightx = 1.0;
gbc.weighty = 0.2;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
contentPane.add(tfield2, gbc);
button2 = new JButton("More");
gbc.gridx = 1;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.NONE;
contentPane.add(button2, gbc);
JScrollPane scroller = new JScrollPane(contentPane);
frame.add(scroller);
frame.pack();
frame.setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new GridBagLayoutDemo().displayGUI();
}
});
}
}
Sorry as my answer me be on the off-side of what you have asked, but why dont you use GroupLayout instead of GridBag Layout, thats much more easier to handle
try it with BorderLayout: controls.setLayout(new BorderLayout()); and then apply it for your JPanel controls.add(yourPanel, BorderLayout.PAGE_START);
I also have problems with GridBagLayout so i solved it with BorderLayout and it works so fine.
So i wrote for your little example:
private void initComponents() {
controls = new Container();
controls = getContentPane();
controls.setLayout(new BorderLayout());
panel = new JPanel();
panel.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
field = new JTextField(20);
c.gridx = 0;
c.gridy = 0;
panel.add(field, c);
one = new JButton("Go!");
c.gridx = 1;
c.gridy = 0;
panel.add(one, c);
controls.add(panel, BorderLayout.PAGE_START);
}
Hope it helps!
I think this could be simple and possible, you can
put Nested JPanel to the JScrollPane
to this JPanel
put JPanels contains JComponent to the GridLayout (notice about scrolling, you have to change scrolling increment)
or use most complex JComponents as
put JPanels contains JComponent as Item to the JList
put JPanels contains JComponent as row to the JTable (with only one Column, with or without TableHeader)
Add one panel at the right and one at the bottom.
Right Panel:
Set Weight X to 1.0.
Set Fill to horizontal.
Bottom Panel:
Set Weight Y to 1.0.
Set Fill to vertical
There may be better ways to that, but this one worked for me.
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 :