java JPanel How to fixed sizes - java

I want to have a resizable panel, that always has the top green panel of a fixed depth. i.e. all changes in height should effect the yellow panel only.
My code below is almost OK, except the green panel varies in size a little.
How do I do this?
Panel.setLayout(new BoxLayout(Panel, BoxLayout.Y_AXIS));
Panel.setAlignmentX(Component.LEFT_ALIGNMENT);
JPanel TopPanel = new JPanel();
TopPanel.setPreferredSize(new Dimension(80,150));
TopPanel.setVisible(true);
TopPanel.setBackground(Color.GREEN);
JPanel MainPanel = new JPanel();
MainPanel.setPreferredSize(new Dimension(80,750));
MainPanel.setVisible(true);
MainPanel.setOpaque(true);
MainPanel.setBackground(Color.YELLOW);
Panel.add(TopPanel);
Panel.add(MainPanel);

Your question didn't restrict the solution to a BoxLayout, so I am going to suggest a different layout manager.
I would attack this with a BorderLayout and put the green panel in the PAGE_START location. Then put the yellow panel in the CENTER location without a preferredSize call.
http://docs.oracle.com/javase/tutorial/uiswing/layout/border.html
Here is an SSCCE example of the solution:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TestPad extends JFrame {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.getContentPane().setLayout(new BorderLayout());
JPanel green = new JPanel();
green.setPreferredSize(new Dimension(80, 150));
green.setBackground(Color.GREEN);
JPanel yellow = new JPanel();
yellow.setBackground(Color.YELLOW);
frame.getContentPane().add(green, BorderLayout.PAGE_START);
frame.getContentPane().add(yellow, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
}

If you make your Panel use BorderLayout instead of BoxLayout and put TopPanel in BorderLayout.NORTH and MainPanel in BorderLayout.CENTER, then they will both resize horizontally, but only the MainPanel will resize vertically.
See the BorderLayout documentation

Related

How to set width of specific panel with BoxLayout Manager

The code below places 3 JPanels inside a JFrame. I want the blue colored panel to have a width of 300 (assume the enclosing Frame has a width of greater than 300). The width of the other two panels should be the remainder. How do I do that?
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PanelTest extends JFrame {
private JPanel leftpanel;
public PanelTest() {
getContentPane().setLayout(new BoxLayout(this.getContentPane(), BoxLayout.X_AXIS));
this.leftpanel = new JPanel() {
#Override
public Dimension getMaximumSize() {
return new Dimension(300, 9999);
}
#Override
public Dimension getMinimumSize() {
return new Dimension(300, 0);
}
};
this.leftpanel.setBackground(Color.blue);
getContentPane().add(leftpanel);
JPanel rightpanel = new JPanel();
getContentPane().add(rightpanel);
rightpanel.setLayout(new BoxLayout(rightpanel, BoxLayout.Y_AXIS));
JPanel upperpanel = new JPanel();
upperpanel.setBackground(Color.red);
rightpanel.add(upperpanel);
JPanel lowerpanel = new JPanel();
lowerpanel.setBackground(Color.yellow);
rightpanel.add(lowerpanel);
pack();
setVisible(true);
setExtendedState(Frame.MAXIMIZED_BOTH);
}
public static void main(String[] args) {
new PanelTest();
}
}
I slightly updated the above code using #camickr's suggestion of using BorderLayout. The width is now as desired. Thanks #camickr.
I still think BoxLayout should have respected the minimum and maximum sizes. Taking those into consideration, it should have set the width to 500.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PanelTest extends JFrame {
public PanelTest() {
getContentPane().setLayout(new BorderLayout());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel leftpanel = new JPanel();
int width = 500;
leftpanel.setPreferredSize(new Dimension(width, 1));
leftpanel.setBackground(Color.blue);
getContentPane().add(leftpanel, BorderLayout.LINE_START);
JPanel rightpanel = new JPanel();
getContentPane().add(rightpanel, BorderLayout.CENTER);
rightpanel.setLayout(new BoxLayout(rightpanel, BoxLayout.Y_AXIS));
JPanel upperpanel = new JPanel();
upperpanel.setBackground(Color.red);
rightpanel.add(upperpanel);
JPanel lowerpanel = new JPanel();
lowerpanel.setBackground(Color.yellow);
rightpanel.add(lowerpanel);
pack();
setVisible(true);
setExtendedState(Frame.MAXIMIZED_BOTH);
}
public static void main(String[] args) {
new PanelTest();
}
}
The most important size of a component is the preferred size. Most layout managers will use this size first and then maybe use the minimum/maximum sizes depending on the space available.
If you don't specify a preferred size of the panel it will be (10, 10) since this is the default size of a panel using the FlowLayout when no components are added.
This size is outside the bounds of your minimum/maximum values so it appears the BoxLayout will then allocate space to each component in a ratio based on the maximum size of each panel. The blue panel has a size of 300 and the other panel has a size of Integer.MAX_VALUE so much more space gets allocated to the other panel.
One solution is to add:
leftpanel.setPreferredSize(new Dimension(300, 1));
I want the blue colored panel to have a width of 300
I would not change the content pane to use a BoxLayout and instead just use the default BorderLayout of the frame. Then you:
add the blue panel to the BorderLayout.LINE_START.
Add the panel containing the red/yellow components to the BorderLayout.CENTER.
The BorderLayout will respect the width of the blue panel and give the remaining space to the component in the center.
Using this approach there is no need to override the minimum/maximum values of the blue panel.
Of course you would still need to set the preferred size of the blue panel.

Jscrollpane center aligns when label is too small

This question is very similiar to this: JScrollPane doesn't top align when there is more than enough space to show the content I tried this solution, but it does not work.
When I add a jlabel to jscrollpane, when the jlabel is small, the label becomes centered. It works normally when the scrollbar shows. Setting boxlayout does not change anything. I feel like this isn't working properly because I'm setting a perferred size to the panel? But if I remove the line panel.setPreferredSize(new Dimension((int)(screenSize.width*0.7 - 50), screenSize.height-150)); The label becomes small when there is no text, and grows to accomdate text, which I don't want. If I add the panel instead of the label, it makes the screen scrollable even though there isn't text?
This is my code:
public class Test {
// JFrame
static JFrame frame = new JFrame("Test");
//panel 1
static JPanel panel = new JPanel(new BorderLayout());
// label to display text
static JLabel label = new JLabel();
//scroll panel in main method
public static void main(String[] args) throws Exception {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
label.setBorder(new EmptyBorder(5, 5, 5, 20));
label.setText("any text makes it centered beyond 40 lines");
//create panel
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.add(label, BorderLayout.NORTH);
panel.add(Box.createVerticalGlue());
panel.setPreferredSize(new Dimension((int)(screenSize.width*0.7 - 50), screenSize.height-150));
panel.setBorder(new EmptyBorder(5, 5, 5, 10));
JScrollPane jspanel = new JScrollPane(label, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
//jspanel.add(label, BorderLayout.CENTER);
jspanel.setPreferredSize(new Dimension((int)(screenSize.width*0.7 - 70), screenSize.height-180));
jspanel.getVerticalScrollBar().setUnitIncrement(20);
jspanel.setBorder(BorderFactory.createEmptyBorder());
jspanel.setAlignmentX(JScrollPane.LEFT_ALIGNMENT);
jspanel.setAlignmentY(JScrollPane.TOP_ALIGNMENT);
//panel.setPreferredSize(new Dimension(640, 480));
//frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(jspanel);
frame.setSize((int)(screenSize.width*0.7), screenSize.height - 50);
frame.revalidate();
frame.pack();
frame.setVisible(true);
}
}
jspanel.setAlignmentX(JScrollPane.LEFT_ALIGNMENT);
jspanel.setAlignmentY(JScrollPane.TOP_ALIGNMENT);
That will align the scrollpane in its parent container, depending on the layout manager being used. It does not affect the alignment of any component added to the scrollpane. It is not needed.
the label becomes centered
The label is sized to fill the entire space available, so you need to customize how the text of the label is painted.
If you don't want it centered then you can place it at the top using:
label.setVerticalAlignment( SwingConstants.TOP );
After reworking your code, I came up with the following GUI.
I added a call to the SwingUtilities invokeLater method. This method ensures that all Swing components are created and executed on the Event Dispatch Thread.
I eliminated all static references, except for the main method.
I reworked your code into methods so I could focus on one part of the GUI at a time.
Here's the complete runnable example. This is a minimal reproducible example.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
public class JScrollPaneTestGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new JScrollPaneTestGUI());
}
#Override
public void run() {
JFrame frame = new JFrame("JScrollPane Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JScrollPane jspanel = createJScrollPane();
frame.add(jspanel, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
private JScrollPane createJScrollPane() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBackground(Color.YELLOW);
panel.setPreferredSize(new Dimension(400, 300));
JLabel label = new JLabel();
label.setBorder(new EmptyBorder(5, 5, 5, 20));
label.setText("any text makes it centered beyond 40 lines");
//create panel
panel.add(label, BorderLayout.NORTH);
JScrollPane jspanel = new JScrollPane(panel);
return jspanel;
}
}

Add multiple jlabel on jpanel and on same line using box layout

Want to add two jlabel with some space on same line to jpanel, japnel layout is set to box layout,due to some constraints i can't change layout to another and property of box layout from Y_AXIS to LINE_AXIS, so please provide me with some solution, so i can put jlabel on same line..
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
So please let me know the solution for the same mentioned above.
Wrap your labels in a JPanel with a Border layout. Add one to the West panel and another to the East panel. Set the alignment of the JLabels as needed. Then add the JPanel to your box layout.
It looks like you believe you can't change the layout because you're dealing with the content pane of a JFrame and you don't want to change the rest of the window.
If that's the case, you can use nested layouts by adding the two JLabels to a separate JPanel (let's call it labelPanel) and adding that to the content pane. It would look something like this:
JPanel labelPanel = new JPanel();
labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.X_AXIS));
labelPanel.add(leftLabel);
labelPanel.add(Box.createGlue()); //creates space between the JLabels
labelPanel.add(rightLabel);
contentPane.add(labelPanel);
Try this out: JPanel with GridLayout, and JLabels left and right aligned. The frame is a Box still uses a box. What should interest you is the JPanel panel code. That's where I'm adding the labels. All you have to do is nest components and layouts
import java.awt.*;
import javax.swing.*;
import javax.swing.border.LineBorder;
public class TwoLabels extends JFrame{
public TwoLabels(){
Box box = Box.createVerticalBox();
JPanel panel = new JPanel(new GridLayout(1, 2));
panel.setBorder(new LineBorder(Color.black));
JLabel label1 = new JLabel("Hello");
JLabel label2 = new JLabel("World");
label1.setHorizontalAlignment(JLabel.LEADING);
label2.setHorizontalAlignment(JLabel.TRAILING);
panel.add(label1);
panel.add(label2);
box.add(new JPanel(){
public Dimension getPreferredSize(){
return new Dimension(300, 300);
}
});
box.add(panel);
add(box);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setVisible(true);
}
public static void main(String[] args) {
new TwoLabels();
}
}

