Container with BoxLayout is resized by component - java

I'm currently working on a project for my studies and I have a little problem concerning the GUI.
Here is some code:
private JButton zoomUp, zoomDown;
private JComboBox fractalList;
private JLabel choice,space;
private JPanel ui,display;
private JFrame window;
public FractalView(FractalModel m, FractalController c, String title, int size_X, int size_Y)
{
window =new JFrame();
window.setTitle(title);
window.setSize(size_X,size_Y);
window.setLocationRelativeTo(null);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setResizable(false);
window.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor=GridBagConstraints.FIRST_LINE_START;
ui=new JPanel();
ui.setBackground(Color.GRAY);
ui.setBorder(BorderFactory.createTitledBorder("Interface de Controle et Options"));
BoxLayout uiLayout = new BoxLayout(ui, BoxLayout.PAGE_AXIS);
ui.setLayout(uiLayout);
ui.setMaximumSize(ui.getPreferredSize());
zoomUp = new JButton("Zoom +");
zoomUp.setAlignmentX(LEFT_ALIGNMENT);
zoomUp.setBorder(BorderFactory.createLineBorder(Color.RED));
ui.add(zoomUp);
zoomDown = new JButton("Zoom -");
//ui.add(zoomDown);
choice = new JLabel("Choisir une fractale : ");
//ui.add(choice);
Object[] elements = new Object[]{"Mandelbrot", "Julia", "Buddhabrot"};
fractalList = new JComboBox<Object>(elements);
//fractalList.setBorder(BorderFactory.createLineBorder(Color.RED));
fractalList.setAlignmentX(LEFT_ALIGNMENT);
fractalList.setMaximumSize(new Dimension(Short.MAX_VALUE,20));
//ui.add(fractalList);
gbc.weighty=1;
gbc.ipadx=300;
gbc.gridheight=1;
gbc.fill=GridBagConstraints.VERTICAL;
gbc.gridx=0;
gbc.gridy=0;
window.add(ui,gbc);
display=new JPanel();
display.setBackground(Color.RED);
gbc.weightx=1;
gbc.gridheight=1;
gbc.gridwidth=1;
gbc.fill=GridBagConstraints.BOTH;
gbc.gridx=1;
gbc.gridy=0;
window.add(display,gbc);
window.setVisible(true);
}
The problem comes from JPanel ui . As long it is empty the size is as desired. But when I add any component to it it's weight increases.
I tried to use setMaxSize() but even though it gets resized and this could cause problem with what I want to display on JPanel display. I would prefer to avoid using GridBagLayout again.
Does someone have an idea?

If you just want to split the Frame and don't want to fight with GridBagLayout, you could just use a BorderLayout.
Then, add one panel to BorderLayout.WEST and the other one to the BorderLayout.EAST position. And remember to call setPreferredSize to fix your desired width and height.
I've made some changes to your code. Check it out:
public class TestFrame {
private JButton zoomUp, zoomDown;
private JComboBox fractalList;
private JLabel choice, space;
private JPanel ui, display;
private JFrame window;
public TestFrame(String title, int size_X, int size_Y) {
window = new JFrame();
window.setTitle(title);
window.setSize(size_X, size_Y);
window.setLocationRelativeTo(null);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setResizable(false);
window.setLayout(new BorderLayout());
ui = new JPanel();
ui.setPreferredSize(new Dimension(size_X/2,size_Y));
ui.setBackground(Color.GRAY);
ui.setBorder(BorderFactory.createTitledBorder("Interface de Controle et Options"));
BoxLayout uiLayout = new BoxLayout(ui, BoxLayout.PAGE_AXIS);
ui.setLayout(uiLayout);
zoomUp = new JButton("Zoom +");
// zoomUp.setAlignmentX(LEFT_ALIGNMENT);
zoomUp.setBorder(BorderFactory.createLineBorder(Color.RED));
ui.add(zoomUp);
zoomDown = new JButton("Zoom -");
ui.add(zoomDown);
choice = new JLabel("Choisir une fractale : ");
ui.add(choice);
Object[] elements = new Object[] { "Mandelbrot", "Julia", "Buddhabrot" };
fractalList = new JComboBox<Object>(elements);
// fractalList.setBorder(BorderFactory.createLineBorder(Color.RED));
// fractalList.setAlignmentX(LEFT_ALIGNMENT);
fractalList.setMaximumSize(new Dimension(Short.MAX_VALUE, 20));
ui.add(fractalList);
window.add(ui, BorderLayout.WEST);
display = new JPanel();
display.setBackground(Color.RED);
display.setPreferredSize(new Dimension(size_X/2,size_Y));
window.add(display, BorderLayout.EAST);
window.setVisible(true);
}
public static void main(String[] args) {
new TestFrame("test of BorderLayout with WEST and EAST", 800, 600);
}
}
If you need something more complex than that, you could go with miglayout.

