简体   繁体   English

Java如何:正确的GUI编码?

[英]Java How to: proper GUI coding?

This one is a long one, bellow is my "primary" class that holds the majority of my UI logic and all of its listeners etc. Anyhow you can see i stuck a lot of code in to one class and the whole thing just seems unreadable however it does work. 这是一个很长的,下面是我的“主要”类,它拥有我的大部分UI逻辑和所有的听众等。无论如何你可以看到我把很多代码插入到一个类中,整个事情似乎是不可读的但它确实有效。

  1. I created the final look of my GUI whit Netbeans GUI Editor 我创建了GUI whit Netbeans GUI Editor的最终外观
  2. The source code generated by Nebeans gives you private variables that allow you to interact whit all components you added to the form. Nebeans生成的源代码为您提供了私有变量,允许您与添加到表单中的所有组件进行交互。
  3. I opened that Java class in Notepad and i removed all comments that prevent me from editing the generated code in Netbeans now i can edit that entire class to my liking. 我在记事本中打开了Java类,我删除了所有阻止我编辑Netbeans中生成的代码的注释,现在我可以根据自己的喜好编辑整个类。

I have a separate GUI class in a separate package i call the class in my initUI() function then from here i reference all the components and write methods that get these components as arguments and add specific Listeners to those components. 我在一个单独的包中有一个单独的GUI类,我在我的initUI()函数中调用该类,然后从这里引用所有组件并编写将这些组件作为参数的方法,并为这些组件添加特定的监听器。 I also reference each GLOBAL variable whit a method setters/getters instead of directly referencing them. 我还引用方法setter / getters的每个GLOBAL变量而不是直接引用它们。 As you can see the list of functions is piling up in initUI() and i am not even half way there. 正如你所看到的那样,函数列表在initUI()中堆积起来,我甚至都不在那里。

I am guessing this is not even near professional approach, could you please provide me whit newbie tip, examples and suggestions how to improve all this code because even tho all this is working as it should it is very very ugly to look at and there are no books or tutorials that explain how approach coding a larger application. 我猜这甚至不是专业的方法,你能不能给我提供新手提示,例子和建议如何改进所有这些代码,因为即使这一切都有效,因为它应该是非常非常丑陋的看,有没有书籍教程解释如何编写更大的应用程序的方法。

Also even tho i am mid way done whit this GUI i like to experiment and i have been told that JavaFX is much better for doing Java GUI and that code you get is much more pleasing that what you would get as in Java Swing but on the other hand there is a lot of down vote for JavaFX regarding that its not really fully ready for use. 即使我在这个GUI中途完成这个GUI我喜欢尝试,并且我被告知JavaFX对于使用Java GUI更好,而且你获得的代码更令人愉快,就像你在Java Swing中得到的那样但在另一方面,JavaFX有很多关于其尚未完全准备好使用的投票。

Anyways here is my code: 无论如何这里是我的代码:

package ept.controller;

import ept.view.EPTMain;
import ept.model.EPTEvent_Model;
import ept.model.EPTLocal_Model;
import ept.model.EPTModule_Model;
import java.awt.Font;
import java.awt.MouseInfo;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.DefaultListModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JProgressBar;


public class EPTIndex_Controler {

    public EPTIndex_Controler() {
        initUI();
    }

    //Globals
    protected String selectedTower = null;
    protected Integer selectedModules = 0;

    public void setSelectedTower(String tower){
        this.selectedTower = tower;
    }

    public String getSelectedTower(){
        return this.selectedTower;
    }

    public void setSelectedModules(Integer i){
        this.selectedModules += i;
    }

    public void decrementSelectedModule(Integer i){
        this.selectedModules -= 1;
    }

    public Integer getSelectedModules(){
        return this.selectedModules;
    }