Layout Manager preferredSize Java

I'm still trying to learn how layout managers work. I made a Frame with two JPanels.
The first one contains a textArea with a boxLayout.
The second one contains a flow layout with a button.
I set the preferredSize of each panel accordingly, packed them, but got unexpected results.
import java.awt.*;
import javax.swing.*;
public class LayoutMgrTest
{
public static void main(String[] args)
{
TableBasic frame = new TableBasic();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.setVisible(true);
frame.getContentPane().setLayout(new GridLayout(2,1));
JPanel controlPane = new JPanel();
JPanel buttonPane = new JPanel();
controlPane.setLayout(new BoxLayout(controlPane, BoxLayout.PAGE_AXIS));
controlPane.setPreferredSize(new Dimension(200, 200));
controlPane.add(new JScrollPane(new JTextArea()));
buttonPane.setLayout(new FlowLayout(FlowLayout.LEFT));
buttonPane.setPreferredSize(new Dimension(100,20));
buttonPane.add(new JButton("Button1"));
buttonPane.add(new JButton("Button2"));
frame.getContentPane().add(controlPane, BorderLayout.NORTH);
frame.getContentPane().add(buttonPane, BorderLayout.SOUTH);
frame.setSize(new Dimension(500,500));
frame.pack();
}
}
Whatever I do, if I use a grid Layout, it seems to always allocate half of the available space to each control. I have been told that:
The height of each row is dependent on the height of each component
added in each row.
The buttonpane's height is 20. It's allocating much more than that to it:
What's wrong with this code?
I would like to leave the two JPanels intact please. It's easy to simply add the textbox and the buttons directly to the frame, but I need to do it with JPanels (because I will be adding borders and other things).
That's the result of using GridLayout as layout manager. Change it to BorderLayout:
frame.getContentPane().setLayout(new BorderLayout());
For example, this code (I changed a little as possible from the original):
import java.awt.*;
import javax.swing.*;
public class LayoutMgrTest
{
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
//frame.setVisible(true);
//frame.getContentPane().setLayout(new BorderLayout());
JPanel controlPane = new JPanel();
JPanel buttonPane = new JPanel();
controlPane.setLayout(new BoxLayout(controlPane, BoxLayout.PAGE_AXIS));
controlPane.setPreferredSize(new Dimension(200, 200));
controlPane.add(new JScrollPane(new JTextArea()));
buttonPane.setLayout(new FlowLayout(FlowLayout.LEFT));
buttonPane.setPreferredSize(new Dimension(100,40));
buttonPane.add(new JButton("Button1"));
buttonPane.add(new JButton("Button2"));
frame.add(controlPane, BorderLayout.NORTH);
frame.add(buttonPane, BorderLayout.SOUTH);
//frame.setSize(new Dimension(500,500));
frame.pack();
frame.setVisible(true);
}
}
Generates this frame:
I set the preferredSize of each panel accordingly,
That is another problem. You should NOT set the preferred size. That is the job of the layout manager. Just add your components to the panels and let the layout manager do its job.
Most compnents have a default preferred size. For some you need to give it a little tip.
For example when using a text area you would give a "suggested" preferred size by using:
JTextArea textArea = new JTextArea(rows, columns);
If you use LayoutManager, you should not set a size on a component except the frame.
the size for the components is calculated from the different layout managers.
you find more infos at http://download.oracle.com/javase/tutorial/uiswing/layout/howLayoutWorks.html
in your code, you can add the panel with the textarea to BorderLayout.CENTER. this should solve your problem. the component in BorderLayout.CENTER takes the whole space, except the space needed for the components in NORTH, EAST, SOUTH and WEST.

