There are two buttons
left = new JButton("prev");
right = new JButton("next");
I add them to jframe like this
mainframe.add(left,BorderLayout.WEST);
mainframe.add(right,BorderLayout.EAST);
But there have got height the same as mainframe's height. How to set my own width and height?
And how to set their position(not only in the NORTH,WEST,EAST,SOUTH)?.
How to set my own width and height
Don't do that, instead just constrain the size using the NORTH or SOUTH of a JPanel that itself is added to the EAST or WEST of the outer (parent) layout.
Much like this:
import java.awt.*;
import javax.swing.*;
class BorderGUI {
BorderGUI() {
JPanel gui = new JPanel(new BorderLayout(2,2));
JPanel westConstrain = new JPanel(new BorderLayout(2,2));
// LINE_START will be WEST for l-r languages, otherwise EAST
gui.add(westConstrain, BorderLayout.LINE_START);
JPanel westControls = new JPanel(new GridLayout(0,1,2,2));
for (int ii=1; ii<3; ii++) {
westControls.add( new JButton("" + ii) );
}
westConstrain.add(westControls, BorderLayout.PAGE_START);
JPanel eastConstrain = new JPanel(new BorderLayout(2,2));
gui.add(eastConstrain, BorderLayout.LINE_END);
JPanel eastControls = new JPanel(new GridLayout(0,1,2,2));
for (int ii=1; ii<4; ii++) {
eastControls.add( new JButton("" + ii) );
}
// show at the bottom
eastConstrain.add(eastControls, BorderLayout.PAGE_END);
gui.add( new JScrollPane(new JTextArea(6,10)), BorderLayout.CENTER );
JOptionPane.showMessageDialog(null, gui);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new BorderGUI();
}
});
}
}
Related
I have the GUI displaying properly for the most part, except for one thing. The TitledBorder("Numeric Type") does not display the entire title for the right JPanel. I believe it has something to do with the BorderLayout Manager. Instead of displaying "Numeric Type" within the border, just "Numeric..." displays. Any help will be greatly appreciated.
public class P3GUI extends JFrame {
private JLabel originalList;
private JTextField originalSort;
private JLabel sortedList;
private JTextField newSort;
private JPanel panel;
private JButton performSort;
private JRadioButton ascending;
private JRadioButton descending;
private ButtonGroup sort;
private JRadioButton integer;
private JRadioButton fraction;
private ButtonGroup numType;
private JPanel inputPanel, outputPanel, calculatePanel, radioPanel;
private JPanel left, right;
public P3GUI () {
super("Binary Search Tree Sort");
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
originalList = new JLabel("Original List");
originalSort = new JTextField(20);
inputPanel = new JPanel();
inputPanel.add(originalList);
inputPanel.add(originalSort);
sortedList = new JLabel("Sorted List");
newSort = new JTextField(20);
newSort.setEditable(false);
outputPanel = new JPanel();
outputPanel.add(sortedList);
outputPanel.add(newSort);
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(inputPanel);
panel.add(outputPanel);
add(panel, BorderLayout.NORTH);
performSort = new JButton("Perform Sort");
calculatePanel = new JPanel();
calculatePanel.add(performSort);
add(calculatePanel, BorderLayout.CENTER);
ascending = new JRadioButton("Ascending");
descending = new JRadioButton("Descending");
sort = new ButtonGroup();
sort.add(ascending);
sort.add(descending);
integer = new JRadioButton("Integer");
fraction = new JRadioButton("Fraction");
numType = new ButtonGroup();
numType.add(integer);
numType.add(fraction);
radioPanel = new JPanel();
radioPanel.setLayout(new FlowLayout());
left = new JPanel();
left.setLayout(new GridLayout(2,1));
left.setBorder(BorderFactory.createTitledBorder("Sort Order"));
left.add(ascending);
left.add(descending);
right = new JPanel();
right.setLayout(new GridLayout(2,1));
right.setBorder(BorderFactory.createTitledBorder("Numeric Type"));
right.add(integer);
right.add(fraction);
radioPanel.add(left);
radioPanel.add(right);
add(radioPanel, BorderLayout.SOUTH);
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new P3GUI().setVisible(true);
}
});
}
}
The problem is that the right JPanel is too small to display the entire title, and so it gets truncated. I'd suggest placing the bottom two JPanels into another that uses GridLayout, and then place them in such a way that they expand to fit the bottom of your GUI. When spread out, the title has a much greater chance of being fully displayed (but not a guarantee, mind you!).
For example, if you make the main GUI use a BorderLayout, and add this GridLayout using JPanel into the BorderLayout.CENTER position, it will fill it completely. Then the top components, the TextFields and JButton can be added to another JPanel, say one that uses a GridBagLayout, and add that to the main JPanel's BorderLayout.PAGE_START position.
For example, the following code produces this GUI:
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.KeyEvent;
import javax.swing.*;
#SuppressWarnings("serial")
public class P3GUI2 extends JPanel {
private static final int COLS = 20;
private JTextField originalSort = new JTextField(COLS);
private JTextField newSort = new JTextField(COLS);
private JButton performSort = new JButton("Perform Sort");
private JRadioButton ascending = new JRadioButton("Ascending");
private JRadioButton descending = new JRadioButton("Descending");
private ButtonGroup sort = new ButtonGroup();
private JRadioButton integer = new JRadioButton("Integer");
private JRadioButton fraction = new JRadioButton("Fraction");
private ButtonGroup numType = new ButtonGroup();
public P3GUI2() {
JPanel topPanel = new JPanel(new GridBagLayout());
topPanel.add(new JLabel("Original List:"), createGbc(0, 0));
topPanel.add(originalSort, createGbc(1, 0));
topPanel.add(new JLabel("Sorted List:"), createGbc(0, 1));
topPanel.add(newSort, createGbc(1, 1));
performSort.setMnemonic(KeyEvent.VK_P);
JPanel btnPanel = new JPanel();
btnPanel.add(performSort);
JPanel sortOrderPanel = createTitlePanel("Sort Order");
JPanel numericPanel = createTitlePanel("Numeric Type");
sortOrderPanel.add(ascending);
sortOrderPanel.add(descending);
sort.add(ascending);
sort.add(descending);
numericPanel.add(integer);
numericPanel.add(fraction);
numType.add(integer);
numType.add(fraction);
JPanel radioPanels = new JPanel(new GridLayout(1, 0, 3, 3));
radioPanels.add(sortOrderPanel);
radioPanels.add(numericPanel);
setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
setLayout(new BorderLayout(3, 3));
add(topPanel, BorderLayout.PAGE_START);
add(btnPanel, BorderLayout.CENTER);
add(radioPanels, BorderLayout.PAGE_END);
}
private JPanel createTitlePanel(String title) {
JPanel panel = new JPanel(new GridLayout(0, 1, 3, 3));
panel.setBorder(BorderFactory.createTitledBorder(title));
return panel;
}
private GridBagConstraints createGbc(int x, int y) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = x;
gbc.gridy = y;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.anchor = x == 0 ? GridBagConstraints.WEST : GridBagConstraints.EAST;
gbc.insets = new Insets(3, 3, 3, 3);
gbc.weightx = 1.0;
gbc.weighty = 1.0;
return gbc;
}
private static void createAndShowGui() {
P3GUI2 mainPanel = new P3GUI2();
JFrame frame = new JFrame("Binary Search Tree Sort");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
Or you could place the above btnPanel into the main one BorderLayout.CENTER and then place the radioPanels into the main one BorderLayout.PAGE_END. This will display a GUI of the same appearance but it will expand differently if re-sized.
The preferred size of the panel (as determined by the layout manager) does not consider the size of the text in the TitledBorder so the title can get truncated.
Here is a custom JPanel that can be used with a TitleBorder. The getPreferredSize() method has been customized to use the maximum width of:
the default getPreferredSize() calculation
the width of the text in the TitledBorder
Here is a simple example:
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class TitledBorderPanel extends JPanel
{
/**
** The preferred width on the panel must consider the width of the text
** used on the TitledBorder
*/
#Override
public Dimension getPreferredSize()
{
Dimension preferredSize = super.getPreferredSize();
Border border = getBorder();
int borderWidth = 0;
if (border instanceof TitledBorder)
{
Insets insets = getInsets();
TitledBorder titledBorder = (TitledBorder)border;
borderWidth = titledBorder.getMinimumSize(this).width + insets.left + insets.right;
}
int preferredWidth = Math.max(preferredSize.width, borderWidth);
return new Dimension(preferredWidth, preferredSize.height);
}
private static void createAndShowGUI()
{
JPanel panel = new TitledBorderPanel();
panel.setBorder( BorderFactory.createTitledBorder("File Options Command List:") );
panel.setLayout( new BoxLayout(panel, BoxLayout.Y_AXIS) );
panel.add( new JLabel("Open") );
panel.add( new JLabel("Close") );
// panel.add( new JLabel("A really wierd file option longer than border title") );
JFrame frame = new JFrame("TitledBorderPanel");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( panel );
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater( () -> createAndShowGUI() );
/*
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
*/
}
}
I'm trying to put components into panels having different sizes. But, I realized that GridLayout divides the parts with same sizes. How can it be accomplished as explained below image
enter image description here
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class PanelDemo {
PanelDemo() {
// Create a new JFrame container. Use the default
// border layout.
JFrame jfrm = new JFrame("Use Three JPanels with Different Sizes");
// Specify FlowLayout manager.
jfrm.getContentPane().setLayout(new GridLayout(1, 3));
// Give the frame an initial size.
jfrm.setSize(900, 300);
// Terminate the program when the user closes the application.
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Create the first JPanel.
JPanel jpnl = new JPanel();
jpnl.setLayout(new GridLayout(2, 4));
// Set the preferred size of the first panel.
jpnl.setPreferredSize(new Dimension(500, 300));
// Make the panel opaque.
jpnl.setOpaque(true);
// Add a blue border to the panel.
jpnl.setBorder(
BorderFactory.createLineBorder(Color.BLUE));
// Create the second JPanel.
JPanel jpnl2 = new JPanel();
//jpnl2.setLayout(new FlowLayout());
// Set the preferred size of the second panel.
jpnl2.setPreferredSize(new Dimension(300, 300));
// Make the panel opaque.
jpnl2.setOpaque(true);
jpnl2.setBorder(
BorderFactory.createLineBorder(Color.RED));
JPanel jpnl3 = new JPanel();
jpnl3.setOpaque(true);
jpnl3.setPreferredSize(new Dimension(100, 300));
jpnl3.setBorder(
BorderFactory.createLineBorder(Color.ORANGE));
// Add the panels to the frame.
jfrm.getContentPane().add(jpnl);
jfrm.getContentPane().add(jpnl3);
jfrm.getContentPane().add(jpnl2);
// Display the frame.
jfrm.setVisible(true);
}
public static void main(String args[]) {
// Create the frame on the event dispatching thread.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new PanelDemo();
}
});
}
}
import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class TwoPanelWithButtonsLayout {
private JComponent ui = null;
private Insets buttonMargin = new Insets(10,10,10,10);
TwoPanelWithButtonsLayout() {
initUI();
}
public void initUI() {
if (ui!=null) return;
ui = new JPanel(new BorderLayout(4,4));
ui.setBorder(new EmptyBorder(4,4,4,4));
int gap = 5;
JPanel buttons1 = new JPanel(new GridLayout(2, 4, gap, gap));
// 50 is the gap on right, alter as needed
buttons1.setBorder(new EmptyBorder(0, 0, 0, 50));
for (int ii=1; ii<9; ii++) {
buttons1.add(getBigButton("" + ii));
}
ui.add(buttons1, BorderLayout.CENTER);
JPanel buttons2 = new JPanel(new GridLayout(2, 2, gap, gap));
for (int ii=1; ii<5; ii++) {
buttons2.add(getBigButton("" + ii));
}
ui.add(buttons2, BorderLayout.LINE_END);
}
private JButton getBigButton(String text) {
JButton b = new JButton(text);
Font f = b.getFont();
b.setFont(f.deriveFont(f.getSize()*3f));
b.setMargin(buttonMargin);
return b;
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
TwoPanelWithButtonsLayout o = new TwoPanelWithButtonsLayout();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
}
You could use FlowLayout but if they resize your frame then it will wrap the panels.
I want to add multiple jpanels to jpanel.So i added a root panel to jscrollpane.and then added all individual jpanels to this root panel.I made jscrollpane's scrolling policy as needed.i.e HORIZONTAL_SCROLLBAR_AS_NEEDED,VERTICAL_SCROLLBAR_AS_NEEDED.
But the problem is all individual panels are not shown inside root panel.
Code:
JScrollPane scPanel=new JScrollPane();
JPanel rootPanel=new JPanel();
rootPanel.setLayout(new FlowLayout());
JPanel indPanel = new JPanel();
rootPanel.add(indPanel);
JPanel indPanel2 = new JPanel();
rootPanel.add(indPanel2);
//.....like this added indPanals to rootPanel.
scPanel.setViewPortView(rootPanel);
//scPanel.setHorizontalScrollPolicy(HORIZONTAL_SCROLLBAR_AS_NEEDED);
And one more thing is, as i scroll the scrollbar the panels are going out of jscrollpane area.
I am not able to see all individual panels,
Please suggest me.
Edit: code snippet from double post:
MosaicFilesStatusBean mosaicFilesStatusBean = new MosaicFilesStatusBean();
DefaultTableModel tableModel = null;
tableModel = mosaicFilesStatusBean.getFilesStatusBetweenDates(startDate, endDate);
if (tableModel != null) {
rootPanel.removeAll();
rootPanel.setLayout(new BoxLayout(rootPanel, BoxLayout.PAGE_AXIS));
for (int tempRow = 0; tempRow < tableModel.getRowCount(); tempRow++) {
int fileIdTemp = Integer.parseInt(tableModel.getValueAt(tempRow, 0).toString());
String dateFromTemp = tableModel.getValueAt(tempRow, 3).toString();
String dateToTemp = tableModel.getValueAt(tempRow, 4).toString();
int processIdTemp = Integer.parseInt(tableModel.getValueAt(tempRow, 5).toString());
int statusIdTemp = Integer.parseInt(tableModel.getValueAt(tempRow, 6).toString());
String operatingDateTemp = tableModel.getValueAt(tempRow, 7).toString();
MosaicPanel tempPanel =
new MosaicPanel(fileIdTemp, dateFromTemp, dateToTemp, processIdTemp, statusIdTemp, operatingDateTemp);
rootPanel.add(tempPanel);
}
rootPanel.revalidate();
}
The main reason, why you couldn't see your JPanel is that you are using FlowLayout as the LayoutManager for the rootPanel. And since your JPanel added to this rootPanel has nothing inside it, hence it will take it's size as 0, 0, for width and height respectively. Though using GridLayout such situation shouldn't come. Have a look at this code example attached :
import java.awt.*;
import javax.swing.*;
public class PanelAddition
{
private void createAndDisplayGUI()
{
JFrame frame = new JFrame("Panel Addition Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new GridLayout(0, 1));
JScrollPane scroller = new JScrollPane();
CustomPanel panel = new CustomPanel(1);
contentPane.add(panel);
scroller.setViewportView(contentPane);
frame.getContentPane().add(scroller, BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
for (int i = 2; i < 20; i++)
{
CustomPanel pane = new CustomPanel(i);
contentPane.add(pane);
contentPane.revalidate();
contentPane.repaint();
}
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new PanelAddition().createAndDisplayGUI();
}
});
}
}
class CustomPanel extends JPanel
{
public CustomPanel(int num)
{
JLabel label = new JLabel("" + num);
add(label);
}
#Override
public Dimension getPreferredSize()
{
return (new Dimension(200, 50));
}
}
Don't use FlowLayout for the rootPanel. Instead consider using BoxLayout:
JPanel rootPanel=new JPanel();
// if you want to stack JPanels vertically:
rootPanel.setLayout(new BoxLayout(rootPanel, BoxLayout.PAGE_AXIS));
Edit 1
Here's an SSCCE that's loosely based on your latest code posted:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.util.Random;
import javax.swing.*;
#SuppressWarnings("serial")
public class PanelsEg extends JPanel {
private static final int MAX_ROW_COUNT = 100;
private Random random = new Random();
private JPanel rootPanel = new JPanel();
public PanelsEg() {
rootPanel.setLayout(new BoxLayout(rootPanel, BoxLayout.PAGE_AXIS));
JScrollPane scrollPane = new JScrollPane(rootPanel);
scrollPane.setPreferredSize(new Dimension(400, 400)); // sorry kleopatra
add(scrollPane);
add(new JButton(new AbstractAction("Foo") {
#Override
public void actionPerformed(ActionEvent arg0) {
foo();
}
}));
}
public void foo() {
rootPanel.removeAll();
// rootPanel.setLayout(new BoxLayout(rootPanel, BoxLayout.PAGE_AXIS)); // only need to set layout once
int rowCount = random.nextInt(MAX_ROW_COUNT);
for (int tempRow = 0; tempRow < rowCount ; tempRow++) {
int fileIdTemp = tempRow;
String data = "Data " + (tempRow + 1);
MosaicPanel tempPanel =
new MosaicPanel(fileIdTemp, data);
rootPanel.add(tempPanel);
}
rootPanel.revalidate();
rootPanel.repaint(); // don't forget to repaint if removing
}
private class MosaicPanel extends JPanel {
public MosaicPanel(int fileIdTemp, String data) {
add(new JLabel(data));
}
}
private static void createAndShowGui() {
PanelsEg mainPanel = new PanelsEg();
JFrame frame = new JFrame("PanelsEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
This SSCCE works, in that it easily shows removing and adding JPanels to another JPanel that is held by a JScrollPane. If you're still having a problem, you should modify this SSCCE so that it shows your problem.
In my project, I use Swing controls. I had used a label together with a button group, but there is an unwanted line. Please help. There is a label associated with each radio button group. The unwanted line is there.how to add the labels and corresponding radio button group to the same panel
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
//import java.util.Arrays;
public class Online extends JFrame {
static JRadioButton[] choice = new JRadioButton[6];
JFrame jtfMainFrame, jtfMainFrame1;
public void createWindow() {
jtfMainFrame = new JFrame("Online Examination");
jtfMainFrame.setSize(800, 500);
jtfMainFrame.setLocation(200, 150);
jtfMainFrame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
JPanel pa = new JPanel();
JPanel panlabels = new JPanel(new GridLayout(0, 1, 0, 60));
JPanel pancontrols = new JPanel(new GridLayout(0, 1, 0, 60));
JPanel panEast = new JPanel();
JPanel pan = new JPanel(new FlowLayout());
JLabel qLabel = new JLabel("Question.");
qLabel.setOpaque(true);
qLabel.setForeground(Color.blue);
qLabel.setBackground(Color.lightGray);
JLabel aLabel = new JLabel("Question.");
aLabel.setOpaque(true);
aLabel.setForeground(Color.blue);
aLabel.setBackground(Color.lightGray);
JLabel bLabel = new JLabel("a.");
bLabel.setOpaque(true);
bLabel.setForeground(Color.blue);
bLabel.setBackground(Color.lightGray);
JLabel cLabel = new JLabel("b.");
cLabel.setOpaque(true);
cLabel.setForeground(Color.blue);
cLabel.setBackground(Color.lightGray);
JLabel dLabel = new JLabel("c.");
dLabel.setOpaque(true);
dLabel.setForeground(Color.blue);
dLabel.setBackground(Color.lightGray);
JLabel eLabel = new JLabel("d.");
eLabel.setOpaque(true);
eLabel.setForeground(Color.blue);
eLabel.setBackground(Color.lightGray);
panlabels.add(aLabel, BorderLayout.WEST);
panlabels.add(bLabel, BorderLayout.CENTER);
panlabels.add(cLabel, BorderLayout.CENTER);
panlabels.add(dLabel, BorderLayout.CENTER);
panlabels.add(eLabel, BorderLayout.CENTER);
//panlabels.add(fLabel, BorderLayout.WEST);
//fLabel.setVisible(false);
JLabel ques = new JLabel("q");
ques.setBackground(Color.red);
choice[1] = new JRadioButton("a");
choice[1].setBackground(Color.red);
choice[2] = new JRadioButton("b");
choice[2].setBackground(Color.red);
choice[3] = new JRadioButton("c");
choice[3].setBackground(Color.red);
choice[4] = new JRadioButton("d");
choice[4].setBackground(Color.red);
ButtonGroup bGroup = new ButtonGroup();
pancontrols.add(ques, BorderLayout.WEST);
for (int i = 1; i < 5; i++) {
// pancontrols.add(aLabel,BorderLayout.WEST);
bGroup.add(choice[i]);
pancontrols.add(choice[i], BorderLayout.WEST);
}
choice[4].setVisible(true);
panEast.add("West", panlabels);
panEast.add("West", pancontrols);
pa.add("Center", panEast);
pa.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(), "Select your answer"));
//getContentPane().add(label);
//to be deleted pa.add("South", pan);
pa.setBackground(Color.pink);
jtfMainFrame.add(pa);
jtfMainFrame.setExtendedState(Frame.MAXIMIZED_BOTH);
jtfMainFrame.setVisible(true);
}
public static void main(String[] args) {
Online r = new Online();
r.createWindow();
}
}
First, your naming convention for the choice labels is off. qLabel="questions", aLabel="questions", bLabel="a", cLabel="b", etc. I would suggest you fix that to eliminate confusion and make your code more readable (ie only have one label that is a question).
Second, your use of panEast.add("West",panlabels); and the other two statements is generally not suggested. Read up on BorderLayout to find the more accepted method of doing this:
http://docs.oracle.com/javase/tutorial/uiswing/layout/border.html
As for your problem, I have rewritten your code so things do line up, I will try to point out what I commented out to help:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
//import java.util.Arrays;
public class Online extends JFrame {
static JRadioButton[] choice = new JRadioButton[6];
JFrame jtfMainFrame, jtfMainFrame1;
public void createWindow() {
jtfMainFrame = new JFrame("Online Examination");
jtfMainFrame.setSize(800, 500);
jtfMainFrame.setLocation(200, 150);
jtfMainFrame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
JPanel pa = new JPanel();
//JPanel panlabels = new JPanel(new GridLayout(0, 1, 0, 60));
JPanel pancontrols = new JPanel(new GridLayout(0, 2, 0, 60));
JPanel panEast = new JPanel();
JPanel pan = new JPanel(new BorderLayout());
JLabel qLabel = new JLabel("Question.");
qLabel.setOpaque(true);
qLabel.setForeground(Color.blue);
qLabel.setBackground(Color.lightGray);
JLabel aLabel = new JLabel("Question.");
aLabel.setOpaque(true);
aLabel.setForeground(Color.blue);
aLabel.setBackground(Color.lightGray);
JLabel bLabel = new JLabel("a.");
bLabel.setOpaque(true);
bLabel.setForeground(Color.blue);
bLabel.setBackground(Color.lightGray);
JLabel cLabel = new JLabel("b.");
cLabel.setOpaque(true);
cLabel.setForeground(Color.blue);
cLabel.setBackground(Color.lightGray);
JLabel dLabel = new JLabel("c.");
dLabel.setOpaque(true);
dLabel.setForeground(Color.blue);
dLabel.setBackground(Color.lightGray);
JLabel eLabel = new JLabel("d.");
eLabel.setOpaque(true);
eLabel.setForeground(Color.blue);
eLabel.setBackground(Color.lightGray);
//panlabels.add(fLabel, BorderLayout.WEST);
//fLabel.setVisible(false);
JLabel ques = new JLabel("q");
ques.setBackground(Color.red);
choice[1] = new JRadioButton("a");
choice[1].setBackground(Color.red);
choice[2] = new JRadioButton("b");
choice[2].setBackground(Color.red);
choice[3] = new JRadioButton("c");
choice[3].setBackground(Color.red);
choice[4] = new JRadioButton("d");
choice[4].setBackground(Color.red);
ButtonGroup bGroup = new ButtonGroup();
//pancontrols.add(new JLabel(""));
pancontrols.add(ques, BorderLayout.WEST);
for (int i = 1; i < 5; i++) {
// pancontrols.add(aLabel,BorderLayout.WEST);
bGroup.add(choice[i]);
}
pancontrols.add(qLabel);
pancontrols.add(ques);
pancontrols.add(bLabel);
pancontrols.add(choice[1]);
pancontrols.add(cLabel);
pancontrols.add(choice[2]);
pancontrols.add(dLabel);
pancontrols.add(choice[3]);
pancontrols.add(eLabel);
pancontrols.add(choice[4]);
pancontrols.setSize(400,200);
choice[4].setVisible(true);
pa.add(pancontrols);
pa.setBorder(BorderFactory.createTitledBorder(
BorderFactory.createEtchedBorder(), "Select your answer"));
//getContentPane().add(label);
//to be deleted pa.add("South", pan);
pa.setBackground(Color.pink);
jtfMainFrame.add(pa);
jtfMainFrame.setExtendedState(Frame.MAXIMIZED_BOTH);
jtfMainFrame.setVisible(true);
}
public static void main(String[] args) {
Online r = new Online();
r.createWindow();
}
}
Basically, I removed your unnecessary panels. the only panel you add stuff to now is the pancontrols panel. I changed it to new JPanel(new Gridlayout(0,2,0,60)). With the two column GridLayout you will always have things line up bound wise, due to GridLayout making everything the same size.
Lastly I pulled the adding of choices[] from the loop and did that along with the labels to make sure things line up. I removed all the panels being added except the pancontrols being added to pa, which I assume you want to add more question panels to pa in that case. That covers your question in particular, but there is quite a lot of stuff you should do (ie use choice[0] for example, eliminate unused labels and panels, etc.)
Consider the following figure:
I need to develop a swing GUI the looks like this. I simply named them jLabel's but there a few images and jLabels in it. The default awt background visible is a JPanel and each red background visible is a serperate JPanel. Now I need them to get stacked as shown above. I tried a number of LayoutManagers and still it doesn't work.
The important point here is that the number of red colored divs are not constant. If there is only one red colored div then it must be displayed at the top, not at the center. As far as i know GridBagLayout should work, but it centers the single red colored jpanel available. All the layout managers are centering them but not stacking them from top to bottom.
Even with anchor set to NORTH then the panels will still be centered. You could work around it by adding a dummy panel to fill the remaining space. Personally I'd stay well away from GridBagLayout though.
JFrame frame = new JFrame();
JPanel content = new JPanel();
content.setBorder(BorderFactory.createLineBorder(Color.red));
frame.setContentPane(content);
frame.getContentPane().setLayout(new GridBagLayout());
frame.setSize(400, 300);
for (int i = 0; i < 3; i++) {
JPanel panel = new JPanel();
panel.add(new JLabel("label1"));
panel.add(new JLabel("label2"));
panel.add(new JLabel("label3"));
panel.setBorder(BorderFactory.createLineBorder(Color.red));
GridBagConstraints con = new GridBagConstraints();
con.gridy = i;
con.gridx = 0;
con.anchor = GridBagConstraints.NORTHWEST;
con.ipady = 10;
frame.getContentPane().add(panel, con);
}
// dummy panel to use up the space (force others to top)
frame.getContentPane().add(
new JPanel(),
new GridBagConstraints(0, 3, 1, 1, 1, 1,
GridBagConstraints.NORTHWEST,
GridBagConstraints.VERTICAL, new Insets(0, 0, 0, 0), 0,
0));
frame.setVisible(true);
GroupLayout example (my favourite layout manager).
JFrame frame = new JFrame();
JPanel content = new JPanel();
frame.setContentPane(content);
frame.getContentPane().setLayout(
new BoxLayout(content, BoxLayout.Y_AXIS));
frame.setSize(400, 300);
GroupLayout gLayout = new GroupLayout(content);
content.setLayout(gLayout);
ParallelGroup hGroup = gLayout.createParallelGroup();
gLayout.setHorizontalGroup(hGroup);
SequentialGroup vGroup = gLayout.createSequentialGroup();
gLayout.setVerticalGroup(vGroup);
for (int i = 0; i < 3; i++) {
JPanel panel = new JPanel();
panel.add(new JLabel("label1"));
panel.add(new JLabel("label2"));
panel.add(new JLabel("label3"));
panel.setBorder(BorderFactory.createLineBorder(Color.red));
hGroup.addComponent(panel);
vGroup.addComponent(panel, GroupLayout.PREFERRED_SIZE,
GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE);
vGroup.addGap(10);
}
frame.setVisible(true);
you can use Vertical BoxLayout, for example:
http://www.java-tips.org/java-se-tips/javax.swing/how-to-use-swing-boxlayout.html
nobody tell us that all JComponents must be visible, for example
from code
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.LineBorder;
public class AddComponentsAtRuntime {
private JFrame f;
private JPanel panel;
private JCheckBox checkValidate, checkReValidate, checkRepaint, checkPack;
public AddComponentsAtRuntime() {
f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel(new GridLayout(0, 1));
f.add(panel, "Center");
f.add(getCheckBoxPanel(), "South");
f.setLocation(200, 200);
f.pack();
f.setVisible(true);
}
private JPanel getCheckBoxPanel() {
checkValidate = new JCheckBox("validate");
checkValidate.setSelected(false);
checkReValidate = new JCheckBox("revalidate");
checkReValidate.setSelected(false);
checkRepaint = new JCheckBox("repaint");
checkRepaint.setSelected(false);
checkPack = new JCheckBox("pack");
checkPack.setSelected(false);
JButton addComp = new JButton("Add New One");
addComp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JPanel b = new JPanel(new GridLayout(0, 4));
b.setBackground(Color.red);
b.setBorder(new LineBorder(Color.black, 2));
//b.setPreferredSize(new Dimension(600, 20));
for (int i = 0; i < 4; i++) {
JLabel l = new JLabel("label" + i + 1);
b.add(l);
if (i == 2) {
l.setVisible(false);
}
}
panel.add(b);
makeChange();
System.out.println(" Components Count after Adds :" + panel.getComponentCount());
}
});
JButton removeComp = new JButton("Remove One");
removeComp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int count = panel.getComponentCount();
if (count > 0) {
panel.remove(0);
}
makeChange();
System.out.println(" Components Count after Removes :" + panel.getComponentCount());
}
});
JPanel panel2 = new JPanel();
panel2.add(checkValidate);
panel2.add(checkReValidate);
panel2.add(checkRepaint);
panel2.add(checkPack);
checkPack.setSelected(true);
panel2.add(addComp);
panel2.add(removeComp);
return panel2;
}
private void makeChange() {
if (checkValidate.isSelected()) {
panel.validate();
}
if (checkReValidate.isSelected()) {
panel.revalidate();
}
if (checkRepaint.isSelected()) {
panel.repaint();
}
if (checkPack.isSelected()) {
f.pack();
}
}
public static void main(String[] args) {
AddComponentsAtRuntime makingChanges = new AddComponentsAtRuntime();
}
}
You should try the MigLayout it is simple yet powerful. Below I tell miglayout to grow elements, and fill all possible space, then after each element I tell it to go to a new line (wrap). You can find examples and tutorial on MigLayout page http://www.miglayout.com/:
import net.miginfocom.swing.MigLayout;
public class PanelLearning extends JPanel {
public PanelLearning() {
setLayout(new MigLayout("", "[grow, fill]", ""));
for (int i = 0; i < 3; i++) {
JPanel panel = new JPanel();
panel.add(new JLabel("label1"));
panel.add(new JLabel("label2"));
panel.add(new JLabel("label3"));
panel.setBorder(BorderFactory.createLineBorder(Color.red));
add(panel, "span, wrap");
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("Login");
frame.setVisible(true);
frame.setContentPane(new PanelLearning());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.pack();
}
}
Make sure GridBagConstraints.anchor = GridBagConstraints.NORTH when you add components to the panel.