简体   繁体   中英

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.

  1. I created the final look of my 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.
  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.

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. I also reference each GLOBAL variable whit a method setters/getters instead of directly referencing them. As you can see the list of functions is piling up in initUI() and i am not even half way there.

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.

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. 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/

  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. 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. Makes your code a little readable. Otherwise use Actions and pass them around.

  3. Do all long running stuff like accessing a DB or reading/writing to a file on another thread. Otherwise your GUI will freeze. 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. After that its upto you to separate your classes so that the M, V and C are all separate.

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. Swing is build on top of this and it "forces" developer to design with this approach in mind.

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.

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.

Once you refactor your code into this pattern you will see how the code is more clean, maintable and easily extendable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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