简体   繁体   中英

Card Layout doesn't change the panel after working the process

So I have this game which I just started making and the first problem I come across while making the game is while changing the panels through card Layout when I do the process it does show me that it is instantiating the object and also it is making the panel show but on visual there is no effect.

The code is as follow:

Original class

public class Parking_Mania {

public static void main(String []args)throws Exception
{
    new GameFrame("Paking Mania");
}
}

The game frame class

 public class GameFrame extends JFrame{

public GameFrame(String name)
{
    this.setTitle(name);
    this.setSize(640,510);
    this.setLocationRelativeTo(null);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setResizable(false);
    this.setVisible(true);  

    Frames frame=new Frames();
    this.add(frame);
    frame.panel.show(frame, "opening");

}
}

panel that changes frames

public class Frames extends JPanel{

CardLayout panel= new CardLayout();

public Frames()
{
    this.setLayout(panel);
    System.out.println("hello");
    Opening op=new Opening();
    nxtframe nf= new nxtframe();
    this.add(op, "opening");
    this.add(nf, "nt");
    }

public void nxtf()
{

    panel.show(this, "nt");
}
}

first panel

public class Opening extends JPanel{



JButton but=new JButton();

public Opening(){

    this.setLayout(null);
    this.setBackground(Color.BLACK);
    add(but);
    but.setText("next frame");
    but.setBounds(0, 0, 110, 120);
    but.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e)
            {                   
                Frames f=new Frames();
                f.nxtf();
            }
        });
}

public void paint(Graphics g)
{
    g.fillRect(110, 120, 110, 120);
}


}

Second Panel

public class nxtframe extends JPanel{

JButton but=new JButton();

public nxtframe(){

    System.out.println("hello");
    this.setLayout(null);
    add(but);
    but.setText("next frame");
    but.setBounds(0, 0, 110, 120);
    but.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e)
            {

            }
        });
}

public void paint(Graphics g)
{
    g.setColor(Color.BLUE);
    g.fillOval(110, 120, 110, 120);
}


}

PS: I didn't bother adding comments as I suppose it is self explanatory. Rest assured if you do need me to add the comments I'll add them right away.

Think critically: what do you think this does: new Frames(); within the ActionListener?

Answer: it creates a NEW (accent on the word "new") Frames object. New, as in completely new, distinct and unrelated to the original. Changing the view on this Frames object will have no effect on the currently displayed Frames object, and so the solution to your problem is to *get a reference to the actual displayed object and call your method that changes cards on it.

One solution is to pass the visualized Frames reference into Opening, say through a constructor paramter, eg, change

Opening op=new Opening();

to:

Opening op = new Opening(this); // pass in the current Frames reference

And then in Opening constructor grab that reference and use it:

public class Opening extends JPanel{
    private JButton but=new JButton();
    private Frames f;

    public Opening(final Frames f){
        this.f = f;
        this.setLayout(null);  // !!!! no don't do this!!!
        this.setBackground(Color.BLACK);
        add(but);
        but.setText("next frame");
        but.setBounds(0, 0, 110, 120);  // and don't do this!
        but.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) { 
                // !!Frames f=new Frames();
                f.nxtf();
            }
        });
    }

    public void paint(Graphics g) {
        g.fillRect(110, 120, 110, 120);
    }
} 

Other unrelated issues:

  • Don't use null layouts. Using them makes your GUI rigid, inflexible and hard to maintain and often non-functioning on other platforms
  • Don't override paint but rather paintComponent, and do call the super's method in the override -- read the tutorial on this Lesson: Performing Custom Painting

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM