How can I use JFrame.pack() correctly? - java

Well, Hey guys.
For how I see it, Pack method is used inorder to store in the minimum size that can still hold all the elements inside a frame.(Correct me if I'm worng).
But I think that I'm using it not in the right way.
I tried to add some compoments to a frame under a jpanel.
Then I called the pack method, and the frame suit it self to the compoments.
After I remove all of the old compoments using JFrame.removeAll(), I added new compoments under a new JPanel. And called the pack method again but this time the panel from the begging was in the minimum size that can't hold the first JPanel and not the new JPanel.
My code :
public Window() {
frame = new JFrame("Auto VPN Connection");
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addInstace("loading", new JPanel());
JPanel panel = getInstance("loading");
panel.setSize(new Dimension(300, 200));
JLabel label = new JLabel();
label.setText("Loading..");
panel.add(label);
frame.add(panel);
frame.pack();
frame.show();
Start();
}
public void clearFrame() {
if (frame.getContentPane().getComponents().length > 0)
frame.removeAll();
}
public void Start() {
addInstace("home", new JPanel());
JPanel panel = getInstance("home");
panel.setSize(new Dimension(500, 300));
JButton button = new JButton();
button.setSize(new Dimension(200, 30));
panel.setLayout(null);
button.setText("Welcome");
panel.add(button);
frame.add(panel);
frame.pack();
frame.revalidate();
}
public JPanel getInstance(String name) {
for (Pair<String, JPanel>key : array) {
if (key.getLeft().equalsIgnoreCase(name))
return key.getRight();
}
return null;
}
public void addInstace(String name, JPanel panel) {
if (!instanceExists(name)) {
array.add(new Pair<>(name, panel));
} else {
System.out.print("Exists!");
}
}
public boolean instanceExists(String name) {
for (Pair<String, JPanel>key : array) {
if (key.getLeft().equalsIgnoreCase(name))
return true;
}
return false;
}
If I don't call pack method in Start() so the frame pack It self for the size of the JLabel and It's okay.
But if I do call pack method again in Start(), the frame not pack It self either to the JLabel and to the JButton.
Here are some pictures that exam my situation:
Pack not called in the Start method
Pack is now called in the Start method
Thank you for taking time and read my question, That's it.

Related

Java Sizing JPanel & JPanel Components

I'm trying to build a GUI in Java Swing. I have alot of trouble sizing components. I managed to size a JPanel by setting the dimensions with setPreferredSize(), but I can't get the components within that JPanel to size properly.
This is my screen with only the JPanel visible.
When I add the button to my JPanel the following happens:
As you can see the button is taking up the whole lenght and width of my JPanel/JFrame. Why is this happening? How can I fix it?
Here is my code:
Application.java
public void start() {
ControllerObserveer observeer = new ControllerObserveer();
frame = new JFrame("-");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setLayout(new BorderLayout());
frame.add(observeer.getView(), BorderLayout.CENTER);
frame.setResizable(false);
}
ControllerObserveer.java
public class ControllerObserveer {
private ModelObserveer model;
private ViewObserveer view;
public JPanel getView(){
return this.view.p;
}
}
ViewObserveer.java
public class ViewObserveer {
public JPanel p;
public ViewObserveer(){
this.p = new JPanel(new BorderLayout(), false);
p.setPreferredSize(new Dimension(500, 500));
p.setBackground(Color.red);
JButton b = new JButton("Hello World!");
b.setPreferredSize(new Dimension(40, 40));
p.add(b);
}
}
At last I would like to ask what the diffrences are between the diffrent layouts, like BorderLayout() or BoxLayout() for example.
Thank you for your time!
Install Java WindowBuilder on Eclipse. So, you can get things done.. "but I can't get the components within that JPanel to size properly."

Java Swing - Making a scrollable JPanel inside a JFrame

I have a custom component called FixtureComponent that extends JPanel, it is basically a JPanel containing a number of controls placed inside it, each with it's own size and location. What I am trying to do is to place a number of FixtureComponent vertically in my JFrame as follows:
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
main frame = new main();
FixtureComponent comPanel = new FixtureComponent();
frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS));
frame.setSize(300, 400);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
for (Integer i = 0; i < 20; i++)
{
frame.getContentPane().add(comPanel);
}
frame.setVisible(true);
}
});
}
The problem I am getting is when I run the above code, I get a single FixtureComponent placed at the top of the JFrame instead of getting 20 FixtureComponents placed vertically above each other.
And I would like to also know in case of that I successfully got the above code to work, how to add a scroll bar to scroll across the FixtureComponent?
Thank you.
Create and add a JScrollPane to the frame, setting the JScrollPane context to the content you need scrolling, in the example below this is a JPanel named container.
Add your FixtureComponent objects to container, and boom. Here's the code:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
Main frame = new Main();
JPanel container = new JPanel();
container.setLayout(new BoxLayout(container, BoxLayout.Y_AXIS));
JScrollPane scroller = new JScrollPane(container);
scroller.setPreferredSize(new Dimension(200, 1000));
for (Integer i = 0; i < 20; i++) {
FixtureComponent fixture = new FixtureComponent();
container.add(fixture);
}
frame.setLayout(new BorderLayout());
frame.add(scroller, BorderLayout.WEST);
frame.setSize(300, 400);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}

