borderlayout in swt or swing - java

I want to arrange components as shown in image. I can do this by using gridbaglayout but I want to do this using borderlayout. I tried it but could not achieve what I wanted. so please guide me here.
The black rectangles here are components like JPanel, Button etc.

If you want to do it only with BorderLayout, you need to use 2 BorderLayout. If you cannot use 2 layouts, then you are stuck with GridBagLayout.
This is a demonstration of what I am telling:
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
protected void initUI() {
JFrame frame = new JFrame("test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new BorderLayout());
JPanel panel2 = new JPanel(new BorderLayout());
panel2.add(new JButton("NORTH"), BorderLayout.NORTH);
panel2.add(new JButton("CENTER"));
panel.add(panel2);
panel.add(new JButton("SOUTH"), BorderLayout.SOUTH);
panel.add(new JButton("EAST"), BorderLayout.EAST);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Test().initUI();
}
});
}
}

Border layout doesn't work that way. This is the border layout schematic:
You will not be able to place the EAST layout into the top right-hand corner - NORTH will always float to the right hand side.
Edit: shows how long it's been since I used Swing or AWT - back when I did, it was EAST, NORTH, WEST, SOUTH and CENTER.

Related

How do I resize a button?

How do you resize the button? I've tried various methods like setSize and setPreferredSize but they aren't workng.
package tests;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JButton;
public class RPS extends JPanel{
public static void main(String[] args) {
JFrame frame = new JFrame("Rock Paper Scissors");
JPanel panel = new JPanel();
JLabel label = new JLabel("<html>Will you choose <i>rock,</i> <i>paper,</i> or <i>scissors?</i></html>");
JButton button = new JButton("I am a button.");
label.setHorizontalAlignment(0);
label.setVerticalAlignment(1);
frame.pack();
frame.getContentPane();
frame.setTitle("Rock Paper Scissors");
frame.setSize(640, 480);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.add(label);
frame.add(button);
button.setToolTipText("Y U no click me?");;
}
}
There is generally no need to resize a button. The button will determine its own size based on the text and Font used by the button. The layout manager will then use this information to give the components a size and location based on the rules of the layout manager.
If you want extra space around the text then you can use:
button.setMargin(...);
You have many other problems with your code:
frame.add(panel);
frame.add(label);
frame.add(button);
This won't do anything. By default the content pane of the frame uses a BorderLayout. If you don't specify a constraint, then then component is add to the CENTER, but only one component can be displayed in the CENTER so you only see the last one.
frame.setSize(640, 480);
There is no need for that statement. The pack() will set all the components at their preferred sizes.
frame.setVisible(true);
This should be the last statement executed, "after" all components have been added to the frame.
frame.getContentPane();
This does nothing, you don't assign the returned value to any variable.
label.setHorizontalAlignment(0);
label.setVerticalAlignment(1);
Don't use magic numbers. Nobody knows what 0 and 1 are used for. Read the API for those methods for variables that you can use.
Read the section from the Swing tutorial on Layout Managers for more information and working examples to get you started. Start with the section on How to Use BorderLayout to understand why your current code isn't working and to understand how to specify the "constraints" when you add your components to the frame.
package tests;
import java.awt.BorderLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class RPS extends JPanel{
public static void main(String[] args) {
JFrame frame = new JFrame("Rock Paper Scissors");
JPanel panel = new JPanel();
JLabel label = new JLabel("<html>Will you choose <i>rock,</i> <i>paper,</i> or <i>scissors?</i></html>");
JButton button = new JButton("I am a button.");
label.setHorizontalAlignment(0);
label.setVerticalAlignment(1);
panel.add(button); <-add button to panel
frame.add(panel, BorderLayout.SOUTH); <--- you need to say where you are adding the panel onto the frame.
frame.add(label,BorderLayout.NORTH); <--- same with the label
frame.pack();
frame.setTitle("Rock Paper Scissors");
frame.setSize(640, 480);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
button.setToolTipText("Y U no click me?");;
}
}
If you want a bigger button in the center, you can modify with this:
button.setPreferredSize(new Dimension(300, 300));
panel.add(button);
frame.add(panel, BorderLayout.CENTER); <--adds to center rather than south

Layout to stretch component width but let height be decided by what it holds

