How can I separate components from business logic when I develop a swing desktop program?
This is a problem.
Because I have not thoroughly studied this knowledge, I have never thought about how to implement this separation.
Today, a friend made a small desktop program using swing, which is a simple management system.
The code is very complex, mainly because it is complicated to write and does not have a sense of logic or attention,
Components are everywhere and judgment is everywhere. Every time a function is appended, the code will be rummaged for a long time.
So I had nothing to worry about this evening. I simply wrote some code,
Can I separate components from the business logic?
Don't laugh if hero sees it ~
First, I want a logon interface,
The interface is very simple. Leave a jlabel position on it and output the error message.
The following is the username and password input box.
See:
After the user enters the user name and password, click the login button to verify the user name and password.
If the username and password are empty, an error is returned.
If the user name and password are entered, the logon is considered successful. Because it is only a demonstration, there is no real authentication.
The structure of the Code is as follows.
| -- Com
| -- Bzwm
| -- Testp
| -- Common
| -- Event
| -- Frame
| -- Listener
For example, it consists of four packages.
The common package contains some common classes and some tool classes.
This time, I put eventmgr. Java under the common package to manage events.
Event package, put the event of each action,
I first defined an abstract class baseevent. Java
Next is the event of the function to be implemented: logonevent. Java
The frame package is an implementation class of some images.
Loadframe. java used for this login is placed under this package.
The listener package contains specific service logic implementation classes.
First define the interface ilistener. Java
The screen implements the ilistener interface, which facilitates callback back to the main screen and re-draws components based on the business logic processing results.
Then define the interface iservice. Java
The business logic class must implement the iservice interface,
I have defined two methods in this interface,
The first method is to check whether the user's input data is correct or whether the operation is correct,
The second method completes business logic processing based on user input and events.
The logic class logonservice. java used for this login implements the iservice interface.
Okay, the structure is complete,
Let's look at the code.
1. ilistener. Java
Package COM. bzwm. testp. listener; </P> <p> Import COM. bzwm. testp. event. baseevent; </P> <p>/** <br/> * @ author bzwm <br/> */<br/> Public interface ilistener {</P> <p>/** <br/> * Processing Event ends <br/> * callback is sent to the screen, easy to reproduce the image <br/> * @ Param event <br/> */<br/> Public void eventcompleted (baseevent event); <br/>}
2. iservice. Java
Package COM. bzwm. testp. listener; </P> <p> Import COM. bzwm. testp. event. baseevent; </P> <p>/** <br/> * @ author bzwm <br/> */<br/> Public interface iservice {<br/ >/** <br/> * start to process events <br/> * user input, perform a preliminary check. If the check fails, there is no need to continue <br/> * @ Param event <br/> */<br/> Public void eventstarted (baseevent event ); </P> <p>/** <br/> * handle events <br/> * perform some logical processing <br/> * to obtain simple data, do not consider components on the screen <br/> * @ Param event <br/> */<br/> Public void Service (baseevent event); <br/>}
3. loadframe. Java
The main screen and program portal implement the ilistener interface.
Package COM. bzwm. testp. frame; </P> <p> Import COM. bzwm. testp. common. eventmgr; <br/> Import COM. bzwm. testp. event. baseevent; <br/> Import COM. bzwm. testp. event. logonevent; <br/> Import COM. bzwm. testp. listener. ilistener; <br/> Import COM. bzwm. testp. listener. logonservice; <br/> Import Java. AWT. borderlayout; <br/> Import Java. AWT. color; <br/> Import Java. AWT. flowlayout; <br/> Import Java. AWT. event. actionevent; <br/> Import Java. AWT. event. actionlistener; <br/> Import javax. swing. jbutton; <br/> Import javax. swing. jframe; <br/> Import javax. swing. jlabel; <br/> Import javax. swing. jpanel; <br/> Import javax. swing. jpasswordfield; <br/> Import javax. swing. jtextfield; </P> <p>/** <br/> * @ author bzwm <br/> */<br/> public class loadframe extends jframe implements ilistener {<br/>/** title: user ID */<br/> private jlabel useridlbl = NULL; </P> <p>/** input box: User ID */<br/> private jtextfield useridtxt = NULL; </P> <p>/** title: password */<br/> private jlabel passwordlbl = NULL; </P> <p>/** input box: password */<br/> private jpasswordfield passwordtxt = NULL; </P> <p>/** logon button */<br/> private jbutton logonbtn = NULL; </P> <p>/** reset button */<br/> private jbutton resetbtn = NULL; </P> <p>/** New User Registration button */<br/> private jbutton registerbtn = NULL; </P> <p>/** error message */<br/> private jlabel errorlbl = NULL; </P> <p> eventmgr MRG = NULL; </P> <p>/** <br/> * constructor <br/> * @ Param title <br/> * Title <br/> */<br/> Public loadframe (String title) {<br/> super (title); <br/> initcomponents (); <br/> layoutcomponents (); <br/> MRG = new eventmgr (); <br/> // append listener <br/> MRG. addlistener (this); <br/> MRG. addservice (New logonservice ()); <br/>}</P> <p>/** <br/> * initialize the component <br/> */<br/> private void initcomponents () {<br/> useridlbl = new jlabel ("username"); <br/> useridtxt = new jtextfield (10 ); </P> <p> passwordlbl = new jlabel ("password"); <br/> passwordtxt = new jpasswordfield (10 ); </P> <p> logonbtn = new jbutton ("login"); <br/> resetbtn = new jbutton ("reset "); <br/> registerbtn = new jbutton ("register"); </P> <p> errorlbl = new jlabel (); <br/> errorlbl. setforeground (color. red); <br/>}</P> <p>/** <br/> * layout, add event listening to components <br/> */<br/> private void layoutcomponents () {<br/> jpanel toppnl = new jpanel (); <br/> toppnl. add (errorlbl); </P> <p> jpanel mainpnl = new jpanel (New borderlayout (); <br/> jpanel inputpnl = new jpanel (New Java. AWT. gridlayout (2, 2, 2, 2); <br/> inputpnl. add (useridlbl); <br/> inputpnl. add (useridtxt); <br/> inputpnl. add (passwordlbl); <br/> inputpnl. add (passwordtxt); <br/> inputpnl. setsize (280,100); <br/> mainpnl. add (inputpnl, borderlayout. north); </P> <p> jpanel footpnl = new jpanel (New flowlayout (flowlayout. right); <br/> logonbtn. addactionlistener (New actionlistener () {<br/> Public void actionreceivmed (actionevent e) {<br/> logonbtnclick (); <br/>}< br/> }); <br/> resetbtn. addactionlistener (New actionlistener () {<br/> Public void actionreceivmed (actionevent e) {<br/> resetbtnclick (); <br/>}< br/> }); </P> <p> registerbtn. addactionlistener (New actionlistener () {<br/> Public void actionreceivmed (actionevent e) {<br/> regbtnclick (); <br/>}< br/> }); </P> <p> footpnl. add (logonbtn); <br/> footpnl. add (resetbtn); <br/> footpnl. add (registerbtn); <br/> mainpnl. add (footpnl, borderlayout. south); <br/> This. add (toppnl, borderlayout. north); <br/> This. add (mainpnl, borderlayout. center); <br/> This. setlocation (200,200); <br/> This. setsize (300,300); <br/> This. setvisible (true); <br/> This. setdefaclocloseoperation (jframe. exit_on_close); <br/>}</P> <p>/** <br/> */<br/> private void logonbtnclick () {<br/> New thread () {<br/> Public void run () {<br/> MRG. dispatch (New logonevent (useridtxt. gettext (), passwordtxt. gettext (); <br/>}< br/> }. start (); <br/>}</P> <p>/** <br/> */<br/> private void resetbtnclick () {<br/> useridtxt. settext (""); <br/> passwordtxt. settext (""); <br/>}</P> <p>/** <br/> */<br/> private void regbtnclick () {<br/>}</P> <p>/* <br/> * (non-javadoc) <br/> * @ see COM. bzwm. testp. listener. ilistener # eventcompleted (COM. bzwm. testp. event. baseevent) <br/> */<br/> Public void eventcompleted (baseevent event) {<br/> string error = event. geterror (); <br/> If (error. equals ("") {<br/> errorlbl. settext ("Logon successful"); <br/>}else {<br/> errorlbl. settext (error); <br/>}</P> <p> Public static void main (string ARGs []) {<br/> New loadframe ("logonframe"); <br/>}< br/>}
4. logonservice. Java
Logic processing of Logon Events
Implemented the iservice Interface
Package COM. bzwm. testp. listener; </P> <p> Import COM. bzwm. testp. event. baseevent; <br/> Import COM. bzwm. testp. event. logonevent; </P> <p>/** <br/> * @ author bzwm <br/> */<br/> public class logonservice implements iservice {< /P> <p>/* <br/> * (non-javadoc) <br/> * @ see COM. bzwm. testp. listener. iservice # eventstarted (COM. bzwm. testp. event. baseevent) <br/> */<br/> Public void eventstarted (baseeven T event) {<br/> logonevent = (logonevent) event; <br/> string id = logonevent. GETID (); <br/> string Password = logonevent. getPassword (); <br/> // perform a preliminary check on user input <br/> If (ID = NULL | "". equals (ID) {<br/> event. seterror ("username is blank"); <br/>}< br/> If (Password = NULL | "". equals (password) {<br/> event. seterror ("password is blank"); <br/>}</P> <p>/* <br/> * (non-javadoc) <br/> * @ see COM. BZ WM. testp. listener. iservice # Service (COM. bzwm. testp. event. baseevent) <br/> */<br/> Public void Service (baseevent event) {<br/> If (! Event. iserror () {<br/> logonevent = (logonevent) event; <br/> // check the user ID and password. log on now, check whether logon has been registered <br/> Logon (logonevent); <br/> // here, the pause is seconds. The server verifies the <br/> try {<br/> thread. sleep (5000); <br/>} catch (interruptedexception e) {<br/> E. printstacktrace (); <br/>}</P> <p> private void Logon (logonevent E) {<br/> // verify the database, whether the user ID exists, and whether the password is correct <br/> // if not, seterror (), incorrect password, seterror () <br/> //... <br/>}< br/>}
5. eventmgr. Java
Manage events
Package COM. bzwm. testp. common; </P> <p> Import COM. bzwm. testp. event. baseevent; <br/> Import COM. bzwm. testp. listener. ilistener; <br/> Import COM. bzwm. testp. listener. iservice; <br/> Import Java. util. arraylist; <br/> Import Java. util. list; </P> <p>/** <br/> * @ author bzwm <br/> */<br/> public class eventmgr {<br/ >/** listener set for callback back to the main screen */<br/> private list <ilistener> listeners = new arraylist <ilistener> (); </P> <p>/** set of Service Logic listeners */<br/> private list <iservice> services = new arraylist <iservice> (); </P> <p>/** <br/> * @ Param event <br/> */<br/> Public void dispatch (baseevent event) {</P> <p> fireeventstarted (event); </P> <p> fireeventservice (event); </P> <p> fireeventcompleted (event ); <br/>}</P> <p>/** <br/> * @ Param listener <br/> */<br/> Public void addlistener (ilistener listener) {<br/> listeners. add (listener ); <br/>}</P> <p>/** <br/> * @ Param listener <br/> */<br/> Public void removelistener (ilistener listener) {<br/> listeners. remove (listener ); <br/>}</P> <p>/** <br/> * @ Param service <br/> */<br/> Public void addservice (iservice Service) {<br/> services. add (service ); <br/>}</P> <p>/** <br/> * @ Param service <br/> */<br/> Public void removeservice (iservice Service) {<br/> services. remove (service ); <br/>}</P> <p>/** <br/> * @ Param event <br/> */<br/> private void fireeventstarted (baseevent event) {<br/> for (iservice service: Services) {<br/> service. eventstarted (event ); <br/>}</P> <p>/** <br/> * @ Param event <br/> */< br/> private void fireeventservice (baseevent event) {<br/> for (iservice service: Services) {<br/> service. service (event ); <br/>}</P> <p>/** <br/> * @ Param event <br/> */< br/> private void fireeventcompleted (baseevent event) {<br/> for (ilistener listener: listeners) {<br/> listener. eventcompleted (event); <br/>}< br/>}
6. baseevent. Java
Abstract class, abstract event
The design is still open to question.
Package COM. bzwm. testp. event; </P> <p>/** <br/> * @ author bzwm <br/> */<br/> public abstract class baseevent {</ p> <p>/** <br/> * error information during processing. You can select a custom error class to complete the process, in addition, this method of saving error information is really stupid <br/> */<br/> private string error = ""; </P> <p>/** <br/> * Save the result returned by processing. Here, you can customize a data file to manage the result, therefore, you do not need to write a single object to return the processing result, which has many limitations <br/> */<br/> private object result = NULL; </P> <p>/** <br/> * @ return the resul T <br/> */<br/> Public object getresult () {<br/> return result; <br/>}</P> <p>/** <br/> * @ Param result <br/> * the result to set <br/> */<br /> Public void setresult (Object result) {<br/> This. result = result; <br/>}</P> <p>/** <br/> * @ return the error <br/> */<br/> Public String geterror () {<br/> return error; <br/>}</P> <p>/** <br/> * @ Param error <br/> * the error to set <br/> */<br /> Public void Seterror (string error) {<br/> This. error = This. error + "" + error; <br/>}</P> <p> Public Boolean iserror () {<br/> return! Error. Equals (""); <br/>}< br/>}
7. logonevent. Java
User Logon Events
Package COM. bzwm. testp. event; </P> <p>/** <br/> * @ author bzwm <br/> */<br/> public class logonevent extends baseevent {< /P> <p>/** user ID */<br/> private string id = NULL; </P> <p>/** password */<br/> private string Password = NULL; </P> <p> Public logonevent (string I, string P) {<br/> setid (I); <br/> setpassword (P ); <br/>}</P> <p>/** <br/> * @ return the id <br/> */<br/> Public String GETID () {<br/> return ID; <br/>}</P> <p>/** <br/> * @ Param id <br/> * The ID to set <br/> */<br /> Public void setid (string ID) {<br/> This. id = ID; <br/>}</P> <p>/** <br/> * @ return the password <br/> */<br/> Public String GetPassword () {<br/> return password; <br/>}</P> <p>/** <br/> * @ Param password <br/> * the password to set <br/> */<br /> Public void setpassword (string password) {<br/> This. password = password; <br/>}< br/>}
Based on the above Code, the basic function is complete.
It may feel that it is not worthwhile to write so many classes for this function,
But the code will be clearer. Although the design, such as the construction of classes, is not reasonable enough,
I didn't think too much. I wrote it out when I thought about it.
But there is another benefit, for example,You want to add the log output function for logon events,
So simple,
You only need to write a class to implement iservice. (Because the log is written in a local file, you do not need to call back to the main screen)
Then, change the Construction Method in loadframe. Java to OK.
The following is the service used to output logs.
8. logservice. Java
Package COM. bzwm. testp. listener; </P> <p> Import COM. bzwm. testp. event. baseevent; <br/> Import COM. bzwm. testp. event. logonevent; </P> <p>/** <br/> * @ author bzwm <br/> * the design of the output log class can also be improved, for example, logservice can be an abstract class, and the following is a specific logonlogservice. <br/> * perform some common operations in the parent class, such as IO operations. <Br/> * because many operations require logs, you can define a log output class for each screen. <br/> * this class is used to manage log information. <Br/> * for the sake of simplicity, there will be no more information, and only the information is printed on the console. <Br/> */<br/> public class logservice implements iservice {</P> <p>/* <br/> * (non-javadoc) <br/> * @ see COM. bzwm. testp. listener. iservice # eventstarted (COM. bzwm. testp. event. baseevent) <br/> */<br/> Public void eventstarted (baseevent event) {<br/> // todo auto-generated method stub <br/> If (event instanceof logonevent) {<br/> logonevent E = (logonevent) event; <br/> system. out. println (E. GETID () + "logged on"); <br/>}</P> <p>/* <br/> * (non-javadoc) <br/> * @ see COM. bzwm. testp. listener. iservice # Service (COM. bzwm. testp. event. baseevent) <br/> */<br/> Public void Service (baseevent event) {<br/> // todo auto-generated method stub <br/> If (event instanceof logonevent) {<br/> logonevent E = (logonevent) event; <br/> string error = E. geterror (); <br/> If (error. equals ("") {<br/> system. out. println (E. GETID () + "logged on"); <br/>} else {<br/> system. out. println (E. GETID () + "Logon Failed" + error); <br/>}< br/>}
Next, modify the loadframe. Java class.
Write only the modified part. Its constructor is as follows:
Public loadframe (String title) {<br/> super (title); <br/> initcomponents (); <br/> layoutcomponents (); <br/> MRG = new eventmgr (); <br/> // append listener <br/> MRG. addlistener (this); <br/> MRG. addservice (New logonservice (); <br/> MRG. addservice (New logservice (); <br/>}
In this way, copy the code,
Run the command again and the log is displayed.
This is only the login function,
If you want to complete the registration function,
The steps are the same,
Write a dialog class that inherits jdialog and implements the ilistener interface,
Define a regevent. Java to inherit baseevent. Java,
Write a regservice class to implement the iservice interface,
In short, add your own Implementations under the corresponding package,
Then you can register the listener to eventmgr.
Okay. Thank you!