Hi all, here's a kinda bullet-pointy explanation of what i have

- I have a simple JFrame
- I create a JPanel called 'ContentPane'

contentPane = new JPanel();
contentPane.setBackground(SystemColor.window);
contentPane.setBorder(new LineBorder(SystemColor.inactiveCaption));
contentPane.setLayout(null);
setContentPane(contentPane);

- the JFrame has a

JMenuBar -> JMenuBar -> JMenuItem

- The JMenuItem has a MouseListener and a override to 'mouseReleased'
- Inside mouseReleased i call

TestPanel p = new TestPanel(null, new Vector2(12, 12));

contentPane.add(p);

- TestPanel extends a JPanel, and ha some simple text boxes and labels in it which are created in its constructor, super(); is called.

- When the event is fired it creates a TestPanel but it is tiny, about an inch long and 5 mm in height, it should be much much bigger.

- If I move the call to instance the TestPanel outside of the event (so the TestPanel is instanced on load) it is drawn fine.

Why does the event effect it in this way ?

Thanks,

Stu.

Recommended Answers

All 19 Replies

Do you have a pack(); somewhere in your code. Do you call pack(); after adding the new panel?

Do you have a pack(); somewhere in your code. Do you call pack(); after adding the new panel?

No i don't, if i add it after the instancing of TestPanel it does make the panel show, but it also makes the JFrame / whole window tiny ( i have to then drag it out to get it back to normal size)

previously its just the new pannel that is tiny, please see the image attached

When you add stuff to a window you need to call pack() after adding everything.

public void pack()

Causes this Window to be sized to fit the preferred size and layouts of its subcomponents. The resulting width and height of the window are automatically enlarged if either of dimensions is less than the minimum size as specified by the previous call to the setMinimumSize method.

If the window and/or its owner are not displayable yet, both of them are made displayable before calculating the preferred size. The Window is validated after its size is being calculated.

If you want the window to start out big enough to show a panel that you will add later you can either use setMinimumSize or use a place-holder component of the right size.

This is all part of the sometimes painful magic of layout managers. They're great and essential when you get control of them, but at first they seem totally out of control and prone to random behaviour.

Thanks for your answer,

So heres what it looks like:

public Main()
	{
		setTitle("Test");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 800, 600);
		setMinimumSize(new Dimension(800, 600));
		
		contentPane = new JPanel();
		contentPane.setBackground(SystemColor.window);
		contentPane.setBorder(new LineBorder(SystemColor.inactiveCaption));
		contentPane.setLayout(null);
		setContentPane(contentPane);

		// ---------------------------------------------------------------------
		// Menu Bar
		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);

		JMenu mnFile = new JMenu("File");
		menuBar.add(mnFile);

		JMenuItem mntmStart = new JMenuItem("Start services");

		mntmStart.addMouseListener(new MouseAdapter()
		{
			@Override
			public void mouseReleased(MouseEvent arg0)
			{
				TestPanel p = new TestPanel(null, new Vector2(12, 12));

				contentPane.add(p);
			}
		});

		mnFile.add(mntmStart);

		// ---------------------------------------------------------------------
		// End Menu Bar


		pack();

	}

However, it still turns out like the screenshot.

Does the pack() need to go in the mouse event as well ?

Like I said:
When you add stuff to a window you need to call pack() after adding everything.
so yes, after you add your panel in the mouse event you need to call pack()

Like I said:
When you add stuff to a window you need to call pack() after adding everything.
so yes, after you add your panel in the mouse event you need to call pack()

Doesn't do anything, still looks like the screenshot

Sorry, got to go out for bit now - I'll have another look at this when I get back, unless you fix it in the meantime (don't forget to mark it solved in that case). J.

Hi, I'm back. Without the code for TestPanel I'm unable to reproduce your problem here. Is it possible for you to post a complete source file that I can compile and run to reproduce the problem? It doesn't have to be your whole app, in fact the smaller the better...

Hi, I'm back. Without the code for TestPanel I'm unable to reproduce your problem here. Is it possible for you to post a complete source file that I can compile and run to reproduce the problem? It doesn't have to be your whole app, in fact the smaller the better...

Sorry i didn't see you reply, here you go.

package Default.Gui;

import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.SystemColor;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.ImageIcon;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;

import Default.Engine.Computer;
import Default.Engine.Vector2;

public class TestPanel extends JPanel
{
	private Computer computer;
	private Vector2 position;

	public TestPanel(Computer computer, Vector2 position)
	{
		super();
		this.computer = computer;
		this.position = position;

		// Setup elements
		this.setBounds((int) position.getX(), (int) position.getY(), 760, 92);
		this.setTransferHandler(new FileDropHandler(computer));

		this.setBorder(new LineBorder(SystemColor.activeCaption));
		this.setBackground(new Color(240, 248, 255));
		this.setVisible(true);

		JLabel lblComputerMonitor = new JLabel("");
		lblComputerMonitor.setBounds(12, 4, 64, 88);
		lblComputerMonitor.setIcon(new ImageIcon(Main.class.getResource("/Resources/monitor_64.png")));

		JLabel lblCustomName_Static = new JLabel("Custom Name:");
		lblCustomName_Static.setBounds(82, 4, 91, 27);
		lblCustomName_Static.setFont(new Font("Segoe UI", Font.PLAIN, 12));

		JLabel lblCustomName = new JLabel("Some guy");
		lblCustomName.setBounds(183, 4, 152, 27);
		lblCustomName.setFont(new Font("Segoe UI", Font.PLAIN, 12));

		JLabel lblNewLabel = new JLabel("Disconnect");
		lblNewLabel.setBounds(674, 5, 78, 27);

		JLabel lblNetworkName_Static = new JLabel("Network Name:");
		lblNetworkName_Static.setBounds(82, 31, 91, 26);
		lblNetworkName_Static.setFont(new Font("Segoe UI", Font.PLAIN, 12));

		JLabel lblNetworkName = new JLabel("Stuarts-pc");
		lblNetworkName.setBounds(183, 31, 152, 26);
		lblNetworkName.setFont(new Font("Segoe UI", Font.PLAIN, 12));

		JLabel lblGroups = new JLabel("Groups");
		lblGroups.setBounds(652, 43, 100, 34);
		lblGroups.setHorizontalAlignment(SwingConstants.LEFT);
		lblGroups.setIcon(new ImageIcon(Main.class.getResource("/Resources/Users2.png")));
		lblGroups.setOpaque(true);
		lblGroups.setBackground(new Color(255, 245, 238));
		lblGroups.setBorder(new LineBorder(new Color(255, 218, 185)));

		JPopupMenu popupMenu = new JPopupMenu();
		addPopup(lblGroups, popupMenu);

		JCheckBoxMenuItem chckbxmntmTest = new JCheckBoxMenuItem("Test");
		popupMenu.add(chckbxmntmTest);

		JCheckBoxMenuItem chckbxmntmTest_1 = new JCheckBoxMenuItem("Test2");
		popupMenu.add(chckbxmntmTest_1);

		JLabel lblNetworkIP_Static = new JLabel("Network IP:");
		lblNetworkIP_Static.setBounds(82, 60, 91, 26);
		lblNetworkIP_Static.setFont(new Font("Segoe UI", Font.PLAIN, 12));

		JLabel lblNetworkIP = new JLabel("192.168.0.2");
		lblNetworkIP.setBounds(183, 60, 152, 26);
		lblNetworkIP.setFont(new Font("Segoe UI", Font.PLAIN, 12));
		this.setLayout(null);
		this.add(lblComputerMonitor);
		this.add(lblNetworkIP_Static);
		this.add(lblNetworkName_Static);
		this.add(lblCustomName_Static);
		this.add(lblNetworkIP);
		this.add(lblNetworkName);
		this.add(lblCustomName);
		this.add(lblNewLabel);
		this.add(lblGroups);

	}

	private static void addPopup(Component component, final JPopupMenu popup)
	{
		component.addMouseListener(new MouseAdapter()
		{
			public void mousePressed(MouseEvent e)
			{
				if (e.isPopupTrigger())
				{
					showMenu(e);
				}
			}

			public void mouseReleased(MouseEvent e)
			{
				if (e.isPopupTrigger())
				{
					showMenu(e);
				}
			}

			public void mouseClicked(MouseEvent e)
			{
				switch (e.getModifiers())
				{
					case InputEvent.BUTTON1_MASK:
					{
						System.out.println("That's the LEFT button");
						showMenu(e);
						break;
					}
					case InputEvent.BUTTON2_MASK:
					{
						System.out.println("That's the MIDDLE button");
						break;
					}
					case InputEvent.BUTTON3_MASK:
					{
						System.out.println("That's the RIGHT button");
						break;
					}
				}
			}

			private void showMenu(MouseEvent e)
			{
				popup.show(e.getComponent(), e.getX(), e.getY());
			}
		});
	}

}
package Default.Gui;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.SystemColor;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.border.LineBorder;

import Default.Engine.NetworkManager;
import Default.Engine.Parameters;
import Default.Engine.Vector2;

public class Main extends JFrame
{

	private static final long serialVersionUID = 6920450838427729933L;
	private JPanel contentPane;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args)
	{
		try
		{
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Throwable e)
		{
			e.printStackTrace();
		}
		EventQueue.invokeLater(new Runnable()
		{
			public void run()
			{
				try
				{
					Main frame = new Main();
					frame.setVisible(true);
				} catch (Exception e)
				{
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public Main()
	{
		setTitle("Test App");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 800, 600);
		setMinimumSize(new Dimension(800, 600));
		setResizable(false);

		contentPane = new JPanel();
		contentPane.setBackground(SystemColor.window);
		contentPane.setBorder(new LineBorder(SystemColor.inactiveCaption));
		contentPane.setLayout(null);
		contentPane.setMinimumSize(new Dimension(800, 600));
		setContentPane(contentPane);

		// ---------------------------------------------------------------------
		// Menu Bar
		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);

		JMenu mnFile = new JMenu("File");
		menuBar.add(mnFile);

		JMenuItem mntmStart = new JMenuItem("Start services");

		mntmStart.addMouseListener(new MouseAdapter()
		{
			@Override
			public void mouseReleased(MouseEvent arg0)
			{
				NetworkManager networkManager = NetworkManager.Instance();

				networkManager.CreateTCPServer(Parameters.tcpListeningPort);

				networkManager.CreateUDPServer(Parameters.udpListeningPort);

				networkManager.CreateUDPClient(Parameters.udpListeningPort);

				TestPanel p = new TestPanel(null, new Vector2(12, 12));

				contentPane.add(p);

				pack();

			}
		});

		mnFile.add(mntmStart);

		// ---------------------------------------------------------------------
		// End Menu Bar

		// pack();

	}

}

OK, that's not going to be easy to run. It uses a package Default.Engine and also requires other stuff from /Resources/, neither of which I have.
Can you cut this down to a single file (only 1 public class, other classes not public) with no external dependencies?

Ah - just saw that you are using a null layout managers. (It's your program, so that's up to you). That changes everything. Forget the pack(), that's for real layout managers. Sorry about that, null layout is something you just don't see in "real life" development, so I had a false hidden assumption.
On the other hand, it's simpler because I now have no idea why the size should depend on where the add method is called from. If you can let me have a stand-alone single file version I'll run it and see what I can find; otherwize I'm afraid I'm not going to be much more use to you :-(

Ah - just saw that you are using a null layout managers. (It's your program, so that's up to you). That changes everything. Forget the pack(), that's for real layout managers. Sorry about that, null layout is something you just don't see in "real life" development, so I had a false hidden assumption.
On the other hand, it's simpler because I now have no idea why the size should depend on where the add method is called from. If you can let me have a stand-alone single file version I'll run it and see what I can find; otherwize I'm afraid I'm not going to be much more use to you :-(

You can pretty much comment out the stuff with the Default.Engine like the 'computer' stuff. The vector2 is just 2 floats - like a normal vector, again just remove it and sub it with '12' where ever .getX()/Y is called
same with the resources.
File drop handler, comment out that line

Apart from those i don't know what else you don't have

P.s i was watching this topic for ages, refreshing every 10 mins or so.. didn't realize it went onto the 2nd page... not very on the ball today

It's 6pm here now, so I'll have a look in the morning. Keep me updated if you get any progress at your end, please.
J

contentPane.setPreferredSize(new Dimension(800, 600));

fixed the problem

pack();
setSize(800, 600);

when pack() is called the frame size goes up to 806 and 649
so calling setSize() makes it go back to 'normal' (but it does flicker a bit.

Seem to of fixed it, maybe a hacky method.

"flicker" is an important clue.
When you have code like pack(); setSize(800, 600); in a listener there are zero screen updates until your whole method is completed, then the screen is repainted with the final version. Swing is by default double-buffered, so no flicker. Flicker implies that there is another method somewhere else that's also changing the screen, so it goes:

your code changes the GUI as many times as it wants
your code completes
Swing updates the screen
some other code changes the GUI
... and completes
Swing updates the screen again

"flicker" is an important clue.
When you have code like pack(); setSize(800, 600); in a listener there are zero screen updates until your whole method is completed, then the screen is repainted with the final version. Swing is by default double-buffered, so no flicker. Flicker implies that there is another method somewhere else that's also changing the screen, so it goes:

your code changes the GUI as many times as it wants
your code completes
Swing updates the screen
some other code changes the GUI
... and completes
Swing updates the screen again

When I say 'flicker' its only the bottom and right edge, where it expands (due to pack()) then gets set back to 800,600

If it doesn't bother you then that's OK. Time to move on to more important things?

If it doesn't bother you then that's OK. Time to move on to more important things?

:) i'm not sure if that's a leading question / you just interested in what this code is for ?

I don't think its that important atm no, when everything else is done i might go back to it.

Thanks for you help though, i getting to understand java GUI's better now, messing around with themes/ styles now - bit of a pain but getting there.

No, not leading Q, just suggesting that you may have better things to do than worry about a slight flicker. I'm always interested in what people are up to, but I don't have remotely enough time to follow up more than a tiny fraction. Mostly its just help fix the problem, mark it solved, onto the next.
J

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.