I can't seem to find the correct layoutmanager, perhaps it doesn't exist, so I wanted to do it in miglayout, yet I can't seem to find my way to do this there either.
Most documentation, tutorials and examples I found don't adress the JPanel having contents at all 0.o
The problem I'm having is, I've got two JPanels(C 1&2) inside a JPanel(B) which in turn is inside a bigger resizeable JPanel(A).
Now both lowest level "C" JPanels contain 5 buttons, when the highest level "A" resizes and gets less width the buttons go from this:
to this:
As you can see the FlowLayout I'm using on the lowest level "C" JPanels is doing it's job!
c.setLayout(new FlowLayout(FlowLayout.LEFT,0,0))
But while the "B" JPanel that holds the C's does exactly what I want for the horizontal part
b.setLayout(new BoxLayout(b, BoxLayout.Y_AXIS));
I don't want it doing that on the height though!
So could anyone point me in the right direction like a tutorial or docs that cover such stuff? For miglayout or swing layout managers?
I have created a solution with a MigLayout manager. The panels keep their
height nicely when the window is resized and never shrink below the size
necessary to hold all the buttons.
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import net.miginfocom.swing.MigLayout;
public class MigLayoutSolution extends JFrame {
public MigLayoutSolution() {
initUI();
}
private void initUI() {
JPanel pnl = new JPanel(new MigLayout());
pnl.add(createPanel1("First"), "push, grow, wrap");
pnl.add(createPanel2("Second"), "push, grow");
add(pnl);
pack();
setTitle("MigLayout solution");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private JPanel createPanel1(String text) {
JPanel pnl = new JPanel(new MigLayout());
pnl.add(new JButton("A"));
pnl.add(new JButton("B"));
pnl.add(new JButton("C"));
pnl.add(new JButton("D"));
pnl.setBorder(BorderFactory.createTitledBorder(text));
return pnl;
}
private JPanel createPanel2(String text) {
JPanel pnl = new JPanel(new MigLayout());
pnl.add(new JButton("E"));
pnl.add(new JButton("F"));
pnl.add(new JButton("G"));
pnl.add(new JButton("H"));
pnl.setBorder(BorderFactory.createTitledBorder(text));
return pnl;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
MigLayoutSolution ex = new MigLayoutSolution();
ex.setVisible(true);
}
});
}
}
The first picture shows two panels with plenty of empty space.
The second picture shows the panels in their minimal size.

JLabel alignment in JPanel

I'm trying to align a JLabel to the right in a JPanel. I'm adding a JTabbedPane, a JPanel which contains my JLabel and JTextArea to a main JPanel.
I have searched SO and tried some methods like setAlignmentX, setHorizontalAlignment(SwingConstants.LEFT) and nested containers to no avail.
Here's my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class LabelProblem
{
public static void main(String[] args)
{
JFrame frame = new JFrame("Label Problem");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel Main = new JPanel();
Main.setLayout(new BoxLayout(Main, BoxLayout.Y_AXIS));
JPanel ComponentPanel = new JPanel();
JLabel label = new JLabel("Sample Text");
label.setHorizontalAlignment(SwingConstants.LEFT);
label.setBorder(BorderFactory.createLineBorder(Color.BLACK));
label.setAlignmentX(Component.RIGHT_ALIGNMENT);
ComponentPanel.add(label);
JTabbedPane Tab = new JTabbedPane();
Tab.add("Document 1", new JPanel());
Main.add(Tab);
Main.add(ComponentPanel);
JTextArea Area = new JTextArea(10,10);
JScrollPane Scroll = new JScrollPane(Area);
frame.add(Main);
frame.add(Scroll, BorderLayout.SOUTH);
frame.setSize(450,450);
frame.setVisible(true);
}
}
How can I align my JLabel to the right?
Thanks!
So, the place of that label is determined by the layout of ComponentPanel. Since you didn't specify any layout it is using the default FlowLayout with a CENTER alignment. Assuming that you are ok with a FlowLayout it is a mere question of setting the alignment of the LEFT since this is possible with this layout.
Here's the code with the fix, however I suspect that as you put more elements to the ComponentPanel you will want to use another layout since FlowLayout is more adequate for menus and the like and not for displaying the main content.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FlowLayout;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
class LabelProblem
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
initGUI();
}
});
}
public static void initGUI()
{
JFrame frame = new JFrame("Label Problem");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel main = new JPanel();
main.setLayout(new BoxLayout(main, BoxLayout.Y_AXIS));
JPanel componentPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
JLabel label = new JLabel("Sample Text");
label.setBorder(BorderFactory.createLineBorder(Color.BLACK));
componentPanel.add(label);
JTabbedPane Tab = new JTabbedPane();
Tab.add("Document 1", new JPanel());
main.add(Tab);
main.add(componentPanel);
JTextArea area = new JTextArea(10, 10);
JScrollPane scroll = new JScrollPane(area);
frame.add(main);
frame.add(scroll, BorderLayout.SOUTH);
frame.setSize(450, 450);
frame.setVisible(true);
}
}
Result:
Note: I also changed the variable names to follow the java style convention: variable names should start with lower case to differenciate them from clases names, starting in upper case.
One simple approach is to set the label's horizontalAlignment to JLabel.RIGHT in the constructor.
import java.awt.*;
import javax.swing.*;
class LabelProblem {
public static void main(String[] args) {
JFrame frame = new JFrame("Label Problem");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(0, 1));
JTabbedPane tab = new JTabbedPane();
tab.add("Document 1", new JPanel());
frame.add(tab);
JLabel label = new JLabel("Sample Text", JLabel.RIGHT);
frame.add(label);
JTextArea area = new JTextArea(10, 10);
JScrollPane scroll = new JScrollPane(area);
frame.add(scroll);
frame.pack();
frame.setSize(450, 450);
frame.setVisible(true);
}
}
I think it may be a matter of you not actually setting layouts where you imagine you're setting layouts.
You have a JPanel with a vertically oriented BoxLayout (Main) enclosing another JPanel with default layout (ComponentPanel), finally enclosing your label. The reason why your label can't be pushed to the right is because is already is pushed to the right within it's enclosing container. If you set a colored border around ComponentPanel, you'll see what I mean -- it only occupies the same amount of space as the JLabel, giving the JLabel nowhere to move.
You need to set a layout and constraints for your intermediate ComponentPanel, allowing it to horizontally fill its parent container so that the label has someplace to go.
You haven't really specified how your layout is supposed to look, but if you change the layout on Main to X_AXIS, your label will pop over to the left (as will its parent container). Without knowing what you're really trying to do, I can't say much more.
I would however, suggest you throw your BoxLayout away entirely and look into using GridBagLayout, which gives you a high level control over your UI. GridBagLayout isn't the most concise construct, but that's the price of control.