    private void initUI(){
        EPTMain runnable = new EPTMain();

        JLabel towerName = runnable.tower_name;
        JComboBox towerSelect = runnable.tower_selection;

        JLabel shield_ = runnable.shield_amount;
        JLabel armor_  = runnable.armor_amount;
        JLabel em_     = runnable.em_amount;
        JLabel th_     = runnable.th_amount;
        JLabel kn_     = runnable.kn_amount;
        JLabel ex_     = runnable.ex_amount;

        JProgressBar cpu_bar = runnable.cpu_bar;
        JProgressBar cap_bar = runnable.capacitor_bar;

        JList mod_browse = runnable.module_browser;
        JList mod_select = runnable.selected_modules;
        Font decode = new Font("monospaced", Font.PLAIN, 12);
        mod_select.setFont(decode);
        //mod_browse.setFont(decode);

        setTowerName(towerName, towerSelect, shield_, armor_, em_, th_, kn_, ex_, cap_bar, cpu_bar);
        removeTower(towerName, shield_, armor_, em_, th_, kn_, ex_, cap_bar, cpu_bar);

        addModule(mod_browse, mod_select, shield_, armor_, em_, th_, kn_, ex_, cap_bar, cpu_bar);
        removeModule(mod_select, shield_, armor_, em_, th_, kn_, ex_, cap_bar, cpu_bar);
        runnable.setExtendedState(EPTMain.MAXIMIZED_BOTH);
        runnable.setVisible(true);
    }



    protected DefaultListModel struct = new DefaultListModel();

    private void removeModule(final JList select, final JLabel shield_, final JLabel armor_, final JLabel em_, final JLabel th_,
            final JLabel kn_, final JLabel ex_, final JProgressBar cap_bar, final JProgressBar cpu_bar){
        select.addMouseListener(new MouseListener(){
            @Override
            public void mouseClicked(MouseEvent e) {
                String removable = select.getSelectedValue().toString();
                if(e.getClickCount() == 2 && removable.equals("No modules have been selected") == false){
                    String cap = select.getSelectedValue().toString().substring(61, 70).trim();
                    String cpu = select.getSelectedValue().toString().substring(75).trim();
                    Integer D_CAP = Integer.valueOf(cap).intValue();
                    Integer D_CPU = Integer.valueOf(cpu).intValue();
                    decConsumedCap(D_CAP);
                    decConsumedCpu(D_CPU);
                    struct.removeElement(select.getSelectedValue());
                    incrementVariables(shield_, armor_, em_, th_, kn_, ex_, cap_bar, cpu_bar);
                    select.setModel(struct);
                    decrementSelectedModule(1);
                }
            }
            @Override
            public void mousePressed(MouseEvent e) {}
            @Override
            public void mouseReleased(MouseEvent e) {}
            @Override
            public void mouseEntered(MouseEvent e) {}
            @Override
            public void mouseExited(MouseEvent e) {}
        });
    }


    private void addModule(final JList browse, final JList select, final JLabel shield_, final JLabel armor_, final JLabel em_, final JLabel th_,
            final JLabel kn_, final JLabel ex_, final JProgressBar cap_bar, final JProgressBar cpu_bar){
        browse.addMouseListener(new MouseListener(){
            @Override
            public void mouseClicked(MouseEvent e) {
                String addable = browse.getSelectedValue().toString();
                if(e.getClickCount() == 2 && getSelectedTower() != null && addable.charAt(0) == ' '){
                            String data[] = new EPTModule_Model().moduleData(addable.trim());
                            String module = data[0];
                            Integer capacitor = Integer.valueOf(data[1]).intValue(); setConsumedCap(capacitor);
                            Integer cpu = Integer.valueOf(data[2]).intValue(); setConsumedCpu(cpu);
                            String module_cap = data[1];
                            String module_cpu = data[2];
                            if(getConsumedCap()+capacitor > getCap() || getConsumedCpu()+cpu > getCpu()){
                                new EPTEvent_Model().eventNoCapOrCpu();                      
                            } else {
                                struct.addElement(String.format("> %-47s Capacitor: %-8s CPU: %s", module, module_cap, module_cpu));
                                select.setModel(struct);
                                setSelectedModules(1);
                                incrementVariables(shield_, armor_, em_, th_, kn_, ex_, cap_bar, cpu_bar);
                            }

                } else if (e.getClickCount() == 2 && getSelectedTower() == null){
                    new EPTEvent_Model().eventNoTowerSelected();
                } 

            }
            @Override
            public void mousePressed(MouseEvent e) {}
            @Override
            public void mouseReleased(MouseEvent e) {}
            @Override
            public void mouseEntered(MouseEvent e) {}
            @Override
            public void mouseExited(MouseEvent e) {}
        });
    }

    private void removeTower(final JLabel type, final JLabel shield_, final JLabel armor_, final JLabel em_, final JLabel th_,
            final JLabel kn_, final JLabel ex_, final JProgressBar cap_bar, final JProgressBar cpu_bar){
        type.addMouseListener(new MouseListener(){
            @Override
            public void mouseClicked(MouseEvent e) {
                if(getSelectedModules() == 0){
                    type.setText("No Control Tower Selected");
                    setSelectedTower(null);
                    resetVariables(shield_, armor_, em_, th_, kn_, ex_, cap_bar, cpu_bar);
                } else {
                    new EPTEvent_Model().eventModuleSelected();
                }
            }
            @Override
            public void mousePressed(MouseEvent e) {}
            @Override
            public void mouseReleased(MouseEvent e) {}
            @Override
            public void mouseEntered(MouseEvent e) {}
            @Override
            public void mouseExited(MouseEvent e) {}    
        });
    }

    private void setTowerName(final JLabel type, final JComboBox type2, final JLabel shield_, final JLabel armor_, final JLabel em_, final JLabel th_,
            final JLabel kn_, final JLabel ex_, final JProgressBar cap_bar, final JProgressBar cpu_bar){
        type2.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e) {
                if(getSelectedTower() != null){
                    new EPTEvent_Model().eventTowerSelected();
                } else {
                    setSelectedTower(type2.getSelectedItem().toString());
                    new EPTDispatch_Controler(type, type2.getSelectedItem().toString());
                    updateVariables(shield_, armor_, em_, th_, kn_, ex_, cap_bar, cpu_bar);

                }
            }
        });
    }

    //Referenced Globals
    protected int cap = 0;
    protected int consumed_cap = 0;
    protected int cpu = 0;
    protected int consumed_cpu = 0;

    public void setCap(int cap){
        this.cap = cap;
    }

    public int getCap(){
        return this.cap;
    }

    public void setCpu(int cpu){
        this.cpu = cpu;
    }

    public int getCpu(){
        return this.cpu;
    }

    public void resetConsumed(){
        this.consumed_cap = 0;
        this.consumed_cpu = 0;
    }

    public void setConsumedCap(int consumed_cap){
        this.consumed_cap += consumed_cap;
    }

    public void decConsumedCap(int consumed_cap){
        this.consumed_cap -= consumed_cap;
    }

    public int getConsumedCap(){
        return this.consumed_cap;
    }

    public void setConsumedCpu(int consumed_cpu){
        this.consumed_cpu += consumed_cpu;
    }

    public void decConsumedCpu(int consumed_cpu){
        this.consumed_cpu -= consumed_cpu;
    }

    public int getConsumedCpu(){
        return this.consumed_cpu;
    }

    //Referenced Globals
    protected int shield = 0;
    protected int armor = 0;
    protected double em = 00.00;
    protected double th = 00.00;
    protected double kn = 00.00;
    protected double ex = 00.00;

    public void setEm(double em){
        this.em = em;
    }

    public double getEm(){
        return this.em;
    }

    public void setTh(double th){
        this.th = th;
    }

    public double getTh(){
        return this.th;
    }

    public void setKn(double kn){
        this.kn = kn;
    }

    public double getKn(){
        return this.kn;
    }

    public void setEx(double ex){
        this.ex = ex;
    }

    public double getEx(){
        return this.ex;
    }

    public void setShield(int shield){
        this.shield = shield;
    }

    public int getShield(){
        return this.shield;
    }

    public void setArmor(int armor){
        this.armor = armor;
    }

    public int getArmor(){
        return this.armor;
    }

    private void setCL(JProgressBar t, int i){
        t.setValue(i);
    }

    private void incrementVariables(final JLabel shield_, final JLabel armor_, final JLabel em_, final JLabel th_,
            final JLabel kn_, final JLabel ex_, final JProgressBar cap_bar, final JProgressBar cpu_bar){

        cap_bar.setMaximum(getCap());
        cap_bar.setValue(getConsumedCap());
        cap_bar.setString(getConsumedCap() + " / " + getCap());
        cap_bar.setStringPainted(true);



        cpu_bar.setMaximum(getCpu());
        cpu_bar.setString(getConsumedCpu() + " / " + getCpu());
        cpu_bar.setStringPainted(true);
        cap_bar.setValue(getConsumedCpu());

        String shieldA = String.valueOf(getShield()).toString();
        shield_.setText(shieldA);

        String armorA = String.valueOf(getArmor()).toString();
        armor_.setText(armorA);

        double e = getEm();
        String emT = String.valueOf(e);
        em_.setText(emT);

        double t = getTh();
        String thT = String.valueOf(t);
        th_.setText(thT);

        double k = getKn();
        String knT = String.valueOf(k);
        kn_.setText(knT);

        double x = getEx();
        String exT = String.valueOf(x);
        ex_.setText(exT);

    }

    private void updateVariables(final JLabel shield_, final JLabel armor_, final JLabel em_, final JLabel th_,
            final JLabel kn_, final JLabel ex_, final JProgressBar cap_bar, final JProgressBar cpu_bar){

        String data[] = new EPTLocal_Model().serializeData(getSelectedTower());

        Integer capA = Integer.valueOf(data[1]).intValue();
        setCap(capA);
        cap_bar.setMaximum(getCap());
        cap_bar.setString(getConsumedCap() + " / " + getCap());
        cap_bar.setValue(getConsumedCap());
        cap_bar.setStringPainted(true);

        Integer cpuA = Integer.valueOf(data[2]).intValue();
        setCpu(cpuA);
        cpu_bar.setMaximum(getCpu());
        cpu_bar.setString(getConsumedCpu() + " / " + getCpu());
        cpu_bar.setValue(getConsumedCpu());
        cpu_bar.setStringPainted(true);

        Integer shieldAmount = Integer.valueOf(data[3]).intValue();
        setShield(shieldAmount);
        shield_.setText(data[3]);

        Integer armorAmount = Integer.valueOf(data[4]).intValue();
        setArmor(armorAmount);
        armor_.setText(data[4]);

        Double emT = Double.valueOf(data[5]).doubleValue();
        setEm(emT);
        em_.setText(data[5]);

        Double thT = Double.valueOf(data[6]).doubleValue();
        setTh(thT);
        th_.setText(data[6]);

        Double knT = Double.valueOf(data[7]).doubleValue();
        setKn(knT);
        kn_.setText(data[7]);

        Double exT = Double.valueOf(data[8]).doubleValue();
        setEx(exT);
        ex_.setText(data[8]);

    }

    private void resetVariables(final JLabel shield_, final JLabel armor_, final JLabel em_, final JLabel th_,
            final JLabel kn_, final JLabel ex_, final JProgressBar cap_bar, final JProgressBar cpu_bar){

        resetConsumed();

        setCap(0);
        cap_bar.setMaximum(getCap());
        cap_bar.setString(getConsumedCap() + " / " + getCap());
        cap_bar.setStringPainted(true);

        setCpu(0);
        cpu_bar.setMaximum(getCpu());
        cpu_bar.setString(getConsumedCpu() + " / " + getCpu());
        cpu_bar.setStringPainted(true);

        setShield(0);
        shield_.setText("0");

        setArmor(0);
        armor_.setText("0");

        setEm(00.00);
        em_.setText("00.00");

        setTh(00.00);
        th_.setText("00.00");

        setKn(00.00);
        kn_.setText("00.00");

        setEx(00.00);
        ex_.setText("00.00");

    }

}
  1. First things first.. Do not ever ever use the Netbeans GUI to drag and drop your components. 首先要做的事情是......永远不要使用Netbeans GUI来拖放组件。 Its easy but will lead into a lot of issues later. 它容易但后来会引发很多问题。 If you resize your window all your components will not resize correctly and if you want to add components dynamically later on you will suffer. 如果您调整窗口大小,则所有组件都不会正确调整大小,如果您想稍后动态添加组件,则会受到影响。 Instead use a good layout manager. 而是使用一个好的布局管理器。 The ones that come with the jdk are difficult to use, try this one: http://www.jgoodies.com/freeware/forms/ 与jdk一起使用的那些很难使用,试试这个: http//www.jgoodies.com/freeware/forms/

  2. Next, if you are making a frame that is huge, its best you split it up into panels. 接下来,如果你正在制作一个巨大的框架,最好将它拆分成面板。 Each panel in a separate class. 每个小组在一个单独的类中。 This will allow you to manage small sets of your GUI easily. 这将允许您轻松管理小型GUI。 Don't litter your code with anonymous inner classes. 不要使用匿名内部类乱丢代码。 Instead let the class implement a listener and use an if block in the actionPerformed() method to deal with your actions. 而是让类实现一个侦听器并使用actionPerformed()方法中的if块来处理您的操作。 Makes your code a little readable. 使您的代码具有一点可读性。 Otherwise use Actions and pass them around. 否则使用Actions并传递它们。

  3. Do all long running stuff like accessing a DB or reading/writing to a file on another thread. 做所有长时间运行的东西,如访问数据库或读取/写入另一个线程上的文件。 Otherwise your GUI will freeze. 否则您的GUI将冻结。 Use a Swing Worker - http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html This will force you to think in the MVC way to a certain extent. 使用Swing Worker - http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html这将迫使您在某种程度上以MVC方式思考。 After that its upto you to separate your classes so that the M, V and C are all separate. 之后,你可以将你的课程分开,这样M,V和C都是分开的。

Separation of concerns is fundamental when building an application. 在构建应用程序时,关注点分离是至关重要的。

A common design pattern to achieve this is the Model-View-Controller which is the norm design approach for GUI applications. 实现这一目标的常见设计模式是模型 - 视图 - 控制器 ,它是GUI应用程序的标准设计方法。 Swing is build on top of this and it "forces" developer to design with this approach in mind. Swing构建于此之上,它“迫使”开发人员在设计时考虑到这种方法。

So if you want tips on how to improve your code you should study the MVC design pattern (thousands of examples in Google) and refactor your code to use it. 因此,如果您需要有关如何改进代码的提示,您应该研究MVC设计模式(Google中的数千个示例)并重构您的代码以使用它。

In a nutshell, you will have 3 logically separate modules, the Model which will encapsulate your data/state, your View which will encapsulate your UI and the Controller which will be the main driver of your application. 简而言之,您将拥有3个逻辑上独立的模块, Model将封装您的数据/状态,您的View将封装您的UI和Controller ,它将成为您应用程序的主要驱动程序。

Once you refactor your code into this pattern you will see how the code is more clean, maintable and easily extendable. 一旦您将代码重构为此模式,您将看到代码如何更干净,可维护且易于扩展。

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

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