简体   繁体   中英

Java Design Architecture

My question is

If I have a Jpanel having some JtextField and ComboBox. Another JPanel containing Buttons like Save, Update, Clear, Exit.

both the JPanel are added into JFrame and by the BoarderLayout.

If I write something in text field and press save button it will save the data into database. I know the connection code to database.

Problem is the connection between the Text Panel and Button Panel. If I made the JTextField public and JButtons Public I can access them in JFrame and Implements Listners to save data into Database, but I guess its not right practice.

Kindly guide me to the how to do it correctly.

Here is the Test Code.

Buttons Panel:

import java.awt.FlowLayout;
import javax.swing.JButton;
import javax.swing.JPanel;

public class Buttons extends JPanel{

    JButton btnSave, btnUpdate, btnClear, btnExit;

    public Buttons(){

        btnSave = new JButton("Save");
        btnUpdate = new JButton("Update");
        btnClear = new JButton("Clear");
        btnExit = new JButton("Exit");


        setLayout(new FlowLayout());

        add(btnSave);
        add(btnUpdate);
        add(btnClear);
        add(btnExit);

        setSize(100,100);     

    }    
} 

TextPanel

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

/**
 *
 * @author Aqeel
 */
public class textPanel  extends JPanel{

    JLabel ID , Name;
    JTextField txtID, txtName;

    GridBagConstraints gridBagConstraints;

    public textPanel(){

        ID = new JLabel("ID:");
        Name = new JLabel("Name:");

        txtID = new JTextField(10);
        txtName = new JTextField(10);


        setLayout(new GridBagLayout());


        add(ID, new GridBagConstraints());
        add(txtID, new GridBagConstraints());

        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        add(Name, gridBagConstraints);


        gridBagConstraints = new GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        add(txtName, gridBagConstraints);

        setSize(300,200);
    }

}

Jframe

 import java.awt.BorderLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import javax.swing.JFrame;
 import javax.swing.UnsupportedLookAndFeelException;
 import org.openide.util.Exceptions;
 /**
  *
  * @author Aqeel
  */
 public class Jframe extends JFrame
 {
  textPanel textpanel;
  Buttons buttons;

  public Jframe() {

   textpanel = new textPanel();
   buttons = new Buttons();

   setLayout(new BorderLayout());

   add(textpanel, BorderLayout.CENTER);
   add(buttons, BorderLayout.SOUTH);

   setSize(400, 200);

   buttons.btnSave.addActionListener(new ActionListener()
   {
    @Override
    public void actionPerformed(ActionEvent e) {
     String ID = textpanel.txtID.getText();
     String Name = textpanel.txtName.getText();

     System.out.println(ID);
     System.out.println(Name);
    }
   });

   buttons.btnExit.addActionListener(new ActionListener()
   {
    @Override
    public void actionPerformed(ActionEvent e) {
       System.exit(0);
    }
   });
  }

  public static void main(String args[]) 
   throws ClassNotFoundException, InstantiationException, UnsupportedLookAndFeelException
   {

   try {
    for (javax.swing.UIManager.LookAndFeelInfo info : 
      javax.swing.UIManager.getInstalledLookAndFeels()
    ) {
     if ("Nimbus".equals(info.getName())) {
      javax.swing.UIManager.setLookAndFeel(info.getClassName());

      break;
     }
    }
   } catch (IllegalAccessException ex) {
    Exceptions.printStackTrace(ex);
   }
   java.awt.EventQueue.invokeLater(new Runnable() {
    @Override
    public void run() {
     new Jframe().setVisible(true);
    }
   });
  }
 }

It's a good practice to isolate the components used in a specific implementation. You can focus on the role of each JPanel instead. The TextPanel has to role of receiving the text input for Id and Name and the Buttons JPanel has the role of triggering specific actions.

A simple way to accomplish this would be to, instead of accessing directly the JButton and JTextField components (either making them public or by getters), create a getter in TextPanel class that returns a String for id and another String for name.

public class textPanel  extends JPanel{

    JLabel ID , Name;
    JTextField txtID, txtName;
    ...    
    public String getId()
    {
        return txtID.getText();
    }

    public String getName()
    {
        return txtName.getText();
    }
}

For the Buttons class, create an interface with methodos for each action.

public class Buttons extends JPanel{

    private JButton btnSave, btnUpdate, btnClear, btnExit;
    private ButtonsActions actionsListener;

    public Buttons(ButtonsActions actionsListener){
       this.actionsListener = actionsListener;

       btnSave.addActionListener(new ActionListener()
          {
           @Override
           public void actionPerformed(ActionEvent e) {
                actionsListener.onSave();
           }
          });
       ...
    }

    public interface ButtonsActions {
        public void onSave();
        public void onUpdate();
        public void onClear();
        public void onExit();
    }
}

The Jframe class would then be able to implement this interface and react to the actions when a button is clicked.

One of the reasons for isolating the implementation from each panel is that, let's say you later change the Buttons panel to have a JRadioButton listing all the action options and one apply button to trigger the selected action. Or if you change the TextPanel to offer o JComboBox instead of a simple JTextField. In any of those cases you would have to change all the places in your code that uses the Buttons or TextPanel classes to work with the new screen design.

use a methods to access or to modify (setters and getters ) attributes as an exemple puts this method in Buttons class :

public JButton getbtnSave()
{
   return this.btnSave;
}

this code is used for getting the btnSave with private access modifier. and also use a method to get txtID (place this in the textPanel class)

public JTextField getTxtID()
{
   return this.txtID;
}

public JTextField getTxtName()
{
    return this.txtName;
}

so the code in the the JFrame will be

  buttons.btnSave.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            String ID = textpanel.getTxtID().getText();
            String Name = textpanel.getTxtName().getText();

            System.out.println(ID);
            System.out.println(Name);
        }
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM