JFrame Layout with JPanels - java

I am having a problem trying to layout my JFrame. I'm trying to add the ToolBar top, then Info below that, then colour below that to the right, then Copies in the center, then Print button to left and then the Printer List to the bottom. If anyone could help me in the right direction would be great.
// Declare GUI Components here
// One JToolBar & JButton
private JPanel mainPanel;
private JPanel detailPanel;
private JPanel toolBarPanel;
private JToolBar jToolbar;
private JButton jbtAdmin, jbtHelp;
// A JPanel called infoPanel & JLabel
private JPanel infoPanel;
private JLabel jlblOne;
// A JPanel called colourPanel
private JPanel colourPanel;
private JRadioButton bwRadioButton, colourRadioButton;
private ButtonGroup btg;
// A JPanel called noCopiesPanel
private JPanel noCopiesPanel;
private JLabel jlbCopies;
private JTextField jtfCopies;
// A JPanel called printerPanel
private JPanel printerPanel;
private JComboBox printerBox;
private JButton jbtPrint;
// Constructor - SetLayout & Add Components here...
// Constructor takes in the selected student and assigns it to currentStudent
public StudentFrame(Student studentIn){
// Set up currentStudent
currentStudent=studentIn;
// Set up Toolbar & add jbtAdmin
toolBarPanel = new JPanel();
toolBarPanel.add(jToolbar = new JToolBar());
jToolbar.add(jbtAdmin = new JButton("Admin"));
jToolbar.add(jbtHelp = new JButton("Help"));
// Set up called infoPanel
infoPanel = new JPanel();
infoPanel.add(jlblOne = new JLabel(currentStudent.toString(), JLabel.CENTER));
// Set up colourPanel with radioButtons
colourPanel = new JPanel(new GridLayout(2,1));
colourPanel.add(bwRadioButton = new JRadioButton("Black & White", true));
colourPanel.add(colourRadioButton = new JRadioButton("Colour"));
btg = new ButtonGroup();
btg.add(bwRadioButton);
btg.add(colourRadioButton);
// Put a TitledBorder around it
colourPanel.setBorder(new TitledBorder("Colour"));
// Set up noCopiesPanel
noCopiesPanel = new JPanel(new GridLayout(1,2));
noCopiesPanel.add(jlbCopies = new JLabel("Copies"));
noCopiesPanel.add(jtfCopies = new JTextField(3));
noCopiesPanel.setBorder(new TitledBorder("Print"));
// Set up jbtPrint JButton
jbtPrint = new JButton("Print",new ImageIcon("Images/printerIcon.png"));
jbtPrint.setHorizontalTextPosition(JButton.CENTER);
jbtPrint.setVerticalTextPosition(JButton.TOP);
jbtPrint.setFont(new Font("Helvetica", Font.BOLD, 30));
jbtPrint.setBackground(Color.LIGHT_GRAY);
jbtPrint.setMnemonic('P');
// Set up printerPanel
printerPanel = new JPanel();
String[] printerList = {"Printer 24001", "Printer 24002", "Printer 24003", "Printer 24004"};
printerPanel.add(printerBox = new JComboBox(printerList));
printerPanel.setBorder(new TitledBorder("Printers"));
detailPanel = new JPanel(new GridLayout(2,1));
detailPanel.add(infoPanel, BorderLayout.NORTH);
detailPanel.add(colourPanel, BorderLayout.WEST);
detailPanel.add(noCopiesPanel, BorderLayout.CENTER);
detailPanel.add(jbtPrint, BorderLayout.EAST);
detailPanel.add(printerPanel, BorderLayout.SOUTH);
mainPanel = new JPanel();
mainPanel.add(toolBarPanel, BorderLayout.NORTH);
mainPanel.add(detailPanel, BorderLayout.SOUTH);
this.add(mainPanel);
//this.add(detailPanel);

detailPanel = new JPanel(new GridLayout(2,1));
detailPanel.add(infoPanel, BorderLayout.NORTH);
You have the layout as GridLayout but you are trying to set BorderLayout positions. If you want to set the positions, set the layout of detailPanel to BorderLayout
mainPanel = new JPanel();
mainPanel.add(toolBarPanel, BorderLayout.NORTH);
Same as above with this case. JPanel has a default FlowLayout. You need to set the layout to BorderLayout.
You should also be adding the detailPanel to the CENTER of the mainPanel.
Also a JToolBar should be added to a container with a BorderLayout
toolBarPanel = new JPanel();
toolBarPanel.add(jToolbar = new JToolBar());
Set the toolBarPanel to BorderLayout

Related

Java GUI Fill Empty spaces

I have the following Java GUI for my project. For some reason, the middle and right panels have been put below leaving empty spaces - marked in red. Is there a way to pull the panels up to fill the spaces.
These empty spaces does not look good. I have tried to check all code but cannot pinpoint where to correct.
Thanks in advance.
public static JPanel main= new JPanel(),
left= new JPanel(),middle= new JPanel(),right = new JPanel();
Container c = getContentPane();
c.setLayout(new FlowLayout()) ;
JPanel pane = new JPanel();
pane.setLayout(new BorderLayout());
pane.add(new JLabel("Enter word/SQL: "), "North");
pane.add(tf, "Center"); //enter keyword
JPanel second = new JPanel();
second.setLayout(new GridLayout(8, 1));
second.add(messageIDText);
//This is the start of adding panels
//create a left side panal and add the sub panels to it
JPanel left = new JPanel();
JPanel middle = new JPanel();
JPanel center = new JPanel();
JTextArea output = new JTextArea("", 60, 60);
JPanel sixth = new JPanel();
JPanel seventh = new JPanel();
JPanel eigth = new JPanel(new GridLayout(8,1));
JPanel labels7 = new JPanel(new GridLayout(5,1));
JPanel controls7 = new JPanel(new GridLayout(5,1));
JPanel tenth = new JPanel();
sixth.setLayout(new BorderLayout(5,5));
JPanel fourth = new JPanel();
fourth.add(firstButton);
sixth.add(labels, BorderLayout.WEST);
sixth.add(controls, BorderLayout.CENTER);
sixth.add(controlsButtons, BorderLayout.EAST);
labels.add(new JLabel("Proposal:"));
controls.add(proposalNumberText);
controlsButtons.add(freeQueryButton);
//add border
pane.setBorder(BorderFactory.createCompoundBorder(new
EmptyBorder(10,10,10,10), BorderFactory.createEtchedBorder()));
fourth.setBorder(BorderFactory.createCompoundBorder(new
EmptyBorder(10,10,10,10), BorderFactory.createEtchedBorder()));
//-------LEFT SIDE -- PARAMETERS
left.setLayout(new BoxLayout(left, BoxLayout.PAGE_AXIS));
JLabel headerLabel,blank;
headerLabel = new JLabel("Navigate Records", JLabel.LEFT);
Font f = headerLabel.getFont();
headerLabel.setFont(f.deriveFont(f.getStyle() ^ Font.BOLD)); // bold
left.add(headerLabel, BorderLayout.PAGE_END);
left.add(fourth, BorderLayout.PAGE_END);
main.add(left);
//---------MIDDLE PART - Messages - tabbed pane
JTabbedPane jtp = new JTabbedPane();
getContentPane().add(jtp);
//jtp.setSize(jtp.getPreferredSize());
JPanel jpA = new JPanel(),jpB = new JPanel(),
jpC = new JPanel(),jpD = new JPanel();
JScrollPane scrollPane2 = new JScrollPane(),jp = new
JScrollPane(activeTSText), jp2 = new JScrollPane(analyseWordsText),
jp3 = new JScrollPane(markedMessageText);
JLabel labelA = new JLabel();
labelA.setText("");
jpA.add(labelA);
jpA.add(jp);
jtp.addTab("Message", jpA);
middle.add(jtp);
main.add(middle);
//----------RIGHT PART - .. //paramters and results
JPanel jj = new JPanel();
jj.setLayout(new BoxLayout(jj, BoxLayout.PAGE_AXIS));
stateJTable.setRowHeight(20); //add JTable
JScrollPane js3 =new JScrollPane(stateJTable);
js3.setVisible(true);
//JTabbedPane jtp2 = new JTabbedPane();
//JPanel StateSubstatesTabOnLeft = new JPanel(),
StateSubstates_PostProcessedTabOnLeft = new JPanel();
JPanel firstleftTabinRightSideOfFrame = new JPanel(),
secondLeftTabinRightSideOfFrame = new
JPanel(),rightTabInRightSideOfFrame = new JPanel();
jj.add(js3);
//downbelow, the state jtable is added to the panel here through the
//scrollpane which contains the jtable
right.add(jj) ; //stateJTable);// add table in panel using add() method
main.add(right);
proposalNumberText.requestFocusInWindow();
I have solved the problem by using Borderlayout and assigning the main panel to it.
The assigning the WEST, CENTER and EAST regions to it.
I have added the code below in the code above at places where the main panel is being added to.
Thank you for the advice to start debugging by using MRE approach.
BorderLayout layout = new BorderLayout();
main.setLayout(layout);
main.add(left,BorderLayout.WEST);
main.add(middle,BorderLayout.CENTER);
main.add(right,BorderLayout.EAST);

How to make method return a panel?

I am making a Java application with tabbed pane, I want some panes to have the same panel layout and structure, I don't want to clutter my code by writing the same code over and over again, so I created a method that returns a JPanel with a structure I want the pane to have.
I am initialising new variables and taking them to the method . My problem is that after I create a panel I can not do anything else in it because it doesn't show up. I can not add labels etc, etc (although if I add the label in the method it does show).
My question is it possible to somehow change the code I've written to make it possible to change it after the panel is returned?
JPanel panel2 = panel2(); // this code bit is in the constructor
JPanel mainPanel = new JPanel(); //Variables needed to create a panel
JPanel LeftPanel = new JPanel();
JPanel RightPanel = new JPanel();
JSplitPane splitPaneH = new JSplitPane();
JPanel panelTop = new JPanel();
JPanel panelBottom = new JPanel();
private JPanel panel2() {
JPanel newPanel = new JPanel();
CreateAPanel(newPanel, LeftPanel,RightPanel,splitPaneH, panelTop,panelBottom);
JLabel label = new JLabel ("lalala");
LeftPanel.add(label,BorderLayout.CENTER);
return newPanel;
}
private JPanel CreateAPanel(JPanel mainPanel, JPanel LeftPanel,JPanel RightPanel, JSplitPane splitPaneH, JPanel panelTop, JPanel panelBottom){
mainPanel.setPreferredSize(new Dimension(1100, 630));
mainPanel.setLayout(new BorderLayout());
LeftPanel = new JPanel();
RightPanel = new JPanel();
splitPaneH = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
panelTop = new JPanel();
panelBottom = new JPanel();
splitPaneH.setTopComponent(panelTop);
splitPaneH.setBottomComponent(panelBottom);
splitPaneH.setDividerLocation(300);
splitPaneH.setPreferredSize(new Dimension(800,630));
mainPanel.add(LeftPanel, BorderLayout.WEST);
mainPanel.add(RightPanel,BorderLayout.EAST);
LeftPanel.setBackground(Color.RED);
LeftPanel.setPreferredSize(new Dimension (300,630));
RightPanel.add(splitPaneH);
return mainPanel;
}
you do not use your return value...
your method CreateAPanel(...) creates the desired panel but you just don't use it
you should adjust your method panel2() in like this:
private JPanel panel2()
{
//JPanel newPanel = new JPanel(); don't create a new panel!
//CreateAPanel(newPanel, LeftPanel,RightPanel,splitPaneH, panelTop,panelBottom);
//instead do this:
JPanel newPanel = CreateAPanel(newPanel, LeftPanel,RightPanel,splitPaneH, panelTop,panelBottom);
JLabel label = new JLabel ("lalala");
LeftPanel.add(label,BorderLayout.CENTER);
return newPanel;
}
It's totally possible to add components to the Panel object afterwards. The only mistake that you have made is that "inside the method body you create new JPanel instances to replace with original param references" so when the method returns there is no effect on the original objects. I suggest doing something different as this:
private JPanel[] CreateAPanel(JPanel mainPanel)
{
mainPanel.setPreferredSize(new Dimension(1100, 630));
mainPanel.setLayout(new BorderLayout());
JPanel leftPanel = new JPanel();
JPanel rightPanel = new JPanel();
JSplitPane splitPaneH = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
JPanel panelTop = new JPanel();
JPanel panelBottom = new JPanel();
splitPaneH.setTopComponent(panelTop);
splitPaneH.setBottomComponent(panelBottom);
splitPaneH.setDividerLocation(300);
splitPaneH.setPreferredSize(new Dimension(800,630));
mainPanel.add(leftPanel, BorderLayout.WEST);
mainPanel.add(rightPanel,BorderLayout.EAST);
leftPanel.setBackground(Color.RED);
leftPanel.setPreferredSize(new Dimension (300,630));
rightPanel.add(splitPaneH);
return new JPanel[]{mainPanel, leftPanel, rightPanel, panelTop, panelBottom};
}
If you want to change or add some more components inside result JPanel you get you can set names to all your components when you create them:
JPanel newPanel = new JPanel();
newPanel .setName("leftPanel");
resultPanel.add(newPanel, BorderLayout.WEST);
Then when you get resultPanel you can get it's components:
Component[] componentList = resultPanel.getContentPane().getComponents();
JPanel leftPanel = null;
for (Component component: componentList) {
if (Objects.equals(component.getName(), "leftPanel")) {
leftPanel = (JPanel) component;
}
}
if (leftPanel != null) {
// do something
}

Multiple JPanel inside another

look here
I have to make a format like this, like make a 1,2 panel, then put a 3,1 panel on the left side. Then, I put 4 text fields in the middle left panel and one button in the bottom left panel.
I'm not sure if I can just use GridLayout or if I have to use BorderLayout too.
How can I get this organized because when I set it up, I can't get the layout right. The textfields are not in the right position, they end up on the right side.
public class CreatePanel extends JPanel
{
private Vector projectList;
private JButton button1;
private ProjectSpendingPanel spendingPanel;
private JFrame frame1;
JPanel panel1;
JPanel leftPanel;
JPanel subPanel;
GridLayout layout1;
BorderLayout layout2;
GridLayout layout3;
JLabel message;
JLabel labelName;
JLabel labelNumber;
JLabel labelLocation;
JLabel labelFunding;
JTextField textField1;
JTextField textField2;
JTextField textField3;
JTextField textField4;
//Constructor initializes components and organize them using certain layouts
public CreatePanel(Vector projectList, ProjectSpendingPanel spendingPanel)
{
this.projectList = projectList;
this.spendingPanel = spendingPanel;
//organize components here
layout1 = new GridLayout(1,2);
layout2 = new BorderLayout(1,3);
layout3 = new GridLayout(4,2);
this.setLayout(layout1);
panel1 = new JPanel(layout1);
leftPanel = new JPanel(layout3);
subPanel = new JPanel(layout2);
add(panel1);
panel1.add(subPanel);
panel1.add(leftPanel);
labelName = new JLabel("Project Name");
leftPanel.add(labelName);
textField1 = new JTextField("", 15);
leftPanel.add(textField1,BorderLayout.SOUTH);
labelName = new JLabel("Project Number");
leftPanel.add(labelName);
textField2 = new JTextField("",15);
leftPanel.add(textField2);
labelLocation = new JLabel("Project Location");
leftPanel.add(labelLocation);
textField3 = new JTextField("",15);
leftPanel.add(textField3);
labelFunding = new JLabel("Initial Funding");
leftPanel.add(labelFunding);
textField4 = new JTextField("",15);
leftPanel.add(textField4);
add(leftPanel);
button1 = new JButton("Create a project");
subPanel.add(button1,BorderLayout.SOUTH);
}
To get the result you probably intended, you need to tweak your code just a little.
Your lines
panel1 = new JPanel(layout1);
leftPanel = new JPanel(layout3);
subPanel = new JPanel(layout2);
should be altered to read
panel1 = new JPanel(new GridLayout(2, 1));
leftPanel = new JPanel(layout3);
subPanel = new JPanel(layout2);
GridLayout takes rows first, then columns. Your layout1 defines one row and two columns but you use it for the text fields and the button, so I assume the two panels need to be above each other.
Second, you need to change the order from
add(panel1);
panel1.add(subPanel);
panel1.add(leftPanel);
to
add(panel1);
panel1.add(leftPanel);
panel1.add(subPanel);
Finally, I think you need to change
add(leftPanel);
button1 = new JButton("Create a project");
to
add(spendingPanel);
button1 = new JButton("Create a project");
Adding leftPanelagain seems to destroy the layout. If you do not want to see your spendingPanel here, you could use new JPanel() instead.
Here is a screenshot of the running program

Trying to get two buttons drawn on top of each other

I;m trying to have a top button and a buttom button. But only the buttom button gets drawn.
Here is the code
add(panel1,BorderLayout.NORTH);
add(panel2,BorderLayout.NORTH);
the complete function
private void initUI() {
/////////////////////////////////////////////////////////////////////////////
// set upui
setTitle("Simple example");
// Set size to match screen
mWidth=(int)Toolkit.getDefaultToolkit().getScreenSize().getWidth()-50;
mHeight=(int)Toolkit.getDefaultToolkit().getScreenSize().getHeight()-50;
setSize( mWidth, mHeight);
setLocationRelativeTo(null);
// Set close operation to exit
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel panel1 =new JPanel();
JButton btn = new JButton("Top Button"); // Button is a Component
btn.addActionListener(this);
panel1.add(btn);
JPanel panel2 =new JPanel();
JButton btn2 = new JButton("Buttom Button"); // Button is a Component
panel2.add(btn2);
add(panel1,BorderLayout.NORTH);
add(panel2,BorderLayout.NORTH);
// Add the chart
// NOTE class DrawCompoment is defifin below where the drawing ooeration is overidden
DrawComponent test = new DrawComponent();
add(test,BorderLayout.CENTER);
///////////////////////////////////////////////////////////////////////////////
// sert up vscreen
vStartX=(double)10;
vStartY=10;
vWidth=mWidth-40;
vHeight=mHeight-80;
dx=vWidth/t.daySize;
dy=vHeight/t.dayBiggest;
// save fdata in spreads sheet
createSpreadSheet();
}
You're adding panel1 and panel2 both to the same BorderLayout position, and only one can be added there. You need perhaps another JPanel to hold them both and then add that one to the BorderLayout.NORTH spot.
e.g.,
JPanel panel1 = new JPanel();
JButton btn = new JButton("Top Button"); // Button is a Component
btn.addActionListener(this);
panel1.add(btn);
JPanel panel2 = new JPanel();
JButton btn2 = new JButton("Buttom Button"); // Button is a Component
panel2.add(btn2);
// A JPanel to hold both panel1 and panel2
JPanel containerPanel = new JPanel(new GridLayout(2, 1));
containerPanel.add(panel1);
containerPanel.add(panel2);
// add only one component to the BorderLayout.NORTH position of the JFrame
add(containerPanel, BorderLayout.NORTH);

Not all components showing

When I run this program, the window blocks out the buttons in panel2 when I use setSize to determine window size.
In addition, if I use frame.pack() instead of setSize(), all components are on one horizontal line but I'm trying to get them so that panel1 components are on one line and panel2 components are on a line below them.
Could someone explain in detail the answers to both of these problems?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Exercise16_4 extends JFrame{
// FlowLayout components of top portion of calculator
private JLabel jlbNum1 = new JLabel("Number 1");
private JTextField jtfNum1 = new JTextField(4);
private JLabel jlNum2 = new JLabel("Number 2");
private JTextField jtfNum2 = new JTextField(4);
private JLabel jlbResult = new JLabel("Result");
private JTextField jtfResult = new JTextField(8);
// FlowLayout Components of bottom portion of calculator
private JButton jbtAdd = new JButton("Add");
private JButton jbtSubtract = new JButton("Subtract");
private JButton jbtMultiply = new JButton("Multiply");
private JButton jbtDivide = new JButton("Divide");
public Exercise16_4(){
JPanel panel1 = new JPanel();
panel1.setLayout(new FlowLayout(FlowLayout.CENTER, 3, 3));
panel1.add(jlbNum1);
panel1.add(jtfNum1);
panel1.add(jlNum2);
panel1.add(jtfNum2);
panel1.add(jlbResult);
panel1.add(jtfResult);
JPanel panel2 = new JPanel();
panel2.setLayout(new FlowLayout(FlowLayout.CENTER, 3, 10));
panel1.add(jbtAdd);
panel1.add(jbtSubtract);
panel1.add(jbtMultiply);
panel1.add(jbtDivide);
add(panel1, BorderLayout.NORTH);
add(panel2, BorderLayout.CENTER);
}
public static void main(String[] args){
Exercise16_4 frame = new Exercise16_4();
frame.setTitle("Caculator");
frame.setSize(400, 200);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//frame.setResizable(false);
frame.setVisible(true);
}
}
You're problem is likely a typographical error in that you're adding all components to panel1 and none to panel2:
// you create panel2 just fine
JPanel panel2 = new JPanel();
panel2.setLayout(new FlowLayout(FlowLayout.CENTER, 3, 10));
// but you don't use it! Change below to panel2.
panel1.add(jbtAdd);
panel1.add(jbtSubtract);
panel1.add(jbtMultiply);
panel1.add(jbtDivide);
Add the buttons to panel2, and then call pack() before setVisible(true). Do not set the size of the GUI.

Categories