How to manually set locations of JComponents etc - java

I have tried setLocation(x,y) and setLocationRelativeTo(null) by setting Layout of JFrame as null but that didn't work out.While searching I found this questions being already asked by two or three people but they have done through setLocation() and setLocationRelativeTo(null).
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.FlowLayout;
public class StartMenu{
JPanel startPanel;
JLabel title;
JButton startTest;
JButton exit;
JFrame menuFrame;
public StartMenu(){
menuFrame = new JFrame("Start Menu");
menuFrame.setLayout(null);
startPanel = new JPanel();
title = new JLabel("Adaptive Test",JLabel.CENTER);
title.setLocation(20,20);
startPanel.add(title);
startTest = new JButton("Start");
startTest.setLocation(40,40);
startPanel.add(startTest);
exit = new JButton("Exit");
exit.setLocation(100,100);
startPanel.add(exit);
menuFrame.setContentPane(startPanel);
menuFrame.setVisible(true);
menuFrame.setSize(500, 500);
menuFrame.setResizable(false);
menuFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

Your JFrame's layout is set to null, but the startPanel's one is not. So first of all, use:
startPanel.setLayout(null);
Now, instead of component.setLocation(x, y), use component.setBounds(x, y, width, height), so you also set a size for them.
But as has been said in the comments, it would be preferable to use layout managers instead of null layout.

First you set to null the JFrame istead of the JPanel, so you have to use
startPanel.setLayout(null);
then you should use setBounds istead of setLocation becouse if you just set the location with a null layout manager you'll probably will see nothing on your panel, becouse all dimensions are initialized to 0 by default.
so, you can rewrite your software like this:
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class StartMenu{
JPanel startPanel;
JLabel title;
JButton startTest;
JButton exit;
JFrame menuFrame;
public StartMenu(){
menuFrame = new JFrame("Start Menu");
menuFrame.setLayout(null);
startPanel = new JPanel();
startPanel.setLayout(null);
title = new JLabel("Adaptive Test",JLabel.CENTER);
title.setBounds(20,20, 100, 30);
startPanel.add(title);
startTest = new JButton("Start");
startTest.setBounds(50,50, 100, 30);
startPanel.add(startTest);
exit = new JButton("Exit");
exit.setBounds(100,100, 100 ,30);
startPanel.add(exit);
menuFrame.setContentPane(startPanel);
menuFrame.setVisible(true);
menuFrame.setSize(500, 500);
menuFrame.setResizable(false);
menuFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Like this you get something working but it isn't a very good programming practice to set by hand all the location and sizes in your software becouse it will not work good on different systems (thus it will not be portable) and you will also find yourself in a debugging nightmare when your software will start growing with tens if not hundreds of graphics elements.
My suggestion is to use the gridBagLayout, it me seem obscure at first, but trust me, it's not so!

Related

Why does a GroupLayout not having a result as per requirement

Here I want to add buttons as per 4-3-3 formation in football but i am getting 3-3-3. how can i put 4 buttons in one row??
I have been referral to this site: https://weblogs.java.net/blog/tpavek/archive/2006/02/getting_to_know_2.html
Code:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import static javax.swing.GroupLayout.Alignment.*;
class Abc extends JFrame
{
JButton b[];
Abc()
{
b=new JButton[11];
JPanel jp=new JPanel();
for(int i=0;i<b.length;i++)
{
b[i]=new JButton();
}
GroupLayout layout=new GroupLayout(jp);
jp.setLayout(layout);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(LEADING)
.addComponent(b[0])
.addComponent(b[1])
.addGroup(layout.createSequentialGroup())
.addComponent(b[2])
.addComponent(b[3]))
.addGroup(layout.createParallelGroup(LEADING)
.addComponent(b[4])
.addComponent(b[5])
.addGroup(layout.createSequentialGroup())
.addComponent(b[6]))
.addComponent(b[7])
.addGroup(layout.createParallelGroup(LEADING)
.addComponent(b[8])
.addComponent(b[9])
.addGroup(layout.createSequentialGroup())
.addComponent(b[10]))
);
layout.setVerticalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(BASELINE)
.addComponent(b[0])
.addComponent(b[4])
.addComponent(b[8]))
.addGroup(layout.createParallelGroup(BASELINE)
.addComponent(b[1])
.addComponent(b[5])
.addComponent(b[9]))
.addGroup(layout.createParallelGroup(BASELINE)
.addComponent(b[2])
.addComponent(b[3])
.addComponent(b[6])
.addComponent(b[10]))
.addComponent(b[7])
);
setTitle("kuvh b");
setSize(1000,1000);
for(int i=0;i<11;i++)
{
add(b[i]);
}
add(jp);
pack();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(
"javax.swing.plaf.metal.MetalLookAndFeel");
// "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
//UIManager.getCrossPlatformLookAndFeelClassName());
} catch (Exception ex) {
ex.printStackTrace();
}
new Abc().setVisible(true);
}
});
}
}
I want to make a structure of 4-3-3 formation with this. Please help me
The code is resulting in 3-3-3 formation. there are 3 buttons on third row but i want 4 how can i do this please help
See the output:
[1]:
http://imgur.com/jxADf2t
i hope i will find my solution as far as possible
I've found two ways to do something like you want; centering the buttons turns out to be something that Swing does not make as easy as it might, but then centering components is probably not as common as other alignments.
You can center components in a FlowLayout; the disadvantage in a FlowLayout is that, if the user shrinks the window to the point the components no longer fit, the layout wraps the components. This is very useful for some things, but not for your football players. I've wrapped my example in a scrollpane so this won't happen.
The other way to center components is with GroupLayout, but GroupLayout is not good for the overall layout you are trying to achieve. GroupLayout is intended for use where you have overall rows and columns in which to line things up, and your four lines of football players are not lined up that way vertically, only horizontally. But you can use the centering characteristic of GroupLayout to do the horizontal centering, and make a separate GroupLayout for each line.
My example uses FlowLayout for the first line, and GroupLayout for the second, just to show how it could be done. I did not address the problem of the gap that appears between the players' lines when the window is made large enough. Especially for examples, I do not use the style of tacking method invocations onto other method invocations and constructors; I think the deeply nested parentheses and non-straightforward logic of this style makes it more difficult to figure out (or keep track of) what's going on.
You can use GridBagLayout to center things, also, but I don't use it at all if anything else will do what I need.
I hope this answers your question.
package grouplayout;
import java.awt.FlowLayout;
import javax.swing.BoxLayout;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class Main2 extends JFrame
{
public static void main(String ... arguments)
{
Main2 main2 = new Main2();
main2.createUI();
main2.setVisible(true);
}
public void createUI()
{
JPanel wingPanel = new JPanel();
FlowLayout flowLayout = new FlowLayout();
flowLayout.setHgap(35);
wingPanel.setLayout(flowLayout);
JButton btnone = new JButton("Lwing");
JButton btntwo = new JButton("center");
JButton btnthr = new JButton("Rwing");
wingPanel.add(btnone);
wingPanel.add(btntwo);
wingPanel.add(btnthr);
// -------------------------------------------
JButton mid1 = new JButton("mid1");
JButton mid2 = new JButton("mid2");
JButton mid3 = new JButton("mid3");
JButton mid4 = new JButton("mid4");
JPanel midfieldPanel = new JPanel();
GroupLayout groupLayout = new GroupLayout(midfieldPanel);
GroupLayout.SequentialGroup horizontalGroup = groupLayout.createSequentialGroup();
groupLayout.setHorizontalGroup(horizontalGroup);
horizontalGroup.addComponent(mid1);
horizontalGroup.addComponent(mid2);
horizontalGroup.addComponent(mid3);
horizontalGroup.addComponent(mid4);
GroupLayout.SequentialGroup verticalGroup = groupLayout.createSequentialGroup();
groupLayout.setVerticalGroup(verticalGroup);
GroupLayout.ParallelGroup midButtonGroup = groupLayout.createParallelGroup(GroupLayout.Alignment.CENTER);
midButtonGroup.addComponent(mid1);
midButtonGroup.addComponent(mid2);
midButtonGroup.addComponent(mid3);
midButtonGroup.addComponent(mid4);
verticalGroup.addGroup(midButtonGroup);
JPanel teamPanel = new JPanel();
BoxLayout boxLayout = new BoxLayout(teamPanel, BoxLayout.PAGE_AXIS);
teamPanel.setLayout(boxLayout);
teamPanel.add(wingPanel);
teamPanel.add(midfieldPanel);
JScrollPane scrollPane = new JScrollPane(teamPanel);
getContentPane().add(scrollPane);
pack();
}
}
EDIT: as requested, the below does the same thing with only GroupLayout.
There is no interaction between the two groups, because GroupLayout aligns things in columns, and your players are not in columns.
And yes, I suppose it is difficult -- GroupLayout, as I understand it, was really intended for use by GUI builder tools, not really for building UIs by hand. I personally have a supporter class or two that allows GroupLayout UIs to be built with slightly simpler logic. But in any event, I think you need to understand the building blocks:
GroupLayout allows - and requires - that you place each component in both horizontal and vertical row/column position independently; this is useful since so many UIs require rows and columns of mixed components and variable extra components.
A sequential group of components in dimension X is arranged sequentially in dimension X; a parallel group in dimension X is also arranged sequentially, but perpendicular to dimension X.
The layout maintains preferred sizes of components; row width and column height are set at the maximum preferred size of the constituent components.
The overall GroupLayout object has one vertical and one horizontal grouping; within that, sequential and parallel groups are created to create the overall layout desired.
I know the examples in the tutorial(s) I've read do not create separate variables to hold the internal sequential and parallel groups, preferring to use forms like new X().addComponent().addGroup() etc. But I think that makes it harder to understand what the code is actually doing, not easier; and the nested parentheses become their own maintenance problem. So I think this is a better way to do things, especially for those just getting started with this layout.
package grouplayout;
import java.awt.FlowLayout;
import javax.swing.BoxLayout;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class Main3 extends JFrame
{
public static void main(String ... arguments)
{
Main3 main2 = new Main3();
main2.createUI();
main2.setVisible(true);
}
public void createUI()
{
JButton btnone = new JButton("Lwing");
JButton btntwo = new JButton("center");
JButton btnthr = new JButton("Rwing");
JPanel wingPanel = new JPanel();
GroupLayout wingGroupLayout = new GroupLayout(wingPanel);
GroupLayout.SequentialGroup wingHorizontalGroup = wingGroupLayout.createSequentialGroup();
wingGroupLayout.setHorizontalGroup(wingHorizontalGroup);
wingHorizontalGroup.addComponent(btnone);
wingHorizontalGroup.addComponent(btntwo);
wingHorizontalGroup.addComponent(btnthr);
GroupLayout.SequentialGroup wingVerticalGroup = wingGroupLayout.createSequentialGroup();
wingGroupLayout.setVerticalGroup(wingVerticalGroup);
GroupLayout.ParallelGroup wingButtonGroup = wingGroupLayout.createParallelGroup();
wingButtonGroup.addComponent(btnone);
wingButtonGroup.addComponent(btntwo);
wingButtonGroup.addComponent(btnthr);
wingVerticalGroup.addGroup(wingButtonGroup);
// -------------------------------------------
JButton mid1 = new JButton("mid1");
JButton mid2 = new JButton("mid2");
JButton mid3 = new JButton("mid3");
JButton mid4 = new JButton("mid4");
JPanel midfieldPanel = new JPanel();
GroupLayout groupLayout = new GroupLayout(midfieldPanel);
GroupLayout.SequentialGroup horizontalGroup = groupLayout.createSequentialGroup();
groupLayout.setHorizontalGroup(horizontalGroup);
horizontalGroup.addComponent(mid1);
horizontalGroup.addComponent(mid2);
horizontalGroup.addComponent(mid3);
horizontalGroup.addComponent(mid4);
GroupLayout.SequentialGroup verticalGroup = groupLayout.createSequentialGroup();
groupLayout.setVerticalGroup(verticalGroup);
GroupLayout.ParallelGroup midButtonGroup = groupLayout.createParallelGroup(GroupLayout.Alignment.CENTER);
midButtonGroup.addComponent(mid1);
midButtonGroup.addComponent(mid2);
midButtonGroup.addComponent(mid3);
midButtonGroup.addComponent(mid4);
verticalGroup.addGroup(midButtonGroup);
JPanel teamPanel = new JPanel();
BoxLayout boxLayout = new BoxLayout(teamPanel, BoxLayout.PAGE_AXIS);
teamPanel.setLayout(boxLayout);
teamPanel.add(wingPanel);
teamPanel.add(midfieldPanel);
JScrollPane scrollPane = new JScrollPane(teamPanel);
getContentPane().add(scrollPane);
pack();
}
}

Java Swing simple center of JPanel in other JPanel

I have this incredibly easy task of wanting a nice centered JPanel inside another JPanel. The parent is set to 900, 550, and the child should be approximately 200,400 or so.
To do this, I thought giving the parent a BorderLayout and then setting the setPreferredSize(200, 400) of the child. This child would be in the CENTER. Two empty JPanels would be on the EAST and WEST. Of course this did not work. Giving the two sidepanels a setPreferredSize() of course DID work. Problem with this is that narrowing the Frame causes the center pane to go away.
Here's some sample code that should give show the issue:
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class Temporary {
public static Temporary myObj = null;
private JFrame mainFrame;
public void go(){
mainFrame = new JFrame("Swing");
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setPreferredSize(new Dimension(900,550));
JPanel mainCards = new JPanel(new CardLayout());
mainCards.add(loginLayer(), "Login");
mainFrame.setContentPane(mainCards);
mainFrame.pack();
mainFrame.setLocationRelativeTo(null);
mainFrame.setVisible(true);
}
public JPanel loginLayer(){
JPanel masterPane = new JPanel(new BorderLayout());
JPanel centerPane = new JPanel();
centerPane.setLayout(new BoxLayout(centerPane, BoxLayout.Y_AXIS));
centerPane.setPreferredSize(new Dimension(100,200));
JLabel label = new JLabel("Swing is overly");
label.setAlignmentX(Component.CENTER_ALIGNMENT);
centerPane.add(label);
JButton button = new JButton("complicated");
button.setAlignmentX(Component.CENTER_ALIGNMENT);
centerPane.add(button);
JTextField textField = new JTextField(10);
centerPane.add(textField);
JPanel filler = new JPanel();
JPanel filler2 = new JPanel();
masterPane.add(filler, BorderLayout.WEST);
masterPane.add(centerPane, BorderLayout.CENTER);
masterPane.add(filler2, BorderLayout.EAST);
return masterPane;
}
public static void main(String[] args){
myObj = new Temporary();
myObj.go();
}
}
BorderLayout will, by it's nature, give as much of the available space as it can to the CENTER component. This is how it's designed.
If you want the component to be centered within the parent container, BUT maintain it's preferred size, you should consider using a GridBagLayout instead. Without any additional constraints, this should achieve the result you're after
For example...
public JPanel loginLayer(){
JPanel masterPane = new JPanel(new GridBagLayout);
JPanel centerPane = new JPanel();
centerPane.setLayout(new BoxLayout(centerPane, BoxLayout.Y_AXIS));
JLabel label = new JLabel("Swing is overly");
label.setAlignmentX(Component.CENTER_ALIGNMENT);
centerPane.add(label);
JButton button = new JButton("complicated");
button.setAlignmentX(Component.CENTER_ALIGNMENT);
centerPane.add(button);
JTextField textField = new JTextField(10);
centerPane.add(textField);
masterPane.add(centerPane);
// Add additional borders to providing padding around the center pane
// as you need
return masterPane;
}
I would also avoid actively setting the preferred size of component in this way, as it's possible that the components you're adding to it will exceed your expectations, instead, make use of things like EmptyBorder (for example) to add additional white space arouond the component and it's contents
In Java Swing, you generally want to avoid creating a bunch of statically positioned items with preferred sizes and absolute positions, because things get weird with resizing (as you've noticed). Instead you want to rely on the fluid LayoutManagers. There is an excellent tutorial here. Or, if you want to supply a mock-up of some sort to show the actual UI you are trying to create, I could provide some more feedback.

Add Multiple JPanels to JFrame

Been having a hard time adding JPanels to JFrame. Am pretty much new on java, always used C++
I need to do 4 Panels inside one Frame.
Here is my Code, just started today..
package project2;
import javax.swing.JOptionPane;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.BorderLayout;
import javax.swing.*;
import java.awt.Container;
import java.awt.Dimension;
public class GUI extends JFrame
{
private JPanel Checks; //Panel to Hold Checks
private JPanel Transactions;
private JPanel History;
private JPanel Graphics;
private JLabel CLabel;
public GUI()
{
super ( "UTB Check-In");
JPanel Checks = new JPanel(); //set up panel
CLabel = new JLabel("Label with text");
Checks.setBackground(Color.red);
Checks.setLayout( new BoxLayout(Checks,BoxLayout.LINE_AXIS));
add(Checks);
// JPanel Transactions = new JPanel();
// Transactions.setToolTipText("Electronic Transactions");
//Transactions.setBackground(Color.blue);
// add(Transactions);
}
}
I was trying to put Transaction and Checks one side from the other with different colors,in this case blue and red it doesnt stay in the middle it those one or the other.
One of my Colleagues told me that the BoxLayout(or any layout) needed to be implemented with the size..something to that extend. am not really sure I been reading
http://docs.oracle.com/javase/tutorial/uiswing/layout/box.html
But I still do not get it completely. If somebody can help me out
thanks!
Your code fail cause you are adding directly to the JFrame which have by default BorderLayout. You are setting BoxLayout to the wrong panel.
You have to setLayout() to the top component(jframe) that you are adding or as i prefer adding to a jpanel rather than directly to the jframe to acomplish what you want to do.
Example:
public GUI()
{
super ( "UTB Check-In");
JPanel parent = new JPanel();
parent.setLayout(new BoxLayout(parent,BoxLayout.LINE_AXIS));
add(parent);
JPanel Checks = new JPanel(); //set up panel
CLabel = new JLabel("Label with text");
Checks.setBackground(Color.red);
parent.add(Checks);
JPanel Transactions = new JPanel();
Transactions.setToolTipText("Electronic Transactions");
Transactions.setBackground(Color.blue);
parent.add(Transactions);
}
By the way, in Java variables starts with lowerCase as a code convention.

Java swing - wrong size

so I have this problem. I wrote this code in Java Eclipse SDK 4.2.1. I haven't wrote it all here, actionPerformed method is irrelevant now and it is called from Main once. The problem is sometimes when I run it, one of the components just fills the whole window and overlaps all others. I tried changing sizes by random numbers for example from 400 to 350 and sometimes it worked and then it broke again. I'm probably missing something, I just don't know what. I searched other forums, but found nothing about it.
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collections;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
public class Window extends JFrame implements ActionListener
{
JTextField field1;
JTextField field2;
public Window()
{
super("Main Window");
setVisible(true);
setSize(500, 500);
setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Initialize();
}
private void Initialize()
{
field1 = new JTextField();
field2 = new JTextField();
field1.setBounds(0, 0, 400, 100);
field2.setBounds(0,100,400,100);
add(field1);
add(field2);
field1.setBackground(Color.PINK);
field1.setForeground(Color.RED);
field2.setBackground(Color.PINK);
field2.setForeground(Color.RED);
JButton button = new JButton("Create");
button.setBounds(0, 200, 400, 100);
add(button);
button.setBackground(Color.BLACK);
button.setForeground(Color.YELLOW);
button.addActionListener(this);
}
Your problem is that your code does not respect the layout manager being used as you're trying to add components as if the layout being used were null when in fact it isn't. The solution is to read up on and learn about layout managers, and use them; this includes avoiding calling setBounds(...). Note that a JFrame's contentPane uses BorderLayout by default. This information should help you get started. Also note that a wrong solution is to use a null layout. So if anyone suggests this, I urge you to ignore them.

Understanding layout managers -- I'm not, please enlighten me

I'm just not understanding why things are being resized when I call the validate() and repaint() methods. I'm struggling to understand this. Essentially, my program is meant to display like this. I have a main frame into which I plug the various JPanels that I'm extending for the various functions of my photo album. The class below is the NewAlbum class that is supposed to allow the user to select files and make a new album out of them.
The code for choosing files works nicely. Once the files are selected, the change to the NewAlbum panel should be the select files button is replaced by a done button. Under the done button is a JSplitPane with the horizontal splitter just off center with the right side being larger than the left. The left side will eventually have a thumbnail of each photo as metadata about the photo is entered into the right side.
The right side pane is to be a JScrollPane with a single JPanel which has, in a grid form, the 4 entries that the user is asked for data about. After adding everything, the dimensions are where I want them to be, but when I call the validate/repaint combination the dimensions become "messed up." I'm pretty sure it's because I'm not understanding how the default layout managers for the various classes I'm using, or extending. Please help me understand. Also, tell me if the GridBagLayout is what I want, or if a different one is what I'm looking for.
The NewAlbum code is below.
I apologize for the uncompilable code. I figured that you'd be able to just look at the class and tell me, "Oh, yeah, this is the problem." Below is compilable and does demonstrate the problem. Once the files are selected, the split pane window is too thin and too long. I want it to fit inside the frame. Actually, it should fit inside the JPanel which is inside the JFrame.
Thanks,
Andy
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
class Main extends JFrame {
static JPanel transientPanel = null;
public Main() {
super();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(640, 480);
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Example");
JMenuItem albumMenu = new JMenuItem("New Album");
albumMenu.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
transientPanel = new NewAlbum();
add(transientPanel);
validate();
repaint();
}
});
menu.add(albumMenu);
menuBar.add(menu);
setJMenuBar(menuBar);
validate();
}
public static void main(String[] args) {
final Main m = new Main();
m.setVisible(true);
}
}
/**
* #description NewAlbum is the window that is presented to the user
* to select new photographs for the album. Once selected, the user
* will be presented a form, of sorts, to complete the metadata for this
* album.
* #author Andy
*/
class NewAlbum extends JPanel {
JButton selectFiles;
JButton done;
JButton nextButton = new JButton("Next Image");
ArrayList<File> filesArray;
JSplitPane splitWindow = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);
JScrollPane scrollWindow;
JPanel rightSidePanel = new JPanel();
JPanel leftSidePanel = new JPanel();
JLabel subjectLabel = new JLabel("Image subject:");
JLabel locationLabel = new JLabel("Image location:");
JLabel commentLabel = new JLabel("Comments:");
JLabel dateLabel = new JLabel("Date (mm/dd/yyyy):");
JTextField subjectText = new JTextField(25);
JTextField locationText = new JTextField(25);
JTextArea commentText = new JTextArea(4, 25);
JTextField dateText = new JTextField(10);
public NewAlbum() {
super();
selectFiles = new JButton("Select Photos");
selectFiles.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
selectFilesForAlbum();
}
});
add(selectFiles);
}
private void configureRightPanel() {
int jPanelX = getParent().getWidth();
int jPanelY = getParent().getHeight() - 30; // this should account for buttons
// now, resize this panel so that it will be the right size for the split pane
jPanelX = jPanelX - (int)(jPanelX * .31);
rightSidePanel.setSize(jPanelX, jPanelY);
rightSidePanel.add(subjectLabel);
rightSidePanel.add(subjectText);
rightSidePanel.add(locationLabel);
rightSidePanel.add(locationText);
rightSidePanel.add(commentLabel);
rightSidePanel.add(commentText);
rightSidePanel.add(dateLabel);
rightSidePanel.add(dateText);
rightSidePanel.add(nextButton);
// iterate over the photos selected, make bogus info for now
}
private ArrayList<File> makeFileIntoArrayList(File[] f) {
ArrayList<File> a = new ArrayList<File>();
a.addAll(Arrays.asList(f));
return filesArray = a;
}
/**
* selectFilesForAlbum
* This method is private to the NewAlbum class. It is the handler for
* when the user clicks on the "select photos" button. When the function
* executes, it displays the JFileChooser so that the user may select
* the desired photos. The files selected are assigned to a class variable
* of type File[] which is used by the enterPhotoInfo method.
*
* #return void
*/
private void selectFilesForAlbum() {
JFileChooser jfc = new JFileChooser();
jfc.setMultiSelectionEnabled(true);
jfc.showOpenDialog(this);
makeFileIntoArrayList(jfc.getSelectedFiles());
changeButtonToDone();
enterPhotoInfo();
// TODO write the photo album to the disk
}
private void changeButtonToDone() {
remove(selectFiles);
done = new JButton("Done");
add(done);
// by the time this gets called, we'll have a parent container
getParent().validate();
getParent().repaint();
}
private void enterPhotoInfo() {
splitWindow.setSize(this.getWidth(), this.getHeight() - 30);
// remove when the left side panel actually has something
Dimension iewDims = splitWindow.getSize();
int leftX = iewDims.width - (int)(iewDims.width * .69);
int leftY = iewDims.height;
leftSidePanel.setSize(leftX, leftY);
configureRightPanel();
scrollWindow = new JScrollPane(rightSidePanel);
scrollWindow.setSize(rightSidePanel.getSize());
splitWindow.setRightComponent(scrollWindow);
splitWindow.setLeftComponent(leftSidePanel);
splitWindow.setDividerLocation(.31);
System.out.println("Printing dimensions of before validate/repaint: this, splitWindow, scrollWindow, LSP, RSP");
debugPrintDimensions(this);
debugPrintDimensions(splitWindow);
debugPrintDimensions(scrollWindow);
debugPrintDimensions(leftSidePanel);
debugPrintDimensions(rightSidePanel);
//infoEntryWindow.add(infoScroller);
this.add(splitWindow);
this.validate();
this.repaint();
System.out.println("Printing dimensions of: this, splitWindow, scrollWindow, LSP, RSP");
debugPrintDimensions(this);
debugPrintDimensions(splitWindow);
debugPrintDimensions(scrollWindow);
debugPrintDimensions(leftSidePanel);
debugPrintDimensions(rightSidePanel);
}
private void debugPrintDimensions(Container c) {
System.out.println("DEBUG: Containers (x,y): (" +
String.valueOf(c.getWidth()) +
"," +
String.valueOf(c.getHeight()) +
")");
}
}
Also, tell me if the GridBagLayout is what I want, or if a different one is what I'm looking for.
You use the appropriate layout manager for the job. This can also mean using different layout managers on different panels.
splitWindow.setSize(this.getWidth(), this.getHeight() - 30);
You should NEVER use setSize(). That is the job of the layout manager, to determine the size of the component based on the rules of the layout manager.
All components have a preferred size which is used by the layout manager. At times you can use the setPreferredSize() to change the default.
By selecting a LayoutManager, you are handing over control of the layout to that layout manager. You can give the LayoutManager hints via layout constraints and restrictions by setting the preferred dimensions on the components you are arranging, but essentially, the layout manager will call the shots.
With GridBagLayoutManager you can achieve almost anything with constraints and component dimension settings, but it can still be tricky to get right. Try setting the preferred size on your components.
I used to use GridBagLayoutManager for everything, but then I came across MigLayout which really is a huge step forward in terms of easy configuration and layout consistency. I recommend you give it a look.

Categories

Resources