Please have a look at the following code
WizardPanel
package wizardGUI;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class WizardPanel extends JDialog
{
private JPanel cardPanel, buttonPanel;
private JButton next,previous;
private CardLayout c1;
private FileSelector fileSelector;
private DelemeterSelector delemeterSelector;
private int count = 1;
public WizardPanel()
{
//Intializing instance variables
fileSelector = FileSelector.getInstance();
delemeterSelector = DelemeterSelector.getInstance();
cardPanel = new JPanel();
c1 = new CardLayout();
cardPanel.setLayout(c1);
cardPanel.add(fileSelector,"1");
cardPanel.add(delemeterSelector,"2");
c1.show(cardPanel, "1");;
buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
next = new JButton("Next");
next.addActionListener(new NextButtonAction());
previous = new JButton("Previous");
buttonPanel.add(next);
buttonPanel.add(previous);
//Creating the GUI
this.setLayout(new BorderLayout());
this.add(cardPanel,"Center");
this.add(buttonPanel,"South");
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
this.setResizable(true);
this.pack();
this.setVisible(true);
}
private class NextButtonAction implements ActionListener
{
public void actionPerformed(ActionEvent ae)
{
c1.show(cardPanel, "2");
}
}
}
FileSelector
package wizardGUI;
/*This is the first panel is wazard GUI. Using this window user can select the correct file
which contains the data required to create the table
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FileSelector extends JPanel
{
private JLabel fileName, description;
private JTextField fileTxt;
private JButton browse;
private GridBagLayout gbl;
private GridBagConstraints gbc;
private static FileSelector instance = null;
private FileSelector()
{
//Intializing instance variables
fileName = new JLabel("File Name: ");
description = new JLabel("Specify the source of the data");
fileTxt = new JTextField(10);
browse = new JButton("Browse");
gbl = new GridBagLayout();
gbc = new GridBagConstraints();
//Creating GUI
this.setLayout(gbl);
gbc.gridx = 1;
gbc.gridy = 1;
gbc.weightx = 0.0;
gbc.weighty = 0.0;
gbc.fill = GridBagConstraints.BOTH;
this.add(description,gbc);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.weightx = 1.0;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(0,10,0,0);
this.add(locationPanel(),gbc);
this.setBorder(BorderFactory.createEmptyBorder());
}
private JPanel locationPanel()
{
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.add(fileName);
panel.add(fileTxt);
panel.add(browse);
return panel;
}
public static FileSelector getInstance()
{
if(instance==null)
{
instance = new FileSelector();
}
return instance;
}
}
DelemeterSelector
/*This is the second windows in wizard
This class is designed to let the user to select the delemeter to break information */
package wizardGUI;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class DelemeterSelector extends JPanel
{
private JLabel description;
private JRadioButton tabBtn, semicolanBtn, commaBtn, spaceBtn;
private JTextArea txtArea;
private JScrollPane scroll;
private ButtonGroup btnGroup;
private GridBagLayout gbl;
private GridBagConstraints gbc;
private static DelemeterSelector instance = null;
private DelemeterSelector()
{
//Initializing instance variables
description = new JLabel("What delemeter separates your fields? Select the appropreiate delemeter");
tabBtn = new JRadioButton("Tab");
semicolanBtn = new JRadioButton("Semicolan");
commaBtn = new JRadioButton("Comma");
spaceBtn = new JRadioButton("Space");
btnGroup = new ButtonGroup();
btnGroup.add(tabBtn);
btnGroup.add(semicolanBtn);
btnGroup.add(commaBtn);
btnGroup.add(spaceBtn);
txtArea = new JTextArea(20,70);
scroll = new JScrollPane(txtArea);
gbl = new GridBagLayout();
gbc = new GridBagConstraints();
this.setLayout(gbl);
//Creating the GUI
gbc.gridx = 1;
gbc.gridy = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(20,0,0,0);
this.add(description,gbc);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = new Insets(20,0,0,0);
this.add(radioPanel(),gbc);
gbc.gridx = 1;
gbc.gridy = 3;
gbc.insets = new Insets(10,0,0,0);
gbc.fill = GridBagConstraints.BOTH;
this.add(scroll,gbc);
}
private JPanel radioPanel()
{
JPanel panel = new JPanel();
panel.setLayout(new FlowLayout());
panel.add(tabBtn);
panel.add(semicolanBtn);
panel.add(commaBtn);
panel.add(spaceBtn);
panel.setBorder(BorderFactory.createTitledBorder("Choose the Delimeter that seperates your fields"));
return panel;
}
public static DelemeterSelector getInstance()
{
if(instance == null)
{
instance = new DelemeterSelector();
}
return instance;
}
}
When I run the code, the "FileSelector" looks really ugly. I want everything to be appear at the top of the pane, but instead, everything appears in middle!! I have even tried GridBagLayout options to make it resizable, it also failed. The look of it is in the attached image
How can I make it look nice and scalable? Please help
Just a quick example which shows the same behavior and a fix, without the need for all that external code (an SSCCE)
import javax.swing.*;
import java.awt.*;
public class CardLayoutDemo {
public static void main( String[] args ) {
EventQueue.invokeLater( new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame( "TestFrame" );
CardLayout cardLayout = new CardLayout();
JPanel contentPane = new JPanel( cardLayout );
JPanel firstPanel = new JPanel( );
firstPanel.setLayout( new BorderLayout( ) );
firstPanel.add( new JLabel( "Contents" ) );
//wrap the smallest panel instead of directly adding it
contentPane.add( firstPanel, "first" );
// JPanel wrappedPanel = new JPanel( new BorderLayout( ) );
// wrappedPanel.add( firstPanel, BorderLayout.NORTH );
// contentPane.add( wrappedPanel, "first" );
JPanel secondPanel = new JPanel( new BorderLayout( ) );
secondPanel.add( new JComponent() {
#Override
public Dimension getPreferredSize() {
return new Dimension( 500, 500 );
}
}, BorderLayout.CENTER );
contentPane.add( secondPanel, "second" );
cardLayout.show( contentPane, "first" );
frame.setContentPane( contentPane );
frame.pack();
frame.setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE );
frame.setVisible( true );
}
} );
}
}
When you run the code without making changes, it will show you a panel where the contents is centered (the firstPanel). Without making any changes to the firstPanel, but simply by wrapping it you can keep it at the top. Just replace the contentPane.add( firstPanel, "first" ) by the 3 lines (in comment) underneath.
There are a lot of times where nesting layouts makes it easier to get the desired result, and imo this is one of them.
The fill constraints are not necessary in this case. Also, gridx and gridy start from 0. This sample code
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.insets = new Insets(10,0,0,0);
this.add(description,gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.weighty = 1;
gbc.insets = new Insets(0,10,0,0);
this.add(locationPanel(),gbc);
produces this
Not sure if this is what you want though.
Related
I have created a class SliderPanel that allows a user to use a JSlider to rotate a picture and return an int representing the selected value on the slider. This object inherits from JPanel, so when I add two or more SliderPanels to the main JPanel (creationPanel), it appears that the pictures disappear from the GUI. Is there a work around for this, I have tried changing to an absolute layout, nesting panels, and resizing.
Here is the code for the SliderPanel:
public class SliderPanel extends JPanel
{
private JSlider slider;
private JLabel[] labelsArray;
private static final GridBagConstraints gbc = new GridBagConstraints();
private int selectedValue = 5;
private boolean isImgVisible;
/**
* Constructor which creates the JPanel and manages the changing of the
* JSlider.
*
* #param headerTitle The title of the Panel.
* #param window The Window object to retrieve the images from.
*/
public SliderPanel(String headerTitle, Window window)
{
setSize(new Dimension(300, 300));
labelsArray = window.getImages();
setLayout(new GridBagLayout());
// Create a header for the label slider and add it to the panel.
JLabel headerLabel = new JLabel("<HTML><U>" + headerTitle +
"</U></HTML>");
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.CENTER;
add(headerLabel, gbc);
Hashtable labels = new Hashtable();
for (int i = 0; i < 12; i++)
labels.put(i, new JLabel(String.valueOf(i)));
JPanel sliderAndImgPanel = new JPanel(new GridBagLayout());
JPanel imgPanel = new JPanel();
sliderAndImgPanel.setSize(new Dimension(200, 200));
slider = new JSlider(0, 10, 5);
slider.setLabelTable(labels);
slider.setPaintLabels(true);
slider.setPaintTicks(true);
slider.addChangeListener((ChangeEvent e) -> {
selectedValue = ((JSlider) e.getSource()).getValue();
System.out.println(selectedValue);
if (isImgVisible)
{
System.out.println("in");
sliderAndImgPanel.remove(imgPanel);
imgPanel.removeAll();
}
validate();
repaint();
JLabel pic = labelsArray[selectedValue];
pic.setPreferredSize(new Dimension(150, 150));
imgPanel.add(pic);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.CENTER;
sliderAndImgPanel.add(imgPanel, gbc);
isImgVisible = true;
validate();
window.validate();
});
JLabel pic = labelsArray[5];
pic.setPreferredSize(new Dimension(150, 150));
imgPanel.add(pic);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.CENTER;
sliderAndImgPanel.add(imgPanel, gbc);
sliderAndImgPanel.validate();
gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.CENTER;
sliderAndImgPanel.add(slider, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.anchor = GridBagConstraints.CENTER;
add(sliderAndImgPanel, gbc);
}
/**
* This method returns the value selected on the JSlider.
*
* #return The selected value. [0, 10]
*/
public int getSelectedValue()
{
return selectedValue;
}
}
And here is the Window class where the panels get added to the JFrame:
import java.awt.GridLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Window extends JFrame
{
private static JLabel[] imagesArray;
public static void main(String[] args)
{
new Window();
}
public Window()
{
super("Testing");
setLayout(new GridLayout(2,1,5,5));
setSize(1000, 700);
setVisible(true);
imagesArray = loadImages();
add(new SliderPanel("test 1", this));
add(new SliderPanel("test 2", this));
}
// Accessor method.
public static JLabel[] getImages()
{
return imagesArray;
}
// Loads images from project directory.
private static JLabel[] loadImages()
{
JLabel[] array = new JLabel[11];
// Load each image into the array.
for (int i = 0; i < 11; i++)
{
try
{
BufferedImage newImg = ImageIO.read(new File(i + ".png"));
array[i] = new JLabel(new ImageIcon(newImg));
} catch (IOException ex)
{
System.out.println("Exception: " + i);
}
}
return array;
}
}
Thanks in advance!
PS: Here are the links to the images I uploaded:
https://i.imgur.com/BvIehj5.png,
https://i.imgur.com/f527RdK.png,
https://i.imgur.com/98mgTHr.png,
https://i.imgur.com/Jsqm08U.png,
https://i.imgur.com/0pHTDgE.png,
https://i.imgur.com/TvtEiFm.png,
https://i.imgur.com/VeEDFfn.png,
https://i.imgur.com/3rp59Oz.png,
https://i.imgur.com/AjVf9pU.png,
https://i.imgur.com/sqEO7GL.png,
https://i.imgur.com/dXlush6.png
private static JLabel[] imagesArray;
You are creating a static array for a JLabel component.
Later it looks to me like you attempt to add a JLabel from the array to your panel:
JLabel pic = labelsArray[selectedValue];
pic.setPreferredSize(new Dimension(150, 150));
imgPanel.add(pic);
The problem is a Swing component can only have a single parent.
So by adding the JLabel to the second panel you remove it from the first panel.
Don't keep a static array of JLabels.
Instead keep a static array of ImageIcon. An Icon CAN be shared by multiple components.
Then when you want to add the label to the panel you create a new JLabel using the ImageIcon.
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:
Can someone please tell me what's wrong with this code?
I need it to pop up a frame and fill the frame with certain field a namer field and an intake field and also display a button at the bottom of the grid.
Any help would be welcomed, Thanks!!
import java.awt.*;
import javax.swing.*;
public class FrameDemo
//To create the gui and show it.
{
public static void createAndShowGUI()
{
//create and set up the window.
JFrame frame = new JFrame("RungeKutta");
GridLayout first = new GridLayout(1,14);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create, name and Populate TextField
JTextField PL = new JTextField("Pendulum Length", 20);
//Set TextField to Uneditable. Each will have Empty Field Below For Variables
PL.setEditable(false);
//Set Textfield for user entered dat
JTextField PLv = new JTextField();
//Allow handler for user input on Empty Textfield?
JTextField AD = new JTextField("Angular Displacement", 20);
AD.setEditable(false);
JTextField ADv = new JTextField();
JTextField AV = new JTextField("Angular Velocity", 20);
AV.setEditable(false);
JTextField Avv = new JTextField();
JTextField TS= new JTextField("Time Steps", 20);
TS.setEditable(false);
JTextField TSv = new JTextField();
JTextField MT = new JTextField("Max Time", 20);
MT.setEditable(false);
JTextField MTv = new JTextField();
JTextField V = new JTextField("Viscosity (0-1)", 20);
V.setEditable(false);
JTextField Vv = new JTextField();
//Create Button to Restart
JButton BNewGraph = new JButton("Draw New Graph"); //Button to restart entire drawing process
JLabel emptyLabel = new JLabel("");
emptyLabel.setPreferredSize(new Dimension(600,500));
frame.getContentPane().add(PL, first);
frame.getContentPane().add(PLv, first);
frame.getContentPane().add(AD, first);
frame.getContentPane().add(ADv, first);
frame.getContentPane().add(AV, first);
frame.getContentPane().add(Avv, first);
frame.getContentPane().add(TS, first);
frame.getContentPane().add(TSv, first);
frame.getContentPane().add(MT, first);
frame.getContentPane().add(MTv, first);
frame.getContentPane().add(V, first);
frame.getContentPane().add(Vv, first);
frame.getContentPane().add(BNewGraph, first);
//display the window
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args)
{
//add job to event scheduler
//create and show GUI
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
This is not how you use GridLayout:
frame.getContentPane().add(PL, first);
Instead you'd set the container's layout using the layout manager:
frame.getContentPane().setLayout(first);
and then add components to the container:
frame.getContentPane().add(PL);
frame.getContentPane().add(PLv);
frame.getContentPane().add(AD);
frame.getContentPane().add(ADv);
frame.getContentPane().add(AV);
frame.getContentPane().add(Avv);
frame.getContentPane().add(TS);
frame.getContentPane().add(TSv);
frame.getContentPane().add(MT);
frame.getContentPane().add(MTv);
// and so on for all the components.
You will want to read the tutorial on how to use GridLayout which you can find here: GridLayout Tutorial.
As an aside, note that this:
frame.getContentPane().add(PL);
can be shortened to this:
frame.add(PL);
Also you will want to study and learn Java naming conventions: class names begin with an upper case letter and all method and variables with lower case letters. Also avoid variable names like pl or plv, or ad or adv, and instead use names that are a little bit longer and have meaning, names that make your code self-commenting. So instead of AD, consider angularDisplacementField for the JTextfield's name.
Myself, I'd use a GridBagLayout and do something like:
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.swing.*;
public class GuiDemo extends JPanel {
// or better -- use an enum for this
public static final String[] FIELD_LABELS = {
"Pendulum Length", "Angular Displacement", "Angular Velocity",
"Time Steps", "Max Time", "Viscocity (0-1)"
};
private static final int TEXT_FIELD_COLUMNS = 10;
private static final int GAP = 3;
private static final Insets RIGHT_GAP_INSETS = new Insets(GAP, GAP, GAP, 3 * GAP);
private static final Insets BALANCED_INSETS = new Insets(GAP, GAP, GAP, GAP);
private Map<String, JTextField> labelFieldMap = new HashMap<>();
public GuiDemo() {
JPanel labelFieldPanel = new JPanel(new GridBagLayout());
int row = 0;
// to make sure that no focusAccelerator is re-used
Set<Character> focusAccelSet = new HashSet<>();
for (String fieldLabelLText : FIELD_LABELS) {
JLabel fieldLabel = new JLabel(fieldLabelLText);
JTextField textField = new JTextField(TEXT_FIELD_COLUMNS);
labelFieldPanel.add(fieldLabel, getGbc(row, 0));
labelFieldPanel.add(textField, getGbc(row, 1));
labelFieldMap.put(fieldLabelLText, textField);
for (char c : fieldLabelLText.toCharArray()) {
if (!focusAccelSet.contains(c)) {
textField.setFocusAccelerator(c);
fieldLabel.setDisplayedMnemonic(c);
focusAccelSet.add(c);
break;
}
}
row++;
}
JButton button = new JButton(new DrawGraphAction("Draw New Graph"));
labelFieldPanel.add(button, getGbc(row, 0, 2, 1));
setLayout(new BorderLayout(GAP, GAP));
add(labelFieldPanel, BorderLayout.CENTER);
}
private class DrawGraphAction extends AbstractAction {
public DrawGraphAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO calculation method
}
}
public static GridBagConstraints getGbc(int row, int column) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = column;
gbc.gridy = row;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
if (column == 0) {
gbc.anchor = GridBagConstraints.LINE_START;
gbc.fill = GridBagConstraints.BOTH;
gbc.insets = RIGHT_GAP_INSETS;
} else {
gbc.anchor = GridBagConstraints.LINE_END;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = BALANCED_INSETS;
}
return gbc;
}
public static GridBagConstraints getGbc(int row, int column, int width, int height) {
GridBagConstraints gbc = getGbc(row, column);
gbc.gridwidth = width;
gbc.gridheight = height;
gbc.insets = BALANCED_INSETS;
gbc.fill = GridBagConstraints.BOTH;
return gbc;
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Gui Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new GuiDemo());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
So I'm trying to create a series of radio buttons and check boxes that are displayed as follows:
Radio Button
Check Box
Radio Button
Check Box
Radio Button
However, I'm still in the learning process for java and I was wondering if anyone could solve this problem. At the moment the buttons and boxes are being displayed in the correct location, however the first radio button ("Courier") is not being displayed for some reason. If you could perhaps describe the reason and a possible solution that'd be great.
Thanks
Updated Code:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
public class Question2 {
public static void main(String[] args) {
MyFrame f = new MyFrame("Font Chooser");
f.init();
}
}
class MyFrame extends JFrame {
MyFrame(String title) {
super(title);
}
private JPanel mainPanel;
private GridBagConstraints gbc = new GridBagConstraints();
private GridBagLayout gbLayout = new GridBagLayout();
void init() {
mainPanel = new JPanel();
mainPanel.setLayout(gbLayout);
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20));
this.setContentPane(mainPanel);
gbc.gridx = 0;
gbc.gridy = 1;
JCheckBox cb = new JCheckBox("Bold");
gbLayout.setConstraints(cb, gbc);
mainPanel.add(cb);
gbc.gridy = 3;
gbLayout.setConstraints(cb, gbc);
cb = new JCheckBox("Italic");
mainPanel.add(cb);
gbc.gridx = 1;
gbc.gridy = 0;
JRadioButton rb = new JRadioButton("Times");
gbLayout.setConstraints(rb, gbc);
mainPanel.add(rb, gbc);
gbc.gridy = 2;
rb = new JRadioButton("Helvatica");
mainPanel.add(rb, gbc);
rb = new JRadioButton("Courier");
gbc.gridy = 4;
mainPanel.add(rb, gbc);
this.pack();
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
}
}
3 issues
Y Coordinate not re-assigned to different value causing last 2 radio buttons to exist at same location
GridBagConstraints not being used for left-hand side components
setConstraints erroneously being used to set constraints
Resultant code:
public class GoodGridBagApp {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Font Chooser");
frame.add(getMainPanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
private JPanel getMainPanel() {
JPanel mainPanel = new JPanel();
GridBagConstraints gbc = new GridBagConstraints();
mainPanel.setLayout(new GridBagLayout());
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20));
gbc.gridx = 1;
gbc.gridy = 2;
JCheckBox cb = new JCheckBox("Bold");
mainPanel.add(cb, gbc);
gbc.gridy = 4;
cb = new JCheckBox("Italic");
mainPanel.add(cb, gbc);
gbc.gridx = 2;
gbc.gridy = 1;
JRadioButton rb = new JRadioButton("Times");
mainPanel.add(rb, gbc);
gbc.gridy = 3;
rb = new JRadioButton("Helvatica");
mainPanel.add(rb, gbc);
rb = new JRadioButton("Courier");
gbc.gridy = 5;
mainPanel.add(rb, gbc);
return mainPanel;
}
});
}
}
Read: How to Use GridBagLayout
I want the various components to spread out and fill the entire window.
Have you tried anything else? Yes, I tried GridLayout but then the buttons look huge. I also tried pack() which made the window small instead. The window should be 750x750 :)
What I was trying is this:
These 4 buttons on the top as a thin strip
The scroll pane with JPanels inside which will contain all the video conversion tasks. This takes up the maximum space
A JPanel at the bottom containing a JProgressBar as a thin strip.
But something seems to have messed up somewhere. Please help me solve this
SSCCE
import java.awt.*;
import javax.swing.*;
import com.explodingpixels.macwidgets.*;
public class HudTest {
public static void main(String[] args) {
HudWindow hud = new HudWindow("Window");
hud.getJDialog().setSize(750, 750);
hud.getJDialog().setLocationRelativeTo(null);
hud.getJDialog().setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel buttonPanel = new JPanel(new FlowLayout());
JButton addVideo = HudWidgetFactory.createHudButton("Add New Video");
JButton removeVideo = HudWidgetFactory.createHudButton("Remove Video");
JButton startAll = HudWidgetFactory.createHudButton("Start All Tasks");
JButton stopAll = HudWidgetFactory.createHudButton("Stop All Tasks");
buttonPanel.add(addVideo);
buttonPanel.add(startAll);
buttonPanel.add(removeVideo);
buttonPanel.add(stopAll);
JPanel taskPanel = new JPanel(new GridLayout(0,1));
JScrollPane taskScrollPane = new JScrollPane(taskPanel);
IAppWidgetFactory.makeIAppScrollPane(taskScrollPane);
for(int i=0;i<10;i++){
ColorPanel c = new ColorPanel();
c.setPreferredSize(new Dimension(750,100));
taskPanel.add(c);
}
JPanel progressBarPanel = new JPanel();
JComponent component = (JComponent) hud.getContentPane();
component.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
Insets in = new Insets(2,2,2,2);
gbc.insets = in;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 10;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
component.add(buttonPanel,gbc);
gbc.gridy += 1;
gbc.gridheight = 17;
component.add(taskScrollPane,gbc);
gbc.gridy += 17;
gbc.gridheight = 2;
component.add(progressBarPanel,gbc);
hud.getJDialog().setVisible(true);
}
}
Use this
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridbagConstraints.BOTH
Why not simply place three JPanels on top of one JPanel with BorderLayout as Layout Manager, where the middle JPanel with all custom panels with their respective sizes can be accommodated inside a JScrollPane, as shown in the below example :
import javax.swing.*;
import java.awt.*;
import java.util.Random;
/**
* Created with IntelliJ IDEA.
* User: Gagandeep Bali
* Date: 5/17/13
* Time: 6:09 PM
* To change this template use File | Settings | File Templates.
*/
public class PlayerBase
{
private JPanel contentPane;
private JPanel buttonPanel;
private JPanel centerPanel;
private CustomPanel[] colourPanel;
private JPanel progressPanel;
private JButton addVideoButton;
private JButton removeVideoButton;
private JButton startAllButton;
private JButton stopAllButton;
private JProgressBar progressBar;
private Random random;
public PlayerBase()
{
colourPanel = new CustomPanel[10];
random = new Random();
}
private void displayGUI()
{
JFrame playerWindow = new JFrame("Player Window");
playerWindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel(new BorderLayout(5, 5));
contentPane.setBorder(
BorderFactory.createEmptyBorder(5, 5, 5, 5));
buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 5));
addVideoButton = new JButton("Add New Video");
removeVideoButton = new JButton("Remove Video");
startAllButton = new JButton("Start all tasks");
stopAllButton = new JButton("Stop all tasks");
buttonPanel.add(addVideoButton);
buttonPanel.add(removeVideoButton);
buttonPanel.add(startAllButton);
buttonPanel.add(stopAllButton);
contentPane.add(buttonPanel, BorderLayout.PAGE_START);
JScrollPane scroller = new JScrollPane();
centerPanel = new JPanel(new GridLayout(0, 1, 2, 2));
for (int i = 0; i < colourPanel.length; i++)
{
colourPanel[i] = new CustomPanel(new Color(
random.nextInt(255), random.nextInt(255)
, random.nextInt(255)));
centerPanel.add(colourPanel[i]);
}
scroller.setViewportView(centerPanel);
contentPane.add(scroller, BorderLayout.CENTER);
progressPanel = new JPanel(new BorderLayout(5, 5));
progressBar = new JProgressBar(SwingConstants.HORIZONTAL);
progressPanel.add(progressBar);
contentPane.add(progressPanel, BorderLayout.PAGE_END);
playerWindow.setContentPane(contentPane);
playerWindow.pack();
//playerWindow.setSize(750, 750);
playerWindow.setLocationByPlatform(true);
playerWindow.setVisible(true);
}
public static void main(String[] args)
{
Runnable runnable = new Runnable()
{
#Override
public void run()
{
new PlayerBase().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
class CustomPanel extends JPanel
{
public CustomPanel(Color backGroundColour)
{
setOpaque(true);
setBackground(backGroundColour);
}
#Override
public Dimension getPreferredSize()
{
return (new Dimension(750, 100));
}
}
OUTPUT :