i want to ask if anything goes wrong with my code. i've set my frame with borderlayout . and on the center part, i want to use gridlayout with 7rows and 2 cols inside them.
paneltengah= new JPanel();
paneltengah.setLayout(new GridLayout(7,2));
labelname = new JLabel(lbl_name,SwingConstants.LEFT);
labelusername = new JLabel(lbl_username,SwingConstants.LEFT);
labelpassword = new JLabel(lbl_password,SwingConstants.LEFT);
labelgender = new JLabel(lbl_gender,SwingConstants.LEFT);
labelemail = new JLabel(lbl_email,SwingConstants.LEFT);
labelhobby = new JLabel(lbl_hobby,SwingConstants.LEFT);
labelrole = new JLabel(lbl_role,SwingConstants.LEFT);
textname = new JTextField(20);
textusername = new JTextField(20);
textpassword = new JPasswordField(20);
textemail = new JTextField(20);
comboboxhobby = new JComboBox();
comboboxrole = new JComboBox();
radiobuttonmale = new JRadioButton("Male");
radiobuttonfemale = new JRadioButton("Female");
ButtonGroup btngroup = new ButtonGroup();
btngroup.add(radiobuttonmale);
btngroup.add(radiobuttonfemale);
paneltengah.add(labelname);
paneltengah.add(labelusername);
paneltengah.add(labelpassword);
paneltengah.add(labelgender);
paneltengah.add(labelemail);
paneltengah.add(labelrole);
paneltengah.add(labelhobby);
//// paneltengah.add(textname); when i open this, the layout become awkward
//// paneltengah.add(textusername);
//// paneltengah.add(textpassword);
//// paneltengah.add(radiobuttonmale);
//// paneltengah.add(radiobuttonfemale);
//// paneltengah.add(comboboxhobby);
//// paneltengah.add(comboboxrole);
pane.add(paneltengah, BorderLayout.CENTER);
the following pictures is shown without opening the comment
the following picture is shown with uncomment
what is wrong with my code ?
First of all, a GridLayout sizes all components evenly in its associated Container, which explains why your labels and fields are all the same size. For example, if you had a JTextArea 200 columns × 20 lines in your JPanel, then even the tiniest label would occupy that huge a space as well!
Next, according to the GridLayout Javadoc, when a GridLayout instance is constructed with two non-zero arguments, the number of rows gets fixed and the number of columns is adjusted according to the number of components put into the parent Container.
What I suggest is using a BorderLayout to set up your main form layout. Put your title at NORTH and keep the CENTER for your labels and fields (your current JPanel).
For your labels and fields, the simplest solution might be using a GridLayout(0, 2) (fixed number of columns). But all your components will still be equally sized.
If you need more control over the size of your components (e.g., fields wider than labels), then I suggest using another layout manager such as GridBagLayout. I know it's more complex to manage but using a GridBagLayout formatting preview utility should help. Such a program may be named something like GridBagLab (I know David Geary's book Graphic Java volume 2 — Swing features one on its companion CD).
There is also a GridBagLayout tutorial at https://www.youtube.com/watch?v=Ts5fsHXIuvI.
Related
I have some JLabel components in a JPanel (taskPanel) with a BoxLayout (which is in a panel with a GridBagLayout) and the labels are refusing to be aligned to the right. They keep aligning to the left no matter how I manipulate them.
Here I setup the GridBagConstraints for the panel that has the labels
GridBagConstraints taskPanelC = new GridBagConstraints();
taskPanelC.gridx = 4;
taskPanelC.gridy = 0;
taskPanelC.gridwidth = 1;
taskPanelC.anchor = GridBagConstraints.NORTHEAST;
taskPanelC.weighty = 1;
taskPanelC.weightx = 1;
taskPanelC.insets = new Insets(10, 10, 10, 10);
timePanel.add(taskPanel, taskPanelC);
Here are the GridBagConstraints for the panel before the task panel
//Setup the gridBagLayout
GridBagConstraints timeTextC = new GridBagConstraints();
timeTextC.gridx = 1;
timeTextC.gridy = 0;
timeTextC.gridwidth = 3;
timeTextC.anchor = GridBagConstraints.CENTER;
timeTextC.weighty = 1;
timeTextC.weightx = 1;
Here I add a header to the taskPanel (I don't really care how this is aligned)
taskListLabel = new JLabel("Task List");
taskListLabel.setFont(new Font("Helvetica", Font.BOLD, 24));
taskPanel.add(taskListLabel);
Here is where I am adding the labels I want to be right-justified/aligned. I have tried setHorizontalTextPosition and setAlignmentX and both do not work, causing the text to stay left aligned. However, when I tried setAlignmentX, the header became unaligned with the task labels
JLabel task = new JLabel(name, SwingConstants.RIGHT);
//Allow deleting of the label
task.addMouseListener(new ClickListener());
//Add task to the task panel
taskPanel.add(task);
This is what it currently looks like
I want the text under task list to be right-aligned so the time is always on the right
Here is a link to the full code in case the summary was not enough: Github Repo
Check out the following methods from the JLabel API:
setHorizontalAlignment(...) - used to align the text when the width of the label is greater than the width of the text
setAlignmentX(...) - might be used by the layout manager to align component
I copied the entire code from the link
https://github.com/kennyftang/WorkflowTimer/blob/master/src/WorkflowTimer.java
I guess the code is incomplete, as addTask(String name) method is not called anywhere in the code.
I am really confused about which label you want to be on the right side? As I observed that the "task list" are already on the right side.
Please provide the image explaining which label you want on which side? Also, don't use so many layouts and get confused for this small UI just one layout is enough.
Step 1 Comment the following line.
// taskPanel.add(taskListLabel);
Step2 Add the following 4 lines in that place,
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(taskListLabel, BorderLayout.EAST);
taskPanel.add(panel,BorderLayout.LINE_END);
Step3 Comment the following line.
//taskPanel.add(task);
Step4 Add the following 4 lines in that place,
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(task,BorderLayout.EAST);
taskPanel.add(panel,BorderLayout.LINE_END);
Let me know if you have any issues. Thanks.
I know this is bit heavy solution, here instead of Jpanel we may use some even light weight component as well.
I am using MigLayout I find it flexible etc,but I am having a problem with centring stuff with it. I tried using gapleft 50% but it seems like the percent number needs to change on different frame sizes, because it's also depending on component's size. so if the component is centred using gapleft 25%, it will be on a different location if i resize the width of my frame.
I've tried using just align center and it doesn't nothing at all.
I've also tried new CC().alignX("center").spanX() and same thing:
(source: gyazo.com)
It's sticks to left, however it does work when I use gapleft, why?
super.setLayout(new MigLayout());
this.loginPane = new LoginPanel();
BufferedImage logo = ImageIO.read(new File("assets/logo.png"));
JLabel logoLabel = new JLabel(new ImageIcon(logo));
super.add(logoLabel, new CC().alignX("center").spanX());
It's sticks to left, however it does work when I use gapleft, why?
Based on this single line:
super.setLayout(new MigLayout()); // why super? Did you override setLayout() method?
By default MigLayout rows doesn't fill all available width but only the necessary to display the longest row (based on components width). Having said this your JLabel fits the logo image width and nothing more and it looks like stick to left side. You have to tell the layout manager that it has to fill all available width when you instantiate it:
super.setLayout(new MigLayout("fillx"));
Or
LC layoutConstraints = new LC();
layoutConstraints.setFillX(true);
super.setLayout(new MigLayout(layoutConstraints);
Then, your component constraints will work as expexted.
Picture
Based on this code snippet:
MigLayout layout = new MigLayout("fillx, debug");
JPanel content = new JPanel(layout);
JLabel label = new JLabel("Warehouse");
label.setFont(label.getFont().deriveFont(Font.BOLD | Font.ITALIC, 18));
CC componentConstraints = new CC();
componentConstraints.alignX("center").spanX();
content.add(label, componentConstraints);
Note: you can enable debug feature by doing this:
super.setLayout(new MigLayout("fillx, debug"));
Or
LC layoutConstraints = new LC();
layoutConstraints.setFillX(true);
layoutConstraints.setDebugMillis(500);
super.setLayout(new MigLayout(layoutConstraints);
how to add a JLabel simple text over/above a JTextField.
I tried many commands as you can see in my code but nothings works.
this is a snapshot of my code
private JPanel createTextPanel() {
int panelWidth = PANEL_SIZE.width;
int panelHeight = PANEL_SIZE.height/3;
Dimension panelSize = new Dimension(panelWidth,panelHeight);
JPanel textPanel = new JPanel();
textPanel.setPreferredSize(panelSize);
//textPanel.setLayout(null);
/* Add text */
JLabel Text_RED = new JLabel();
Text_RED.setText("Red");
//Text_RED = new JLabel("\nRED\n");
//Text_RED.setHorizontalTextPosition(SwingConstants.TOP);
//Text_RED.setVerticalAlignment(SwingConstants.TOP);
Red = new JTextField(3);
//Red.setVerticalAlignment(JTextField.TRAILING );
Red.setLocation(100,100);
//Red.setLocation(50, 50);
JLabel Text_Green = new JLabel("Green");
Green = new JTextField(3);
JLabel Text_Blue = new JLabel("Blue");
Blue = new JTextField(3);
//setLayout(new GridLayout(2,2,10,10));
textPanel.add(Text_RED);
textPanel.add(Red);
textPanel.add(Text_Green);
textPanel.add(Green);
textPanel.add(Text_Blue);
textPanel.add(Blue);
return textPanel;
}
Suggestions:
Don't use null layouts and absolute positioning. While it seems initially that using these tools is the easiest way to create complex GUI's, it's really a newbie fallacy, as the more you understand and use the layout managers, the more you'll find that they make the job of creating GUI's much easier, and the results much more attractive.
Learn about and use the layout managers. Tutorial link.
Consider using a BorderLayout and adding your JLabel BorderLayout.CENTER and the JTextField at BorderLayout.PAGE_END. As a side note, I generally avoid placing JTextFields in a BorderLayout.CENTER position since this will cause horizontal stretching of the field if the GUI changes size, which I don't think is aesthetically pleasing.
So my buttons are overwriting each other, instead of all going up North like a tool bar..
I'm trying to get the buttons to go up North if that makes sense. I know my GUI is awful, and I'll rewire it once I get this prototype done.
// panels
mainPuzzlerPanel = new Panel();
mainPuzzlerPanel.setLayout(new BorderLayout());
puzzlePanel = new Panel();
//mainPuzzlerPanel.setLayout(null);
puzzlePanel.setLocation(100, 120);
// text fields
debugTxt = new TextArea(null,6,40,1);
debugTxt.setEditable(false);
mainPuzzlerPanel.add(debugTxt,BorderLayout.NORTH);
// buttons
Button newPuzzle = new Button("New Puzzle");
Button loadImage = new Button("Load Image");
Button assignLocation = new Button("Assign Location");
Button assignTimestamp = new Button("Assign Timestamp");
Button savePuzzle = new Button("Save Puzzle");
Button clearPuzzleCreator = new Button("Clear");
newPuzzle.addActionListener(this);
loadImage.addActionListener(this);
assignLocation.addActionListener(this);
assignTimestamp.addActionListener(this);
savePuzzle.addActionListener(this);
clearPuzzleCreator.addActionListener(this);
mainPuzzlerPanel.add(assignLocation,BorderLayout.NORTH);
mainPuzzlerPanel.add(assignTimestamp,BorderLayout.NORTH);
mainPuzzlerPanel.add(loadImage,BorderLayout.NORTH);
mainPuzzlerPanel.add(savePuzzle,BorderLayout.NORTH);
mainPuzzlerPanel.add(clearPuzzleCreator,BorderLayout.NORTH);
mainPuzzlerPanel.add(newPuzzle,BorderLayout.NORTH);
mainPuzzlerPanel.add(puzzlePanel,BorderLayout.CENTER);
add(mainPuzzlerPanel, "Controls");
setSize(1200, 700);
setVisible(true);
You can't add all the components BorderLayout.NORTH, makes no sense. Instead, add the JButtons to a JPanel that uses a different layout, say GridLayout, and then add that JPanel BorderLayout.NORTH. But most important -- read a tutorial on how to use the layout managers. It looks like you're guessing at this and that's not an efficient way to learn how to use these complex tools.
Regading,
I know my GUI is awful, and I'll rewire it once I get this prototype done.
Also not a good plan. It's much easier to write it well the first time through.
e.g.,
// after creating all of your JButtons, put them in an array...
JButton[] btnArray = {newPuzzle, loadImage, assignLocation, assignTimestamp,
savePuzzle, clearPuzzleCreator};
JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 0));
for (JButton btn : btnArray) {
buttonPanel.add(btn);
}
mainPuzzlerPanel.add(buttonPanel, BorderLayout.NORTH);
Edit: Oops, I notice now you're using Buttons and Panels, not JButtons and JPanels. I urge you to change your app to be a Swing app not an AWT app.
Layout manager tutorial: Laying Out Components Within a Container
I have this layout that I need to program for an assignment and this is the first time I have used layout managers in the GUI so I'm having problems getting the layout to match. I need your help
I Have two tabs labeled Account creation and Account transfer (those are ok) what I need is to have the JLabel (Account ID) and the first text field in one line then the next JLabel (Amount) and text field in the line under the first. Under that needs to be the JButton Centered (Create an Account). Lastly the JTextArea (No account) needs to be in a column to the right in the empty space separate from the labels, text fields, and button.
Here is the code I have started with:
public CreatePanel(Vector accountList, TransferPanel transferPanel)
{
this.accountList = accountList;
this.transferPanel = transferPanel;
JLabel l1 = new JLabel("Account ID");
JTextField t1 = new JTextField();
JLabel l2 = new JLabel("Amount");
JTextField t2 = new JTextField();
JButton b1 = new JButton("Create an Account");
JTextArea a1 = new JTextArea("No Account");
JPanel panel1 = new JPanel();
panel1.setLayout(new GridLayout(2,3));
panel1.add(l1);
panel1.add(t1);
panel1.add(l2);
panel1.add(t2);
panel1.add(b1, BorderLayout.SOUTH);
b1.setVerticalAlignment(JLabel.CENTER);
JPanel panel2 = new JPanel();
panel2.add(a1);
a1.setSize(200, 300);
add(panel1);
add(panel2);
}
This is how I would approach it. Instead of adding the outer panel to a frame though, it would be added to a tab of the tabbed pane.
The above is an example of a nested or compound layout. The titled borders show the layouts used and the arguments (if any) used to construct them.
The size of the button is suggested by the content (the text). The sizes of the text fields and text area is suggested in the constructor (which itself has been included as the text value).
To get the TALL effect in the text fields, set an HUGE font but use less columns for the constructor.
See also
Another nested layout.
GridBagLayout is the most powerful Layout that you can use to easily implement grid-like displays. It's a layout with n rows and m columns where each cell is customizable independently of the others in several aspects. In this layout you have to attach a GridBagConstraints object to each panel.add(JComponent, Constraints) as constraints. In the tutorial it's clearly specified what is customizable. It might look a little harsh at the beginning but once you get the hang of it it's great. It's powerful and flexible and you don't have to worry about the uncustomizable restrictions you might encounter with other Layouts.
In your layout, the most inconvenient thing I see is having the "Account ID" label aligned by its center with the TextField AND with the empty space over both of them. It would be easier if the label was aligned with the bottom of the TextField. To solve this I'll assume that the Label and the TextField are inside a panel I constructed beforehand that aligns each other correctly (easily with BorderLayout or GridBagLayout... or anything really) and I'll just place the panels in the Layout.
Then I see this Layout as a GridBagLayout with 3 rows and 2 columns that looks like this:
This is an overview of how I'd put the constraints to specify each component in the layout.
Panel 1 (Account ID Label + TextField)
gridx = 0
gridy = 0
weighty = 0.5
weightx = 0.5
anchor = PAGE_END
fill = HORIZONTAL
Panel 2 (Amount Label + TextField)
gridx = 0
gridy = 1
weighty = 0.0
fill = HORIZONTAL
Button
gridx = 0
gridy = 2
anchor = PAGE_START
weighty = 0.5
TextArea
gridx = 1
gridy = 0
gridheight = 3
weightx = 0.5
fill = BOTH
There is a couple of details I overlooked but the core issues can be aproached with these constraints. The least obvious thing to learn about the GridBagLayout is how do weights work in complex cases, for example what happens when there are several different weightx values in the same column. Does it count the max? or the sum?...
For the sake of discussion, you could avoid having those panels using an extra initial row with an invisible component with weighty > 0 and then having 2 columns: one for the JLabels and the other one for the JTextFields, with the apropiate anchors; the button would have gridwith = 2... but that's totally unnecesary, go for the two auxiliar panels.