在CardLayout中的类之间传递数据

时间:2012-11-21 17:22:07

标签: java swing methods cardlayout

请查看以下代码

WizardPanel.java

package wizardGUI;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class WizardPanel extends JDialog
{
    private JPanel cardPanel, buttonPanel;
    private JButton next,previous;
    private CardLayout c1;

    private FileSelector fileSelector;
    private DelemeterSelector delemeterSelector;

    private int count = 1;

    public WizardPanel()
    {
        //Intializing instance variables
        fileSelector = FileSelector.getInstance();
        delemeterSelector = DelemeterSelector.getInstance();

        cardPanel = new JPanel();
        c1 = new CardLayout();
        cardPanel.setLayout(c1);

        cardPanel.add(fileSelector,"1");
        cardPanel.add(delemeterSelector,"2");

        c1.show(cardPanel, "1");;


        buttonPanel = new JPanel();
        buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));

        next = new JButton("Next");
        next.addActionListener(new NextButtonAction());
        previous = new JButton("Previous");

        buttonPanel.add(next);
        buttonPanel.add(previous);

        //Creating the GUI
        this.setLayout(new BorderLayout());
        this.add(cardPanel,"Center");
        this.add(buttonPanel,"South");

        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        this.setResizable(true);
        this.pack();
        this.setVisible(true);

    }

    private class NextButtonAction implements ActionListener
    {
        public void actionPerformed(ActionEvent ae)
        {

                c1.show(cardPanel, "2");

        }
    }
}

FileSelector.java

package wizardGUI;

/*This is the first panel is wazard GUI. Using this window user can select the correct file
  which contains the data required to create the table
 */

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class FileSelector extends JPanel
{
    private JLabel fileName, description;
    private JTextField fileTxt;
    private JButton browse;

    private GridBagLayout gbl;
    private GridBagConstraints gbc;

    private static FileSelector instance = null;

    private FileSelector()
    {
        //Intializing instance variables
        fileName = new JLabel("File Name: ");
        description = new JLabel("Specify the source of the data");

        fileTxt = new JTextField(10);

        browse = new JButton("Browse");

        gbl = new GridBagLayout();
        gbc = new GridBagConstraints();

        //Creating GUI
        this.setLayout(gbl);

        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.weightx = 0.0;
        gbc.weighty = 0.0;
        gbc.fill = GridBagConstraints.BOTH;
        this.add(description,gbc);

        gbc.gridx = 1;
        gbc.gridy = 2;
        gbc.weightx = 1.0;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.insets = new Insets(0,10,0,0);
        this.add(locationPanel(),gbc);

        this.setBorder(BorderFactory.createEmptyBorder());
    }

    private JPanel locationPanel()
    {
        JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout());

        panel.add(fileName);
        panel.add(fileTxt);
        panel.add(browse);

        return panel;
    }

    public static FileSelector getInstance()
    {
        if(instance==null)
        {
            instance = new FileSelector();
        }

        return instance;
    }
}

DelemeterSelector.java

/*This is the second windows in wizard
This class is designed to let the user to select the delemeter to break information */

package wizardGUI;

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;

public class DelemeterSelector extends JPanel
{
    private JLabel description;
    private JRadioButton tabBtn, semicolanBtn, commaBtn, spaceBtn;
    private JTextArea txtArea;
    private JScrollPane scroll;
    private ButtonGroup btnGroup;

    private GridBagLayout gbl;
    private GridBagConstraints gbc;

    private static DelemeterSelector instance = null;