Make JPanel size of JFrame?

I've been staring at my code for hours, and I've cut out almost everything down to the simplest bits and I don't know how to make a JPanel expand to the size of the frame. Ideally (in the end) I'd like a container panel with a north and south content panels. The north panel needs to take up whatever space is leftover once the south panel is placed.
For now, though, I have a tiny red speck that is only as big as its content. Can someone give me some insight into what I am doing fundamentally wrong?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class TestCode extends JFrame {
private DescriptionPanel window = new DescriptionPanel();
public static void main(String[] args){
TestCode frame = new TestCode();
frame.pack();
frame.setTitle("Grape Project");
frame.setLocationRelativeTo(null);
frame.setSize(400, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public TestCode(){
add(window);
}
}
And the DescriptionPanel class:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DescriptionPanel extends JPanel{
private JPanel container = new JPanel();
public DescriptionPanel(ImageIcon pic, JLabel text){
container.setBackground(Color.red);
add(container);
}
}
This is a typical BorderLayout scenario.
By default, JPanels have a FlowLayout already set, so you need to call setLayout, or you can initialize your DescriptionPanel with the proper layout manager :
super(new BorderLayout());
// setLayout(new BorderLayout());
add(top, BorderLayout.CENTER); // take all available upper space left
add(bottom, BorderLayout.SOUTH); // take the vertical space specified
Set the LayoutManager to BorderLayout:
setLayout(new BorderLayout());

JPanel layout Issue

So I have a slight issue with adding two JPanels to a main main panel. I've put it as a quick example of what I want to do since you don't want to be looking through loads of lines of unnecessary code :). I want panel one to be added first (north) and then panel two (south). I've tried using Border layout and positioning them invoking north and south on BorderLayout when adding the panels but still no luck.
Thanks in advance.
private JPanel one,two;
public Example(){
one = new JPanel();
one.setSize(new Dimension(400,400));
two = new JPanel(new GridLayout(7,8));
two.setSize(new Dimension(400,400));
one.setBackground(Color.BLACK);
two.setBackground(Color.BLUE);
JPanel mainpanel = new JPanel();
mainpanel.setBackground(Color.orange);
mainpanel.add(one);
mainpanel.add(two);
add(mainpanel);
setSize(500,500);
setVisible(true);
}
If you want to use BorderLayout, then BorderLayout.CENTER takes up as much space as it can, and the other directions take only what they need. If you add extra stuff to the JPanels, they will get bigger, based on the needs of the objects they contain.
If you want to just divide the space evenly within the main JPanel, try this:
JPanel mainpanel = new JPanel(new GridLayout(2, 1));
That creates a GridLayout with 2 rows and 1 column...
Try this code. There was issue that apparently if you install grid layout on a panel and you add no components it will not take space.
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Example extends JFrame
{
private JPanel one, two;
public Example()
{
one = new JPanel();
two = new JPanel();///new GridLayout(7, 8));
one.setBackground(Color.BLACK);
two.setBackground(Color.BLUE);
JPanel mainpanel = new JPanel(new BorderLayout());
mainpanel.setBackground(Color.orange);
mainpanel.add(one, BorderLayout.NORTH);
mainpanel.add(two, BorderLayout.SOUTH);
setContentPane(mainpanel);
setSize(500, 500);
setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
Example f = new Example();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
});
}
}
GridLayout ignores the values set in setSize method of contained components. If you want to control the size of each component, consider using GridBagLayout.

Categories

Resources