I am using a BorderLayout for the frame (the first one that "caught" my attention in the tuts) and a FlowLayout for the labels (the one I found appropriate for what I do), and the result shows up like this:
My objective is to push the "2*1" a little bit down, to sort of "center" it.
I looked around and found a lot of people saying to use a null layout, but then saying it's not the best alternative (even though my window is not resizable), and the other solution I found was using a combo of layouts (unless I misunderstood).
The question is the one on top of this, plus if not, what really is the best alternative? (The following is the code that makes this window (minus the vars and other methods, to simplify visualization).
public Frame() {
super("Jogo de Multiplicar!");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new BorderLayout());
setSize(300, 200);
setResizable(false);
getContentPane().setBackground(pink);
mensagem = new TransparentPanel();
operacao = new TransparentPanel();
//added stuff in mensagem and operacao
add(operacao);
add(mensagem, BorderLayout.SOUTH);
}
My objective is to push the "2*1" a little bit down, to sort of "center" it.
If you just want more space at the top then you can use a Border:
operacao.setBorder( new EmptyBorder(...) );
Read the section from the Swing tutorial on How to Use Borders for more information.
If you want to actually center it you can use a BoxLayout:
Box box = Box.createVerticalBox();
box.add( Box.createVerticalGlue() );
box.add( topPanel );
box.add( Box.createVerticalGlue() );
box.add( bottomPanel );
The tutorial also has a section on How to Use BoxLayout. Search the table of contents.
You could use MigLayout as your only LayoutManager. It's pretty mighty and usually offers everything that the other managers do too.
With this it's pretty simple to center the components:
public class MultiplyExample extends JFrame{
private static final long serialVersionUID = 1L;
JLabel testLabel = new JLabel("2*2 = 4");
public MultiplyExample(){
super("Example");
setBounds(300, 50, 200, 200);
// Set the MigLayout, so that columns and then rows get centered
setLayout(new MigLayout("center, center"));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(testLabel);
}
public static void main(String[] args) {
JFrame testFrame = new MultiplyExample();
testFrame.setVisible(true);
}
}
Result:
Here is a demo what the MigLayout has to offer:
http://www.miglayout.com/swingdemoapp.jnlp
Here is a quickstart-guide:
http://www.miglayout.com/QuickStart.pdf
If you have to use BorderLayout, you could put your components onto another panel and put this one into the center by using BorderLayout.CENTER:
pane.add(button, BorderLayout.CENTER);
Related
I have a JPanel. Inside Panel I have kept one JLabel and three JCheckBox.
I want to keep all the checkBox in one line after JLabel. Here is the sample code and some screenshots.
Output 1
Output 2
When i change to X_AXIS it is coming everything in one line and when i switch to Y_AXIS then it is coming new line means vertically.
But my requirement is all the checkbox should come next line means after JLabel.
JLabel should come in line and all the checkBox should come in one line.
public class CheckBoxWithJLabel {
public static void main(String[] args) {
JFrame f= new JFrame("CheckBox Example");
JPanel panel = new JPanel();
panel.setBounds(40,80,600,200);
JCheckBox chk_Embrodary=new JCheckBox("Embrodary");
JCheckBox chk_Cutting=new JCheckBox("Cutting");
JCheckBox cb_Sewing=new JCheckBox("Sewing");
panel.setLayout(new javax.swing.BoxLayout(panel, javax.swing.BoxLayout.X_AXIS));
JLabel lblHeader=new JLabel("Job Work Process Selection");
panel.add(lblHeader);
panel.add(chk_Embrodary);
panel.add(chk_Cutting);
panel.add(cb_Sewing);
f.add(panel);
f.setSize(600,400);
f.setLayout(null);
f.setVisible(true);
}
}
I want this output like
this
How to solve this problem?
I would highly suggest you to have a look through the Java Swing Tutorial, especially the Laying Out Components Within a Container section, since it seems you lack some basic understanding of how Swing and its Layout Managers are supposed to be used.
Regarding your problem:
Currently, you are using a single BoxLayout, which " puts components in a single row or column". You only want that behavior for your JCheckBoxes though, and not for your JLabel. Keeping this in mind, the solution is to split up your components and to not put all of them in a single JPanel. Doing this will grant you more flexibility in how you design your GUI, since you can use multiple layouts in different nested panels.
You could do something like this (explanation in the code comments):
public static void main(String[] args) {
JFrame f = new JFrame("CheckBox Example");
// add a Y_AXIS boxlayout to the JFrames contentpane
f.getContentPane().setLayout(new BoxLayout(f.getContentPane(), BoxLayout.Y_AXIS));
JCheckBox cbEmbrodary = new JCheckBox("Embrodary");
JCheckBox cbCutting = new JCheckBox("Cutting");
JCheckBox cbSewing = new JCheckBox("Sewing");
// no need to set the bounds, since the layoutmanagers will determine the size
JPanel labelPanel = new JPanel(); // default layout for JPanel is the FlowLayout
JLabel lblHeader = new JLabel("Job Work Process Selection");
labelPanel.add(lblHeader); // JPanel for the label done
// JPanel for the comboboxes with BoxLayout
JPanel cbPanel = new JPanel();
cbPanel.setLayout(new BoxLayout(cbPanel, BoxLayout.X_AXIS));
cbPanel.add(cbEmbrodary);
cbPanel.add(cbCutting);
cbPanel.add(cbSewing);
f.add(labelPanel);
f.add(cbPanel);
// No need to set the size of the JFrame, since the layoutmanagers will
// determine the size after pack()
f.pack();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
Output:
Sidenotes:
Don't set fixed sizes via setSize() or setBounds() to your components. Swing is designed to be used with appropariate LayoutManagers, and if you do that, calling pack() on the JFrame before setting it visible will layout the components and determine their appropriate size. (Also, don't use null-layout for the same reasons)
If you need the JLabel to not be centered but left aligned, like in your screenshot, then use the following:
FlowLayout layout = (FlowLayout) labelPanel.getLayout();
layout.setAlignment(FlowLayout.LEFT);
I have done tons of searching over the past two hours, and I've given up. The image below shows what I am trying to achieve (don't judge my drawing it's late and I made it in paint quickly):
Basically, I want a JScrollPane to have a JPanel with a 2-column GridLayout, and as I add elements I want the GridLayout to expand downward. I want the elements to use their Preferred Size and to NOT expand within the GridLayout.
Currently I have a JScrollPane and a JPanel with a GridLayout, and a JPanel containing the grid with a FlowLayout. As a test, I add 10 buttons to the grid. Here's my current code:
// Setup main panel
JPanel pnlUsers = new JPanel(new GridLayout(0, 2));
pnlUsers.setOpaque(true);
pnlUsers.setBackground(Color.GREEN);
// Setup GridLayout Container
JPanel pnl2 = new JPanel();
pnl2.setOpaque(false);
pnl2.add(pnlusers);
// Setup scrollpane
JScrollPane scrUsers = new JScrollPane(pnl2);
scrUsers.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scrUsers.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrUsers.setOpaque(false);
scrUsers.getViewport().setOpaque(false);
scrUsers.setBorder(null);
// Add users
for (int i = 0; i < 10; i++) {
pnlUsers.add(new JButton("Button " + (i + 1));
}
This gives a very good result, with the buttons using their preferred size as seen in the image below:
Unfortunately, the buttons are still not filling the horizontal space. So, I attempted to make pnl2 a BoxLayout instead and add some vertical glue...
// Setup GridLayout Container
JPanel pnl2 = new JPanel();
pnl2.setLayout(new BoxLayout(pnl2, BoxLayout.Y_AXIS));
pnl2.setOpaque(false);
pnl2.add(pnlusers);
pnl2.add(Box.createVerticalGlue());
I also created my own temporary button class that sets the preferred size to use the minimum size:
public class TempButton extends JButton {
public PLTempButton(String msg) {
super(msg);
this.setPreferredSize(this.getMinimumSize());
}
}
Which resulted in the following:
This is much better, but there's still a problem. If there are not enough buttons to cause the JScrollPane to scroll, the buttons height are not consistent and will resize as you resize the window vertically. Why?
Obviously when I add 100 buttons, they use their preferred size:
Maybe I'm just not understanding the differences between minimum, preferred and maximum size? But I want the buttons to use the height they're set even if there aren't enough to cause the scroll-pane to, well, scroll. What can I do to fix this?
1) How do I even get a GridLayout within a ScrollPane?
Create a JPanel
Apply a GridLayout to the JPanel
Wrap the JPanel in a JScrollPane
For example
JPanel panel = new JPanel(new GridLayout(0, 2));
JScrollPane scrollPane = new JScrollPane(panel);
// Add the scroll pane to what ever parent container you're using
2) How do I get said GridLayout to expand horizontally, including the added components?
That doesn't make sense with regards to all previous part of the question, you said "and have it slowly expand downward the more things I add"
Having said that, the "basic" answer is, you configure the GridLayout and let it do it's job. The above example is configured for 2 columns and n number of roes
3) How would I add a "margin" to the components?
That's a broad answer, you could:
Make use of the horizontal and vertical gap properties of the GridLayout
Use a compound layout and adjust the insets of the an appropriate layout manager (like GridBagLayout)
Recommendations
I would recommend reading through Laying Out Components Within a Container to get a better understanding of the layout managers.
Remember, you not stuck to using one.
I would also recommend reading through How to Use Scroll Panes as you're asking basic questions about the API which are better covered through the tutorials
The following mre demonstrates creating a JPanel with GridLayout warped by JScrollPane and setting its horizontal and vertival gaps.
The Jpanel is added using a BorderLayout (the default layout manager of JFrame content pane) which allows it to expand:
import java.awt.BorderLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class SwingMain {
private String text ="Growing ";
private JPanel grid;
private JFrame f;
SwingMain() {
creategui();
}
void creategui(){
f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationRelativeTo(null);
JButton addComponentBtn = new JButton("Add Component");
addComponentBtn.addActionListener(e-> addComponent());
f.add(addComponentBtn, BorderLayout.PAGE_START);
grid = new JPanel(new GridLayout(0, 2, 10, 10)); //any number of rows, 2 columns, H and V gap
f.add(new JScrollPane(grid), BorderLayout.CENTER);
f.pack();
f.setVisible(true);
}
void addComponent() {
grid.add(new JLabel(text) );
text +="."; //make text longer so JLable grows
f.pack();
}
public static void main(String[] args) {
new SwingMain();
}
}
I am a newbie, I have a question. I am trying to use Eclipse to write a Java windows application, in which I will have a main window, which will contain several things, like a dashboard sort of thing, and it will have buttons, for example to add a record to a database, and this button when pressed, will open a new relevant window on top.
I tried to start, I wrote this code in Java, and for some reason, the button is in the size of the frame...full screen ! How do I fix it ?
Can you suggest me better ideas for a design than what I specified ?
Thank you
public class MainClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
JFrame jfrm = new JFrame("Frame1");
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
jfrm.setSize(screenSize.width, screenSize.height);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel jlab = new JLabel("Hello");
jfrm.add(jlab);
JButton button = new JButton("Button");
button.setSize(new Dimension(50, 50));
button.setLocation(500, 350);
jfrm.getContentPane().add(button);
jfrm.setVisible(true);
}
Add a layout to the JFrame first. For example FlowLayout:
jfrm.setLayout(new FlowLayout());
"I tried to start, I wrote this code in Java, and for some reason, the button is in the size of the frame...full screen ! How do I fix it ?"
The reason the button stretches is because JFrame has a default BorderLayout that does not respect the preferred sizes of child components.
The solution is to set the Layout Manager to layout that does respect preferred sizes. The image blow from this example shows the most common Layout Managers and show visually which one respect the preferred size of child components.
Also, the BorderLayout is also the reason your JLabel does not show. By default, every component that is added to a BorderLayout without a position specified e.g. BorderLayout.SOUTH, will automatically be placed in the BorderLayout.CENTER position. Each position may only have one component. So when you add the JLabel it goes to the CENTER, but when you add the JButton, it also goes the CENTER, kicking out the JLabel.
If you've never encountered Layout Managers, this is probably all confusing to you. You should take the time to go over How to Layout Components Within a Container
You need to use some form of layoutmanager, you can use this information: http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html
You must use Layout manager.
Use this code..
public static void main(String[] args)
{
JFrame jfrm = new JFrame("Frame1");
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
jfrm.setSize(screenSize.width, screenSize.height);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel jlab = new JLabel("Hello");
jfrm.add(jlab);
JButton button = new JButton("Button");
button.setSize(new Dimension(50, 50));
button.setLocation(500, 350);
jfrm.add(button);
jfrm.setVisible(true);
jfrm.setLayout(new FlowLayout());
jfrm.pack();
you forgot to add pack(). so use this code to get Jlabel and JButtion side by side.
Thanks...
The default JLabel draws its text at the middle of its bounds. For example, if height of the label is 20, font height is 14, the Y coordinate would be (20 - 14)/2 = 3. Like this:
What should I do if want to align the text to the TOP of the JLabel bounds? Like this:
UPD:
public class LabelTest extends JFrame {
public LabelTest() {
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setSize(500, 500);
setLocationRelativeTo(null);
JPanel contentPanel = new JPanel();
contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.X_AXIS));
contentPanel.add(Box.createHorizontalStrut(10));
final JLabel label1 = new JLabel("JLabel");
label1.setVerticalAlignment(SwingConstants.TOP); // by the answer of Kevin Workman, doesn't help
label1.setBorder(BorderFactory.createLineBorder(Color.RED));
label1.setFont(new Font("Arial", Font.PLAIN, 14));
contentPanel.add(label1);
setContentPane(contentPanel);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new LabelTest();
}
});
}
}
You should be packing the frame. If you so this, there should be no unused space in the label. If you want empty space, use an empty border
label.setBorder(new EmptyBorder(0, 0, 5, 0));
top, left, bottom, right
Also, don't set sizes, Use Layout Mangers and let them do the sizing for you. Setting sizes will give you. Setting sizes will give you a rigid look that may look and perform differently on different platforms. Layout Managers will allow your GUI to be more fluid and adaptable to different environments.
See Laying out Components Within a Container for more information on working with layouts
Also see Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?
As always, the API is your best friend: http://docs.oracle.com/javase/7/docs/api/javax/swing/JLabel.html#setVerticalAlignment(int)
Edit- Based on your updated SSCCE, the problem is that your BoxLayout is shrinking the JLabel as small as it will go, so the vertical text position doesn't really matter. Try using a BorderLayout to check that.
The problem is that the insets of the JLabel are adding a small space to the top and bottom of the JLabel, so your text looks centered even though it's at the top. Here's a fix for the insets problem: How to change gap in swing label
I have a class PanelTrial extends JPanel & implements GroupLayout. In it, I have a JTabbedPane namely jTabbedPane on left & another JPanel namely rightPanel on right. In rightPanel, I load 2 panels (namely compoPanel, btnsPanel) alternatively during runtime.
My Issue : Width of compoPanel, btnsPanel is different (and I want it to be different). Initially compoPanel (that is bigger in W) is loaded in the rightPanel. I am looking for is, when I load btnsPanel in rightPanel, I want the jTabbedPane's size to increase and occupy all free space. I update the PreferredSize of jTabbedPane & rightPanel - and their sizes also change. BUT location of rightPanel doesn't move to extreme right - this makes it in the middle of jTabbedPane.
Here is the code that I use :
orgTabDimen = new Dimension(350, 600);
newTabDimen = new Dimension(500, 600);
orgRghtDimen = new Dimension(280, 574);
newRghtDimen = new Dimension(50, 574);
private void updateRightPanel(boolean showBtnPanel) {
rightPanel.removeAll();
GroupLayout layout = (GroupLayout) rightPanel.getLayout();
if (showBtnPanel) {
// SHOW BTNSpANEL
layout.setHorizontalGroup(layout.createSequentialGroup()
.addComponent(btnPanel));
layout.setVerticalGroup(layout.createParallelGroup(
Alignment.TRAILING).addComponent(btnPanel));
// Set respective dimesions
rightPanel.setPreferredSize(newRghtDimen);
this.jTabbedPane1.setPreferredSize(newTabDimen);
} else {
// SHOW COMPOpANEL
layout.setHorizontalGroup(layout.createSequentialGroup()
.addComponent(compoPanel));
layout.setVerticalGroup(layout.createParallelGroup(
Alignment.TRAILING).addComponent(compoPanel));
rightPanel.setPreferredSize(orgRghtDimen);
this.jTabbedPane1.setPreferredSize(orgTabDimen);
}
jPanel1.validate();
this.validate();
}
Can anyone help me solve this issue - am stuck up here. Can't figure out a way where the btnsPanel shows up on extreme right. I even tried with calling invalidate(), but that also didn't help me.
Any help is highly appreciative.
Thanks