JLabel doesn't show up

I'm working on a program but my JLabel doesn't show up. My JButton works perfectly (it appears) but for some reason the JLabel does not appear. I have checked on internet but I Haven't found anything.
package com.hinx.client;
import java.awt.Color;
import javax.swing.*;
public class Main {
public static void main(String [] args)
{
createWindow();
}
static void createWindow()
{
//Create panel
JPanel content = new JPanel();
content.setLayout(null);
//Build the frame
JFrame frame = new JFrame("Hinx - A marketplace for apps - Client ALPHA_0.0.1");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(700, 400);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.add(content);
frame.setVisible(true);
//Add the login button
JButton login = new JButton("Login");
login.setBounds(0, 342, 150, 30);
//Create login label
JLabel loginlabel = new JLabel("Login Area");
//Create login panel
JPanel loginpanel = new JPanel();
loginpanel.setLayout(null);
loginpanel.setBounds(0, 0, 150, 400);
loginpanel.setBackground(Color.gray);
loginpanel.add(login);
loginpanel.add(loginlabel);
content.add(loginpanel);
}
}
I have checked on internet but I Haven't found anything.
JFrame is visible before JComponents (frame.add(content);) are added / created
move code line frame.setVisible(true); (better everything about JFrame) to the end of constuctor
Set a layout for your panel. Per example :
loginpanel.setLayout(new BorderLayout());
You can learn more about layouts here.
Here's what I get :
Use layouts. FlowLayout should be fine in this case. Do not call setBounds() and do not set layout as a null.
Add label and button on JPanel
Then add JPanel on JFrame
Call pack() instead of setSize()
Call setVisible(true) in the end.
Good luck!
You are making setLayout null.
JPanel loginpanel = new JPanel();
loginpanel.setLayout(null);
Use this,
JPanel loginpanel = new JPanel();
loginpanel.setLayout(new BorderLayout());
Run the UI on the EDT instead of running on the main thread. Read this post.
Example:
public static void main(String [] args)
{
Runnable r = new Runnable() {
#Override
public void run() {
createWindow();
}
};
EventQueue.invokeLater(r);
}

NullPointerException continues

When I am trying to call JPanel panel2 of Panel2 class on triggering of action event from Next JButton of Panel1 class, I am getting NullPointerException. How to resolve this? plzz help.
public class PanelEventTest
{
/**
* #param args
*/
JFrame frame;
void originalFrame()
{
frame = new JFrame();
frame.setSize(500, 300);
frame.setVisible(true);
frame.setLayout(new FlowLayout());
frame.add(new TestPanel1().panel1());
frame.add(new TestPanel2().panel2());
}
public static void main(String[] args) {
// TODO Auto-generated method stub
new PanelEventTest().originalFrame();
}
}
public class TestPanel1
{
JPanel panel1;
JButton next;
JPanel panel1()
{
panel1 = new JPanel();
next = new JButton("Next");
next.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
new TestPanel2().panel2.removeAll();
}
});
panel1.add(next);
return panel1;
}
}
public class TestPanel2
{
JPanel panel2;
JList jlist;
String[] list = {"Sachin","Tarun","Vipin"};
JPanel panel2()
{
panel2 = new JPanel();
jlist = new JList(list);
panel2.add(jlist);
panel2.add(new JLabel("Test"));
return panel2;
}
}
My last question Nullpointerexception with JPanel was successfully resolved by you guys. Plz help in this. This exception is eating my head.
If you try changing this line:
new TestPanel2().panel2.removeAll();
To:
new TestPanel2().panel2().removeAll();
Will solve the problem, but the current logic is flawed.
A better solution is:
Change TestPanel2 to:
public class TestPanel2 {
JPanel panel2;
JList jlist;
String[] list = { "Sachin", "Tarun", "Vipin" };
public TestPanel2() { // was: JPanel panel2() {
panel2 = new JPanel();
jlist = new JList(list);
panel2.add(jlist);
panel2.add(new JLabel("Test"));
// was: return panel2;
}
}
And then modify TestPanel1 to:
public class TestPanel1 {
JPanel panel1;
JButton next;
public TestPanel1(final JFrame frame, TestPanel2 tp2) { // was: JPanel panel1() {
panel1 = new JPanel();
next = new JButton("Next");
final JPanel panel2 = tp2.panel2; // line created
next.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
panel2.removeAll(); // was: new TestPanel2().panel2.removeAll();
frame.validate(); // line created
frame.paint(); // line created
}
});
panel1.add(next);
// was: return panel1;
}
}
Finally, on PanelEventTest.originalFrame(), change:
frame.add(new TestPanel1().panel1());
frame.add(new TestPanel2().panel2());
to:
TestPanel2 tp2 = new TestPanel2();
frame.add(new TestPanel1(frame, tp2).panel1);
frame.add(tp2.panel2);
frame.validate();
frame.repaint();
Explanation
You are creating methods, when you needed constructors. You must read this: Understanding constructors.
Also, you need to pass TestPanel2 and the frame to TestPanel1:
Your code was creating a new TestPanel2 (attached to no one) and then calling removeAll() on it's pannel. This has no effect at all (as this panel is not shown anywhere).
The changed then code will call removeAll() on TestPanel1's panel.
Also, you need to revalidate/repaint the components everytime you make a change on them.
Currently you change them when you create the frame (adding the panels) and when you remove the panel2 (in the "Next" button's action).

setting the size of a JPanel

I have a class that extends a JPanel called Row. I have a bunch of Row added to a JLabel, the code is the following:
JFrame f=new JFrame();
JPanel rowPanel = new JPanel();
//southReviewPanel.setPreferredSize(new Dimension(400,130));
rowPanel.setLayout(new BoxLayout(rowPanel, BoxLayout.Y_AXIS));
rowPanel.add(test1);
rowPanel.add(test1);
rowPanel.add(test2);
rowPanel.add(test3);
rowPanel.add(test4);
rowPanel.setPreferredSize(new Dimension(600, 400));
rowPanel.setMaximumSize(rowPanel.getPreferredSize());
rowPanel.setMinimumSize(rowPanel.getPreferredSize());
f.setSize(new Dimension(300,600));
JScrollPane sp = new JScrollPane(rowPanel);
sp.setSize(new Dimension(300,600));
f.add(sp);
f.setVisible(true);
where test1...etc is a Row. However when I resize the window the layout of the Row somehow becomes messy (it resizes as well)... how can I prevent this from happening?
Read the Swing tutorial on Using Layout Managers. Each layout manager has its own rules about what happens when the container is resized. Experiment and play.
In the case of a BoxLayout it should respect the maximum size of the components added to the panel so you can do:
childPanel.setMaximumSize( childPanel.getPreferredSize() );
If you need more help post your SSCCE demonstrating the problem.
I took the code in http://download.oracle.com/javase/tutorial/uiswing/examples/layout/BoxLayoutDemoProject/src/layout/BoxLayoutDemo.java and adapted it with what you are trying to do, only using buttons instead of custom JPanels:
public class BoxLayoutDemo {
public static void addComponentsToPane(Container pane) {
JPanel rowPanel = new JPanel();
pane.add(rowPanel);
rowPanel.setLayout(new BoxLayout(rowPanel, BoxLayout.Y_AXIS));
rowPanel.add(addAButton("Button 1"));
rowPanel.add(addAButton("Button 2"));
rowPanel.add(addAButton("Button 3"));
rowPanel.add(addAButton("Button 4"));
rowPanel.add(addAButton("5"));
rowPanel.setPreferredSize(new Dimension(600, 400));
rowPanel.setMaximumSize(rowPanel.getPreferredSize());
rowPanel.setMinimumSize(rowPanel.getPreferredSize());
}
private static JButton addAButton(String text) {
JButton button = new JButton(text);
button.setAlignmentX(Component.CENTER_ALIGNMENT);
return button;
}
private static void createAndShowGUI() {
JFrame frame = new JFrame("BoxLayoutDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set up the content pane.
addComponentsToPane(frame.getContentPane());
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
The end result is this:
As you can see, the button row is perfectly aligned. If you resize the JFrame, they stay aligned. Is that what you are looking for?

Categories