4

请看下面的代码

向导面板.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");

        }
    }
}

文件选择器.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;
    }
}

删除选择器.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;
    }
}

主.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 个“常见”按钮“下一个”和“上一个”,它们位于另一个类中。我不认为在“下一个”或“上一个”按钮的 actionListener 中编写业务逻辑(从“FileSelector”获取选定的文件并将其发送到“DelemeterSelector”)是一个好主意。因为,我必须访问另一个类,获取数据并将其发送到下一个 JPanel(下一个类)。会有更多的 JPanel,所以这将非常困难并且肯定会失败。

我想为每个 JPanel 添加“下一个”和“上一个”按钮,而不是常见的按钮。但是问题是从一个面板转移到另一个面板,因为缺少对 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
               }
       }
}
4

1 回答 1

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;
   }

}

编辑代码说明:

这是对模型-视图-控制器或MVC设计模式的粗略简化,因为它只不过是模型和视图模型包含 GUI 使用的数据和逻辑,本质上是程序的“大脑”,而 GUI 只不过是信息的愚蠢显示。

这里的模型非常简单,只包含一个名为 fileText 的 String 字段。它有这个字段的 setter 和 getter,最有趣的是 setter 是连线的,所以它会通知任何想知道这个字段是否改变过的侦听器。这个使用 PropertyChangeSupport 和允许 PropertyChangeListeners 的过程意味着 fileText 字段是一个“绑定”属性

您的两个 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 对它所拥有的信息做了什么,这是一件好事,因为这意味着“耦合”是相当松散的。

于 2012-11-21T18:03:39.187 回答