Java 带gui的应用服务器/客户端

Java 带gui的应用服务器/客户端,java,Java,我想用java创建一个带有gui的应用服务器/客户机,但我不清楚如何组织这个类。我创建了应用程序gui: 这是密码 import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.Collection; public class AziendaGUI implements ActionListener { private JButton view_list; private JButto

我想用java创建一个带有gui的应用服务器/客户机,但我不清楚如何组织这个类。我创建了应用程序gui:

这是密码

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

import java.util.Collection;

public class AziendaGUI implements ActionListener {

private JButton view_list;
private JButton save_list;
private JTextArea text_area;
private JScrollPane scrollpane;
private JPanel pane;

private JFrame frame;
private GridBagLayout grid;

private Azienda company;

public AziendaGUI() {

    company = new Azienda();

    frame = new JFrame("Immobiliari s.p.a");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    view_list = new JButton("View Property");
    view_list.setActionCommand("view_list");
    view_list.addActionListener(this);

    save_list = new JButton("Save List");
    save_list.setActionCommand("save_list");
    save_list.addActionListener(this);

    text_area = new JTextArea();
    scrollpane = new JScrollPane(text_area);
    scrollpane.setPreferredSize(new Dimension(250,350));

    grid = new GridBagLayout();
    pane = new JPanel(grid);

    /* Set Constraints view_list button */
    grid.setConstraints(view_list, new GridBagConstraints(0,0,1,1,0.0,0.0,GridBagConstraints.WEST,GridBagConstraints.NONE,new Insets(5,5,5,5),0,0));
    pane.add(view_list);

    /* Set Constraints save_list button */
    grid.setConstraints(save_list,new GridBagConstraints(1,0,1,1,0.0,0.0,GridBagConstraints.EAST,GridBagConstraints.NONE,new Insets(5,5,5,5),0,0));
    pane.add(save_list);

    /* Set Constraint text area */
    grid.setConstraints(scrollpane, new GridBagConstraints(0,1,2,1,0.0,0.0,GridBagConstraints.CENTER,GridBagConstraints.NONE,new Insets(5,5,5,5),0,0));
    pane.add(scrollpane);

    frame.setLayout(new FlowLayout());
    frame.add(pane);

    frame.pack();
    frame.setVisible(true);
}

private void viewList(Collection<Immobile> list){

    text_area.setText(""); //Evita che venga ripetuto tutto il contenuto

    for(Immobile imb : list){

        text_area.append(imb.toString()+"\n");
    }
}

private void store(){

    String file_name = JOptionPane.showInputDialog("Inserisci il nome del file");

    company.store(file_name);
}

@Override
public void actionPerformed(ActionEvent e){

    String s = e.getActionCommand();

    if(s.equals("view_list")){

       viewList(company.getImmobili());
    }
    if(s.equals("save_list")){

        store();
    }
}


public static void main(String[] args) {

    SwingUtilities.invokeLater(new Runnable(){@Override
                                              public void run(){new AziendaGUI();}});
}
}
import java.awt.*;
导入java.awt.event.*;
导入javax.swing.*;
导入java.util.Collection;
公共类AziendaGUI实现ActionListener{
私有JButton视图列表;
私有JButton保存列表;
专用JTextArea text_区域;
私有JScrollPane滚动窗格;
私人JPanel窗格;
私有JFrame;
专用网格布局网格;
私营阿齐恩达公司;
公共AziendaGUI(){
公司=新Azienda();
框架=新的JFrame(“Immobiliari s.p.a”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
视图列表=新的JButton(“视图属性”);
view_list.setActionCommand(“view_list”);
查看\u list.addActionListener(此);
保存列表=新的JButton(“保存列表”);
save_list.setActionCommand(“save_list”);
保存_list.addActionListener(此);
text_area=新JTextArea();
scrollpane=新的JScrollPane(文本区域);
scrollpane.setPreferredSize(新维度(250350));
grid=新的GridBagLayout();
窗格=新的JPanel(网格);
/*设置约束查看列表按钮*/
grid.setConstraints(查看列表,新GridBagConstraints(0,0,1,1,0.0,0.0,GridBagConstraints.WEST,GridBagConstraints.NONE,新插入(5,5,5,5),0,0));
窗格。添加(查看列表);
/*设置约束保存列表按钮*/
setConstraints(保存列表,新的GridBagConstraints(1,0,1,1,0.0,0.0,GridBagConstraints.EAST,GridBagConstraints.NONE,新的插入(5,5,5,5),0,0));
添加(保存列表);
/*设置约束文本区域*/
setConstraints(滚动窗格,新的GridBagConstraints(0,1,2,1,0.0,0.0,GridBagConstraints.CENTER,GridBagConstraints.NONE,新的插入(5,5,5,5),0,0));
添加(滚动窗格);
frame.setLayout(新的FlowLayout());
框架。添加(窗格);
frame.pack();
frame.setVisible(true);
}
专用void视图列表(集合列表){
text_area.setText(“”;//Evita che venga ripetuto tutto il contenuto
对于(固定imb:列表){
text_area.append(imb.toString()+“\n”);
}
}
专用存储空间(){
字符串文件_name=JOptionPane.showInputDialog(“Inserisci il nome del file”);
公司商店(文件名);
}
@凌驾
已执行的公共无效操作(操作事件e){
字符串s=e.getActionCommand();
如果(s.equals(“查看列表”)){
视图列表(company.getImmobili());
}
如果(s.equals(“保存列表”)){
store();
}
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){@Override
public void run(){new AziendaGUI();}});
}
}
现在这个应用程序应该作为一个服务器使用,所以我必须用这里解释的所有方法实现
ServerSocket
构造函数


我的问题是:我应该在哪里实现服务器。在同一个类AziendaGUI ora中,我必须创建另一个类,并在AziendaGUI的main中调用它?

在大多数情况下,服务器和客户端是完全不同的进程,不在一个进程中运行。。。它们通常甚至在不同的机器上运行。因此,这种分离也应该在应用程序设计中可见。至少需要两个类,它们有自己的main()-方法,以便启动服务器进程和客户机进程

public Class Server {
    public static void main(...) {
        //Start a Thread that opens ServerSocket and listen for requests.
    }
} 


public Class Client {
    public static void main(...) {
       //Start your GUI and conect to the Server
    }
}
有一条基本的设计准则叫做“关注点分离”。这意味着,把属于一个东西的所有东西放在一个代码单元中,不要在同一个代码单元中混合具有不同性质或不同行为的东西。 您的客户机和服务器具有不同的性质和行为,因此它们需要在不同的类中。 这种设计使得最终更容易理解代码


尝试在抽象类别中思考,并从这些类别中创建类。

有一个主类、一个服务器类、一个客户端类和一个GUI类。然后,为服务器类和客户端类提供对GUI类的引用,以便它们可以在必要时更新GUI

下面是服务器外观的一些示例代码

public class AziendaGUI {
    // GUI objects
    private JFrame someWindow;

    public AziendaGUI() {
         // create and display the GUI
    }

    // export public methods for various GUI updates you want your
    // server class to perform

    public someGUIupdate(String s) {
        // update the GUI
        // for example, add some text to a textbox

        // keep in-mind that this code is being run on the
        // server thread and NOT the event dispatch thread
        // so you need to consider concurrency issues

        // you will need to use either SwingUtilities.invokeLater()
        // or synchronized()
    }
}

public class Server {
    private AziendaGUI gui;

    public Server(AziendaGUI gui) {
        this.gui = gui;
    }

    public start() {
        // start server threads

        // when you want to update the GUI
        gui.someGUIupdate("hello world");
        // these calls will probably be in other methods in your server class
        // that do the actual IO handling
    }
}

public class Main {

    Main() {
            // create and display GUI
            AziendaGUI gui = new AziendaGUI();

            // create and start server
            Server s = new Server(gui);
            s.start();
    }

    public static void main(String args[]) {
        Main m = new Main();
    }
}
大多数人可能会将这些类放在单独的文件中


我想再次指出,GUI类由多个线程访问,因此您必须使用某种形式的并发控制。

我总是将客户机类和服务器类分别放在两个单独的包中,或者更好的项目中。当然,如果它是一个微不足道的客户机/服务器项目,那么所有项目都可以是单个项目。但肯定是分开包装的。假设您的项目名为“myproj”,我会将客户机类放在
myproj.client
中,将服务器类放在
myproj.server
中。我强烈建议不要把所有的东西都放在一个类中。但是我不明白从哪里运行服务器类。哪里应该是“主方法”?如果你想从一个Java类中做任何事情,你必须为服务器生成一个线程,为客户端生成一个或多个线程。您可能希望在构造函数中有一个标志,以便该类知道在哪里充当服务器或客户端。