Passing data between classes in CardLayout

Please review the following code

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

Here we have only two buttons "Next" and "Previous", and they are combined for all JPanels, because they are displayed in the "South" "WizardPanel", while the other JPanels are in the center.

Now let's take the "FileSelector". I think I selected the file using the browse button.

Now, how can I send this information to the next panel? What does "DelemeterSelector" mean ?. I have only 2 "GENERAL" buttons "Next" and "previous", which are in another class. I don’t think writing business logic (getting the selected file from "FileSelector" and sending it to "DelemeterSelector") inside this "Next" or "Previous" button is a good idea. Because I need to access another class, get its data and send it to the next JPanel (next class). There will be more JPanels, so it will be really difficult and unsuccessful.

I was thinking of adding the Next and Previous buttons for each JPanel, not the regular ones. But then the problem moves from one panel to another, because there is no link to CardLayout.

Please help me find the right and efficient way to transfer data from one class to another class in this wizard. Thanks.

PS:

I don’t want to check the conditions in the action class of the Next buttons and let it hold all the actions. For example, see the following code snippet.

 //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
source share
1 answer

The lunch break is over, so I have time to send a sample code, but I will try to return to explain it before the end of the day:

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

Change code explanation:

This is a gross simplification of the design pattern M odel- V iew- C or MVC, as it is nothing more than a model and a view. The model contains data and logic with which the graphical interface works, and, in fact, is the "brain" of the program, and the graphical interface is nothing more than a dull display of information.

The model here is quite simple and contains only one String field called fileText. It has setters and getters for this field, and the most interesting thing about it is that the setter is connected so that it notifies listeners who want to know if this field has changed. This process of using PropertyChangeSupport and using PropertyChangeListeners means that the fileText field is a "bound" property .

Both of your JPanels have fields for binding to a single SimpleModel object, and this model is set using the setter method, setModel (...).

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

I allow the FileSelector object to set the fileText field if its JButton is pressed:

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

I have a DelemeterSelector class that adds the PropertyChangeListener property to the model so that it is notified when the value of the fileText field changes and can respond to it as it sees fit:

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

Note that the model class has no idea what the GUI does with the information it contains, and that this is good, because it means that the β€œconnection” is pretty loose.

+5
source

Source: https://habr.com/ru/post/1447554/


All Articles