I try to do simple game, made of few 'screens' (menu, options, etc), which could work by displaying and hiding several JPanels. When I add some stuff on each panel and run the program, the only thing that appears is empty JFrame. I've made id looking like this:
public class Frame extends JFrame{
JPanel panel1 = new JPanel();
JFrame frame = new JFrame("halo");
JButton button = new Button();
int WIDTH=600,HEIGHT=600;
public Frame(){
frame.add(game);
frame.setSize(WIDTH, HEIGHT);
frame.setVisible(true);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel1);
panel1.setBounds(0,0,WIDTH,HEIGHT)
panel1.add(button);
button.setBounds(10,10,30,30);
}}
Everything essential is imported and declared, it's just 'simpled' version. What's wrong with it?
A few things:
Using the classname Frame may conflict with java.awt.Frame.
You have to set the frame visible by calling frame.setVisible(true); Before that, call frame.pack();
You are subclassing JFrame, but also declaring and preparing a different JFrame. Eliminate one of them.
Add the components to the content pane of the JFrame: frame.getContentPane().add(subcomponent);
Setting a layout manager and packing after adding elements should fix the issue. Also it's unclear why you're referring to frame when you're constructing this. Try this version:
public class Frame extends JFrame{
JPanel panel1 = new JPanel();
JButton button = new Button();
int WIDTH=600,HEIGHT=600;
public Frame(){
setTitle("Halo");
setLayout(new BorderLayout());
add(panel1, BorderLayout.CENTER);
panel1.setBounds(0,0,WIDTH,HEIGHT);
panel1.setLayout(new BorderLayout());
panel1.add(button, BorderLayout.SOUTH);
button.setBounds(10,10,30,30);
pack();
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
JFrame uses a BorderLayout by default, this means that only one component can occupy each of the five available positions that BorderLayout managers.
By default, if you don't specify where you want the component to be, it will be added to the CENTRE position
You should break your UI down into logical units and use JPanels to manage them
You can use a combination of panels and layouts to generate complex UIs
You should also consider using a CardLayout to allow you to switch between base views
You should also call setVisible on the JFrame last, after you've established the basic UI, otherwise you'll need to call revalidate and and repaint to update the UI
You should avoid using setBounds/setSize/setLocation on components and rely on the use of layout managers, as they are designed to manage the differences in rendering pipelines that occurs across multiple different operating systems and hardware platforms
Related
I want to add two jPanels to a JFrame side by side. the two boxes are jpanels and the outer box is a jframe
I have these lines of code. I have one class called seatinPanel that extends JPanel and inside this class I have a constructor and one method called utilityButtons that return a JPanel object. I want the utilityButtons JPanel to be on the right side. the code I have here only displays the utillityButtons JPanel when it runs.
public guiCreator()
{
setTitle("Passenger Seats");
//setSize(500, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = getContentPane();
seatingPanel seatingPanel1 = new seatingPanel();//need to declare it here separately so we can add the utilityButtons
contentPane.add(seatingPanel1); //adding the seats
contentPane.add(seatingPanel1.utilityButtons());//adding the utility buttons
pack();//Causes this Window to be sized to fit the preferred size and layouts of its subcomponents
setVisible(true);
}
The most flexible LayoutManager I would recommend is BoxLayout.
You can do the following :
JPanel container = new JPanel();
container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS));
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
//panel1.set[Preferred/Maximum/Minimum]Size()
container.add(panel1);
container.add(panel2);
then add container to object to your frame component.
You need to read up on and learn about the layout managers that Swing has to offer. In your situation it will help to know that a JFrame's contentPane uses BorderLayout by default and you can add your larger center JPanel BorderLayout.CENTER and the other JPanel BorderLayout.EAST. More can be found here: Laying out Components in a Container
Edit 1
Andrew Thompson has already shown you a bit on layout managers in his code in your previous post here: why are my buttons not showing up?. Again, please read the tutorial to understand them better.
I am very new and still have a lot to learn. Thank you so much for anyone who takes the time to help me with this. I have tried a variety of different methods to position my button at specific coordinates with the frame, but for some reason, none of the usual statements that work for placing JButtons is working. Any suggestions?
Here is my current working code
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class GUI extends JFrame
{
JButton b1; // Declares Swing button variable and gives identifier (b1)
JButton b2; // Declares Swing label variable and gives identifier (l1)
public GUI()
{
setTitle("Virus Explortation");
setSize(400,400);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
setLayout(new BorderLayout());
setContentPane(new JLabel(new ImageIcon("C:\\Pictures\\matrix.gif")));
setLayout(new FlowLayout());
b1=new JButton("I am a button");
add(b1);
b2=new JButton("I am also a button");
add(b2);
setSize(399,399);
setSize(400,400);
}
public static void main(String args[])
{
new GUI();
}
}
Why can't I position the JButton using setLocation in this code?
It is because all the containers in Java swing has a default layout. You are adding the button directly into the JFrame where I see you using a BorderLayout for the frame. (BorderLayout is also the default layout for JFrame).
When a layout is used, the layout manager will decide on the position (and sometimes the dimension) for your added components. Which means your attempt of manually setting the position may become futile.
If you want to set the components' position to exactly where you want, you will have to set the layout of the container (such as JFrame or JPanel) to null:
JPanel pnlMain = new JPanel();
pnlMain.setLayout(null);
After you set it to null, you will have to set the location for every components you add to the container. If not, it won't show up. You may use the setBounds method to set the size and location:
JButton btn = new JButton();
btn.setBounds(x, y, width, height);
However, setting layout to null is not recommended for many reasons. One of the most prominent reason being that you loses control and predictability on how your UI will present on different Systems and different usage by the users.
It is also advisable not to extends from JFrame but rather extends from a container like JPanel. Then add the container to the frame. It is quite rare that you need to make a customized JFrame.
I made a basic game on a JFrame and I'm currently trying to add a scoreboard on top my frame by using two separate JPanels. I tried to do it with WindowBuilder but the problem is that my GameFrame class component isn't shown fully in the game frame. It looks like this:
The code is as follows:
JFrame frame = new JFrame("Game");
frame.setSize(500, 700);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.getContentPane().setLayout(null);
JPanel panel = new JPanel();
panel.setBounds(0, 100, 500, 600);
panel.add(new GameFrame());
frame.getContentPane().add(panel);
frame.setVisible(true);
How can I solve the problem?
A JPanel uses FlowLayout by default which respects preferred sizes. As its unlikely that this is currently overridden for your GameFrame component class, you need to use a layout manager which uses the maximum area available
panel.setLayout(new BorderLayout());
I think setting the layout to null is this issue. Set a proper Layout as shown below
frame.setLayout(new GridLayout(1,1));)
Have you tried one of these: http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html ?
If so, what's not working?
A BorderLayout could be useful if you want the scoreboard along the top, by using panel.add(new ScoreBoard(), BorderLayout.PAGE_START) for example.
I want to add two jPanels to a JFrame side by side. the two boxes are jpanels and the outer box is a jframe
I have these lines of code. I have one class called seatinPanel that extends JPanel and inside this class I have a constructor and one method called utilityButtons that return a JPanel object. I want the utilityButtons JPanel to be on the right side. the code I have here only displays the utillityButtons JPanel when it runs.
public guiCreator()
{
setTitle("Passenger Seats");
//setSize(500, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container contentPane = getContentPane();
seatingPanel seatingPanel1 = new seatingPanel();//need to declare it here separately so we can add the utilityButtons
contentPane.add(seatingPanel1); //adding the seats
contentPane.add(seatingPanel1.utilityButtons());//adding the utility buttons
pack();//Causes this Window to be sized to fit the preferred size and layouts of its subcomponents
setVisible(true);
}
The most flexible LayoutManager I would recommend is BoxLayout.
You can do the following :
JPanel container = new JPanel();
container.setLayout(new BoxLayout(container, BoxLayout.X_AXIS));
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
//panel1.set[Preferred/Maximum/Minimum]Size()
container.add(panel1);
container.add(panel2);
then add container to object to your frame component.
You need to read up on and learn about the layout managers that Swing has to offer. In your situation it will help to know that a JFrame's contentPane uses BorderLayout by default and you can add your larger center JPanel BorderLayout.CENTER and the other JPanel BorderLayout.EAST. More can be found here: Laying out Components in a Container
Edit 1
Andrew Thompson has already shown you a bit on layout managers in his code in your previous post here: why are my buttons not showing up?. Again, please read the tutorial to understand them better.
I have a simple swing application which consists of a JLabel and three buttons. The three buttons are in their own JPanel which is in a JFrame along with the JLabel. The JPanel uses flowlayout manager to arrange the buttons horizontally and the JFrame uses the BorderLayout manager to arrange the JLabel and JPanel vertically.
My problem is when I launch the application, during the course of use the text on one of the buttons changes which increases its width. However, the window doesn't resize to accomdate this and one of the buttons disappears. I thought about calling pack() again, but the JFrame is a local variable in my constructor, also, I shouldn't have to tell my program to resize, right? I haven't been able to find anything on google or here to help me but there must be a simple solution, what am I missing? Code is below.
playButton = new JButton("Play");
pauseButton = new JButton("Pause");
stopButton = new JButton("Stop");
curTrackLabel = new JLabel("No Track Selected");
JFrame myFrame = new JFrame("MediaPlayer");
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setTitle("MediaPlayer");
myFrame.setLocation(400,300);
JPanel topPanel = new JPanel();
topPanel.setLayout(new BorderLayout());
myFrame.add(topPanel);
JPanel buttonPanel = new JPanel(new FlowLayout());
buttonPanel.add(playButton);
buttonPanel.add(pauseButton);
buttonPanel.add(stopButton);
topPanel.add(buttonPanel, BorderLayout.CENTER);
topPanel.add(curTrackLabel, BorderLayout.NORTH);
playButton.addActionListener(new playButtonHandler());
pauseButton.addActionListener(new pauseButtonHandler());
stopButton.addActionListener(new stopButtonHandler());
myFrame.pack();
myFrame.setVisible(true);
Maybe try
((JFrame)myButton.getTopLevelAncestor()).pack();
Where myButton is the button whose text is modified during execution.
As with learning any GUI software, experimentation is best. Try messing with BorderLayouts with nested JPanels.
Ultimately, you use JPanel with a BorderLayout (Flow Layout is OK but really when resizing the window, it epically fails). See http://download.oracle.com/javase/tutorial/uiswing/layout/border.html to learn more about BorderLayouts.
Now for your layout scheme it should be something along the lines of:
Top Level Container: JFrame
JFrame contains a JPanel (Call this
JPanel 1) with a BorderLayout.
The three buttons should be in a
SEPARATE jPanel (JPanel 2). JPanel
1 should add the three buttons as
BorderLayout.CENTER. In this way,
the window will resize if the button
changes its width and/or hright.
The JLabel should be added as
BorderLayout.LINE_START.
The tutorial at: http://download.oracle.com/javase/tutorial/uiswing/layout/border.html should help you with this. But in general, use the following:
Use JPanel and nest JPanels as necessary
BorderLayout.CENTER will accomodate size changes---this is the key! (Experiment with this)
JFrame should only be used as a top level container (for more complex GUIs, this is true).
If you require more flexibility, check out JGoodies: http://www.jgoodies.com/ . This is more along the lines of creating forms.