Pass parameter to another panel swing java - java

I have a problem.
For example: We have MainFrame, on this form we have mainPanel. Next, creates new classes with names FirstPanel and SecondPanel wich extends JPanel. Now in MainFrame writes:
public MainFrame() {
initComponents();
setLocationRelativeTo(null);
Main main = new Main();
main.setMainPanel(mainPanel);
mainPanel.setLayout( new BorderLayout() );
mainPanel.add( PANELS_LIST.get(0) );
mainPanel.validate();
}
PANELS_LIST - arrayList with all panels. PANELS_LIST.get(0) - jpanel with name FirstPanel .
After this we will see FirstPanel. On the FirstPanel we have button. So, on this button click I want to change mainPanel state (need SecondPanel overwrites FirstPanel). How can i do this? Tried to send mainPanel like a param with creating setter or getter but doesn't work..
At all I need mainPanel to be accesable from any panel in any class
PS: ofcourse I can set mainPanel like a public and static, but.. I think this is bad solution

Related

Why is my JPanel not showing up when called into JFrame?

Initially, I created my buttons and my JPanel in my GUI but I want to take them out of my GUI and create a different class for them since I have to add on to them.
Here is the following code that's giving me an issue.
The issue being that my JPanel isn't showing up. I extended the VButtons class to JPanel assuming that adding the JPanel to JFrame would work but no luck.
Any suggestions?
public static void vGui() {
JFrame frame = new JFrame();
B b;
b = new B();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(b, BorderLayout.WEST);
frame.setVisible(true);
}
public static class B extends JPanel {
B() {
JPanel Panel1 = new JPanel();
JRadioButton 1st button = new JRadioButton("1st button");
JRadioButton 2nd button = new JRadioButton("2nd button");
Panel1.add(1st button);
Panel1.add(2nd button);
Panel1.setLayout(new GridLayout(9,1))
}
}
VButtons extends JPanel <-- This itself is a JPanel
JPanel Panel1 <-- But you are adding everything inside Panel1
And panel1 is just created and left unused.
So, remove Panel1.
Just call add method, because you are inside a subclass of JPanel.
You can call this.add(...) if that is clearer to read.
You need to use the vertex from the left intersection to compile the right for layout of the entire grid. The vertices won't intersect if you use 9,1. I like how you you used removeVertex but it is unnecessary.

Why is JPanel not adding any component at Runtime?

public class Create_JFrame extends JFrame{
public Create_JFrame(){
//Create a Frame
JFrame Frame = new JFrame("Bla-Bla");
JPanel Panel_1 = new JPanel();
JPanel Panel_2 = new JPanel();
JButton Option_1 = new JButton("Option-1");
//Layout management for Panels
Frame.getContentPane().add(BorderLayout.WEST, Panel_1);
//Add button to Panel
Panel_1.add(Option_1);
//Registering Listeners for all my buttons
Option_1.addActionListener(new ListenerForRadioButton(Panel_2));
//Make the frame visible
Frame.setSize(500, 300);
Frame.setVisible(true);
}//end of Main
}//end of Class
public class ListenerForRadioButton implements ActionListener{
JPanel Panel_2;
JButton browse = new JButton("Browse");
//Constructor, will be used to get parameters from Parent methods
public ListenerForRadioButton(JPanel Panel){
Panel_2 = Panel;
}
//Overridden function, will be used for calling my 'core code' when user clicks on button.
public void actionPerformed(ActionEvent event){
Panel_2.add(browse);
System.out.println("My listener is called");
}//end of method
}//end of class
Problem Statement:
I have 2 JPanel components in a a given JFrame. Panel_1 is having a Option_1 JButton. When user clicks on that I am expecting my code to add a JButton 'browse' in Panel_2 at runtime.
Runtime Output:
System is not adding any JButton in Panel_2. However, I see my debug message in output, indicating that system was successful in identifying user's click action on 'option-1'.
Question:
Why is JPanel not adding any component at Runtime?
Panel_2.add(browse);
Panel_2.revalidate();
adding a 'revalidate' will solve the problem.
There are some reasons. but:
usually it's because of using unsuitable LayoutManager.
sometimes it's because of adding the JPanel to it's root component in worng way. which any operation (add, remove,...) works but is not visible.
you must refresh the view when you make some changes on it, like adding or removing components to/from it.
try to use Panel_2.revalidate() to refresh.
if it doesn't work properly use it with Panel_2.repaint() method.
see Java Swing revalidate() vs repaint()
see Difference between validate(), revalidate() and invalidate() in Swing GUI
using setSize twice for your jframe is another way.
Frame.setSize(498, 300); then Frame.setSize(500, 300);

