FlowLayout or BoxLayout? in JAVA - java

I try to do this:
but if I use GridLayout, the heigth is bery small
PanelPost.setLayout(new GridLayout(20, 1, 0, 12));
for(int y=0;y<15;y++){
JPanel p=new JPanel();
p.setBackground(Color.RED);
p.setLayout(null);
p.setSize(PanelPost.getWidth(),150);
PanelPost.add(p);
}
if I use FlowLayout, only displays some points
With BoxLayout
setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
the panels are in the center and the width and height are not respected
and if i use setLayout(null) the scroll does not work then
What is the best way to do this? :C

Your problem starts here -> p.setLayout(null);. GridLayout will use the preferredSize of the components to determine the cell sizes it wants to use. This value is determine by the panel's layout manager...which you've now discarded...
Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Scrollable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(new ListOfStuffPane()));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ListOfStuffPane extends JPanel implements Scrollable {
public ListOfStuffPane() {
setLayout(new GridLayout(20, 1, 0, 12));
for (int y = 0; y < 15; y++) {
JPanel p = new JPanel(new FlowLayout(FlowLayout.LEFT));
p.setBackground(Color.RED);
p.add(new JLabel("Boo"));
add(p);
}
}
#Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(100, 200);
}
#Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 128;
}
#Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 128;
}
#Override
public boolean getScrollableTracksViewportWidth() {
return true;
}
#Override
public boolean getScrollableTracksViewportHeight() {
return false;
}
}
}
See Laying Out Components Within a Container for more details

You can use BoxLayout to solve this issue. Let me explain. First of all, let's consider your scenario; you want a scrollable list, right ? with components having fixed height, but varying width (since you had used the container's getWidth() as the width). So, for creating some thing "Scrollable", you need a ScrollPane in Java. JScrollPane is the preferred scrollable container. Now set this JScrollPane as the basecontainer. Now create a new JPanel object with the BoxLayout set as having Y_AXIS orientation. Now set this newly created JPanel object as the viewport of the JScrollPane container. So, by here, we had created a scrolling container.
Next step is what you mentioned in your code sample, ie adding 'post' elements. For that just as you did, inside the for loop create each JPanel objects. But instead of using setSize() method, you should use setPreferredSize(new Dimension(w,h)) method. This forces your components to render according to the dimension specified. For inserting vertical gaps between each post objects, you can use java.awt.Box class's createVerticalStrut(int height) method. I am giving the code below. Feel free to ask if you have any doubt. :)
import java.awt.*;
import javax.swing.*;
public class LinkedInLayout extends JFrame{
public LinkedInLayout(){
setTitle("Linked In Layout Resolution");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setBounds(0,0,500,520);
JPanel postPane = new JPanel(new FlowLayout(FlowLayout.LEADING));
JScrollPane container = new JScrollPane(postPane,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
setContentPane(container);
postPane.setLayout(new BoxLayout(postPane,BoxLayout.Y_AXIS));
for(int y=0;y<15;y++){
postPane.add(Box.createVerticalStrut(35));
JPanel p=new JPanel();
p.setBackground(new Color(247,221,221));
p.setLayout(null);
p.setPreferredSize(new Dimension(postPane.getWidth(),75));
postPane.add(p);
}
setVisible(true);
}
public static void main(String[] args) {
new LinkedInLayout();
}
}

Related

Setting JPanel background while using BoxLayout

I am developing a simple application, and am currently working on the gui design using Swing. In my program I have a JPanel which I would like to have a background color black like so:
JPanel playerPanel = new JPanel();
playerPanel.setOpaque(true);
playerPanel.setBackground(Color.BLACK);
This code works fine. However, the problem is when I assign a Layout Manager to the panel:
JPanel playerPanel = new JPanel();
playerPanel.setOpaque(true);
playerPanel.setBackground(Color.BLACK);
playerPanel.setLayout(new BoxLayout(playerPanel, BoxLayout.PAGE_AXIS));
For some reason, this makes the black color of the panel go away. This happens no matter where I place the .setLayout(...) command, before or after the .setBackground(...) and .setOpaque(true).
Why is this, and how do I work around this? How do I keep a black JPanel that uses a BoxLayout manager?
Verify that your panel's content is not obscuring the altered background. Resize the example below, which I've artificially enlarged, to see the effect.
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.Random;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
* #see https://stackoverflow.com/a/57785802/230513
*/
public class BoxTest {
public static final Random random = new Random();
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new BoxTest().create();
}
});
}
void create() {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setBackground(Color.BLACK);
panel.add(Box.createVerticalGlue());
for (int i = 0; i < 4; i++) {
panel.add(new VariablePanel());
panel.add(Box.createVerticalGlue());
}
JFrame f = new JFrame("BoxTest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(panel);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
f.setSize(f.getWidth(), f.getHeight() + 64);
}
}
/**
* A VariablePanel has a label showing its current size,
* as well as a variable number of text items.
*/
class VariablePanel extends JPanel {
private static final String text =
"Sed ut perspiciatis unde omnis iste natus error sit.";
private final JLabel sizeLabel = new JLabel("Size:");
public VariablePanel() {
this.setLayout(new GridLayout(0, 1));
this.add(sizeLabel);
int count = BoxTest.random.nextInt(5) + 1;
for (int i = 0; i < count; i++) {
this.add(new JLabel(text));
}
this.addComponentListener(new ComponentAdapter() {
#Override
public void componentResized(ComponentEvent e) {
int w = e.getComponent().getWidth();
int h = e.getComponent().getHeight();
sizeLabel.setText("Size: " + w + "\u00d7" + h);
}
});
}
}
Swing components (except JLabel) are opaque by default. This means:
you don't need playerPanel.setOpaque(true)
most components you add to the panel will be opaque and cover the background of your playerPanel.
Also, the BoxLayout respects the maximum size of any component you add to the panel. So if you add a component:
like a JButton which has a defined maximum size, you will see the button on top of the playerPanel and the background will surround the button.
like a JPanel, which does not have a defined maximum size, the panel will be resized to fill the entire area of the playerPanel and you won't see the background of the playerPanel.
If you want to see the background of the playerPanel show through a component added to the playerPanel, then you need to use setOpaque(false) on the component. For example:
JPanel child = new JPanel();
child.setOpaque( false );
playerPanel.add( child );