    private DelemeterSelector()
    {
        //Initializing instance variables
        description = new JLabel("What delemeter separates your fields? Select the appropreiate delemeter");

        tabBtn = new JRadioButton("Tab");
        semicolanBtn = new JRadioButton("Semicolan");
        commaBtn = new JRadioButton("Comma");
        spaceBtn = new JRadioButton("Space");

        btnGroup = new ButtonGroup();
        btnGroup.add(tabBtn);
        btnGroup.add(semicolanBtn);
        btnGroup.add(commaBtn);
        btnGroup.add(spaceBtn);

        txtArea = new JTextArea(20,70);

        scroll = new JScrollPane(txtArea);

        gbl = new GridBagLayout();
        gbc = new GridBagConstraints();

        this.setLayout(gbl);

        //Creating the GUI
        gbc.gridx = 1;
        gbc.gridy = 1;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.insets = new Insets(20,0,0,0);
        this.add(description,gbc);

        gbc.gridx = 1;
        gbc.gridy = 2;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.insets = new Insets(20,0,0,0);
        this.add(radioPanel(),gbc);

        gbc.gridx = 1;
        gbc.gridy = 3;
        gbc.insets = new Insets(10,0,0,0);
        gbc.fill = GridBagConstraints.BOTH;
        this.add(scroll,gbc);
    }

    private JPanel radioPanel()
    {
        JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout());

        panel.add(tabBtn);
        panel.add(semicolanBtn);
        panel.add(commaBtn);
        panel.add(spaceBtn);

        panel.setBorder(BorderFactory.createTitledBorder("Choose the Delimeter that seperates your fields"));

        return panel;
    }

    public static DelemeterSelector getInstance()
    {
        if(instance == null)
        {
            instance = new DelemeterSelector();
        }

        return instance;
    }
}

Main.java

package wizardGUI

    import java.awt.event.*;
    import java.awt.*;
    import javax.swing.*;

    public class Main extends JFrame
    {
        public Main()
        {
            new WizardPanel().setVisible(true);
        }

        public static void main(String[]args)
        {
            try
            {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                new Main();
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
    }

在这里,我们只有两个按钮“Next”和“Previous”,它们适用于所有JPanel,因为它出现在“WizardPanel”的“South”中,而其他JPanel则位于中心。

现在,我们来看看“FileSelector”。猜猜我使用浏览按钮选择了一个文件。

现在我该如何将这些信息发送到下一个面板?这意味着“DelemeterSelector”?我只有2个'COMMON'按钮“Next”和“previous”位于另一个类中。 我不认为在“Next”或“Previous”按钮的actionListener中编写业务逻辑(从'FileSelector'获取所选文件并将其发送到'DelemeterSelector')是一个好主意。因为,我必须访问另一个类,获取数据并将其发送到下一个JPanel(下一个类)。将会有更多的JPanels,所以这将是非常困难并且无法确定。

我想到为每个JPanel而不是普通的JPanel添加“Next”和“Previous”按钮。但问题是从一个面板转移到另一个面板,因为缺少对CardLayout的引用。

请帮助我找到一种正确有效的方法,在此向导中将数据从一个类传递到另一个类。感谢。

PS:

我不想在“下一步”按钮动作类中进行条件检查,并让它保留所有动作。有关示例,请参阅以下示例代码段

//NON TESTED, NON COMPILED EXAMPLE CODE.
private class NextButtonAction implements ActionListener
{
         public void actionPerformed(ActionEvent ae)
         {

              if(fileSelector.isVisible(true))
              {
                  //Access FileSelector
                  // Get the Data
                  // send data into delemeter class
               }
               else if(delemeterSelector.isVisible(true))
               {
                  //Access delemeterSelector
                  // Get the Data
                  // send data into other class
               }
                else if(SOME_OTHER_CLASS.isVisible(true))
               {
                  //Access delemeterSelector
                  // Get the Data
                  // send data into other class
               }
       }
}

1 个答案:

答案 0 :(得分:5)

午休时间结束了,所以我有时间发布示例代码,但我会在一天结束前回来解释:

import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;

public class MainGui {
   public MainGui() {
      new WizardPanel().setVisible(true);
   }

   public static void main(String[] args) {
      try {
         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
         new MainGui();
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

class WizardPanel extends JDialog {
   private JPanel cardPanel, buttonPanel;
   private JButton next, previous;
   private CardLayout c1;
   private SimpleModel simpleModel = new SimpleModel();

   private FileSelector fileSelector;
   private DelemeterSelector delemeterSelector;

   private int count = 1;

   public WizardPanel() {
      fileSelector = FileSelector.getInstance();
      delemeterSelector = DelemeterSelector.getInstance();

      fileSelector.setModel(simpleModel); //!!
      delemeterSelector.setModel(simpleModel); //!!

      cardPanel = new JPanel();
      c1 = new CardLayout();
      cardPanel.setLayout(c1);

      cardPanel.add(fileSelector, "1");
      cardPanel.add(delemeterSelector, "2");

      c1.show(cardPanel, "1");

      buttonPanel = new JPanel();
      buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));

      next = new JButton("Next");
      next.addActionListener(new NextButtonAction());
      previous = new JButton("Previous");

      buttonPanel.add(next);
      buttonPanel.add(previous);

      // Creating the GUI
      this.setLayout(new BorderLayout());
      this.add(cardPanel, "Center");
      this.add(buttonPanel, "South");

      this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      this.setResizable(true);
      this.pack();
      this.setVisible(true);

   }

   private class NextButtonAction implements ActionListener {
      public void actionPerformed(ActionEvent ae) {

         // c1.show(cardPanel, "2");
         c1.next(cardPanel); //!!

      }
   }
}

class FileSelector extends JPanel {
   private JLabel fileName, description;
   private JTextField fileTxt;
   private JButton browse;

   private GridBagLayout gbl;
   private GridBagConstraints gbc;
   private SimpleModel simpleModel;

   private static FileSelector instance = null;

   private FileSelector() {
      // Intializing instance variables
      fileName = new JLabel("File Name: ");
      description = new JLabel("Specify the source of the data");

      fileTxt = new JTextField(10);

      browse = new JButton("Browse");
      browse.addActionListener(new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent e) {
            if (simpleModel != null) {
               simpleModel.setFileText(fileTxt.getText());
            }
         }
      });

      gbl = new GridBagLayout();
      gbc = new GridBagConstraints();

      // Creating GUI
      this.setLayout(gbl);

      gbc.gridx = 1;
      gbc.gridy = 1;
      gbc.weightx = 0.0;
      gbc.weighty = 0.0;
      gbc.fill = GridBagConstraints.BOTH;
      this.add(description, gbc);

      gbc.gridx = 1;
      gbc.gridy = 2;
      gbc.weightx = 1.0;
      gbc.fill = GridBagConstraints.BOTH;
      gbc.insets = new Insets(0, 10, 0, 0);
      this.add(locationPanel(), gbc);

      this.setBorder(BorderFactory.createEmptyBorder());
   }

   public void setModel(SimpleModel simpleModel) {
      this.simpleModel = simpleModel;
   }

   private JPanel locationPanel() {
      JPanel panel = new JPanel();
      panel.setLayout(new FlowLayout());

      panel.add(fileName);
      panel.add(fileTxt);
      panel.add(browse);

      return panel;
   }

   public static FileSelector getInstance() {
      if (instance == null) {
         instance = new FileSelector();
      }

      return instance;
   }
}

class DelemeterSelector extends JPanel {
   private JLabel description;
   private JRadioButton tabBtn, semicolanBtn, commaBtn, spaceBtn;
   private JTextArea txtArea;
   private JScrollPane scroll;
   private ButtonGroup btnGroup;

   private GridBagLayout gbl;
   private GridBagConstraints gbc;
   private SimpleModel simpleModel;

   private static DelemeterSelector instance = null;

   private DelemeterSelector() {
      description = new JLabel(
            "What delemeter separates your fields? Select the appropreiate delemeter");

      tabBtn = new JRadioButton("Tab");
      semicolanBtn = new JRadioButton("Semicolan");
      commaBtn = new JRadioButton("Comma");
      spaceBtn = new JRadioButton("Space");

      btnGroup = new ButtonGroup();
      btnGroup.add(tabBtn);
      btnGroup.add(semicolanBtn);
      btnGroup.add(commaBtn);
      btnGroup.add(spaceBtn);

      txtArea = new JTextArea(20, 70);

      scroll = new JScrollPane(txtArea);

      gbl = new GridBagLayout();
      gbc = new GridBagConstraints();

      this.setLayout(gbl);

      // Creating the GUI
      gbc.gridx = 1;
      gbc.gridy = 1;
      gbc.fill = GridBagConstraints.BOTH;
      gbc.insets = new Insets(20, 0, 0, 0);
      this.add(description, gbc);

      gbc.gridx = 1;
      gbc.gridy = 2;
      gbc.fill = GridBagConstraints.BOTH;
      gbc.insets = new Insets(20, 0, 0, 0);
      this.add(radioPanel(), gbc);

      gbc.gridx = 1;
      gbc.gridy = 3;
      gbc.insets = new Insets(10, 0, 0, 0);
      gbc.fill = GridBagConstraints.BOTH;
      this.add(scroll, gbc);
   }

   private JPanel radioPanel() {
      JPanel panel = new JPanel();
      panel.setLayout(new FlowLayout());

      panel.add(tabBtn);
      panel.add(semicolanBtn);
      panel.add(commaBtn);
      panel.add(spaceBtn);

      panel.setBorder(BorderFactory
            .createTitledBorder("Choose the Delimeter that seperates your fields"));

      return panel;
   }

   //!!
   public void setModel(final SimpleModel simpleModel) {
      this.simpleModel = simpleModel;
      simpleModel.addPropertyChangeListener(new PropertyChangeListener() {

         @Override
         public void propertyChange(PropertyChangeEvent evt) {
            if (SimpleModel.FILE_TEXT.equals(evt.getPropertyName())) {
               txtArea.append("File Text: " + simpleModel.getFileText() + "\n");
            }         
         }
      });
   }

   public static DelemeterSelector getInstance() {
      if (instance == null) {
         instance = new DelemeterSelector();
      }

      return instance;
   }
}

class SimpleModel {
   public static final String FILE_TEXT = "file text";
   private SwingPropertyChangeSupport pcSupport = 
      new SwingPropertyChangeSupport(this);
   private String fileText;

   public void addPropertyChangeListener(PropertyChangeListener listener) {
      pcSupport.addPropertyChangeListener(listener);
   }

   public void removePropertyChangeListener(PropertyChangeListener listener) {
      pcSupport.removePropertyChangeListener(listener);
   }

   public void setFileText(String fileText) {
      String oldValue = this.fileText;
      String newValue = fileText;
      this.fileText = fileText;
      pcSupport.firePropertyChange(FILE_TEXT, oldValue , newValue);

   }

   public String getFileText() {
      return fileText;
   }

}

编辑代码说明:

这是 M odel- V iew- C ontroller或MVC设计模式的大致简化,因为它只不过是模型并查看。该模型保存了GUI所使用的数据和逻辑,并且基本上是程序的“大脑”,而GUI只是信息的愚蠢显示。

这里的模型非常简单,只包含一个名为fileText的String字段。它有这个字段的setter和getter,最有趣的是setter是有线的,所以它会通知任何想知道这个字段是否被改变的听众。使用PropertyChangeSupport并允许使用PropertyChangeListeners的过程意味着fileText字段是"bound" property

两个JPanel都有字段来保存对同一个SimpleModel对象的引用,这个模型是通过setter方法setModel(...)设置的。

  fileSelector.setModel(simpleModel); // !!
  delemeterSelector.setModel(simpleModel); // !!

如果按下JButton,我让FileSelector对象设置fileText字段:

  browse.addActionListener(new ActionListener() {

     @Override
     public void actionPerformed(ActionEvent e) {
        if (simpleModel != null) {
           simpleModel.setFileText(fileTxt.getText());
        }
     }
  });

我有一个DelemeterSelector类将一个PropertyChangeListener添加到模型中,以便在每次更改fileText字段的值时通知它,并且可以在它认为合适时响应它:

public void setModel(final SimpleModel simpleModel) {
  this.simpleModel = simpleModel;
  simpleModel.addPropertyChangeListener(new PropertyChangeListener() {

     @Override
     public void propertyChange(PropertyChangeEvent evt) {
        if (SimpleModel.FILE_TEXT.equals(evt.getPropertyName())) {
           txtArea.append("File Text: " + simpleModel.getFileText() + "\n");
        }
     }
  });
}

请注意,模型类不知道GUI对它所拥有的信息做了什么,这是一件好事,因为它意味着“耦合”相当松散。