簡體   English   中英

如何在Java Swing Gui中從用戶輸入存儲變量以備將來使用?

[英]How to store variables for further use from User-input in Java Swing Gui?

我目前有一個簡單的Java AWT / Swing代碼,該代碼創建了一個簡單的GUI,該GUI接受多個String User輸入,並將其存儲並顯示在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);
            }

        }



    }
}

關鍵是,我的主程序需要在執行之前接受並存儲多個字符串變量(即類型,源,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條件和操作下,將class.method這樣放置。 基本上,我在各個組件(復選框,按鈕等)中鍵入所有變量,然后按“生成報告”

 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);
        }


    }

盡管代碼有其局限性,我無法先按“生成報告”,否則程序將拋出錯誤,因為未存儲任何變量。

我還遇到了一個障礙,在這里我試圖找到與Flush Scanner函數等效的Swing,以允許用戶在同一程序實例中生成多個報告。

這將調用一些基本原則:

  • Model-View-Controller-將“數據”與視圖和用於收集數據的機制分開
  • 觀察者模式-用於在某些狀態更改時生成通知,以便感興趣的各方可以采取行動。

觀察者模式在大多數UI框架中得到了廣泛的使用,它們通常是事件驅動的(某些事情會發生,您對此做出響應),而不是過程驅動或線性驅動。

通常,您將創建一個“表單”,其中包含將捕獲所需數據的字段和某種“按鈕”,當按下該按鈕時,將啟動下一步-驗證數據,構建模型並生成通知,表格已經完成。

然后,觀察者將采用該模型並根據需要對其進行處理。

這些只是UI開發中使用的一些基本概念。 看一下:

有關更多詳細信息

您可以將其分解為兩個不同的jar:

  1. 讀取輸入並將其寫入臨時文件。
  2. 讀取輸入並將其寫入文件后,調用您的GUI jar應用程序,這可以從臨時文件中讀取內容。

您可以參考有關如何從Java應用程序調用jar的問題

我注意到,你設置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!

另外,為什么要使用復選框而不是單選按鈕? 對於這種“從以下選項中選擇一個”的用法,單選按鈕更適合。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM