swing flow layout break element - java

I have panel which is using flow layout.
How can I make break in flow layout? Like <br/> in html. Some special break element or another trick to indicate that specified element and all subsequent have to go to the next line.

In a case like this, I'd put two containers with flowlayout one on top of each other inside a BoxLayout. Nesting layouts is fairly inexpensive.

The Wrap Layout might be a solution for you. It automatically moves components to the next line when a line is full.

You want to manually divide the components in multiple rows? So you know where you want the linebreak to be.
In that case I would use 3 panels:
1 panel containing the other 2 panels with a GridLayout with 1 column
2 panels inside the GridLayout, each with a FlowLayout
Example code:
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
{
panel = new JPanel();
frame.getContentPane().add(panel, BorderLayout.NORTH);
panel.setLayout(new GridLayout(0, 1, 0, 0));
{
panel_1 = new JPanel();
panel.add(panel_1);
{
lblPanelFlowlayout = new JLabel("Panel 2: FlowLayout");
panel_1.add(lblPanelFlowlayout);
}
}
{
panel_2 = new JPanel();
panel.add(panel_2);
{
lblPanel = new JLabel("Panel 3: FlowLayout");
panel_2.add(lblPanel);
}
}
}
You can add as many new Panels with a FlowLayout as you want. Each time you would do a BR you now set the next panel as active (possibly creationg it dynamically).

I don't think that is possible in a flow layout, you might want to try another layout like GridLayout or GridBagLayout

I'd make multiple placeholder panels with no insets, and then use some code to work out when a component needs to be moved to the next panel because it's below a minimum width threshold. It's ugly, but it should work. You'd need to do all the removal and addition by hand, and within the EDT.

Related

How to Keep JCheckBox Horizontally inside JPanel

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);

Position of buttons in rows, in a JPanel based 'menu bar'

I'm trying Swing programming but I can't do what I want.
I would like to place a top bar button with 2 lines of button but I just have 1 line in my case.
Here is my code:
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
setMinimumSize(new Dimension(1000,500));
setMaximumSize(new Dimension(1000,500));
JPanel panelButton = new JPanel();
JPanel panelTopButton = new JPanel();
JPanel panelBottomButton = new JPanel();
panelTopButton.add(dashboard);
panelTopButton.add(journal);
panelTopButton.add(myPlans);
panelTopButton.add(myFavorites);
panelTopButton.add(shoppingCart);
panelBottomButton.add(profile);
panelBottomButton.add(notifications);
panelButton.add(panelTopButton, BorderLayout.NORTH);
panelButton.add(panelBottomButton, BorderLayout.SOUTH);
contentPane.add(panelButton,BorderLayout.NORTH);
//Display
setSize(400,120);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
I have this
And I want this
Can somebody help me?
You need one panel for each line.
Try to do this:
JPanel panelButtonsL1 = new JPanel();
JPanel panelButtonsL2 = new JPanel();
panelButtonsL1.add(dashboard);
panelButtonsL1.add(journal);
panelButtonsL1.add(myPlans);
panelButtonsL1.add(myFavorites);
panelButtonsL1.add(shoppingCart);
panelButtonsL2.add(profile);
panelButtonsL2.add(notifications);
The default layour of JPanel is FlowLayout. Bear in mind that layout is very important to work with swing component disposition.
Define the bottom panel as GridLayout.
JPanel panelButton = new JPanel(new GridLayout(2, 1)); // 2 rows x 1 column
panelButton.add(panelButtonsL1);
panelButton.add(panelButtonsL2);
Details of GridLayout you can find on API.
You can achieve that using a GridLayout: assign a GridLayout to panelButton with two rows and one column, and then add the two panels to it.
According to what you want there is a simpler alternative by continue using the default FlowLayout from the panel. It is more appropriate than using GridLayout since you wanted the last 2 buttons to move to the next row and center itself.
If you use GridLayout, the buttons at the next row are likely going to be directly below one of the buttons above. Here are 2 ways to get what you want.
Method 1. Reduce the width of the main panel holding your buttons:
Dosing so, you will have to add the main panel using BorderLayout.CENTER.
Method 2. Add the buttons to a sub-panel of smaller width and add it to the main panel. All your buttons will be added to the smaller sub-panel:

How to add jpanel to a specific cell of GridLayout

in the below code, i created a GridLayot with 3 rows and 3 columns, what i want to do is,,to add jpanel_1 into
a specifc cell of the Gridlayout, lets say in the grid cell number (2,3).
Code:
private void setUpGUI2() {
// TODO Auto-generated method stub
jFrame_2 = new JFrame("Border Demo");
GridLayout gridLayOut = new GridLayout(3,3);
jFrame_2.setLayout(gridLayOut);
jPanel_1 = new JPanel(new BorderLayout());
jPanel_2 = new JPanel(new BorderLayout());
jPanel_1.setBorder(BorderFactory.createTitledBorder("title"));
//jPanel_1.setBounds(30, 100, 110, 300);
jPanel_1.add(jLabel_Hello, BorderLayout.EAST);
jPanel_2.setBorder(BorderFactory.createLoweredBevelBorder());
//jPanel_2.setBounds(20, 50, 120, 80);
jPanel_2.add(jLabel_Hello, BorderLayout.SOUTH);
//jFrame_2.setBounds(0, 0, 600, 600);
jFrame_2.add(jPanel_1);//how to add jpanel_1 to a specific cell of Gridlayout defined above
//jPanel_1.add(jPanel_2);
jFrame_2.add(jPanel_2);
jFrame_2.pack();
jFrame_2.setVisible(true);
}
I think there is no chance. You need to add them one by one.
frame.add(...); frame.add(...);
I don't clearly understand what you want as result, but using GridLayout(3, 3) with only 2 panels is the same as use GridLayout(0, 2).
P.S. Check out GridBagLayout - it can be more useful for you.
Depending on what you want to do, you could add "dummy" components (like a JLabel) to the cells you don't want to use. If I recall correctly, GridLayout will layout in col/row order
So of you wanted to add a component to the second column on the second row, you would have to add four JLabel's first, do pad out the layout