Problems with BorderLayout() in Java

I've tried a lot of different ways, but I will explain two and what was happening (no error messages or anything, just not showing up like they should or just not showing up at all):
First, I created a JPanel called layout and set it as a BorderLayout. Here is a snippet of how I made it look:
JPanel layout = new JPanel();
layout.setLayout(new BorderLayout());
colorChoice = new JLabel("Choose your color: ");
layout.add(colorChoice, BorderLayout.NORTH);
colorBox = new JComboBox(fireworkColors);
colorBox.addActionListener(this);
layout.add(colorBox, BorderLayout.NORTH);
In this scenario what happens is they don't show up at all. It just continues on with whatever else I added.
So then I just tried setLayout(new BorderLayout()); Here is a snippet of that code:
setLayout(new BorderLayout());
colorChoice = new JLabel("Choose your color: ");
add(colorChoice, BorderLayout.NORTH);
colorBox = new JComboBox(fireworkColors);
colorBox.addActionListener(this);
add(colorBox, BorderLayout.NORTH);
In this scenario they are added, however, the width takes up the entire width of the frame and the textfield (not shown in the snippet) takes up basically everything else.
Here is what I have tried:
setPreferredSize() & setSize()
Is there something else that I am missing? Thank you.
I also should note that this is a separate class and there is no main in this class. I only say this because I've extended JPanel instead of JFrame. I've seen some people extend JFrame and use JFrame, but I haven't tried it yet.
You created a JPanel, but didn't add it to any container. It won't be visible until it is added to something (a JFrame, or another panel that is in a frame somewhere up the hierarhcy)
You added two components to the same position in the BorderLayout. The last one added is the one that will occupy that position.
Update:
You do not need to extend JFrame. I never do, instead I always extend JPanel. This makes my custom components more flexible: they can be added in another panel, or they can be added to a frame.
So, to demonstrate the problem I will make an entire, small, program:
public class BadGui
{
public static void main(String[] argv)
{
final JFrame frame = new JFrame("Hello World");
final JPanel panel = new JPanel();
panel.add(new JLabel("Hello"), BorderLayout.NORTH);
panel.add(new JLabel("World"), BorderLayout.SOUTH);
frame.setVisible(true);
}
}
In this program I created a panel, but did not add it to anything so it never becomes visible.
In the next program I will fix it by adding the panel to the frame.
public class FixedGui
{
public static void main(String[] argv)
{
final JFrame frame = new JFrame("Hello World");
final JPanel panel = new JPanel();
panel.add(new JLabel("Hello"), BorderLayout.NORTH);
panel.add(new JLabel("World"), BorderLayout.SOUTH);
frame.getContentPane().add(panel);
frame.setVisible(true);
}
}
Note that in both of these, when I added something to the panel, I chose different layout parameters (one label I put in 'North' and the other in 'South').
Here is an example of a JPanel with a BorderLayout that adds a JPanel with a button and label to the "North"
public class Frames extends JFrame
{
public Frames()
{
JPanel homePanel = new JPanel(new BorderLayout());
JPanel northContainerPanel = new JPanel(new FlowLayout());
JButton yourBtn = new JButton("I Do Nothing");
JLabel yourLabel = new JLabel("I Say Stuff");
homePanel.add(northContainerPanel, BorderLayout.NORTH);
northContainerPanel.add(yourBtn);
northContainerPanel.add(yourLabel);
add(homePanel);
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setLocationRelativeTo(null);
setExtendedState(JFrame.MAXIMIZED_BOTH);
setTitle("Cool Stuff");
pack();
setVisible(true);
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(Frames::new);
}
}
The below suggestion is assuming that your extending JFrame.
Testing
First of all, without seeing everything, theres always a numerous amount of things you can try.
First off, after you load everything, try adding this in (Again, assuming your extending JFrame:
revalidate();
repaint();
I add this into my own Swing projects all the time, as it refreshes and checks to see that everything is on the frame.
If that doesn't work, make sure that all your JComponent's are added to your JPanel, and ONLY your JPanel is on your JFrame. Your JFrame cannot sort everything out; the JPanel does that.
JPanel window = new JPanel();
JButton button = new JButton("Press me");
add(window);
window.add(button); // Notice how it's the JPanel that holds my components.
One thing though, you still add your JMenu's and what-not through your JFrame, not your JPanel.

Remove Jframe panels

JFrame frame1 = new JFrame("frame");
frame1.setVisible(true);
frame1.setPreferredSize(new Dimension(800, 600));
frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel Panel1 = new JPanel();
JPanel Panel2 = new JPanel();
frame1.add(Panel1,BorderLayout.SOUTH);
frame1.add(Panel2,BorderLayout.North);
How do i do something like this that if something happens the frame is blank
if(SOMETHINGHAPPENS)
{
//remove all panels from frame 1 so i have a blank frame
//now i want to add some new panels
}
Simple answer, don't.
Instead, use a CardLayout on the JFrame
This will allow you to setup a series of "views" which you can switch between as needed
Try this. Jframe.remove(JPanel). Then call JFrame.pack()
, and possibly JFrame.repaint() in order to refresh the graphics if necessary.
JPanel extends JComponent, so it should work just fine. Remember to substitute JFrame and JPanel in the code above with the names of the frames/panels you are using the methods on.

jpanel as inner class

I need to write a simple tennis game.
To move between different windows(panel with main menu, panel with game, panel with settings) I decided to use inner classes extends JPanel and replace it when some events like start new game occurs.
but the problem is - it doesn't see my inner class. I mean I add it to JFrame
mainframe.add(new MainMenuPanel());
but there is nothing on the screen when I run program. What's the problem?
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class MainFrame{
JFrame mainframe;
public static void main(String[] args){
new MainFrame();
}
public MainFrame() {
mainframe = new JFrame();
mainframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainframe.setSize(300, 400);
mainframe.setTitle("X-Tennis v0.1");
mainframe.add(new MainMenuPanel());
mainframe.getContentPane().setLayout(new GridLayout());
mainframe.getContentPane().setBackground(Color.WHITE);
mainframe.setVisible(true);
}
public class MainMenuPanel extends JPanel {
JPanel mainmenupanel;
JLabel label1;
JButton btnNewGame,btnJoinGame;
ImageIcon iconNewGame,iconJoinGame;
public MainMenuPanel(){
mainmenupanel = new JPanel();
label1 = new JLabel("X-TENNIS");
label1.setFont(new Font("Comic Sans MS",Font.ITALIC,20));
label1.setForeground(Color.BLUE);
btnNewGame = new JButton("New Game", iconNewGame);
btnNewGame.setFocusPainted(false);
btnNewGame.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e){
JOptionPane.showMessageDialog(mainframe, "New game");
//delete current panel and add another to mainframe
}
}
);
btnNewGame.setPreferredSize(new Dimension(140,30));
btnJoinGame = new JButton("Join game",iconJoinGame);
mainmenupanel.add(label1);
mainmenupanel.add(btnNewGame);
}
}
}
There is no need for mainmenupanel within the MainMenuPanel class as MainMenuPanel is a JPanel itself
Simple add all the components in MainMenuPanel directly to itself
You create a new JPanel, mainmenupanel, inside MainMenuPanel but never add that to the container itself. You could do
add(mainmenupanel);
If you intend for this JPanel to occupy the full area of the parent, then you can simply add your components directly to your instance of MainMenuPanel as indicated by #Mad
First you should add your component to the ContentPane. In Swing, all the non-menu components displayed by the JFrame should be in the ContentPane.
mainframe.getContentPane().add(new MainMenuPanel());
Edit: I was wrong about the content pane, see #MadProgrammer comment.
Then you have to add the JPanel that you create in MainMenuPanel to the MainMenuPanel instance itself.
add(mainmenupanel);
But you should probably get rid of that intermediary container itself and add your labels to the MainMenuPanel instance itself:
add(label1);
add(btnNewGame);
mainmenupanel.add(label1);
mainmenupanel.add(btnNewGame);
try this :
super.add(label1);
super.add(btnNewGame);

Categories