java – 在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”,它们是所有JPanels的共同点,因为它出现在“WizardPanel”的“South”中,而其他JPanels位于中心.
现在,我们来看看“FileSelector”.猜猜我使用浏览按钮选择了一个文件.
现在我该如何将这些信息发送到下一个面板?这意味着“DelemeterSelector”?我只有2个’COMMON’按钮“Next”和“previous”位于另一个类中.
我不认为在“Next”或“Previous”按钮的actionListener中编写业务逻辑(从’FileSelector’获取所选文件并将其发送到’DelemeterSelector’)是一个好主意.因为,我必须访问另一个类,获取数据并将其发送到下一个JPanel(下一个类).将有更多的JPanels,所以这将是非常困难和失败的肯定.
我想到为每个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
}
}
}
解决方法:
午休时间结束了,所以我有时间发布示例代码,但我会在一天结束前回来解释它:
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字段是“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对它所拥有的信息做了什么,这是一件好事,因为它意味着“耦合”相当松散.
标签:java,methods,swing,cardlayout 来源: https://codeday.me/bug/20190620/1246794.html