Java problems with gif in label

A gif that I tried to put into a JPanel isn't showing up after clicking the button that triggers it until I resize the window. When it does show up, it does not fit the JPanel and is not animated. I looked at several posts that dealt with this but I don't understand how to use them in my case.
/*
* Author: Raymo111
* Date: 13/04/2018
* Description: Wishes happy birthday to a special someone
*/
//Imports java GUI classes
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
// Main class with JFrame and ActionListener enabled
public class Happy_Birthday_GUI extends JFrame implements ActionListener {
// Class variables
private static JButton startButton = new JButton("CLICK TO START");
private static JPanel startPanel = new JPanel(), gifPanel = new JPanel();
private static Color blue = new Color(126, 192, 238), pink = new Color(255, 192, 203);
private static GridLayout grid1 = new GridLayout(1, 1);
// Constructor
public Happy_Birthday_GUI() {
// Initial screen
startButton.addActionListener(this);
startButton.setFont(new Font("Comic Sans MS", Font.PLAIN, 50));
startPanel.setLayout(grid1);
startPanel.add(startButton);
startPanel.setBorder(BorderFactory.createLineBorder(blue, 100));
startButton.setBackground(pink);
getContentPane().add(startPanel);
// Sets title, size, layout (grid 1x1), and location of GUI window (center)
setTitle("Happy Birthday from Dolphin");
setSize(840, 840);
setLayout(grid1);
setLocationRelativeTo(null);
setVisible(true);
}
// Main method
public static void main(String[] args) {
new Happy_Birthday_GUI();
}
// Action Performed method
public void actionPerformed(ActionEvent event) {
// Proceed to gif and song
if (startButton == event.getSource()) {
getContentPane().removeAll();
BufferedImage dolphin;
gifPanel.setLayout(grid1);
gifPanel.setBorder(BorderFactory.createLineBorder(pink, 100));
try {
dolphin = ImageIO.read(new File("C:\\Users\\raymo\\Pictures\\dolphin.gif"));
JLabel gifLabel = new JLabel(new ImageIcon(dolphin));
gifPanel.add(gifLabel);
} catch (IOException e) {
e.printStackTrace();
}
getContentPane().add(gifPanel);
}
}
}
Here is dolphin.gif. It's cute.
How do I get it to show up immediately after clicking the start button as an animated gif that fits the JPanel? Thanks in advance.
BufferedImage doesn't support painting animated Gifs, instead, you'll need to make use of Image (or preferably, ImageIcon).
This could then be applied directly to a JLabel, which will perform the animation operation itself.
animated gif that fits he JPanel?
Okay, that's a much more complex problem. One approach would be to convert the Gif to the required size, but needless to say, that's very, very complex.
A simpler solution might be to use a AffineTransform and scale the image to meet the requirements of the component itself. This would require a custom component, capable of calculating the scale and painting each frame of the image.
Luckily for you, JPanel is an ImageObserver, this means it's capable of painting the gif animation
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private ImageIcon image;
public TestPane() {
image = new ImageIcon("/Users/swhitehead/Downloads/NbENe.gif");
}
#Override
public Dimension getPreferredSize() {
return new Dimension(600, 600);
}
#Override
protected void paintComponent(Graphics g) {
int imageWidth = image.getIconWidth();
int imageHeight = image.getIconHeight();
if (imageWidth == 0 || imageHeight == 0) {
return;
}
double widthScale = (double)getWidth() / (double)imageWidth;
double heightScale = (double)getHeight() / (double)imageHeight;
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(image.getImage(), AffineTransform.getScaleInstance(widthScale, heightScale), this);
g2d.dispose();
}
}
}
I tried to put into a JPanel isn't showing up after clicking the button
When you add (or remove) components from a visible GUI the basic code is:
panel.add(...);
panel.revalidate();
panel.repaint();
The revalidate() is need to invoke the layout manager so the component is given a size.
is not animated.
Use a JLabel with an ImageIcon to display images. A JLabel will animated the gif.
When it does show up, it does not fit the JPanel and
You can try the Stretch Icon which is designed to fill the space available to the label.
I ended up doing:
gifPanel.add(new TestPane());
getContentPane().add(gifPanel);
revalidate();
repaint();
using camickr's revalidate and repaint, and MadProgrammer's TestPane class,
which worked very well to get the gif to animate, resize correctly and display immediately.

Scrollbar not appearing on custom Panel

I have made a class RefreshablePanel that extends JPanel
public class RefreshablePanel extends JPanel {
static String description="";
static int x=10;
static int y=11;
protected void paintComponent(Graphics g){
super.paintComponent(g);
for (String line : description.split("\n"))
g.drawString(line, x, y += g.getFontMetrics().getHeight());
}
void updateDescription(String dataToAppend){
description = description.concat("\n").concat(dataToAppend);
System.out.println("The description is "+description);
}
}
and then I am adding it into my GUI_class like this
JScrollPane scrollPane_2 = new JScrollPane();
scrollPane_2.setBounds(32, 603, 889, 90);
frmToolToMigrate.getContentPane().add(scrollPane_2);
descriptionPanel = new RefreshablePanel();
scrollPane_2.setViewportView(descriptionPanel);
descriptionPanel.setBackground(Color.WHITE);
descriptionPanel.setLayout(null);
I have added the scrollbar in the class where I am making an instance of RefreshablePanel but scrollbar is not appearing.
I have tried adding
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 1010);
}
to refreshable Panel but then the string is disappearing like this
and nothing is appearing when I scroll down
You're using null layouts, so nothing is going to work the way it should. Swing is designed at the core to utilise layout managers.
You're RefreshablePanel has no discernible size, meaning that when you add to the scroll pane, the scroll pane is likely to simply think it's size should 0x0. RefreshablePanel needs to provide some kind of size hint back to the scrollpane, preferably via the getPreferredSize method
You could use a JLabel (with text wrapped in html) or a non-editable JTextArea to achieve the same results
Updated
Take a quick check of your code. You are declaring the x and y values as static and you are incrementing the y value in your paintComponent method
static int x=10;
static int y=11;
protected void paintComponent(Graphics g){
super.paintComponent(g);
for (String line : description.split("\n"))
g.drawString(line, x, y += g.getFontMetrics().getHeight());
}
This means two things.
If you have more than one instance of your RefreshablePanel they will ALL share the same x/y values AND update them
y is constantly being update to a new position, so if the panel is painted twice, on the second paint, the y position will start from the position it was last at when the first call exited.
Remember, you don't control the paint process. A paint cycle may be executed at any time that the system decides it needs to...
Make the x/y values local variables to the paintComponent method...
Updated
The scroll pane will try and match the preferred size of the component if the available space allows for it. This may mean that the scroll bars may not appear until you resize the window...but you're using a null layout so that won't work for you...
To affect the size of the scroll pane, you can use the Scrollable interface instead...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.Scrollable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Scrollable01 {
public static void main(String[] args) {
new Scrollable01();
}
public Scrollable01() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
RefreshablePanel pane = new RefreshablePanel();
pane.updateDescription("1. You're using null layouts, so nothing is going to work the way it should. Swing is designed at the core to utilise layout managers.");
pane.updateDescription("2. You're RefreshablePanel has no discernible size, meaning that when you add to the scroll pane, the scroll pane is likely to simply think it's size should 0x0. RefreshablePanel needs to provide some kind of size hint back to the scrollpane, preferably via the getPreferredSize method");
pane.updateDescription("3. You could use a JLabel (with text wrapped in html) or a non-editable JTextArea to achieve the same results");
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JScrollPane(pane));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class RefreshablePanel extends JPanel implements Scrollable {
public String description = "";
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 1010);
}
#Override
protected void paintComponent(Graphics g) {
int x = 10;
int y = 11;
super.paintComponent(g);
for (String line : description.split("\n")) {
g.drawString(line, x, y += g.getFontMetrics().getHeight());
}
}
void updateDescription(String dataToAppend) {
description = description.concat("\n").concat(dataToAppend);
System.out.println("The description is " + description);
repaint();
}
#Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(400, 400);
}
#Override
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 64;
}
#Override
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 64;
}
#Override
public boolean getScrollableTracksViewportWidth() {
return false;
}
#Override
public boolean getScrollableTracksViewportHeight() {
return false;
}
}
}

How to get the painted size of a Swing component?

When I add Swing component (like a JButton) to a JPanel, it renders with it's 'preferred size'.
However, the preferred size is actually larger than the painted button. There appears to be an invisible border around it.
Here's a simple frame with my test panel:
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TestPanel pnl = new TestPanel();
frame.getContentPane().add(pnl);
frame.pack();
frame.setVisible(true);
Here's my test panel ...
public class TestPanel extends JPanel {
JButton btn1 = new JButton("Test1");
JButton btn2 = new JButton("Test2");
public TestPanel() {
this.add(btn1);
this.add(btn2);
}
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.RED);
Dimension dim = btn1.getPreferredSize();
g.drawRect(btn1.getX(), btn1.getY(), (int)(dim.getWidth()), (int)(dim.getHeight()));
}
}
Notice I painted btn1's "PreferredSize" in RED to demonstrate that the preferredSize is actually larger than the button itself.
My question is, how can I determine the width and height of the painted button, not the JButton's preferredSize?
Any help is greatly appreciated, thanks!
UPDATE
Because I actually need this to work for all Swing components, here's a screen shot with the more components.
Unfortunately, I need to figure this out, determining the "real" size of the visible widget is crucial to my application.
I don't think this is particular or practically achievable.
The problem is, the button is using the "unpainted" area to paint other elements, like the focus highlight.
You could try look at the AbstractButton#set/getMargin
If nothing better comes along, note that the authors "recommend that you put the component in a JPanel and set the border on the JPanel."
Addendum: Based on your comments below, it's clear that your question is not about rendering borders but about establishing a component's boundary. What you perceive as unused space is actually reserved by the UI delegate for any number of uses, e.g. selection highlighting or esthetic coherence. You can get an idea of how this varies by selecting different Look & Feel themes in the examples here and here.
Using getbounds():
Using setBorder():
import component.Laf;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
* #see https://stackoverflow.com/a/15490187/230513
*/
public class Test {
private void display() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new FlowLayout());
// https://stackoverflow.com/a/11949899/230513
f.add(Laf.createToolBar(f));
f.add(decorate(new JButton("Test")));
f.add(decorate(new JTextField("Test")));
f.add(decorate(new JTextArea(3, 8)));
f.add(decorate(new JCheckBox("Test")));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private JPanel decorate(final JComponent c) {
JPanel p = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Rectangle r = c.getBounds();
g.setColor(Color.red);
// NB pen hangs down and to the right
g.drawRect(r.x - 1, r.y - 1, r.width + 1, r.height + 1);
}
};
p.add(c);
return p;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Test().display();
}
});
}
}

