文章目录
- 说明
- GUI
- 1. GUI 总体布局
- 2. GUI 代码理解
- 2.1 对话框相关控件
- 2.1.1 ApplicationShowdown.java(关闭应用程序)
- 2.1.2 DialogCloser.java(关闭对话框)
- 2.1.3 ErrorDialog.java(显示错误信息)
- 2.1.4 HelpDialog.java(显示帮助信息)
- 2.1.5 GUICommon.java (通用的 GUI 配置信息和变量)
- 2.2 数据读取控件
- 2.2.1 DoubleField.java(输入功能的文本字段且只能输入double类型)
- 2.2.2 IntegerField.java(输入功能的文本字段且只能输入int类型)
- 2.2.2 FilenameField.java(输入功能的文本字段且用于输入文件名或文件路径)
- 2.3 整体布局GUI
- 2.4 GUI之接口与监听机制
- 2.5 总结
说明
闵老师的文章链接: 日撸 Java 三百行(总述)_minfanphd的博客-CSDN博客
自己也把手敲的代码放在了github上维护:https://github.com/fulisha-ok/sampledata
GUI
1. GUI 总体布局
我是copy代码直接运行了GUI的一个总体代码,最后运行的界面如下,这个界面实现了灵活输入参数(神经层数,激活函数,训练次数等。点击OK即可完成一次)再执行神经网络的训练和测试(其中训练的方式以及前向传播函数和后向传播函数都是调用的通用神经网络的方法)
2. GUI 代码理解
在看了一个整体的思路,在来详细看代码类。
2.1 对话框相关控件
2.1.1 ApplicationShowdown.java(关闭应用程序)
package machinelearing.gui;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
/**
* @author: fulisha
* @date: 2023/7/17 15:39
* @description:
*/
public class ApplicationShutdown implements WindowListener, ActionListener {
/**
* Only one instance.
*/
public static ApplicationShutdown applicationShutdown = new ApplicationShutdown();
private ApplicationShutdown() {
}
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
@Override
public void windowClosed(WindowEvent e) {
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
}
- 实现了WindowListener和ActionListener接口(java中,继承只能单继承,但能多实现)主要处理程序的关闭事件,并提供了在窗口关闭时退出应用程序的功能
- 从代码中可以知道 虽然重写了很多方法,但实际上主要是actionPerformed和windowClosing方法,实现了System.exit(0);来终止应用程序,使其退出
- 这个类使用了单例模式(23种设计模式中的一种)
它确保一个类只有一个实例,并提供全局访问点以访问该实例。所以ApplicationShutdown 这个类就是一个单例模式的实现。常见的实现方式
- 懒汉式,线程不安全
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- 懒汉式,线程安全
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- 饿汉式
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
2.1.2 DialogCloser.java(关闭对话框)
package machinelearing.gui;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
/**
* @author: fulisha
* @date: 2023/7/17 15:41
* @description:
*/
public class DialogCloser extends WindowAdapter implements ActionListener {
/**
* The dialog under control.
*/
private Dialog currentDialog;
/**
* The first constructor.
*/
public DialogCloser() {
super();
}
/**
* The second constructor.
*
* @param paraDialog the dialog under control
*/
public DialogCloser(Dialog paraDialog) {
currentDialog = paraDialog;
}
/**
* Close the dialog which clicking the cross at the up-right corner of the window.
* @param paraWindowEvent From it we can obtain which window sent the message because X was used.
*/
@Override
public void windowClosing(WindowEvent paraWindowEvent) {
paraWindowEvent.getWindow().dispose();
}
/**
* Close the dialog while pushing an "OK" or "Cancel" button.
* @param paraEvent Not considered.
*/
@Override
public void actionPerformed(ActionEvent paraEvent) {
currentDialog.dispose();
}
}
- 实现了 WindowAdapter 和 ActionListener 接口,用于监听对话框的关闭事件
- 重写windowClosing方法,当用户点击对话框的关闭按钮触发WindowEvent事件(通常是对话框的上右角的“X”按钮)时,会触发该方法。在此方法中,通paraWindowEvent.getWindow().dispose(); 来关闭对话框; 重写actionPerformed方法,监听ActionEvent事件触发currentDialog.dispose()来关闭对话框
2.1.3 ErrorDialog.java(显示错误信息)
package machinelearing.gui;
import java.awt.*;
/**
* @author: fulisha
* @date: 2023/7/17 16:04
* @description:
*/
public class ErrorDialog extends Dialog{
/**
* Serial uid. Not quite useful.
*/
private static final long serialVersionUID = 124535235L;
/**
* The ONLY ErrorDialog.
*/
public static ErrorDialog errorDialog = new ErrorDialog();
/**
* The label containing the message to display.
*/
private TextArea messageTextArea;
/**
***************************
* Display an error dialog and respective error message. Like other dialogs,
* this constructor is private, such that users can use only one dialog,
* i.e., ErrorDialog.errorDialog to display message. This is helpful for
* saving space (only one dialog) since we may need "many" dialogs.
***************************
*/
private ErrorDialog(){
// This dialog is module.
super(GUICommon.mainFrame, "Error", true);
// Prepare for the dialog.
messageTextArea = new TextArea();
Button okButton = new Button("OK");
okButton.setSize(20, 10);
okButton.addActionListener(new DialogCloser(this));
Panel okPanel = new Panel();
okPanel.setLayout(new FlowLayout());
okPanel.add(okButton);
// Add TextArea and Button
setLayout(new BorderLayout());
add(BorderLayout.CENTER, messageTextArea);
add(BorderLayout.SOUTH, okPanel);
setLocation(200, 200);
setSize(500, 200);
addWindowListener(new DialogCloser());
setVisible(false);
}
/**
* set message.
* @param paramMessage the new message
*/
public void setMessageAndShow(String paramMessage) {
messageTextArea.setText(paramMessage);
setVisible(true);
}
}
- 这个类也采用了单例模式,也是只有一个实例
- 构造函数创建了一个对话框,用于显示错误信息和"OK"按钮
2.1.4 HelpDialog.java(显示帮助信息)
package machinelearing.gui;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.RandomAccessFile;
/**
* @author: fulisha
* @date: 2023/7/17 15:44
* @description:
*/
public class HelpDialog extends Dialog implements ActionListener {
/**
* Serial uid. Not quite useful.
*/
private static final long serialVersionUID = 3869415040299264995L;
/**
* Display the help dialog.
*
* @param paraTitle the title of the dialog.
* @param paraFilename the help file.
*/
public HelpDialog(String paraTitle, String paraFilename) {
super(GUICommon.mainFrame, paraTitle, true);
setBackground(GUICommon.MY_COLOR);
TextArea displayArea = new TextArea("", 10, 10, TextArea.SCROLLBARS_VERTICAL_ONLY);
displayArea.setEditable(false);
String textToDisplay = "";
try {
RandomAccessFile helpFile = new RandomAccessFile(paraFilename, "r");
String tempLine = helpFile.readLine();
while (tempLine != null) {
textToDisplay = textToDisplay + tempLine + "\n";
tempLine = helpFile.readLine();
}
helpFile.close();
} catch (IOException ee) {
dispose();
ErrorDialog.errorDialog.setMessageAndShow(ee.toString());
}
// Use this if you need to display Chinese. Consult the author for this
// method.
// textToDisplay = SimpleTools.GB2312ToUNICODE(textToDisplay);
displayArea.setText(textToDisplay);
displayArea.setFont(new Font("Times New Romans", Font.PLAIN, 14));
Button okButton = new Button("OK");
okButton.setSize(20, 10);
okButton.addActionListener(new DialogCloser(this));
Panel okPanel = new Panel();
okPanel.setLayout(new FlowLayout());
okPanel.add(okButton);
// OK Button
setLayout(new BorderLayout());
add(BorderLayout.CENTER, displayArea);
add(BorderLayout.SOUTH, okPanel);
setLocation(120, 70);
setSize(500, 400);
addWindowListener(new DialogCloser());
setVisible(false);
}
/**
* Simply set it visible.
*/
@Override
public void actionPerformed(ActionEvent ee) {
setVisible(true);
}
}
2.1.5 GUICommon.java (通用的 GUI 配置信息和变量)
package machinelearing.gui;
import javax.swing.*;
import java.awt.*;
/**
* @author: fulisha
* @date: 2023/7/17 15:43
* @description:
*/
public class GUICommon {
/**
* Only one main frame.
*/
public static Frame mainFrame = null;
/**
* Only one main pane.
*/
public static JTabbedPane mainPane = null;
/**
* For default project number.
*/
public static int currentProjectNumber = 0;
/**
* Default font.
*/
public static final Font MY_FONT = new Font("Times New Romans", Font.PLAIN, 12);
/**
* Default color
*/
public static final Color MY_COLOR = Color.lightGray;
/**
* Set the main frame. This can be done only once at the initialzing stage.
* @param paraFrame the main frame of the GUI.
* @throws Exception If the main frame is set more than once.
*/
public static void setFrame(Frame paraFrame) throws Exception {
if (mainFrame == null) {
mainFrame = paraFrame;
} else {
throw new Exception("The main frame can be set only ONCE!");
}
}
/**
* Set the main pane. This can be done only once at the initialzing stage.
* @param paramPane the main pane of the GUI.
* @throws Exception If the main panel is set more than once.
*/
public static void setPane(JTabbedPane paramPane) throws Exception {
if (mainPane == null) {
mainPane = paramPane;
} else {
throw new Exception("The main panel can be set only ONCE!");
}
}
}
2.2 数据读取控件
2.2.1 DoubleField.java(输入功能的文本字段且只能输入double类型)
package machinelearing.gui;
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
/**
* @author: fulisha
* @date: 2023/7/17 16:10
* @description:
*/
public class DoubleField extends TextField implements FocusListener {
/**
* Serial uid. Not quite useful.
*/
private static final long serialVersionUID = 363634723L;
/**
* The value
*/
protected double doubleValue;
/**
* Give it default values.
*/
public DoubleField() {
this("5.13", 10);
}
/**
* Only specify the content.
* @param paraString The content of the field.
*/
public DoubleField(String paraString) {
this(paraString, 10);
}
/**
* Only specify the width.
* @param paraWidth The width of the field.
*/
public DoubleField(int paraWidth) {
this("5.13", paraWidth);
}
/**
* Specify the content and the width.
* @param paraString The content of the field.
* @param paraWidth The width of the field.
*/
public DoubleField(String paraString, int paraWidth) {
super(paraString, paraWidth);
addFocusListener(this);
}
/**
* Implement FocusListener.
* @param paraEvent The event is unimportant.
*/
@Override
public void focusGained(FocusEvent paraEvent) {
}
/**
* Implement FocusListener.
* @param paraEvent The event is unimportant.
*/
@Override
public void focusLost(FocusEvent paraEvent) {
try {
doubleValue = Double.parseDouble(getText());
} catch (Exception ee) {
ErrorDialog.errorDialog
.setMessageAndShow("\"" + getText() + "\" Not a double. Please check.");
requestFocus();
}
}
/**
* Get the double value.
* @return the double value.
*/
public double getValue() {
try {
doubleValue = Double.parseDouble(getText());
} catch (Exception ee) {
ErrorDialog.errorDialog
.setMessageAndShow("\"" + getText() + "\" Not a double. Please check.");
requestFocus();
}
return doubleValue;
}
}
- 重写focusLost方法(当文本字段失去焦点时触发):将输入的文本转换为 double 类型的值,并将其存储在 doubleValue 变量中,如果失败调用ErrorDialog显示错误信息
- 自定义方法getValue,用于获取文本字段中输入的浮点数值
2.2.2 IntegerField.java(输入功能的文本字段且只能输入int类型)
和DoubleField同理
package machinelearing.gui;
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
/**
* @author: fulisha
* @date: 2023/7/17 16:12
* @description:
*/
public class IntegerField extends TextField implements FocusListener {
/**
* Serial uid. Not quite useful.
*/
private static final long serialVersionUID = -2462338973265150779L;
/**
* Only specify the content.
*/
public IntegerField() {
this("513");
}
/**
* Specify the content and the width.
* @param paraString The default value of the content.
* @param paraWidth The width of the field.
*/
public IntegerField(String paraString, int paraWidth) {
super(paraString, paraWidth);
addFocusListener(this);
}
/**
* Only specify the content.
* @param paraString The given default string.
*/
public IntegerField(String paraString) {
super(paraString);
addFocusListener(this);
}
/**
* Only specify the width.
* @param paraWidth The width of the field.
*/
public IntegerField(int paraWidth) {
super(paraWidth);
setText("513");
addFocusListener(this);
}
/**
* Implement FocusListenter.
* @param paraEvent The event is unimportant.
*/
@Override
public void focusGained(FocusEvent paraEvent) {
}
/**
* Implement FocusListenter.
* @param paraEvent The event is unimportant.
*/
@Override
public void focusLost(FocusEvent paraEvent) {
try {
Integer.parseInt(getText());
// System.out.println(tempInt);
} catch (Exception ee) {
ErrorDialog.errorDialog.setMessageAndShow("\"" + getText()
+ "\"Not an integer. Please check.");
requestFocus();
}
}
/**
* Get the int value. Show error message if the content is not an int.
* @return the int value.
*/
public int getValue() {
int tempInt = 0;
try {
tempInt = Integer.parseInt(getText());
} catch (Exception ee) {
ErrorDialog.errorDialog.setMessageAndShow("\"" + getText()
+ "\" Not an int. Please check.");
requestFocus();
}
return tempInt;
}
}
2.2.2 FilenameField.java(输入功能的文本字段且用于输入文件名或文件路径)
package machinelearing.gui;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.io.File;
/**
* @author: fulisha
* @date: 2023/7/17 16:14
* @description:一个带有文件选择功能的文本输入框,用于方便用户选择文件路径,并将选择的文件路径显示在文本输入框中。它还具有一些对文本内容的处理,如检查文件是否存在并显示错误消息等。
*/
public class FilenameField extends TextField implements ActionListener,
FocusListener{
/**
* Serial uid. Not quite useful.
*/
private static final long serialVersionUID = 4572287941606065298L;
/**
* No special initialization..
*/
public FilenameField() {
super();
setText("");
addFocusListener((FocusListener) this);
}
/**
* No special initialization.
* @param paraWidth The width of the .
*/
public FilenameField(int paraWidth) {
super(paraWidth);
setText("");
addFocusListener(this);
}// Of constructor
/**
* No special initialization.
* @param paraWidth The width of the .
* @param paraText The given initial text
*/
public FilenameField(int paraWidth, String paraText) {
super(paraWidth);
setText(paraText);
addFocusListener(this);
}
/**
* No special initialization.
* @param paraWidth The width of the .
* @param paraText The given initial text
*/
public FilenameField(String paraText, int paraWidth) {
super(paraWidth);
setText(paraText);
addFocusListener(this);
}
/**
* Avoid setting null or empty string.
* @param paraText The given text.
*/
@Override
public void setText(String paraText) {
if (paraText.trim().equals("")) {
super.setText("unspecified");
} else {
super.setText(paraText.replace('\\', '/'));
}
}
/**
* Implement ActionListenter.
* @param paraEvent The event is unimportant.
*/
@Override
public void actionPerformed(ActionEvent paraEvent) {
FileDialog tempDialog = new FileDialog(GUICommon.mainFrame,
"Select a file");
tempDialog.setVisible(true);
if (tempDialog.getDirectory() == null) {
setText("");
return;
}
String directoryName = tempDialog.getDirectory();
String tempFilename = directoryName + tempDialog.getFile();
//System.out.println("tempFilename = " + tempFilename);
setText(tempFilename);
}
/**
* Implement FocusListenter.
* @param paraEvent The event is unimportant.
*/
@Override
public void focusGained(FocusEvent paraEvent) {
}
/**
* Implement FocusListenter.
* @param paraEvent The event is unimportant.
*/
@Override
public void focusLost(FocusEvent paraEvent) {
// System.out.println("Focus lost exists.");
String tempString = getText();
if ((tempString.equals("unspecified"))
|| (tempString.equals("")))
return;
File tempFile = new File(tempString);
if (!tempFile.exists()) {
ErrorDialog.errorDialog.setMessageAndShow("File \"" + tempString
+ "\" not exists. Please check.");
requestFocus();
setText("");
}
}
}
- 实现actionPerformed方法,该方法打开文件选择对话框,让用户选择文件,并将选中的文件名或文件路径设置为文本字段的内容
- 实现focusLost方法(当文本字段失去焦点时触发),检查文本字段的内容是否为空或为 "unspecified"如果是则返回反之它会检查检查文件是否存在,若不存在,则调用ErrorDialog来显示错误信息。
2.3 整体布局GUI
package machinelearing.gui;
import machinelearing.ann.FullAnn;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Date;
/**
* @author: fulisha
* @date: 2023/7/18 16:02
* @description:
*/
public class AnnMain implements ActionListener {
/**
* Select the arff file.
*/
private FilenameField arffFilenameField;
/**
* The setting of alpha.
*/
private DoubleField alphaField;
/**
* The setting of alpha.
*/
private DoubleField betaField;
/**
* The setting of alpha.
*/
private DoubleField gammaField;
/**
* Layer nodes, such as "4, 8, 8, 3".
*/
private TextField layerNodesField;
/**
* Activators, such as "ssa".
*/
private TextField activatorField;
/**
* The number of training rounds.
*/
private IntegerField roundsField;
/**
* The learning rate.
*/
private DoubleField learningRateField;
/**
* The mobp.
*/
private DoubleField mobpField;
/**
* The message area.
*/
private TextArea messageTextArea;
/**
* The only constructor.
*/
public AnnMain() {
// A simple frame to contain dialogs.
Frame mainFrame = new Frame();
mainFrame.setTitle("ANN");
// The top part: select arff file.
arffFilenameField = new FilenameField(30);
arffFilenameField.setText("D:/sampledata/sampledata/src/data/iris.arff");
Button browseButton = new Button(" Browse ");
browseButton.addActionListener(arffFilenameField);
Panel sourceFilePanel = new Panel();
sourceFilePanel.add(new Label("The .arff file:"));
sourceFilePanel.add(arffFilenameField);
sourceFilePanel.add(browseButton);
// Setting panel.
Panel settingPanel = new Panel();
settingPanel.setLayout(new GridLayout(3, 6));
settingPanel.add(new Label("alpha"));
alphaField = new DoubleField("0.01");
settingPanel.add(alphaField);
settingPanel.add(new Label("beta"));
betaField = new DoubleField("0.02");
settingPanel.add(betaField);
settingPanel.add(new Label("gamma"));
gammaField = new DoubleField("0.03");
settingPanel.add(gammaField);
settingPanel.add(new Label("layer nodes"));
layerNodesField = new TextField("4, 8, 8, 3");
settingPanel.add(layerNodesField);
settingPanel.add(new Label("activators"));
activatorField = new TextField("sss");
settingPanel.add(activatorField);
settingPanel.add(new Label("training rounds"));
roundsField = new IntegerField("5000");
settingPanel.add(roundsField);
settingPanel.add(new Label("learning rate"));
learningRateField = new DoubleField("0.01");
settingPanel.add(learningRateField);
settingPanel.add(new Label("mobp"));
mobpField = new DoubleField("0.5");
settingPanel.add(mobpField);
Panel topPanel = new Panel();
topPanel.setLayout(new BorderLayout());
topPanel.add(BorderLayout.NORTH, sourceFilePanel);
topPanel.add(BorderLayout.CENTER, settingPanel);
messageTextArea = new TextArea(80, 40);
// The bottom part: ok and exit
Button okButton = new Button(" OK ");
okButton.addActionListener(this);
// DialogCloser dialogCloser = new DialogCloser(this);
Button exitButton = new Button(" Exit ");
// cancelButton.addActionListener(dialogCloser);
exitButton.addActionListener(ApplicationShutdown.applicationShutdown);
Button helpButton = new Button(" Help ");
helpButton.setSize(20, 10);
helpButton.addActionListener(new HelpDialog("ANN", "D:/sampledata/sampledata/src/data/help.txt"));
Panel okPanel = new Panel();
okPanel.add(okButton);
okPanel.add(exitButton);
okPanel.add(helpButton);
mainFrame.setLayout(new BorderLayout());
mainFrame.add(BorderLayout.NORTH, topPanel);
mainFrame.add(BorderLayout.CENTER, messageTextArea);
mainFrame.add(BorderLayout.SOUTH, okPanel);
mainFrame.setSize(600, 500);
mainFrame.setLocation(100, 100);
mainFrame.addWindowListener(ApplicationShutdown.applicationShutdown);
mainFrame.setBackground(GUICommon.MY_COLOR);
mainFrame.setVisible(true);
}
/**
* Read the arff file.
*/
@Override
public void actionPerformed(ActionEvent ae) {
String tempFilename = arffFilenameField.getText();
// Read the layers nodes.
String tempString = layerNodesField.getText().trim();
int[] tempLayerNodes = null;
try {
tempLayerNodes = stringToIntArray(tempString);
} catch (Exception ee) {
ErrorDialog.errorDialog.setMessageAndShow(ee.toString());
return;
}
double tempLearningRate = learningRateField.getValue();
double tempMobp = mobpField.getValue();
String tempActivators = activatorField.getText().trim();
FullAnn tempNetwork = new FullAnn(tempFilename, tempLayerNodes, tempLearningRate, tempMobp,
tempActivators);
int tempRounds = roundsField.getValue();
long tempStartTime = new Date().getTime();
for (int i = 0; i < tempRounds; i++) {
tempNetwork.train();
}
long tempEndTime = new Date().getTime();
messageTextArea.append("\r\nSummary:\r\n");
messageTextArea.append("Trainng time: " + (tempEndTime - tempStartTime) + "ms.\r\n");
double tempAccuray = tempNetwork.test();
messageTextArea.append("Accuracy: " + tempAccuray + "\r\n");
messageTextArea.append("End.");
}
/**
* Convert a string with commas into an int array.
* @param paraString The source string
* @return An int array.
* @throws Exception Exception for illegal data.
*/
public static int[] stringToIntArray(String paraString) throws Exception {
int tempCounter = 1;
for (int i = 0; i < paraString.length(); i++) {
if (paraString.charAt(i) == ',') {
tempCounter++;
}
}
int[] resultArray = new int[tempCounter];
String tempRemainingString = new String(paraString) + ",";
String tempString;
for (int i = 0; i < tempCounter; i++) {
tempString = tempRemainingString.substring(0, tempRemainingString.indexOf(",")).trim();
if (tempString.equals("")) {
throw new Exception("Blank is unsupported");
}
resultArray[i] = Integer.parseInt(tempString);
tempRemainingString = tempRemainingString
.substring(tempRemainingString.indexOf(",") + 1);
}
return resultArray;
}
/**
* The entrance method.
* @param args The parameters.
*/
public static void main(String args[]) {
new AnnMain();
}
}
AnnMain构造方法,是程序的入口方法,他初始化 GUI 界面并添加监听事件。所以从这个构造方法去了解这些代码
- mainFrame 来包含所有的对话框
- FilenameField实例化对象:arffFilenameField用于选择输入文件,将 arffFilenameField 对象注册为按钮 browseButton 的事件监听器
- 创建 Panel 面板 sourceFilePanel,主要用来放文件选择和按钮
- 创建 Panel 面板 settingPanel,并且采用网格布局(代码中是3行6列),并将DoubleField、TextField,IntegerField对象排列在一起,这些都是神经网络的参数
- 创建一个 TextArea 对象 messageTextArea,用于显示训练过程和结果的信息
- 创建 “OK” 按钮 okButton,并将 this 对象注册为它的事件监听器,这里的this就是当前对象ANN实例化的整个对象;创建 Exit按钮 exitButton并把ApplicationShutdown对象注册上去,创建 Help 按钮 helpButton,并将HelpDialog对象注册到这个按钮上。并创建 Panel 面板 okPanel,把这三个按钮都放上去
- 利用mainFrame 把所有的面板组件都放上去就成了如下:
2.4 GUI之接口与监听机制
下面这5个类的实现其实体现了设计模式中的策略模式,具体知识可跳转到此文章
- Flying接口类
package machinelearing.gui.test;
/**
* @author: fulisha
* @date: 2023/7/23 17:12
* @description:
*/
public interface Flying {
public void fly();
}
接口类,定义了一个方法fly(),无实现。但所有实现了这个接口类的类都要实现这个fly方法。
- Controller类
package machinelearing.gui.test;
/**
* @author: fulisha
* @date: 2023/7/23 17:14
* @description:
*/
public class Controller {
Flying flying;
Controller(){
flying = null;
}
void setListener(Flying paraFlying){
flying = paraFlying;
}
void doIt(){
flying.fly();
}
}
Controller类是一个控制器类,它用来执行飞行对象的飞行操作. 它包含一个Flying类型的成员变量flying,可以通过setListener()方法设置飞行对象,并通过doIt()方法执行飞行。
- Bird类
package machinelearing.gui.test;
/**
* @author: fulisha
* @date: 2023/7/23 17:15
* @description:
*/
public class Bird implements Flying {
double weight = 0.5;
@Override
public void fly(){
System.out.println("Bird fly, my weight is " + weight + " kg.");
}
}
Bird类实现了Flying接口,它必须提供fly()方法的具体实现。
- Plane
package machinelearing.gui.test;
import machinelearing.gui.test.Flying;
/**
* @author: fulisha
* @date: 2023/7/23 17:15
* @description:
*/
public class Plane implements Flying {
double price = 100000000;
@Override
public void fly() {
System.out.println("Plan fly, my price is " + price + " RMB.");
}
}
Plane类也实现了Flying接口,同样需要提供fly()方法的具体实现
- InterfaceTest类
package machinelearing.gui.test;
/**
* @author: fulisha
* @date: 2023/7/23 17:17
* @description:
*/
public class InterfaceTest {
public static void main(String[] args){
Controller tempController = new Controller();
Flying tempFlying1 = new Bird();
tempController.setListener(tempFlying1);
tempController.doIt();
Flying tempFlying2 = new Plane();
tempController.setListener(tempFlying2);
tempController.doIt();
}
}
通过使用Flying接口作为控制器Controller的成员变量,可以将不同的飞行对象(Bird和Plane)传递给Controller,使得Controller可以控制这些飞行对象的行为,这样的设计模式可以很容易地添加新的飞行对象,而不需要去修改Controller类的代码,这使得代码更灵活性,扩展性更强.
2.5 总结
今天学习的GUI 是 创建了一个包含输入和输出界面的 GUI 窗口,并为界面上的按钮注册了相应的事件监听器,当用户输入参数后,点击 OK 按钮可以神经网络训练和测试(这里的方法都是FullAnn里面的),点击 Exit 按钮可以退出程序,点击 Help 按钮可以查看帮助信息。今天的代码主要是学习的GUI布局,而关于神经网络学习是之前已经学习的知识(FullAnn类),可再巩固。