【问题标题】:Call method from a panel at another class(the method) that terminats current panel从终止当前面板的另一个类(方法)的面板调用方法
【发布时间】:2014-05-18 07:12:20
【问题描述】:

我有三个类 {FirstFrame, Login, Register} ...FirstFrame 中有一个方法可以在 LogiRegister 之间切换

FirstFrame 代码:

public class FirstFrame extends javax.swing.JFrame {

public FirstFrame() {
    initComponents();
    setLayout(new BorderLayout());
    changeTo(Login.class);        
}

public void changeTo(Class<?> c){
    getContentPane().removeAll();
    try {
        Object obj = c.newInstance();
        getContentPane().add((Component) obj);
        pack();
        setVisible(true);
        System.out.println("here");
    } catch (InstantiationException ex) {
        Logger.getLogger(FirstFrame.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        Logger.getLogger(FirstFrame.class.getName()).log(Level.SEVERE, null, ex);
    }

}
}

Register我有一个存储数据的按钮然后返回Login(假设)

如果我从FirstFrame 内的任何按钮调用,效果很好

这里的问题是如何从Register 内部调用changeTo(Class&lt;?&gt; c)

【问题讨论】:

  • @peeskillet 感谢您的高光 :)

标签: java swing class methods jpanel


【解决方案1】:
  1. 使用CardLayout 来帮助您进行交换,因为这正是它的用途。
  2. 为 FirstFrame 提供一个公共方法,允许其他类进行交换。
  3. 将 FirstFrame 的实例传递给需要调用此方法的对象。这可以通过构造函数或 setter 方法参数来完成。

例如,

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.*;

public class FirstFrame extends JPanel {
   private static final int PREF_W = 400;
   private static final int PREF_H = 300;
   private Login login = new Login(this);
   private Register register = new Register(this);
   private CardLayout cardLayout = new CardLayout();

   public FirstFrame() {
      setLayout(cardLayout);
      add(login, Login.class.toString());
      add(register, Register.class.toString());
   }

   public void swapCards(String key) {
      cardLayout.show(this, key);
   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private static void createAndShowGui() {
      FirstFrame mainPanel = new FirstFrame();

      JFrame frame = new JFrame("FirstFrame");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class SwapCardAction extends AbstractAction {
   private String key;
   private FirstFrame firstFrame;

   public SwapCardAction(String name, int mnemonic, String key,
         FirstFrame firstFrame) {
      super(name);
      this.key = key;
      this.firstFrame = firstFrame;
      putValue(MNEMONIC_KEY, mnemonic);
   }

   @Override
   public void actionPerformed(ActionEvent evt) {
      firstFrame.swapCards(key);
   }
}

class Register extends JPanel {

   public Register(final FirstFrame firstFrame) {
      setBackground(new Color(255, 200, 200));
      JButton gotToLoginBtn = new JButton(new SwapCardAction("Login",
            KeyEvent.VK_L, Login.class.toString(), firstFrame));
      JPanel btnPanel = new JPanel();
      btnPanel.setOpaque(false);
      btnPanel.add(gotToLoginBtn);

      setLayout(new BorderLayout());
      JLabel label = new JLabel("Register", SwingConstants.CENTER);
      add(label, BorderLayout.CENTER);
      add(btnPanel, BorderLayout.SOUTH);
   }

}

class Login extends JPanel {

   public Login(FirstFrame firstFrame) {
      JButton gotToRegisterBtn = new JButton(new SwapCardAction("Register",
            KeyEvent.VK_R, Register.class.toString(), firstFrame));
      setBackground(new Color(150, 200, 255));
      JPanel btnPanel = new JPanel();
      btnPanel.add(gotToRegisterBtn);
      btnPanel.setOpaque(false);

      setLayout(new BorderLayout());
      JLabel label = new JLabel("Login", SwingConstants.CENTER);
      add(label, BorderLayout.CENTER);
      add(btnPanel, BorderLayout.SOUTH);
   }

}

【讨论】:

  • 是的,我的朋友可以节省一天时间 :D ... 或者我应该说节省时间(这里是凌晨 4:40 :P)非常感谢 :)
  • 只是一件事......它不相关! ...但是当面板更改时(它们的尺寸不同)pack() 方法不打包:D ...任何想法或参考将不胜感激:)
【解决方案2】:

我可以建议的最简单的解决方案是将FirstFrame 的引用传递给RegisterLogin 的构造函数;或添加另一个 controller 并将其传递给该控制器。

【讨论】:

    【解决方案3】:

    这就是我在 - @Hovercraft Full Of Eels - 以及 - @Elliott Frisch 的简单想法的帮助下所做的 - :

    public class FirstFrame extends javax.swing.JFrame {
    
    
    JPanel cards;
    
    public FirstFrame() {
        initComponents();
    
        cards = new JPanel(new CardLayout());
    
        cards.add(new Login(), "login");
        cards.add(new Register(this), "reg"); //Passing the FirstFrame instance here
    
        setLayout(new BorderLayout());
        add(cards);
    
        changeCard("login"); // Switching Cards
    
        setLocationByPlatform(true);
    
        setVisible(true);
    }
    
    public void changeCard(String cName){
        CardLayout cl = (CardLayout) cards.getLayout();
        cl.show(cards, cName);
    
        pack();
    }
    }
    

    至于注册类:

    public class Register extends javax.swing.JPanel {
    
    FirstFrame firstf;
    
    public Register(FirstFrame ff) {
        initComponents();
        firstf = ff;
    }
    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt)  {                                         
        firstf.changeCard("login");
    
    }     
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-06
      • 1970-01-01
      • 2017-10-10
      • 1970-01-01
      • 2016-11-16
      • 2014-05-23
      • 2012-06-02
      相关资源
      最近更新 更多