1

I have two views : test1 and test2

Switching from test1 to test 2 works fine, but when I switch back from test2 the contentPanel is empty. This is my code. Can someone point out what I'm doing wrong?

test1

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;


public class test1 extends JFrame {

JPanel contentPane;

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

/**
 * Create the frame.
 */
public test1() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    setContentPane(contentPane);

    JButton btnView = new JButton("View2");
    contentPane.add(btnView, BorderLayout.CENTER);
    btnView.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            contentPane.removeAll();
            contentPane.invalidate();
            test2 obj=new test2();
            obj.contentPane.setVisible(true);
            contentPane.add(obj.contentPane);
            ((JPanel)contentPane).revalidate();
            contentPane.repaint();          }
    });
}

}

test2

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;

public class test2 extends JFrame {

JPanel contentPane;

/**
 * Launch the application.
 */
public static void main(String[] args) {

    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                test2 frame = new test2();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public test2() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    JLabel lblThisIsView = new JLabel("this is view 2!");
    lblThisIsView.setBounds(178, 107, 110, 14);
    contentPane.add(lblThisIsView);

    JButton btnView = new JButton("View 1!");
    btnView.setBounds(168, 161, 89, 23);
    contentPane.add(btnView);

    btnView.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            contentPane.removeAll();
            contentPane.invalidate();
            test1 obj=new test1();
            obj.contentPane.setVisible(true);
            contentPane.add(obj.contentPane);
            ((JPanel)contentPane).revalidate();
            contentPane.repaint();
        }
    });
}
    }
mKorbel
  • 109,525
  • 20
  • 134
  • 319
Karthik Balakrishnan
  • 4,353
  • 6
  • 37
  • 69
  • What do you mean by switching? You run in this sequence? test1 > test2 > test2? Am I right? – Michael 'Maik' Ardan Dec 05 '12 at 08:40
  • Yeah, when I'm in test1 I want to go to test2 and vice versa. It works from test1 to test2 but not the other way round. – Karthik Balakrishnan Dec 05 '12 at 08:45
  • 2
    Take a look at [How to use CardLayouts](http://docs.oracle.com/javase/tutorial/uiswing/layout/card.html), it'll do what you're trying to achieve, only simpler – MadProgrammer Dec 05 '12 at 08:53
  • +1 for sscce, +1 to @MadProgrammers comment, see here for more [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/questions/9554636/the-use-of-multiple-jframes-good-bad-practice) you could also use `JDialog` 1) do not extend `JFrame` class unnecessarily. 2) use a [`LayoutManager`](http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html), not `null`/`Absolute` Layout – David Kroukamp Dec 05 '12 at 09:01

2 Answers2

3

It's a basic problem with layouts. In test1.java you have added the components with BorderLayout. But not in test2.java.

The layout of test2 should be BorderLayout. After that all the components should be added with below syntax -

contentPane.add(lblThisIsView,BorderLayout.CENTER);

Completed code of test2.java -

public test2() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(new BorderLayout(0, 0));

        JLabel lblThisIsView = new JLabel("this is view 2!");
        lblThisIsView.setBounds(178, 107, 110, 14);
        contentPane.add(lblThisIsView,BorderLayout.CENTER);

        JButton btnView = new JButton("View 1!");
        btnView.setBounds(168, 161, 89, 23);
        contentPane.add(btnView,BorderLayout.SOUTH);

        btnView.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                contentPane.removeAll();
                contentPane.invalidate();
                test1 obj = new test1();
                obj.contentPane.setVisible(true);
                contentPane.add(obj.contentPane);
                ((JPanel) contentPane).revalidate();
                contentPane.repaint();
            }
        });
    }

Total code is here.


As seen from comments best way is to use CardLayout - To add panels -

public CardLayoutHelper(JPanel panel, JPanel... panels) {
        this(panel);
        for (int i = 0; i < panels.length; i++) {
            JPanel jPanel = panels[i];
            panel.add(jPanel.getName(), jPanel);
        }
    }

To switch the Panel -

 public void switchPanel(String name) {
            layout.show(panel, name);
            panel.revalidate();
            panel.repaint();
        }

You can get the CardLayoutHelper from github.

Chan
  • 2,601
  • 6
  • 28
  • 45
  • yep i agree... But I wanted to find the problem in the code. `CardLayout` definitely is the best solution. Edited the question for it. – Chan Dec 05 '12 at 09:02
  • That works only for the label. If I pass the entire content as the parameter it doesn't work. – Karthik Balakrishnan Dec 05 '12 at 09:13
  • It works for the button as well. You have to change - `contentPane.add(btnView,BorderLayout.SOUTH);`. – Chan Dec 05 '12 at 09:17
  • No, thing is I want the entire thing added at a go. The whole content pane. In my main project I have too many elements to add manually. – Karthik Balakrishnan Dec 05 '12 at 09:23
  • But then the layouts should match. But for these kind of cases use the `CardLayoutHelper`. Because it's never acceptable to use Many jFrames in a production application – Chan Dec 05 '12 at 09:30
-2

To the current frame I just set:

"classname.this.setVisible(false);"

Frame switching works fine now. It isn't the right method but my project submission is today and the solution is simple enough to implement everywhere.

Karthik Balakrishnan
  • 4,353
  • 6
  • 37
  • 69