Java Swing: problems with width

I have problems with understanding the behavior of my application. I want to create a simple window (1000x700px), divided into two parts (250px and 750px width respectively). I tried the following code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Example extends JFrame
{
private static final long serialVersionUID = 1L;
public Example()
{
this.setSize(1000, 700);
this.setTitle("Example");
this.setResizable(false);
this.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
JPanel navigation_panel_wrap = new JPanel();
JPanel content_panel_wrap = new JPanel();
navigation_panel_wrap.setPreferredSize(new Dimension(250, 700));
content_panel_wrap.setPreferredSize(new Dimension(750, 700));
content_panel_wrap.setBackground(Color.green);
navigation_panel_wrap.setBackground(Color.red);
this.getContentPane().add(navigation_panel_wrap);
this.getContentPane().add(content_panel_wrap);
}
public static void main(String[] args)
{
Example example = new Example();
example.setVisible(true);
}
}
As you can see I manually set layout manager for JFrame (FlowLayout instead of BorderLayout with zero horizontal and vertical gaps). Of course, I can just use BorderLayout and than use add() method with BorderLayout.EAST and BorderLayout.WEST parameters, but I want to understand what's wrong with FlowLayout.
When I run my application, I get the following (no green JPanel):
If I decrease width of, for example, content_panel_wrap and make it 744px instead of 750px, everything works correctly.
So the question is - what are these strange 6 pixels? I'm not sure this value is constant for all operating systems, so I want to understand its origin.
There's nothing wrong with FlowLayout but you will need to call pack() for all components to be sized.
As for your codes problem (+1 to #Reimeus) calling pack() is the solution.
as per docs:
Causes this Window to be sized to fit the preferred size and layouts
of its subcomponents. If the window and/or its owner are not yet
displayable, both are made displayable before calculating the
preferred size. The Window will be validated after the preferredSize
is calculated.
Tips:
Dont extend JFrame unnecessarily.
Use Event Dispatch Thread when creating and changing UI components:
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// create UI components etc here
}
});
Dont call setPreferredSize() rather override getPrefferedSize() of component.
Dont call setSize(...) on JFrame rather call JFrame#pack() before setting it visible.
Dont forget to call JFrame#defaultCloseOperation(..) or your initial/EDT thread will not be terminated when JFrame is closed.
Here is an example combining my advice and your code:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Example {
private final JFrame frame;
public Example() {
frame = new JFrame();
frame.setTitle("Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//app exited when frame closes
frame.setResizable(false);
frame.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
JPanel navigation_panel_wrap = new JPanel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(250, 700);
}
};
JPanel content_panel_wrap = new JPanel() {
#Override
public Dimension getPreferredSize() {
return new Dimension(750, 700);
}
};
content_panel_wrap.setBackground(Color.green);
navigation_panel_wrap.setBackground(Color.red);
frame.add(navigation_panel_wrap);
frame.add(content_panel_wrap);
//pack frame (size components to preferred size)
frame.pack();
frame.setVisible(true);//make frame visible
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Example();
}
});
}
}

Categories