Related

Align JTextArea in JPanel

I'm currently building GUI with Java Swing.
My current code produces this.
The JTextArea of Product List makes the GUI looks awkward, how can I make the JTextArea looks like this, where it seems to have an extra row:
The GroupLayout code I'm using is:
gr.setVerticalGroup(gr.createSequentialGroup()
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(productName).addComponent(productText).addComponent(productList))
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(amount).addComponent(amountText).addComponent(prodScroll))
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(description).addComponent(desScroll))
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(addButton).addComponent(remButton)));
gr.setHorizontalGroup(gr.createSequentialGroup()
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(productName).addComponent(amount).addComponent(description).addComponent(addButton))
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.CENTER).addComponent(productText).addComponent(amountText).addComponent(desScroll).addComponent(remButton))
.addGroup(gr.createParallelGroup(GroupLayout.Alignment.CENTER).addComponent(productList).addComponent(prodScroll)));
I think the minority of people would choose to use GridBagLayout. However, I dislike it (among with GroupLayout) since it is "hard to use". I use nested panels instead with various Layout Managers. Using only BorderLayout and GridLayout you can achieve something like the following example, which is totally resizable, giving emphasis to "interaction" components (I mean, there is no reason to resize a constant-texted JLabel, right?)
I did not add any comments in purpose, so you can experiment with constants (and layout constraints) and see their reason of existence while having the documentations opened.
Code:
public class NestedLayoutManagersExample extends JFrame {
private static final long serialVersionUID = -7042997375941726246L;
private static final int labelsWidth = 80;
private static final int textFieldColumns = 15;
private static final int spaceBetweenAllComponents = 10;
public NestedLayoutManagersExample() {
super("test");
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel contentPane = new JPanel(new GridLayout(1, 2, 50, 50));
contentPane.setBorder(BorderFactory.createEmptyBorder(spaceBetweenAllComponents, spaceBetweenAllComponents,
spaceBetweenAllComponents, spaceBetweenAllComponents));
setContentPane(contentPane);
add(createLeftPanel());
add(createRightPanel());
setLocationByPlatform(true);
pack();
}
private Component createRightPanel() {
JPanel mainPanel = new JPanel(new BorderLayout());
JLabel productListLabel = new JLabel("Product list");
mainPanel.add(productListLabel, BorderLayout.PAGE_START);
JList<String> productList = new JList<>();
DefaultListModel<String> listModel = new DefaultListModel<>();
Arrays.asList("Small Chair", "Big Chair", "Flying Chair").forEach(listModel::addElement);
productList.setModel(listModel);
JScrollPane listScrollPane = new JScrollPane(productList);
mainPanel.add(listScrollPane, BorderLayout.CENTER);
return mainPanel;
}
private Component createLeftPanel() {
JPanel mainPanel = new JPanel(new BorderLayout(spaceBetweenAllComponents, spaceBetweenAllComponents));
JPanel topPanel = new JPanel(new GridLayout(2, 1, spaceBetweenAllComponents, spaceBetweenAllComponents));
topPanel.add(createStraightPanel("Product Name"));
topPanel.add(createStraightPanel("Amount"));
mainPanel.add(topPanel, BorderLayout.PAGE_START);
JPanel centerPanel = new JPanel(new BorderLayout());
JLabel label = new JLabel("<html><p style='width:" + labelsWidth + "px';> Description");
label.setVerticalAlignment(JLabel.TOP);
centerPanel.add(label, BorderLayout.LINE_START);
centerPanel.add(createTextAreaPanel());
mainPanel.add(centerPanel, BorderLayout.CENTER);
return mainPanel;
}
private JPanel createTextAreaPanel() {
JPanel mainPanel = new JPanel(new BorderLayout(spaceBetweenAllComponents, spaceBetweenAllComponents));
JTextArea textArea = new JTextArea(1, textFieldColumns);
JScrollPane textAreaScrollPane = new JScrollPane(textArea);
mainPanel.add(textAreaScrollPane, BorderLayout.CENTER);
JPanel buttonsPanel = new JPanel(new BorderLayout());
JButton addButton = new JButton("Add");
buttonsPanel.add(addButton, BorderLayout.LINE_START);
JButton removeButton = new JButton("Remove");
buttonsPanel.add(removeButton, BorderLayout.LINE_END);
mainPanel.add(buttonsPanel, BorderLayout.PAGE_END);
return mainPanel;
}
private Component createStraightPanel(String labelText) {
JPanel mainPanel = new JPanel(new BorderLayout());
JLabel label = new JLabel("<html><p style='width:" + labelsWidth + "px';>" + labelText);
mainPanel.add(label, BorderLayout.LINE_START);
JTextField textField = new JTextField(textFieldColumns);
mainPanel.add(textField, BorderLayout.CENTER);
return mainPanel;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new NestedLayoutManagersExample().setVisible(true));
}
}
Preview:

