我目前有一个简单的Java AWT / Swing代码,可以创建一个简单的GUI,它需要多个字符串用户输入并存储并在Intellij终端中显示它,如下所示:
import javax.swing.*;
import java.awt.*; // Using AWT container and component classes
import java.awt.event.*; // Using AWT event classes and listener interfaces
import java.util.ArrayList;
import java.util.Scanner;
// An AWT program inherits from the top-level container java.awt.Frame
public class DateTime extends JFrame implements ActionListener {
private Label lblCount, lblsource, lbldate1, lbldate2; // Declare a Label component
private JTextField tfCount, date1, date2; // Declare a TextField component
private Button btnCount; // Declare a Button component
private int count = 0; // Counter's value
static String type = null;
private JCheckBox source1, source2;
boolean a = false;
boolean b= false;
static String source, datedefined1, datedefined2;
ArrayList<String> texts = new ArrayList<String>();
// Constructor to setup GUI components and event handlers
public DateTime () {
setLayout(new FlowLayout());
// "super" Frame, which is a Container, sets its layout to FlowLayout to arrange
// the components from left-to-right, and flow to next row from top-to-bottom.
lblCount = new Label("Enter the type of report you want generated; Hourly/ Daily/ Weekly/ EventComparison:"); // construct the Label component
add(lblCount); // "super" Frame container adds Label component
tfCount = new JTextField("", 20); // construct the TextField component
tfCount.setEditable(true); // set to read-only
// "super" Frame container adds TextField component
tfCount.setBounds(10,50,200,40);
add(tfCount);
tfCount.addActionListener(this);
lblsource = new Label("Now choose the source type:");
add(lblsource);
source1 = new JCheckBox("Drivetest", a);
source1.setBounds(10,100,50,30);
add(source1);
source2 = new JCheckBox("Ookla Dump",b);
add(source2);
source1.addActionListener(this);
source2.addActionListener(this);
lbldate1 = new Label("Please enter the Start DATETIME of the chosen duration(YYYY-MM-DD HH:MM:SS) :");
add(lbldate1);
date1 = new JTextField("", 30); // construct the TextField component
date1.setEditable(true);
add(date1);
date1.addActionListener(this);
lbldate2 = new Label("Please enter the end DATETIME of the chosen duration(YYYY-MM-DD HH:MM:SS): ");
add(lbldate2);
date2 = new JTextField("",30);
date2.setEditable(true);
add(date2);
date2.addActionListener(this);
// set to read-only
// "super" Frame container adds TextField component
// "btnCount" is the source object that fires an ActionEvent when clicked.
// The source add "this" instance as an ActionEvent listener, which provides
// an ActionEvent handler called actionPerformed().
// Clicking "btnCount" invokes actionPerformed().
setTitle("Report Generator"); // "super" Frame sets its title
setSize(800, 700); // "super" Frame sets its initial window size
// For inspecting the Container/Components objects
// System.out.println(this);
// System.out.println(lblCount);
// System.out.println(tfCount);
// System.out.println(btnCount);
setVisible(true); // "super" Frame shows
// System.out.println(this);
// System.out.println(lblCount);
// System.out.println(tfCount);
// System.out.println(btnCount);
}
// The entry main() method
public static void main(String[] args) {
// Invoke the constructor to setup the GUI, by allocating an instance
DateTime app = new DateTime();
// or simply "new AWTCounter();" for an anonymous instance
}
// ActionEvent handler - Called back upon button-click.
@Override
public void actionPerformed(ActionEvent evt) {
Object actionsource = evt.getSource();
if(actionsource instanceof JTextField){
JTextField dateget1 = (JTextField) evt.getSource();
JTextField dateget2 = (JTextField) evt.getSource();
if (dateget1 == date1){
datedefined1 = date1.getText();
System.out.println(datedefined1);}
else if(dateget2 == date2){
datedefined2 = date2.getText();
System.out.println(datedefined2);}
else{
type = tfCount.getText();
System.out.println(type);
}
}
else if(actionsource instanceof JCheckBox){
JCheckBox cb = (JCheckBox) evt.getSource();
if(cb == source1){
source = "Drivetest";
System.out.println(source);
}
else if(cb == source2){
source = "Ookla Data Dump";
System.out.println(source);
}
}
}
}
问题是,我的主程序需要在执行之前接收并存储多个字符串变量(即.type,source,date1和date2)。
我的程序正常终端式运行的代码如下所示:
System.out.println("Enter the report type you would like: DailyComparison or HourlyComparison or WeeklyComparison or EventComparison; Type the exact words!");
type = scan.next();
System.out.println("Now enter the type of data you would like analysed: OOKLA or ManualTest: ");
source = scan.next();
if("DailyComparison".equals(type) || "HourlyComparison".equals(type) || "WeeklyComparison".equals(type) ){
Scanner scan2 = new Scanner((System.in));
System.out.println("Now enter the lower bound of the DateTime range(FORMAT YYYY-MM-DD HH:00:00):");
date1 = scan2.nextLine();
System.out.println("Now enter the upper bound of the DateTime range(FORMAT YYYY-MM-DD HH:00:00):");
date2 = scan2.nextLine();
}
用户输入正常通过终端。
然后用户输入来运行程序的其余部分,调用我定义的其他类中的方法:
Report.report(date1, date2, type, filename, source);// Creates the excel .xlsx file report
MailSender.MailSender(filename, type); // Send a email containing the attached report xlsx file
所以我的问题是:如何扩展这个GUI代码的功能,以便首先收集用户输入的字符串变量,然后用于运行程序的其余部分?
编辑:
感谢你们的建议。
我有点工作,但我不确定结构是否合理。以前发生的事情是,因为每个组件都处理一个不同的变量,我想在调用处理这些变量的主方法类之前先存储所有变量。
所以我创建了一个名为“Generate Report”的附加按钮,并在actionlistener条件+ action下执行此按钮,我就像这样放置了class.methods。哪里基本上我键入了各个组件中的所有变量(复选框,按钮等)然后按“生成报告”
if (evt.getActionCommand() == "Generate Report") {
if ("DailyComparison".equals(type)) {
filename = "\\Users\\User\\Documents\\Reports\\" + " Daily SpeedTest Telco Comparison Report";
datedefined3 = null;
datedefined4 = null;
datedefined5 = null;
datedefined6 = null;
} else if ("WeeklyComparison".equals(type)) {
filename = "\\Users\\User\\Documents\\Reports\\" + " Weekly Telco Comparison Report";
datedefined3 = null;
datedefined4 = null;
datedefined5 = null;
datedefined6 = null;
} else if ("HourlyComparison".equals(type)) {
filename = "\\Users\\User\\Documents\\Reports\\" + "Hourly Telco Comparison Report";
datedefined3 = null;
datedefined4 = null;
datedefined5 = null;
datedefined6 = null;
}
if("HourlyComparison".equals(type)|"DailyComparison".equals(type)|"WeeklyComparison".equals(type)) {
Report.report(datedefined1, datedefined2, datedefined3, datedefined4, datedefined5, datedefined6, type, filename, source);// Creates the base excel .xlsx file report
LinechartGenerator.chartgen(0, "upload", datedefined1, datedefined2, datedefined3, datedefined4, datedefined5, datedefined6, source, type, filename);
LinechartGenerator.chartgen(0, "download", datedefined1, datedefined2, datedefined3, datedefined4, datedefined5, datedefined6, source, type, filename);
LinechartGenerator.chartgen(0, "latency", datedefined1, datedefined2, datedefined3, datedefined4, datedefined5, datedefined6, source, type, filename);
}
}
虽然代码有其局限性,但我无法先按生成报告,否则程序只会因为没有存储变量而抛出错误。
我还遇到了一个障碍,我试图找到Swing等效的Flush Scanner功能,以允许用户在同一个程序实例中生成多个报告。
答案 0 :(得分:1)
这会引用一些基本原则:
观察者模式在大多数UI框架中被广泛使用,这些框架往往是事件驱动的(发生的事情,你对它做出反应),而不是程序驱动或线性驱动。
通常,您会创建一个&#34;表格&#34;其中包括将捕获您需要的数据的字段以及某种&#34;按钮&#34;,按下后,将启动下一步 - 验证数据,构建模型并生成表单已被通知完成。
然后观察者将采用该模型并根据需要对其进行处理。
这些只是UI开发中使用的一些基本概念。看看:
了解更多细节
答案 1 :(得分:0)
我注意到您将this
设置为所有复选框和文本字段的动作侦听器。我认为你真正想要的是,只在用户点击按钮时处理用户输入,对吗?
删除这些行:
tfCount.addActionListener(this);
以便this
仅处理按钮的点击。
现在,您可以访问actionPerformed
方法中的所有输入:
dateDefined1 = date1.getText();
dateDefined2 = date2.getText();
type = tfCount.getText();
if (source1.isChecked()) {
source = "Drivertest";
} else {
source = "Ookla Data Dump"
}
// now you can use dateDefined1, dateDefined2, type and source!
另外,为什么使用复选框但不使用单选按钮?对于这种&#34;从下面选项中选择一个&#34;用法,单选按钮更适合。
答案 2 :(得分:-1)
你可以在两个不同的罐子里分解它:
关于如何从java应用程序调用jar,你可以参考这个question。