Java Как: правильное кодирование GUI? - PullRequest
3 голосов
/ 27 декабря 2011

Это длинный, ниже мой «основной» класс, который содержит большую часть моей логики пользовательского интерфейса и всех его слушателей и т. Д. В любом случае вы можете видеть, что я вставил много кода в один класс и все в целом просто кажется нечитаемым, однако это работает.

  1. Я создал окончательный вид моего графического интерфейса для Netbeans GUI Editor
  2. Исходный код, сгенерированный Nebeans, дает вам частные переменные, которые позволяют вам взаимодействовать со всеми компонентами, которые вы добавили в форму.
  3. Я открыл этот класс Java в Блокноте и удалил все комментарии, которые мешают мне редактировать сгенерированный код в Netbeans, теперь я могу редактировать весь этот класс по своему вкусу.

У меня есть отдельный класс GUI в отдельном пакете, я вызываю этот класс в моей функции initUI () , затем отсюда я ссылаюсь на все компоненты и пишу методы, которые получают эти компоненты в качестве аргументов, и добавляют конкретных слушателей. к этим компонентам. Я также ссылаюсь на каждую переменную GLOBAL с помощью метода setters / getters вместо прямой ссылки на них. Как вы видите, список функций накапливается в initUI () , и я даже не на полпути.

Полагаю, это даже не профессиональный подход, не могли бы вы пожалуйста, дайте мне советы для новичков, примеры и предложения, как улучшить весь этот код, потому что даже если все это работает как если на это очень и очень некрасиво смотреть и нет книг или учебные пособия , которые объясняют, как подходить к кодированию больших приложений.

Кроме того, даже если я нахожусь в середине этого графического интерфейса, мне нравится экспериментировать и мне сказали, что JavaFX намного лучше для Java GUI и тот код, который вы получаете, гораздо приятнее того, что вы получите, как в Java Swing, но с другой стороны, есть много отрицательных голосов за JavaFX относительно того, что он не совсем готов к использованию.

В любом случае вот мой код:

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

    }

}

Ответы [ 2 ]

5 голосов
/ 27 декабря 2011
  1. Перво-наперво. Никогда не используйте графический интерфейс Netbeans для перетаскивания компонентов. Это легко, но позже приведет к множеству проблем. Если вы измените размер своего окна, все ваши компоненты не будут корректно изменены, и если вы захотите добавить компоненты динамически позже, вы пострадаете. Вместо этого используйте хороший менеджер макета. Те, которые идут с JDK, трудно использовать, попробуйте это: http://www.jgoodies.com/freeware/forms/

  2. Далее, если вы делаете огромную рамку, лучше всего разбить ее на панели. Каждая панель в отдельном классе. Это позволит вам легко управлять небольшими наборами графического интерфейса. Не засоряйте свой код анонимными внутренними классами. Вместо этого позвольте классу реализовать слушателя и использовать блок if в методе actionPerformed () для обработки ваших действий. Делает ваш код немного читабельным. В противном случае используйте действия и раздайте их.

  3. Выполняйте все длительные операции, такие как доступ к БД или чтение / запись в файл в другом потоке. В противном случае ваш графический интерфейс будет зависать. Используйте работника Swing - http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html Это заставит вас мыслить в манере MVC в определенной степени. После этого вы должны разделить свои классы так, чтобы M, V и C были отдельными.

4 голосов
/ 27 декабря 2011

Разделение интересов является фундаментальным при создании приложения.

Обычным шаблоном проектирования для достижения этой цели является Model-View-Controller , который является нормой подхода проектирования для приложений с графическим интерфейсом.Swing построен на этом, и он «заставляет» разработчика разрабатывать с учетом этого подхода.

Поэтому, если вы хотите получить советы о том, как улучшить ваш код, вам следует изучить шаблон проектирования MVC (тысячи примеров в Google) и реорганизовать код для его использования.

В двух словах, у вас будет 3 логически отдельных модуля: Model, который будет инкапсулировать ваши данные / состояние, ваш View, который будет инкапсулировать ваш пользовательский интерфейс, и Controller, который будет основным драйвером.вашего приложения.

Как только вы реорганизуете свой код в этот шаблон, вы увидите, как код становится более чистым, поддерживаемым и легко расширяемым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...