Add JTabbedPane with buttons, labels ... in a frame with an absolute layout

I have a code in java.
package interfaces;
import javax.swing.JPanel;
public class TabbedPaneDemo extends JPanel {
public TabbedPaneDemo() {
JTabbedPane pane = new JTabbedPane();
JPanel dashboardPanel = new JPanel();
dashboardPanel.add(new JLabel("Dashboard"));
// Add Dashboard Tab
pane.addTab("Dashboard", dashboardPanel);
JPanel transactionPanel = new JPanel();
transactionPanel.add(new JLabel("Transactions"));
// Add Transactions Tab
pane.addTab("Transactions", transactionPanel);
JPanel accountPanel = new JPanel();
accountPanel.add(new JLabel("Account"));
// Add Account Tab
pane.addTab("Account", accountPanel);
this.setLayout(new BorderLayout());
this.setPreferredSize(new Dimension(400, 200));
this.add(pane, BorderLayout.CENTER);
}
public static void main(String[] args) {
JPanel panel = new TabbedPaneDemo();
panel.setOpaque(true);
// panel.setBounds(12, 12, 45, 98);
JFrame frame = new JFrame("JTabbedPane Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(panel);
frame.pack();
frame.setVisible(true);
}}
and the output it's !
I want to change in this code to be like this.
I want to use an absolute layout (null).
I want to add menu, buttons and labels with these tabs ...
How can I do??
You should NOT use absolute layout. There is not reason to use absolute layout.
Instead you should use layout managers.
Maybe create a panel and add buttons to the panel. Then add the panel to the NORTH of the content pane. The tabbed pane would be added to the CENTER.
Read the Swing tutorial on Using Layout Managers.

Categories

Resources