简体   繁体   English

用Java应用程序实现GUI

[英]Implementing GUI with Java application

I'm quite the beginner when it comes to java & coding in general, so I apologise for any overly obvious questions asked. 一般来说,对于Java和编码,我还是一个初学者,因此对于任何过于明显的问题我深表歉意。 I've just completed part of an application which reads data from an SQL database, then sends some stuff to print to socket depending on what information is read. 我刚刚完成了一个应用程序的一部分,该应用程序从SQL数据库读取数据,然后根据读取的信息将一些内容发送到套接字以进行打印。 I'm now trying to learn swing and get a GUI working with the application. 我现在正在尝试学习swing并获得与该应用程序一起使用的GUI。 Currently I have 2 forms, the first is used to select a printer, then the second will (hopefully) work as a log/ console which tells the user what and when stuff is happening. 目前,我有2种表格,第一种用于选择打印机,然后第二种将(希望)用作日志/控制台,告诉用户发生了什么以及何时发生。 I've got the code and the forms together in a project. 我在一个项目中将代码和表单放在一起。

I was wanting to find out how I can make the class which has my code in run when a Jbutton is pressed on a GUI, as well as how I can stop it from running when a different JButton is pressed. 我想了解如何在GUI上按下Jbutton时使运行我的代码的类,以及如何在按下其他JButton时停止运行它的代码。

The code from the Swing Form (Form2.java) is as follows: Swing表单(Form2.java)中的代码如下:

package com.company;
import javax.swing.*;
public class Form2
{
private JTextArea jtaConsole;
private JPanel Jframer;
private JButton stopButton;
private JButton startButton;

public Form2(String message)
{
    JFrame frame = new JFrame("Print Application");
    frame.setContentPane(this.Jframer);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setResizable(true);
    frame.setVisible(true);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    jtaConsole.append("  Printer selected: " + message + "\n");
}

} }

And the code from the class I want the JButton to run is as follows: 我希望运行JButton的类中的代码如下:

package com.company;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.sql.*;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ZebraCode
{
public static void main(String[] args)
{
    {
        while (true)
        {
            //SQL login.
            String connectionString = "jdbc:sqlserver://:;database=;user=;password=!!;";

            //Select Data.
            String SQL = "SELECT TOP 2 [PK_PrintQueueID],[FK_PrinterID],[FK_BarcodeTypeID],[Barcode],[Quantity],[QueueDate],[ProcessedDate] FROM [Brad].[dbo].[PrintQueue] -- WHERE ProcessedDate IS NULL";

            //Connection Variable & Time Settings.
            Connection connection = null;
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = new Date();

            try
            {
                connection = DriverManager.getConnection(connectionString);
                Statement stmt = connection.createStatement();
                Statement stmt2 = null;
                ResultSet rs = stmt.executeQuery(SQL);
                while (rs.next())
                {
                    // Get barcode value to split & Set date.
                    String FK_BarcodeTypeID = rs.getString("FK_BarcodeTypeID");
                    String barcode = rs.getString("Barcode");
                    String[] parts = barcode.split("-");
                    String part1 = parts[0];
                    String SQL2 = "UPDATE PrintQueue SET ProcessedDate = '" + dateFormat.format(date) + "' WHERE PK_PrintQueueID = '" + rs.getString("PK_PrintQueueID")+"'";
                    stmt2 = connection.createStatement();
                    stmt2.executeUpdate(SQL2);

                    // Action based on type of barcode.
                    if (FK_BarcodeTypeID.equals("1"))
                    {
                        // Type 128 barcode.
                        String zpl = "^XA^BY2,3,140^FT80,200^BCN,Y,N,N^FD>:" + rs.getString("Barcode") + "^FS^FT200,250^A0N,42,40^FH^FD" + part1 + "^FS^XZ";
                        printlabel(zpl);
                        System.out.println("New serialized barcode added.\nPrinting: " + (rs.getString("Barcode")));
                        System.out.println("Process date: " + dateFormat.format(date) + ".\n");
                    }
                    else
                    {
                        // Type 39 barcode.
                        String zpl = "CT~~CD,~CC^~CT~ ^XA~TA000~JSN^LT0^MNW^MTT^PON^PMN^LH0,0^JMA^PR4,4~SD15^JUS^LRN^CI0^XZ^XA^MMT^PW674^LL0376 ^LS0 ^BY2,3,151^FT84,249^BCN,,Y,N^FD>:" + rs.getString("Barcode") + "^FS ^PQ1,0,1,Y^XZ";
                        printlabel(zpl);

                        System.out.println("New un-serialized barcode added.\nPrinting: " + (rs.getString("Barcode")));
                        System.out.println("Process date: " + dateFormat.format(date) + ".\n");
                    }
                }
            } catch (SQLException e)
            {
                e.printStackTrace();
            }
            try
            {
                //Makes execution sleep for 5 seconds.
                Thread.sleep(5000);
            }
            catch (InterruptedException ez)
            {
            }
        }
    }
}

//Printer Info.
public static void printlabel(String zpl)
{
    try
    {
        Socket clientSocket;
        clientSocket = new Socket("", );
        DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
        outToServer.writeBytes(zpl);
        clientSocket.close();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}

} }

Any tutorials or direction as to how I can learn this would be appreciated. 任何有关我如何学习的教程或指导都将不胜感激。

Thanks! 谢谢!

You want to add an action listener.. here is an example. 您想添加一个动作监听器..这是一个例子。 Below are two examples on how to do so using lambdas and not using one. 下面是两个有关如何使用lambda而不是一个的示例。

    JButton button = new JButton("Click Me!");

     // Without lambda
    button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
            // Code to execture when clicked
        }
    });


     //With lambda
      button.addActionListener(e -> {
        //code to execute when clicked
    });

