How can I change the JPanel from another Class? - java

Hi, I'm new to Java and I have the following problem:
I created a JFrame and I want the JPanel to change when clicking a JButton. That does almost work.The only problem is that the program creates a new window and then there are two windows. One with the first JPanel and one with the second JPanel.
Here is my current code:
first class:
public class Program {
public static void main (String [] args) {
new window(new panel1());
}
}
second class:
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Window extends JFrame {
private static final long serialVersionUID = 1L;
Window(JPanel panel) {
setLocation((int) Toolkit.getDefaultToolkit().getScreenSize().getWidth() / 2 - 200,
(int) Toolkit.getDefaultToolkit().getScreenSize().getHeight() / 2 - 100);
setSize(400, 200);
setTitle("test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setContentPane(panel);
setVisible(true);
}
}
third class:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
public class Panel1 extends JPanel {
private final long serialVersionUID = 1L;
Panel1() {
JButton nextPanelButton = new JButton("click here");
add(nextPanelButton);
ActionListener changePanel = new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
new window(new panel2());
}
};
nextPanelButton.addActionListener(changePanel);
}
}
fourth class:
public class Panel2 extends JPanel {
private static final long serialVersionUID = 1L;
Panel2() {
JLabel text = new JLabel("You pressed the Button!");
add(text);
}
}
But I just want to change the JPanel without opening a new window. Is there a way to do that?
Thanks in advance!

This is a demo
import javax.swing.*;
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new MainFrame("Title").setVisible(true);
});
}
}
MainFrame.java
import javax.swing.*;
import java.awt.*;
public class MainFrame extends JFrame {
private JPanel viewPanel;
public MainFrame(String title) {
super(title);
createGUI();
}
private void createGUI() {
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
setLayout(new BorderLayout());
setMinimumSize(new Dimension(600, 480));
viewPanel = new JPanel(new BorderLayout());
add(viewPanel, BorderLayout.CENTER);
showView(new View1(this));
pack();
}
public void showView(JPanel panel) {
viewPanel.removeAll();
viewPanel.add(panel, BorderLayout.CENTER);
viewPanel.revalidate();
viewPanel.repaint();
}
}
View1.java
import javax.swing.*;
import java.awt.*;
public class View1 extends JPanel {
final private MainFrame owner;
public View1(MainFrame owner) {
super();
this.owner = owner;
createGUI();
}
private void createGUI() {
setLayout(new FlowLayout());
add(new JLabel("View 1"));
JButton button = new JButton("Show View 2");
button.addActionListener(event -> {
SwingUtilities.invokeLater(() -> owner.showView(new View2(owner)));
});
add(button);
}
}
View2.java
import javax.swing.*;
import java.awt.*;
public class View2 extends JPanel {
final private MainFrame owner;
public View2(MainFrame owner) {
super();
this.owner = owner;
createGUI();
}
private void createGUI() {
setLayout(new FlowLayout());
add(new JLabel("View 2"));
JButton button = new JButton("Show View 1");
button.addActionListener(event -> {
SwingUtilities.invokeLater(() -> owner.showView(new View1(owner)));
});
add(button);
}
}

First of all, take a look at Java naming conventions, in particular your class names should start with a capitalized letter.
If you want to avoid to open a new window every time you click the button, you could pass your frame object to Panel1 constructor, and setting a new Panel2 instance as the frame content pane when you click the button. There is also no need to pass Panel1 to Window constructor (please note that Window class is already defined in java.awt package, it would be better to avoid a possible name clash renaming your class ApplicationWindow, MyWindow or something else).
You could change your code like this (only relevant parts):
public class Program
{
public static void main (String [] args) {
SwingUtilities.invokeLater (new Runnable () {
#Override public void run () {
new Window ().setVisible (true);
}
};
}
}
class Window extends JFrame
{
// ...
Window () {
// ...
setContentPane(new Panel1 (this));
}
}
class Panel1 extends JPanel
{
// ...
Panel1 (JFrame parent) {
// ...
ActionListener changePanel = new ActionListener() {
#Override
public void actionPerformed(ActionEvent event) {
parent.setContentPane (new Panel2 ());
}
};
// ...
}
Also note the SwingUtilities's invokeLater call, which is the best way to initialise your GUI in the EDT context (for more info look at this question).
Finally, you could avoid to create a new Panel2 instance every time you click the button, simply by using a CardLayout.
Take a look at the official tutorial.

This is an old post, but it may be useful to answer it in a simplified way. Thanks to mr mcwolf for the first answer.
If we want to make 1 child jframe interact with a main jframe in order to modify its content, let's consider the following case.
parent.java and child.java.
So, in parent.java, we have something like this:
Parent.java
public class Parent extends JFrame implements ActionListener{
//attributes
//here is the class we want to modify
private some_class_to_modify = new some_class_to_modify();
//here is a container which contains the class to modify
private JPanel container = new JPanel();
private some_class = new some_class();
private int select;
//....etc..etc
//constructor
public Parent(){
this.setTitle("My title");
//etc etc
//etc....etc
container.add(some_class_to_modify,borderLayout.CENTER);
}
//I use for instance actionlisteners on buttons to trigger the new JFrame
public void actionPerformed(ActionEvent arg0){
if((arg0.getSource() == source_button_here)){
//Here we call the child class and send the parent's attributes with "this"
Child child = new Child(this);
}
//... all other cases
}//Here is the class where we want to be able to modify our JFrame. Here ist a JPanel (Setcolor)
public void child_action_on_parent(int selection){
this.select = selection;
System.out.println("Selection is: "+cir_select);
if(select == 0) {
//Do $omething with our class to modify
some_class_to_modify.setcolor(Color.yellow);
}
}
In child.java we would have something like this:
public class Child extends JFrame implements ActionListener {
//Again some attributes here
private blabla;
//Import Parent JFrame class
private Parent owner;
private int select_obj=0;
//Constructor here and via Parent Object Import
public Child(Parent owner){
/*By calling the super() method in the constructor method, we call the parent's
constructor method and gets access to the parent's properties and methods:*/
super();
this.owner = owner;
this.setTitle("Select Method");
this.setSize(400, 400);
this.setContentPane(container);
this.setVisible(true);
}
class OK_Button implements ActionListener {
public void actionPerformed(ActionEvent e) {
Object Selection = select;
if(Selection == something) {
select_obj=0;
valid = JOptionPane.showConfirmDialog(null,"You have chosen option 1. Do you want to continue?","Minimum diameter",2);
}
System.out.println("Option is:"+valid);
if(valid == 0) {
setVisible(false);
//Here we can use our herited object to call the child_action_on_parent public class of the Parent JFrame. So it can modify directly the Panel
owner.child_action_on_parent(select_obj);
}
}
}

Related

Utilize a ActionListener object from a separate JFrame class to main class

I am building a GUI program in which specific code takes place when a certain condition is meant (JButton is pressed). I have a seperate class that constructs my Jframe called "MyFrame" .
Essentially I want to know the proper way to use my use a ActionListener/ ActionEvent from my "MyFrame" class in conjunction when a JButton is pressed in which it would correlate properly in the main class.
For example i am able to initiate specific code when a JButton is pressed in my MyFrame class through the actionPerformed provided method by java in my Myframe class, I am just puzzled on how I can make the same thing work through my main class as well.
Any assistance would be appreciated
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Main {
public static void main(String[] args) {
MyFrame mf;
mf= new MyFrame();
Expenses exp ;
BudgetSystem system ;
ActionEvent e ;
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
class MyFrame extends JFrame implements ActionListener {
JFrame myFrame;
JPanel myPanel;
JLabel greetText ;
JButton addReportButton;
JButton exitButton;
ActionListener event ;
BorderLayout layout ;
MyFrame() {
myFrame = new JFrame();
myPanel = new JPanel();
greetText = new JLabel();
addReportButton = new JButton();
exitButton = new JButton();
myPanel.setBorder(null);
myFrame.setPreferredSize(new Dimension(400,300));
greetText.setText("Please choose one of the following options to begin:" );
myPanel.add(greetText);
myFrame.add(myPanel);
addReportButton.setText("Add a budget report");
addReportButton.addActionListener(this);
myPanel.add(addReportButton);
exitButton.setText("Close Program");
exitButton.addActionListener(this);
myPanel.add(exitButton);
myFrame.setVisible(true);
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setLocationRelativeTo(null);
myFrame.pack();
}
#Override
public void actionPerformed(ActionEvent e) {
/*
if (e.getSource()==addReportButton)
{
JOptionPane.showMessageDialog(myFrame,"This button Works!");
}
else if (e.getSource()== dummyButton)
{
JOptionPane.showMessageDialog(myFrame,"This is the dummy button ! , you are targeting specific buttons now ! ... YOU ROCK :) ");
}else
JOptionPane.showMessageDialog(myFrame,"This is does not work :( ");
*/
}
}
I tried to make a specific ActionEvent object in main but that did not work properly.
I also tried to use a MyFrame object to access the actionPerformed method in java but that doesnt seem to work either.
If your goal is to add listeners to a JButton from another class, one option is to give the class that holds the JButton a public method that allows this to happen, for instance:
public void addMyButtonListener(ActionListener listener) {
myButton.addActionListener(listener);
}
This would allow any object that holds an instance of the class that holds the JButton to call this method and pass in a listener.
For instance:
import java.awt.Dimension;
import java.awt.event.ActionListener;
import javax.swing.*;
public class AddOutsideActionListener {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
SomeGUI mainPanel = new SomeGUI();
mainPanel.addMyButtonListener(e -> {
String message = "Message from the main method";
String title = "Message";
int type = JOptionPane.PLAIN_MESSAGE;
JOptionPane.showMessageDialog(mainPanel, message, title, type);
});
JFrame frame = new JFrame("Some GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
class SomeGUI extends JPanel {
public static final int PREF_W = 600;
public static final int PREF_H = 400;
private JButton myButton = new JButton("My Button");
public SomeGUI() {
add(myButton);
setPreferredSize(new Dimension(PREF_W, PREF_H));
}
public void addMyButtonListener(ActionListener listener) {
myButton.addActionListener(listener);
}
}

How to swap JPanel's from an action in a JPanel

I am new(ish) to Java Swing but I have not been able to find an elegant solution to my issue so I thought I'd raise a question here.
I am trying to make my current JPanel change to another JPanel based on a button click event from within the current JPanel. In essence just hiding one panel and displaying the other. I feel this can be done within my MainFrame class however I'm not sure how to communicate this back to it. Nothing I am trying simply seems to do as desired, I'd appreciate any support. Thanks
App.java
public static void main(final String[] args) {
MainFrame mf = new MainFrame();
}
MainFrame.java
public class MainFrame extends JFrame {
public MainFrame(){
setTitle("Swing Application");
setSize(1200, 800);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setVisible(true);
// First Page Frame switch
getContentPane().add(new FirstPage());
}
}
FirstPage.java
public class FirstPage extends JPanel {
public FirstPage() {
setVisible(true);
JButton clickBtn = new JButton("Click");
clickBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
// Change to SecondPage JPanel here.
}
});
add(clickBtn);
}
}
SecondPage.java
public class SecondPage extends JPanel {
public SecondPage() {
setVisible(true);
add(new JLabel("Welcome to the Second Page"));
}
}
Any more information needed, please ask thanks :)
I think the best way is to use CardLayout. It is created for such cases. Check my example:
public class MainFrame extends JFrame {
private CardLayout cardLayout;
public MainFrame() {
super("frame");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
cardLayout = new CardLayout();
getContentPane().setLayout(cardLayout);
getContentPane().add(new FirstPage(this::showPage), Pages.FIRST_PAGE);
getContentPane().add(new SecondPage(this::showPage), Pages.SECOND_PAGE);
setLocationByPlatform(true);
pack();
}
public void showPage(String pageName) {
cardLayout.show(getContentPane(), pageName);
}
public static interface PageContainer {
void showPage(String pageName);
}
public static interface Pages {
String FIRST_PAGE = "first_page";
String SECOND_PAGE = "second_page";
}
public static class FirstPage extends JPanel {
public FirstPage(PageContainer pageContainer) {
super(new FlowLayout());
JButton button = new JButton("next Page");
button.addActionListener(e -> pageContainer.showPage(Pages.SECOND_PAGE));
add(button);
}
}
public static class SecondPage extends JPanel {
public SecondPage(PageContainer pageContainer) {
super(new FlowLayout());
add(new JLabel("This is second page."));
JButton button = new JButton("Go to first page");
button.addActionListener(e -> pageContainer.showPage(Pages.FIRST_PAGE));
add(button);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new MainFrame().setVisible(true));
}
}
CardLayout is the right tool for the job.
You can simply create the ActionListener used to swap pages in JFrame class, and pass a reference of it to FirstPage:
import java.awt.CardLayout;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class MainFrame extends JFrame {
public MainFrame(){
setTitle("Swing Application");
setSize(1200, 800);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLocationByPlatform(true);
//Create card layout and set it to the content pane
CardLayout cLayout = new CardLayout();
setLayout(cLayout);
//create and add second page to the content pane
JPanel secondPage = new SecondPage();
add("SECOND",secondPage);
//create an action listener to swap pages
ActionListener listener = actionEvent ->{
cLayout.show(getContentPane(), "SECOND");
};
//use the action listener in FirstPage
JPanel firstPage = new FirstPage(listener);
add("FIRST", firstPage);
cLayout.show(getContentPane(), "FIRST");
setVisible(true);
}
public static void main(String[] args) {
new MainFrame();
}
}
class FirstPage extends JPanel {
public FirstPage(ActionListener listener) {
JButton clickBtn = new JButton("Click");
clickBtn.addActionListener(listener);
add(clickBtn);
}
}
class SecondPage extends JPanel {
public SecondPage() {
add(new JLabel("Welcome to the Second Page"));
}
}

Can't get Jframe to close when user hits (X)

I cannot get my Jframe to close when a user hits the (X) button. I tried many ways to do them but none of them work.
I tried:
JFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Nothing happens. My main class extends jframe and implements action listener. What am I doing wrong?
My code:
package com.xflare.Bot;
import static java.lang.System.out;
import java.awt.*;
import java.lang.String;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Main extends JFrame implements ActionListener{
private static Frame frame;
private static boolean debug = true;
private static boolean enabled = true;
private static JButton exitbutton; // reference to the button object
private static JButton webbutton; // reference to the button object
private static JButton aboutbutton; // reference to the button object
public static void main(String[] args) {
new Main().start();
}
private void start(){
//start up
printSystem("starting");
//create frame
printSystem("Creating a frame...");
createFrame();
//create button(s)
createQuitButton();
createWebButton();
createAboutButton();
//Spawn init.
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getFrame().setResizable(false);
getFrame().setVisible(true);
printSystem("Started up successfully!");
}
private void createFrame(){
Main.frame = new Frame("app");
frame.setSize(600, 300);
}
private void createQuitButton(){
exitbutton = new JButton("Exit!");
getFrame().setLayout(null);
exitbutton.setBounds(225,45,150,75);//setBounds(x,y,width,height)
exitbutton.setActionCommand("exit");
exitbutton.addActionListener(this);
getFrame().add(exitbutton);
}
private void createWebButton(){
webbutton = new JButton("Open hacked browser");
getFrame().setLayout(null);
webbutton.setBounds(225,130,150,75);//setBounds(x,y,width,height)
webbutton.setActionCommand("web");
webbutton.addActionListener(this);
getFrame().add(webbutton);
}
private void createAboutButton(){
aboutbutton = new JButton("About");
getFrame().setLayout(null);
aboutbutton.setBounds(225,215,150,75);//setBounds(x,y,width,height)
aboutbutton.setActionCommand("about");
aboutbutton.addActionListener(this);
getFrame().add(aboutbutton);
}
private Frame getFrame(){
return Main.frame;
}
public void actionPerformed(ActionEvent e) {
String actionCommand = ((JButton) e.getSource()).getActionCommand();
printDebug("Button " + actionCommand + " was pressed.");
if(actionCommand.equals("exit")){
exitbutton.setVisible(false);
shutdown();
}
else if(actionCommand.equals("about")){
aboutbutton.setVisible(false);
webbutton.setVisible(false);
exitbutton.setVisible(false);
showAbout();
}
else{
printCritical("Unknown button pressed!");
}
}
private void showAbout(){
}
private void shutdown(){
printSystem("Attempting to shut down...");
enabled = false;
printSystem("Shut down successful!");
System.exit(0);
}
private boolean debugEnabled(){
return debug;
}
private String getVersion(){
return "1.0.0";
}
private String getCodename(){
return "[BeastReleased]";
}
private static void printSystem(String var){
out.println("System> " + var);
}
private static void printError(String var){
out.println("Error> " + var);
}
private static void printCritical(String var){
out.println("Critical> " + var);
}
private void printDebug(String var){
if(debugEnabled()) {
out.println("Debug> " + var);
}
}
}
Link to same code: http://pastebin.com/1fDbjm74
This: setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
needs to be called on the JFrame that you're actually displaying, Main.frame. You're not doing this.
getFrame().setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
getFrame().setVisible(true);
You've got too many Frame / JFrames. Your class extends JFrame but you're not displaying it. You've also got a Frame variable called frame, (NOT a JFrame variable) that you are displaying, and of course since this is not a JFrame, you can't make JFrame method calls, like the one above on it.
Simplify: create ONE JFrame not a Frame, and call this method on it and set it visible. So either get rid of the frame variable and use the class itself, the this, as your JFrame, and display it, or don't have your class extend JFrame and use your frame variable, but make it a JFrame object not a Frame object, since Frame does not have the setDefaultCloseOperation(...) method.
Also you're over-using static modifiers where they shouldn't be used. All your fields should be instance (non-static) fields.
Also, use of null layouts and setBounds will bite you in the end. For instance when I run your program, portions of the middle button's text are missing because its size has been artificially constrained in a bad way. Much better is to us layout managers to your advantage. For example:....
Please have a look at this program structure:
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Font;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class MyMain extends JPanel {
public static final String MENU_PANEL = "MENU";
public static final String ABOUT_PANEL = "About";
private CardLayout cardLayout = new CardLayout();
public MyMain() {
JPanel aboutPanel = new JPanel(new GridBagLayout());
JLabel aboutLabel = new JLabel("About");
aboutLabel.setFont(aboutLabel.getFont().deriveFont(Font.BOLD, 32));
aboutPanel.add(aboutLabel);
JPanel buttonPanel = new JPanel(new GridLayout(0, 1, 10, 10));
buttonPanel.add(createButton(new ExitAction("Exit!", KeyEvent.VK_X)));
buttonPanel.add(createButton(new OpenBrowserAction("Open Hacked Browser", KeyEvent.VK_O)));
buttonPanel.add(createButton(new AboutAction("About", KeyEvent.VK_A, this)));
JPanel menuPanel = new JPanel(new GridBagLayout());
int ebGap = 40;
menuPanel.setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
menuPanel.add(buttonPanel);
setLayout(cardLayout);
add(menuPanel, MENU_PANEL);
add(aboutPanel, ABOUT_PANEL);
}
private JButton createButton(Action action) {
JButton button = new JButton(action);
Font btnFont = button.getFont().deriveFont(Font.BOLD, 20);
button.setFont(btnFont);
return button;
}
private static void createAndShowGui() {
JFrame frame = new JFrame("My Main Application");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new MyMain());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
public void showPanel(String cardLayoutKey) {
cardLayout.show(this, cardLayoutKey);
}
}
class ExitAction extends AbstractAction {
public ExitAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
Component comp = (Component) e.getSource();
if (comp != null) {
Window win = SwingUtilities.getWindowAncestor(comp);
if (win != null) {
win.dispose();
}
}
}
}
class OpenBrowserAction extends AbstractAction {
public OpenBrowserAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("Open Browswer");
}
}
class AboutAction extends AbstractAction {
private MyMain myMain;
public AboutAction(String name, int mnemonic, MyMain myMain) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
this.myMain = myMain;
}
#Override
public void actionPerformed(ActionEvent e) {
if (myMain != null) {
myMain.showPanel(MyMain.ABOUT_PANEL);
}
}
}
You are calling the setDefaultCloseOperation method on the wrong place. Here's what you should do:
private void start(){
//start up
printSystem("starting");
//create frame
printSystem("Creating a frame...");
createFrame();
//Spawn init.
getFrame().setResizable(false);
getFrame().setVisible(true);
printSystem("Started up successfully!");
}
private void createFrame(){
Main.frame = new Frame("app");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 300);
}

Use variables from other class from other file to another in java

There are two players who will input their name in the JTextFields. What I want to do is that the data I entered from the Welcome frame in Enter.java will be transferred to the JLabels in ActualGame.java.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
public class Enter extends JFrame implements ActionListener {
private String one = "";
private String two = "";
private JTextField txtOne = new JTextField();
private JTextField txtTwo = new JTextField();
public Enter() {
this.setLayout(new FlowLayout());
setDefaultCloseOperation(EXIT_ON_CLOSE);
setTitle("Welcome");
setSize(200, 130);
setVisible(true);
setResizable(false);
setLocationRelativeTo(null);
add(txtOne);
add(txtTwo);
enter.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
Main main = new Main();
this.setVisible(false);
one = txtOne.getText();
two = txtTwo.getText();
}
}
Main is the main class that holds the JFrame of ActualGame() and also the main class of Enter().
import javax.swing.*;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
public class Main extends JFrame {
public Main() {
add(new ActualGame());
setDefaultCloseOperation(EXIT_ON_CLOSE);
setTitle("Main");
setSize(400, 557);
setVisible(true);
setResizable(false);
setLocationRelativeTo(null);
}
public static void main(String[] args) {
Enter enter=new Enter();
}
}
the ActualGame:
import java.awt.*;
import javax.swing.*;
public class ActualGame extends JPanel{
private JLabel lblOne = new JLabel(one);//how i wish it would be that easy
private JLabel lblTwo = new JLabel(two);
public ActualGame() {
setLayout(new FlowLayout());
add(lblOne);
add(lblTwo);
}
}
What should I do to be able to use the String variable one and two from Enter.java to ActualGame.java?
I'm new and noob in programming especially java swing. Open to criticisms and suggestions. Thank you.
Suggestions:
Passing information from one object to another is no different with Swing as with other Java programs. You can call methods or constructors and pass information in via parameters.
A key difference though is when to pass information. With event driven programs, this is often triggered by an event, a listener, and so use of the observer design pattern is comment.
For your purposes, the first window could be a modal dialog such as a JOptionPane or a modal JDialog which will make it easier to figure out when to pass information. When using a modal dialog, all code flow in the calling program is paused while the dialog is visible, and then resumes once the dialog is no longer visible. It's easy then to have the calling program query the dialog once this occurs, because you'll know precisely where in your code this will occur.
You'll want to avoid excessive showing of different windows in your application as it can quickly get annoying to the user. A few dialogs here and there are OK, especially if you need the information to be given in a modal fashion, but in general it's better to swap GUI "views" when needed, and a CardLayout is good for this.
But having said this, separate views are often created by separate classes, so the problem of passing information back and forth remains a problem with similar solutions as described above.
Specifically, give your Enter class a getText method that will allow other objects to query it for the state of its JTextField:
public String getTxtOneText() {
return txtOne.getText();
}
Also, change your ActualGame class so that it can accept String information when needed:
class ActualGame extends JPanel {
private JLabel lblOne = new JLabel();
public ActualGame(String text) {
lblOne.setText(text);
setLayout(new FlowLayout());
add(lblOne);
}
public void setLblOneText(String text) {
lblOne.setText(text);
}
}
e.g.,
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Foo {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
ActualGame actualGame = new ActualGame("");
Main main = new Main(actualGame);
main.pack();
Enter enter = new Enter(main);
enter.setVisible(true);
actualGame.setLblOneText(enter.getTxtOneText());
main.pack();
main.setLocationRelativeTo(null);
main.setVisible(true);
}
});
}
}
class Enter extends JDialog implements ActionListener {
private String one = "";
private JTextField txtOne = new JTextField(10);
private JButton enter = new JButton("Enter");
public Enter(JFrame frame) {
super(frame, "Welcome", true);
this.setLayout(new FlowLayout());
enter.addActionListener(this);
txtOne.addActionListener(this);
add(txtOne);
add(enter);
pack();
setLocationRelativeTo(null);
// this has to be done last
// setVisible(true);
}
public String getTxtOneText() {
return txtOne.getText();
}
public void actionPerformed(ActionEvent e) {
setVisible(false);
}
}
class Main extends JFrame {
ActualGame actualGame;
public Main(ActualGame actualGame) {
super("Main");
this.actualGame = actualGame;
add(actualGame);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class ActualGame extends JPanel {
private JLabel lblOne = new JLabel();
public ActualGame(String text) {
lblOne.setText(text);
setLayout(new FlowLayout());
add(lblOne);
}
public void setLblOneText(String text) {
lblOne.setText(text);
}
}
Try to make ActualGam as a underclass of Enter
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
public class Enter extends JFrame implements ActionListener {
private String one = "";
private JTextField txtOne = new JTextField();
public Enter() {
this.setLayout(new FlowLayout());
setDefaultCloseOperation(EXIT_ON_CLOSE);
setTitle("Welcome");
setSize(200, 130);
setVisible(true);
setResizable(false);
setLocationRelativeTo(null);
add(txtOne);
enter.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
Main main = new Main();
this.setVisible(false);
one = txtOne.getText();
}
class ActualGame extends JPanel{
private JLabel lblOne = new JLabel(one);
public ActualGame() {
setLayout(new FlowLayout());
Enter.this.add(lblOne);
}
}
}

Sending Jframe Jtextfield to another class

I have a JFrame that has a textfield and a button. It should become visible at the start of program and when I click on the button, It should become invisible and send the text of textfield to another class. but It send nothing and when I click on the button the IDE goes to the debug mode.
public class JframeFoo extends JFrame {
private String username = new String();
public JframeFoo() {
// --------------------------------------------------------------
// Making Frame for login
final JTextField usernameFiled = new JTextField();
this.add(usernameFiled);
JButton signinButton = new JButton();
// ------------------------------------------------------------
signinButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
username = usernameFiled.getText();
setVisible(false);
Main.mainpage.setVisible(true);
}
});
// --------------------------------------------------------------------------
}
public String getuserName() {
return this.username;
}
}
my another class calls Jframe:
System.out.println(JframeFoo.getusername);
Ignoring for a moment that having multiple JFrames jumping out at the user is not a great user interface design, for one object to communicate with another object, it must have a valid reference to the other object. (sorry interrupted by daughter).
So for one JFrame class to get information from the other, it must have a reference to the first object that gets the text, and I don't see you passing that reference, such as in a constructor or setter method.
So for instance if an object of Class1 has information that an object of Class2 needs, then one way to pass it is to give Class2 a reference to the valid instance of Class1, and then have Class2 get the information from the Class1 instance. e.g.,
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class ClassMain {
private static void createAndShowGui() {
ClassMain mainPanel = new ClassMain();
JFrame frame = new Class1();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class Class1 extends JFrame {
private JTextField textfield = new JTextField(10);
public Class1() {
JPanel contentPane = (JPanel) getContentPane();
contentPane.setLayout(new FlowLayout());
add(textfield);
add(new JButton(new AbstractAction("Open Window") {
#Override
public void actionPerformed(ActionEvent arg0) {
Class2 class2 = new Class2(Class1.this);
Class1.this.setVisible(false);
class2.pack();
class2.setVisible(true);
class2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}));
}
public String getTextfieldText() {
return textfield.getText();
}
}
class Class2 extends JFrame {
private Class1 class1;
private JLabel label = new JLabel("");
public Class2(Class1 class1) {
this.class1 = class1;
label.setText(class1.getTextfieldText());
add(label);
}
}

Categories