How to control the size of the panels

I'm learning swing gui and I get this result when I use the following code:-
The code I use :-
private void initUI() {
JTextArea visualize=new JTextArea();
visualize.setEditable(false);
//DEFINE BUTTONS....
JButton[] buttons1={addition,subtraction,division,multiplication};
JButton [] buttons2={expr,date,conversion};
JPanel numerical=new JPanel(new FlowLayout());
numerical.setPreferredSize(new Dimension(350, 50));
for(int i=0;i<buttons1.length;i++){
numerical.add(buttons1[i]);
}
numerical.setBorder(new TitledBorder("Numerical Operations"));
JPanel nonnum=new JPanel(new FlowLayout());
nonnum.setPreferredSize(new Dimension(500, 50));
for(int i=0;i<buttons2.length;i++){
nonnum.add(buttons2[i]);
}
nonnum.setBorder(new TitledBorder("Non-numerical Operations"));
JPanel operations = new JPanel(new BorderLayout(2,2));
operations.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
operations.setSize(800, 100);
operations.add(numerical,BorderLayout.WEST);
operations.add(nonnum,BorderLayout.EAST);
JTable sheet = new JTable(10,5);
add(visualize, BorderLayout.NORTH);
add(sheet,BorderLayout.SOUTH);
add(operations,BorderLayout.CENTER);
pack();
setSize(1000, 700);
setTitle("Spreadsheet Application");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
But what I really want is this:-
My questions :-
Why is the operations panel too long?
How can I change it's height?
Doesn't "operations.setSize(..)" work?
Try using GroupLayout.
I'm also new to swing gui and had similar problems - GroupLayout saved the day
JPanel complete=new JPanel();
GroupLayout gl=new GroupLayout(complete);
complete.setLayout(gl);
gl.setAutoCreateContainerGaps(true);
gl.setHorizontalGroup(gl.createParallelGroup() //this is parallel bcz you need components vertically
.addComponent(visualize) //you MUST add components to both horizontal and vertical groups
.addComponent(operations)
.addComponent(sheet)
);
gl.setVerticalGroup(gl.createSequentialGroup() //NOTE that this is sequential
.addComponent(visualize)
.addComponent(operations)
.addGap(50) //you can add gaps if you want
.addComponent(sheet)
);
add(complete);
Because that's how BorderLayout works, take a closer look at How to Use BorderLayout. The CENTRE position will occupy all the remaining space of the frame, where as the NORTH and SOUTH positions will try and honour the preferred sizes of the components.
You could use a GridBagLayout, which will allow you more control over the layout or use a series of compound layouts.
Something like...
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.fill = GridBagConstraints.BOTH;
add(visualize, gbc);
add(operations, gbc);
gbc.gridy = 1;
add(sheet, gbc);
It is generally discouraged to extend from a top level container like JFrame, instead you should use something like JPanel to define your UIs and then add them to the containers you want. This increases there re-usability and makes it easier to use on different containers
You may also like to take a look at How to Use Scroll Panes
SOME of us find GridBagLayout to be a royal pain, and you may not have to use it to do what you want to do.
The idea behind a layout manager is to let the layout manager control the size and position of its components so that you don't have to futz with them. MP is right, GridBag allows you a lot of control, but that also means you have to get a lot of things right to have it do what you want it to do.
So, an alternative: Make a JPanel to hold the visualize and operations panels; give this new panel a BoxLayout with a Y_AXIS orientation, then add them in the order you want them to appear, top-to-bottom.
Then put sheet in the BorderLayout.CENTER of the JFrame. In fact, I think you'll want to take MP's advice and go through a tutorial on JScrollPane; as best I remember, you create the panel, then create the JScrollPane instance with the panel as a construction parameter, then add the scrollpane instance to the JFrame (in the CENTER, in your case).
Being in the center, it will then expand and contract as the user changes window size.
Good luck. Swing takes some getting used to.

Scrolling issue (Java-JFrame-JScrollBar)

INTRO:
I created a java application using JFrame. I have a JMenuBar at the top and under that I'd like to display rows of text.
PURPOSE:
When I have 50 rows and only 20 are displayable at once, I'd like to be able to scroll down and back up again.
PROBLEM:
Of course, my theory doesn't wanna work as it should. My problem is that I don't know how to add a vertical scroll properly.
QUESTION:
How should I change this code to reach my goal?
public void display(){
Container content = this.window.getContentPane();
content.setLayout(new BorderLayout());
Border border = LineBorder.createGrayLineBorder();
//this is just a sample
for(int i = 0;i<50;i++){
JLabel lab = new JLabel("lonyaladek");
lab.setSize(570, 20);
lab.setBorder(border);
lab.setLocation(10, 20+(i*25));
content.add(lab);
}
//scroll
JScrollBar sb = new JScrollBar(JScrollBar.VERTICAL, 0, 0, 0, 0);
content.add(sb);
}
First you need to start with a layout manager that allows you to add multiple components to the container. Maybe a GridLayout is the best place to start.
Then you add this container to the scrollPane and then you add the scrollpane to the window.
So the basic code would be:
JPanel panel = new JPanel( new GridLayout(0, 1) );
panel.add(...);
panel.add(...);
JScrollPane scrollPane = new JScrollPane( panel );
window.add(scrollPane, BorderLayout.CENTER);
I suggest you read the section from the Swing tutorial on How to Use Scroll Panes for more info.

Categories

Resources