GridBagLayout isn't formatting correctly

I'm trying to get the config panel to take up the top of the screen, and then have the input and output panels side-by-side. I'm also trying to get the text areas to be 70 characters wide each and 30 rows tall. However, right now, the config panel isn't showing up at all, and the text areas are only 35 characters wide and 2 rows tall. I've followed all the examples and tutorials I've found. What am I doing wrong?
public class BorderWrapper {
public static void main(String[] args) {
//Create frame
JFrame frame = new JFrame("Border Wrapper");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create main panel
MainPanel panel = new MainPanel();
frame.getContentPane().add(panel, BorderLayout.NORTH);
//Display frame
Dimension minSize = new Dimension(650, 375);
frame.setPreferredSize(minSize);
frame.setMinimumSize(minSize);
frame.pack();
frame.setVisible(true);
}
}
public class MainPanel extends JPanel {
private static final Font INPUT_FONT = new Font("Monospaced", Font.PLAIN, 12);
private JTextArea inputArea, outputArea;
private JTextField titleField, topBorderField, sideBorderField;
public MainPanel() {
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
//Set up config panel
JPanel configPanel = new JPanel();
configPanel.setLayout(new BoxLayout(configPanel, BoxLayout.X_AXIS));
configPanel.setMaximumSize(new Dimension(400, 200));
titleField = new JTextField(25);
titleField.setFont(INPUT_FONT);
topBorderField = new JTextField(1);
topBorderField.setFont(INPUT_FONT);
sideBorderField = new JTextField(4);
sideBorderField.setFont(INPUT_FONT);
configPanel.add(new JLabel("Title:"));
configPanel.add(titleField);
configPanel.add(new JLabel("Top border:"));
configPanel.add(topBorderField);
configPanel.add(new JLabel("Side border:"));
configPanel.add(sideBorderField);
c.gridwidth = 2;
c.gridx = 0;
c.gridy = 0;
add(configPanel, c);
//Set up Input panel
JPanel inputPanel = new JPanel();
inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.Y_AXIS));
inputArea = new JTextArea("Type or paste your stuff here . . .");
inputArea.setFont(INPUT_FONT);
inputArea.setLineWrap(true);
inputArea.setWrapStyleWord(true);
inputArea.setColumns(75);
JScrollPane inputPane = new JScrollPane(inputArea);
inputPane.setMinimumSize(new Dimension(250, 400));
JLabel inputLabel = new JLabel("Text Box");
inputLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
inputPanel.add(inputLabel);
inputPanel.add(inputPane);
inputPanel.setMinimumSize(new Dimension(250, 400));
c.gridwidth = 1;
c.gridx = 0;
c.gridy = 1;
add(inputPanel, c);
//Set up Output panel
JPanel outputPanel = new JPanel();
outputPanel.setLayout(new BoxLayout(outputPanel, BoxLayout.Y_AXIS));
outputArea = new JTextArea();
outputArea.setFont(INPUT_FONT);
outputArea.setLineWrap(true);
outputArea.setWrapStyleWord(true);
outputArea.setColumns(75);
JScrollPane outputPane = new JScrollPane(outputArea);
outputPane.setMinimumSize(new Dimension(250, 400));
JLabel outputLabel = new JLabel("Wrapped Output");
outputLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
outputPanel.add(outputLabel);
outputPanel.add(outputPane);
outputPanel.setMinimumSize(new Dimension(250, 400));
c.gridwidth = 1;
c.gridx = 1;
c.gridy = 1;
add(outputPanel, c);
}
}
Originally, I was going to try to use a BorderLayout, since it seemed that made the most sense for the layout I was trying to make, but that did an even worse job when I set them to BorderLayout.WEST and BorderLayout.EAST.
Have modified your program to use BorderLayout in the MainPanel and few other minor changes to get the desired look and feel.Check if this helps.
public class BorderWrapper {
public static void main(String[] args) {
// Create frame
JFrame frame = new JFrame("Border Wrapper");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create main panel
MainPanel panel = new MainPanel();
frame.getContentPane().add(panel);
// Display frame
Dimension minSize = new Dimension(650, 375);
frame.setPreferredSize(minSize);
frame.setMinimumSize(minSize);
frame.pack();
frame.setVisible(true);
}
}
class MainPanel extends JPanel {
private static final Font INPUT_FONT = new Font("Monospaced", Font.PLAIN, 12);
private JTextArea inputArea, outputArea;
private JTextField titleField, topBorderField, sideBorderField;
public MainPanel() {
setLayout(new BorderLayout());
// Set up config panel
JPanel configPanel = new JPanel();
configPanel.setLayout(new BoxLayout(configPanel, BoxLayout.X_AXIS));
configPanel.setMaximumSize(new Dimension(400, 200));
titleField = new JTextField(25);
titleField.setFont(INPUT_FONT);
topBorderField = new JTextField(1);
topBorderField.setFont(INPUT_FONT);
sideBorderField = new JTextField(4);
sideBorderField.setFont(INPUT_FONT);
configPanel.add(new JLabel("Title:"));
configPanel.add(titleField);
configPanel.add(new JLabel("Top border:"));
configPanel.add(topBorderField);
configPanel.add(new JLabel("Side border:"));
configPanel.add(sideBorderField);
add(configPanel, BorderLayout.NORTH);
// Set up Input panel
JPanel lowerPanel = new JPanel(new GridLayout(1, 1));
JPanel inputPanel = new JPanel();
inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.Y_AXIS));
inputArea = new JTextArea("Type or paste your stuff here . . .");
inputArea.setFont(INPUT_FONT);
inputArea.setLineWrap(true);
inputArea.setWrapStyleWord(true);
inputArea.setColumns(75);
JScrollPane inputPane = new JScrollPane(inputArea);
JLabel inputLabel = new JLabel("Text Box");
inputLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
inputPanel.add(inputLabel);
inputPanel.add(inputPane);
lowerPanel.add(inputPanel);
// Set up Output panel
JPanel outputPanel = new JPanel();
outputPanel.setLayout(new BoxLayout(outputPanel, BoxLayout.Y_AXIS));
outputArea = new JTextArea();
outputArea.setFont(INPUT_FONT);
outputArea.setLineWrap(true);
outputArea.setWrapStyleWord(true);
outputArea.setColumns(75);
JScrollPane outputPane = new JScrollPane(outputArea);
JLabel outputLabel = new JLabel("Wrapped Output");
outputLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
outputPanel.add(outputLabel);
outputPanel.add(outputPane);
lowerPanel.add(outputPanel);
add(lowerPanel, BorderLayout.CENTER);
}
}
I felt it convenient to use BorderLayout for this format.Anyways, you can still make few changes to the code you posted using GridBagConstraints to get the desired look.Make the below changes one by one and you will observe the differences.
1.You were aligning the MainPanel to the NORTH by using BorderLayout.But in your case the entire set of components is placed in MainPanel,so better place it in center.So instead of NORTH use below :(after this change,you will see the complete input and output panels)
MainPanel panel = new MainPanel();
frame.getContentPane().add(panel, BorderLayout.CENTER);
2.You have set the dimension of the Parent frame to Dimension(height=375)
minSize = new Dimension(650, 375);
You components(configPanel=200,outputPanel=400) combined height is more than 375.Increase the height of the Parent, to about 600.
3.Instead of BoxLayout try using GridLayout for configPanel.
configPanel.setLayout(new GridLayout(1,6,5,0));
Making the above 3 changes to your existing code will get the expected output.Hope this clarifies.

Creating JTabbedPane in a JDialog and making the frame available

I'm working with GUI in Java and I've made several JDialogs opening one above the other.
I tried to create a JTabbedPane and I have succeed. However, I have to make the JTabbedPane in a JFrame. I've tried but the JPanel opens all blank.
Second of all when I use JFrame (so the new JTabbedPane became operational) that same frame appears behind the previous one.
So my questions are:
How can I create the tabbed pane in a JDialog ?
How do I make the JTabbedPane appear in front of all other frames, if I use JFrame ?
Here's my code, this JFrame opened when I click on a JButton from a previous JDialog
public class AddComponents extends JDialog {
private String[] arr = {"House", "Microgrid", "CSP", "VPP"};
public AddComponents(JDialog pai, String titulo)
{
super(pai, titulo);
frame = new JFrame(titulo);
// Display the window.
frame.setSize(500, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// set grid layout for the frame
frame.getContentPane().setLayout(new GridLayout(1, 1));
tabbedPane = new JTabbedPane(JTabbedPane.TOP);
pack();
for (int i = 0; i < arr.length; i++) {
String tmp = arr[i];
tabbedPane.addTab(tmp, makePanel(tmp));
}
frame.getContentPane().add(tabbedPane);
frame.setMinimumSize(new Dimension(getWidth(), getHeight()));
frame.setLocation(pai.getX() + 85, pai.getY() + 25);
frame.setEnabled(true);
}
private JPanel makePanel(String text) {
JPanel p = new JPanel();
//p.setLayout(new GridLayout(0,1));
JPanel p1 = new JPanel();
JPanel p2 = new JPanel();
if(text.equals("House"))
{ //CADA UM DOS ifs chama a class correspondente para criar o interface
p1.setLayout(new GridLayout(4, 2));
idLabel = new JLabel("Component ID:");
idText = new JTextField("");
p1.add(idLabel);
p1.add(idText);
maxUsageLabel = new JLabel("Max usage per hour:");
maxUsageText = new JTextField("");
p1.add(maxUsageLabel);
p1.add(maxUsageText);
minUsageLabel = new JLabel("Min usage per hour:");
minUsageText = new JTextField("");
p1.add(minUsageLabel);
p1.add(minUsageText);
averageUsageLabel = new JLabel("Average usage per hour:");
averageUsageText = new JTextField("");
p1.add(averageUsageLabel);
p1.add(averageUsageText);
// emptyLabel = new JLabel("");
saveButton = new JButton("Save");
// p.add(emptyLabel);
p2.add(saveButton);
p.add(p1);
p.add(p2);
}
if(text.equals("Microgrid"))
{
p.setLayout(new GridLayout(5, 2));
outroLabel = new JLabel(" Microgrid");
p.add(outroLabel);
}
if(text.equals("VPP"))
{
p.setLayout(new GridLayout(5, 2));
outroLabel = new JLabel(" VPP");
p.add(outroLabel);
}
if(text.equals("CSP"))
{
p.setLayout(new GridLayout(5, 2));
outroLabel = new JLabel(" CSP");
p.add(outroLabel);
}
return p;
}
}
"How can I create the tabbed pane in a JDialog ?"
same as you would if you added it to a JFrame. There is essentially no difference here whatsoever.
"How do I make the JTabbedPane appear in front of all other frames, if I use JFrame ?"
you don't. You use a JDialog if you want to display a window above other windows.
For creating the JDialog use:
final JDialog dialog = new JDialog();
dialog.add(tabbedPane);
dialog.setVisible(true);
Java applications normally have only one JFrame, so nobody worries about the Z-order. If you like them, you can use JInternalFrame. Here is the tutorial. You can, however, use dialogs instead.

How to activate ActionEvent inside JMenu to show new panel on the frame?(Basic)

I just started to learn swing by myself, I'm little bit confused why my event does not work here:
1.I'm trying to delete everything from my panel if the user click menu bar -> load but it force me to change the panel to final because i'm using it inside the event!
2.I have defined new panel in my event and defined two more container to add to that panel and then add it to the main frame but it seems nothing happening!
Please help me if you can find out what is wrong.
Sorry in advance for messy code.
I appreciate any hints.
public class SimpleBorder {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable()
{
public void run()
{
myFrame frame = new myFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
}
class MyFrame extends JFrame {
public MyFrame()
{
setSize(500,500);
JPanel panel = new JPanel();
panel.setLayout(null);
JLabel label = new JLabel("my name is bernard...");
Color myColor = new Color(10, 150, 80);
panel.setBackground(myColor);
label.setFont(new Font("Serif", Font.PLAIN, 25));
Dimension size = label.getPreferredSize();
Insets insets = label.getInsets();
label.setBounds(85+insets.left, 120+insets.top , size.width, size.height);
panel.add(label);
JMenuBar menu = new JMenuBar();
setJMenuBar(menu);
JMenu col = new JMenu("Collection");
menu.add(col);
JMenu help = new JMenu("Help");
menu.add(help);
Action loadAction = new AbstractAction("Load")//menu item exit goes here
{
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent event)
{
JTextArea text = new JTextArea(10, 40);
JScrollPane scrol1 = new JScrollPane(text);
String[] items = {"A", "B", "C", "D"};
JList list = new JList(items);
JScrollPane scrol2 = new JScrollPane(list);
JPanel panel2 = new JPanel(new BorderLayout());
panel2 = new JPanel(new GridLayout(1, 2 ));
panel2.add(scrol1,BorderLayout.WEST);
panel2.add(scrol2,BorderLayout.EAST);
add(panel2);
}
};
JMenuItem load = new JMenuItem(loadAction);
col.add(load);
add(panel);
}
}
Call revalidate()/repaint() on your JFrame instance after adding the new panel:
JPanel panel2 = new JPanel(new BorderLayout());
// panel2 = new JPanel(new GridLayout(1, 2 ));//why this it will overwrite the above layout
panel2.add(scrol1,BorderLayout.WEST);
panel2.add(scrol2,BorderLayout.EAST);
add(panel2);
revalidate();
repaint();
Also call pack() on you JFrame instance so all components are spaced by the layoutmanager. As said in a comment dont extend the JFrame class, create a variable of the frame and initiate all that you need on the frames instance, and dont set a layout to null, unless you love hard work :P
Alternatively as mentioned by mKorbel, a CardLayout may be more what you want, it will allow you to use a single JPanel and switch between others/new ones:
JPanel cards;
final static String BUTTONPANEL = "Card with JButtons";
final static String TEXTPANEL = "Card with JTextField";
//Where the components controlled by the CardLayout are initialized:
//Create the "cards".
JPanel card1 = new JPanel();
...
JPanel card2 = new JPanel();
...
//Create the panel that contains the "cards".
cards = new JPanel(new CardLayout());
cards.add(card1, BUTTONPANEL);
cards.add(card2, TEXTPANEL);
//add card panel to frame
frame.add(cards);
//swap cards
CardLayout cl = (CardLayout)(cards.getLayout());//get layout of cards from card panel
cl.show(cards, TEXTPANEL);//show another card

BorderLayout.CENTER "disappears"

I'm coding a prototype, but got problems with the GUI.
I want the JPanel pCustomer to be centered, but doing so it disappears completely. If I put it for example in the SOUTH, everything is fine.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Test extends JPanel implements ActionListener {
private JPanel pTop = new JPanel();
private JPanel pMenue = new JPanel();
private JPanel pContent = new JPanel();
private JPanel pCustomer = new JPanel();
private JPanel pEnq = new JPanel();
private JPanel pCustomerMenue = new JPanel();
private JTextField tf1 = new JTextField();
private JButton bCustomer = new JButton("Customer");
private JButton bEnq = new JButton("Product");
private JButton bCNew = new JButton("New Customer");
private JLabel lCustomer = new JLabel("Customer");
String[] customerString = {"--- SELECT -- ", "New Customer", "Edit Customer", "Delete Customer"};
private JComboBox cb1 = new JComboBox(customerString);
private JLabel lRes = new JLabel();
String[] productString = {"--- SELECT -- ", "Sell Product", "Enquire Product", "Complain Product"};
private JLabel lWelcome = new JLabel("Welcome to our System!");
private JLabel lNo = new JLabel("Customer Number: ");
private JLabel lEnq = new JLabel("Enquiry");
public Test() {
this.setLayout(new BorderLayout());
// pTop
this.add(pTop, BorderLayout.NORTH);
pTop.setLayout(new BorderLayout());
pTop.add(lNo, BorderLayout.WEST);
pTop.add(tf1, BorderLayout.CENTER);
// pMenue
this.add(pMenue, BorderLayout.WEST);
pMenue.setLayout(new GridLayout(5, 1));
pMenue.add(bCustomer);
pMenue.add(bEnq);
// pContent
this.add(pContent, BorderLayout.CENTER);
pContent.add(lWelcome);
pContent.setLayout(new BorderLayout());
pContent.setBackground(Color.GREEN);
// pCustomer
pContent.add(pCustomer, BorderLayout.CENTER); // EAST, SOUTH, WEST works, but I want it to be centered.
pCustomer.add(cb1);
pCustomer.add(lRes);
pCustomer.setVisible(false);
pCustomer.setBackground(Color.blue);
// pCustomerMenue
pContent.add(pCustomerMenue, BorderLayout.NORTH);
pCustomerMenue.add(bCNew);
pCustomerMenue.setVisible(false);
pCustomerMenue.setBackground(Color.red);
// pEnq
pContent.add(pEnq, BorderLayout.CENTER);
pEnq.add(lEnq);
pEnq.setVisible(false);
// ---
bCustomer.addActionListener(this);
bEnq.addActionListener(this);
}
#Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
lWelcome.setVisible(false);
if (source == bCustomer) {
init();
pCustomer.setVisible(true);
pCustomerMenue.setVisible(true);
bCustomer.setEnabled(false);
}
if (source == bEnq) {
init();
pEnq.setVisible(true);
bEnq.setEnabled(false);
}
}
public void init() {
pCustomer.setVisible(false);
pCustomerMenue.setVisible(false);
pEnq.setVisible(false);
bCustomer.setEnabled(true);
bEnq.setEnabled(true);
}
}
If I remove these 3 lines:
pContent.add(pEnq, BorderLayout.CENTER);
pEnq.add(lEnq);
pEnq.setVisible(false);
I can even put it in the Centre and it works.
Read up about border layout. Basically you have 5 positions (NORTH, EAST, SOUTH, WEST, CENTER) and whenever you put a component into one of those positions any component already in that position is replaced.
Thus pContent.add(pEnq, BorderLayout.CENTER); will replace pCustomer with pEnq.
If you want both panels in the center you either need to put an intermediate panel into the center and then add the other panels to that one or use another layout manager, e.g. MiGLayout.
With MiGLayout your pContent layout might look like this:
pContent.setLayout(new MiGLayout());
pContent.add(pCustomerMenue, "pushx, wrap"); //fill the available width, new line after this component
pContent.add(pCustomer, "pushx, wrap"); //fill the available width, new line after this component
pContent.add(pEnq, "pushx"); //fill the available width
You try to add two different Panels to the Center of the BorderLayout.
First you add
pContent.add(pCustomer, BorderLayout.CENTER); // EAST, SOUTH, WEST works, but I want it to be centered.
And a few Lines later you do:
pContent.add(pEnq, BorderLayout.CENTER);
So pEnq lays over pCustomer!

Categories

Resources