I'd also advise you to do a little reading, http://www.tutorialspoint.com/design_pattern/mvc_pattern.htm 我也建议您做一些阅读, http://www.tutorialspoint.com/design_pattern/mvc_pattern.htm

Your question is a bit broad but let me offer some suggestions: 您的问题有点广泛,但让我提供一些建议:

  • First off, you really don't want to have a JButton run the database code unchanged as doing this would be shoehorning a linear console program into an event-driven GUI, a recipe for disaster. 首先,您真的不想让JButton不变地运行数据库代码,因为这样做将把线性控制台程序塞入事件驱动的GUI中,这是灾难的根源。 Note that as written all your database code is held within a single static main method, and so there would be no way for the GUI to be able to control the running of that code. 请注意,在编写本文时,所有数据库代码都保存在一个静态 main方法中,因此GUI无法控制该代码的运行。 Either it runs or it doesn't, that's it, and no easy way for the database code to return its data to the GUI. 它要么运行,要么不运行,仅此而已,并且没有简单的方法来使数据库代码将其数据返回给GUI。
  • Instead first change that database code so that it is much more modular and OOP-friendly, including creating proper classes with state (instance fields) and behavior (instance methods), and getting almost all that code out of the static main method. 取而代之的是,首先更改该数据库代码,以使其更具模块化和对OOP友好性,包括使用状态(实例字段)和行为(实例方法)创建适当的类,并从静态main方法中获取几乎所有代码。
  • What I'm asking you to do is to create a proper model for your GUI, aka your view . 我要你做的是为您的GUI(即您的view)创建一个合适的模型 Only after doing this would you have your GUI create a model object and call its methods on button push within your ActionListener. 只有这样做之后,您才能让GUI创建模型对象,并在ActionListener中的按钮按下时调用其方法。 You will also want to call any long-running code within a background thread such as can be obtained with a SwingWorker. 您还将希望在后台线程中调用任何长时间运行的代码,例如可以使用SwingWorker获得的代码。

Other issues: 其他事宜:

  • You never initialize your JPanel or JTextArea variables, and so you're both adding a null variable as your JFrame's JPanel and calling methods on a null JTextArea variable, both of which will throw NullPointerExceptions. 您永远不会初始化JPanel或JTextArea变量,因此都将添加一个空变量作为JFrame的JPanel并在一个空的JTextArea变量上调用方法,这两个变量都会抛出NullPointerExceptions。

Here's a part of code I developed to better understand Java gui. 这是我为了更好地理解Java gui而开发的一部分代码。 I'm also a begginer. 我也是初学者。 It's three classes: starter class, ongoing non gui processes, gui with the swingworker method. 它分为三个类:入门类,正在进行的非gui进程,带有swingworker方法的gui。 Simple, works, can safely update a lot of gui components from Swingworkers process method (passes a class instance as argument). 简单,可行,可以安全地从Swingworkers流程方法中更新许多gui组件(将类实例作为参数传递)。 Whole code so it can be copy/pasted: 完整代码,因此可以复制/粘贴:

package structure;

public class Starter {

public static void main(String[] args) {
    Gui1 thegui = new Gui1();   

}

}

LOGIC 逻辑

    package structure;

public class Logical {
String realtimestuff;

public String getRealtimestuff() {
    return realtimestuff;
}

public void setRealtimestuff(String realtimestuff) {
    this.realtimestuff = realtimestuff;
}
//MAIN LOGICAL PROCESS..
public void process(){
    // do important realtime stuff
    if (getRealtimestuff()=="one thing"){
        setRealtimestuff("another thing");
    }else{setRealtimestuff("one thing");
}
    // sleep a while for readibility of label in GUI
    //System.out.println(getRealtimestuff());
    try {
        Thread.sleep(250);
    } catch (InterruptedException e) {
         System.out.println("sleep interrupted");
        return;
    }

}
}

GUI CLASS with Swingworker Swingworker的GUI类

package structure;

import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JLabel;
import java.util.List;
import javax.swing.*;

public class Gui1  {    

final class Dataclass{
    String stringtosend;    
    public Dataclass(String jedan){
        //super();
        this.stringtosend = jedan;
    }
    }

// EDT constructor
JFrame frame;
public Gui1(){
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {                   
                initialize();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });     
}

public void initialize() {
    // JUST A FRAME WITH A PANEL AND A LABEL I WISH TO UPDATE

    frame = new JFrame();
    frame.setBounds(100, 100, 200, 90);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel panel = new JPanel();
    frame.getContentPane().add(panel, BorderLayout.NORTH);

    JLabel lblNovaOznaka = new JLabel();                
    panel.add(lblNovaOznaka);
    frame.setVisible(true);


    SwingWorker <Void, Dataclass> worker = new SwingWorker <Void, Dataclass>(){

        @Override
        protected Void doInBackground() throws Exception {                  
            Logical logic = new Logical();
            boolean looper = true;
            String localstring;
            while (looper == true){
                logic.process();
                localstring = logic.getRealtimestuff();                 
                publish(new Dataclass(localstring));

            }
            return null;
        }

        @Override
        protected void process(List<Dataclass> klasa) {
            // do a lot of things in background and then pass a loto of arguments for gui updates
            Dataclass xxx = klasa.get(getProgress());               
            lblNovaOznaka.setText(xxx.stringtosend);    

        }

    };
    worker.execute();

}

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM