学习来源:https://blog.csdn.net/minfanphd/article/details/116974889
一、GUI (1. 对话框相关控件)
1、GUI(图形用户接口)是指采用图形方式显示的计算机操作用户界面。GUI便捷、准确,实用性很强,主要功能是实现人与计算机等电子设备的人机交互。
2、图形用户界面是一种人与计算机通信的界面显示格式,允许用户使用鼠标等输入设备操纵屏幕上的图标或菜单选项,以选择命令、调用文件、启动程序或执行其它一些日常任务。与通过键盘输入文本或字符命令来完成例行任务的字符界面相比,图形用户界面有许多优点。图形用户界面由窗口、下拉菜单、对话框及其相应的控制机制构成,在各种新式应用程序中都是标准化的,即相同的操作总是以同样的方式来完成,在图形用户界面,用户看到和操作的都是图形对象,应用的是计算机图形学的技术。
3、主要组成。桌面、视图、标签、菜单、图标和按钮等。
4、ApplicationShowdown.java 仅用于退出图形用户界面 GUI。
5、代码
package bp神经网络;
/**
* @time 2022/6/8
* @author Liang Huang
*/
import java.awt.event.*;
public class ApplicationShutdown implements WindowListener, ActionListener {
/**
* Only one instance.
*/
public static ApplicationShutdown applicationShutdown = new ApplicationShutdown();
/**
***************************
* This constructor is private such that the only instance is generated here.
***************************
*/
private ApplicationShutdown() {
}// Of ApplicationShutdown.
/**
***************************
* Shutdown the system
***************************
*/
public void windowClosing(WindowEvent comeInWindowEvent) {
System.exit(0);
}// Of windowClosing.
public void windowActivated(WindowEvent comeInWindowEvent) {
}// Of windowActivated.
public void windowClosed(WindowEvent comeInWindowEvent) {
}// Of windowClosed.
public void windowDeactivated(WindowEvent comeInWindowEvent) {
}// Of windowDeactivated.
public void windowDeiconified(WindowEvent comeInWindowEvent) {
}// Of windowDeiconified.
public void windowIconified(WindowEvent comeInWindowEvent) {
}// Of windowIconified.
public void windowOpened(WindowEvent comeInWindowEvent) {
}// Of windowOpened.
public void actionPerformed(ActionEvent ee) {
System.exit(0);
}// Of actionPerformed.
}// Of class ApplicationShutdown
6、DialogCloser.java 用于关闭窗口, 而不是整个的 GUI。
package bp神经网络;
/**
* @time 2022/6/8
* @author Liang Huang
*/
import java.awt.*;
import java.awt.event.*;
public class DialogCloser extends WindowAdapter implements ActionListener {
/**
* The dialog under control.
*/
private Dialog currentDialog;
/**
***************************
* The first constructor.
***************************
*/
public DialogCloser() {
super();
}// Of the first constructor
/**
***************************
* The second constructor.
*
* @param paraDialog the dialog under control
***************************
*/
public DialogCloser(Dialog paraDialog) {
currentDialog = paraDialog;
}// Of the second constructor
/**
***************************
* Close the dialog which clicking the cross at the up-right corner of the window.
*
* @param comeInWindowEvent
* From it we can obtain which window sent the message because X
* was used.
***************************
*/
public void windowClosing(WindowEvent paraWindowEvent) {
paraWindowEvent.getWindow().dispose();
}// Of windowClosing.
/**
***************************
* Close the dialog while pushing an "OK" or "Cancel" button.
*
* @param paraEvent
* Not considered.
***************************
*/
public void actionPerformed(ActionEvent paraEvent) {
currentDialog.dispose();
}// Of actionPerformed.
}// Of class DialogCloser
7、ErrorDialog.java 用于显示出错信息。
package bp神经网络;
/**
* @time 2022/6/8
* @author Liang Huang
*/
import java.awt.*;
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);
}// Of constructor
/**
***************************
* set message.
*
* @param paramMessage the new message
***************************
*/
public void setMessageAndShow(String paramMessage) {
messageTextArea.setText(paramMessage);
setVisible(true);
}// Of setTitleAndMessage
}// Of class ErrorDialog
8、GUICommon.java 存储一些公用变量。
package bp神经网络;
/**
* @time 2022/6/8
* @author Liang Huang
*/
import java.awt.*;
import javax.swing.*;
public class GUICommon extends Object {
/**
* 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!");
} // Of if
}// Of setFrame
/**
***************************
* 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!");
} // Of if
}// Of setPAne
}// Of class GUICommon
9、HelpDialog.java 显示帮助信息, 这样, 在主界面点击 Help 按钮时, 就会显示相关参数的说明。
package bp神经网络;
/**
* @time 2022/6/8
* @author Liang Huang
*/
import java.io.*;
import java.awt.*;
import java.awt.event.*;
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);
}// Of constructor
/**
*************************
* Simply set it visible.
*************************
*/
public void actionPerformed(ActionEvent ee) {
setVisible(true);
}// Of actionPerformed.
}// Of class HelpDialog
##二、 GUI (2. 数据读取控件)
1、DoubleField.java 用于接受实型值。
package bp神经网络;
/**
* @time 2022/6/10
* @author Liang Huang
*/
import java.awt.*;
import java.awt.event.*;
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);
}// Of the first constructor
/**
***************************
* Only specify the content.
*
* @param paraString The content of the field.
***************************
*/
public DoubleField(String paraString) {
this(paraString, 10);
}// Of the second constructor
/**
***************************
* Only specify the width.
*
* @param paraWidth The width of the field.
***************************
*/
public DoubleField(int paraWidth) {
this("5.13", paraWidth);
}// Of the third constructor
/**
***************************
* 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);
}// Of the fourth constructor
/**
**********************************
* Implement FocusListener.
*
* @param paraEvent The event is unimportant.
**********************************
*/
public void focusGained(FocusEvent paraEvent) {
}// Of focusGained
/**
**********************************
* Implement FocusListener.
*
* @param paraEvent The event is unimportant.
**********************************
*/
public void focusLost(FocusEvent paraEvent) {
try {
doubleValue = Double.parseDouble(getText());
} catch (Exception ee) {
ErrorDialog.errorDialog
.setMessageAndShow("\"" + getText() + "\" Not a double. Please check.");
requestFocus();
} // Of try
}// Of focusLost
/**
**********************************
* 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();
} // Of try
return doubleValue;
}// Of getValue
}// Of class DoubleField
2、IntegerField.java
package bp神经网络;
/**
* @time 2022/6/10
* @author Liang Huang
*/
import java.awt.*;
import java.awt.event.*;
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");
}// Of constructor
/**
***************************
* 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);
}// Of constructor
/**
***************************
* Only specify the content.
*
* @param paraString The given default string.
***************************
*/
public IntegerField(String paraString) {
super(paraString);
addFocusListener(this);
}// Of constructor
/**
***************************
* Only specify the width.
*
* @param paraWidth The width of the field.
***************************
*/
public IntegerField(int paraWidth) {
super(paraWidth);
setText("513");
addFocusListener(this);
}// Of constructor
/**
**********************************
* Implement FocusListenter.
*
* @param paraEvent The event is unimportant.
**********************************
*/
public void focusGained(FocusEvent paraEvent) {
}// Of focusGained
/**
**********************************
* Implement FocusListenter.
*
* @param paraEvent The event is unimportant.
**********************************
*/
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();
}
}// Of focusLost
/**
**********************************
* 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;
}// Of getValue
}// Of class IntegerField
3、FilenameField.java 则需要借助于系统提供的 FileDialog。
package bp神经网络;
/**
* @time 2022/6/10
* @author Liang Huang
*/
import java.io.*;
import java.awt.*;
import java.awt.event.*;
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(this);
}// Of constructor
/**
***************************
* 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);
}// Of constructor
/**
***************************
* 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);
}// Of constructor
/**
**********************************
* Avoid setting null or empty string.
*
* @param paraText The given text.
**********************************
*/
public void setText(String paraText) {
if (paraText.trim().equals("")) {
super.setText("unspecified");
} else {
super.setText(paraText.replace('\\', '/'));
}//Of if
}// Of setText
/**
**********************************
* Implement ActionListenter.
*
* @param paraEvent The event is unimportant.
**********************************
*/
public void actionPerformed(ActionEvent paraEvent) {
FileDialog tempDialog = new FileDialog(GUICommon.mainFrame,
"Select a file");
tempDialog.setVisible(true);
if (tempDialog.getDirectory() == null) {
setText("");
return;
}//Of if
String directoryName = tempDialog.getDirectory();
String tempFilename = directoryName + tempDialog.getFile();
//System.out.println("tempFilename = " + tempFilename);
setText(tempFilename);
}// Of actionPerformed
/**
**********************************
* Implement FocusListenter.
*
* @param paraEvent The event is unimportant.
**********************************
*/
public void focusGained(FocusEvent paraEvent) {
}// Of focusGained
/**
**********************************
* Implement FocusListenter.
*
* @param paraEvent The event is unimportant.
**********************************
*/
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("");
}
}// Of focusLost
}// Of class FilenameField
三、GUI (3. 总体布局)
1、用了 GridLayout 和 BorderLayout 来组织控件。
2、按下 OK 执行 actionPerformed。
package bp神经网络;
/**
* @time 2022/6/13
* @author Liang Huang
*/
import java.awt.*;
import java.awt.event.*;
import java.util.Date;
import machinelearning.ann.FullAnn;
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. minfanphd@163.com");
// The top part: select arff file.
arffFilenameField = new FilenameField(30);
arffFilenameField.setText("d:/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", "src/machinelearning/gui/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);
}// Of the constructor
/**
***************************
* Read the arff file.
***************************
*/
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;
} // Of try
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();
} // Of for n
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.");
}// Of actionPerformed
/**
**********************************
* 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++;
} // Of if
} // Of for i
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");
} // Of if
resultArray[i] = Integer.parseInt(tempString);
tempRemainingString = tempRemainingString
.substring(tempRemainingString.indexOf(",") + 1);
} // Of for i
return resultArray;
}// Of stringToIntArray
/**
***************************
* The entrance method.
*
* @param args The parameters.
***************************
*/
public static void main(String args[]) {
new AnnMain();
}// Of main
}// Of class AnnMain
四、GUI (4. 接口与监听机制)
1、接口本质上支持多继承.
2、从监听机制、接口等角度, 分析在 GUI 上的各种操作分别会触发哪些代码。
package bp神经网络;
/**
* @time 2022/6/13
* @author Liang Huang
*/
interface Flying{
public void fly();
}//Of interface Flying
//Define a controller to cope with it.
class Controller{
Flying flying;
Controller(){
flying = null;
}//Of the constructor
void setListener(Flying paraFlying){
flying = paraFlying;
}//Of addListener
void doIt(){
flying.fly();
}//Of doIt
}//Of Controller
// Define class Bird for the interface.
class Bird implements Flying{
double weight = 0.5;
public void fly(){
System.out.println("Bird fly, my weight is " + weight + " kg.");
}//Of fly
}//Of class Bird
//Define class Plane for the interface.
class Plane implements Flying{
double price = 100000000;
public void fly(){
System.out.println("Plan fly, my price is " + price + " RMB.");
}//Of fly
}//Of class Plane
// Test the interface.
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();
}//Of main
}//Of class InterfaceTest