0

我刚开始使用 MVC 模式做 Java Swing 应用程序,到目前为止,我发现它大大简化了我的工作并解决了很多问题。现在我有几个问题困扰我或现在不知道如何解决:

这是我的用户界面视图:

package env.view;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import net.miginfocom.swing.MigLayout;

import env.helper.*;

public class UI_View extends JFrame
{

    private JPanel left         = new JPanel(new MigLayout());
    private JPanel center       = new JPanel(new MigLayout());
    private JPanel right        = new JPanel(new MigLayout());

    //LEFT PANEL
    private Tower_Helper towers = new Tower_Helper();
    private Tree_Helper modules = new Tree_Helper();
    private JScrollPane mod_bar = new JScrollPane(modules);

    //CENTER PANEL
    private Browse_Helper browser = new Browse_Helper();
    private JScrollPane   browser_bar = new JScrollPane(browser);

    //RIGHT PANEL - LABELS
    private JLabel tower_name = new JLabel("No tower selected");
    private JLabel shield     = new JLabel("0");
    private JLabel armor      = new JLabel("0");
    private JLabel em         = new JLabel("0.0");
    private JLabel th         = new JLabel("0.0");
    private JLabel kn         = new JLabel("0.0");
    private JLabel ex         = new JLabel("0.0");

    //RIGHT PANEL - CONTROLLS
    private JProgressBar cap_bar    = new JProgressBar();
    private JProgressBar cpu_bar    = new JProgressBar();
    private int total   = 0;
    private int consumed    = 0;

    public UI_View()
    {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setMinimumSize(new Dimension(800, 600));
        this.setExtendedState(JFrame.MAXIMIZED_BOTH);
        this.setTitle("Environment Prototype");
        this.setLayout(new MigLayout());

        left.setMinimumSize(new Dimension(252, 540));
        left.setMaximumSize(new Dimension(252, 37500));
        left.add(towers, "growx, pushx, wrap");
        left.add(mod_bar,"grow, push");

        center.setMinimumSize(new Dimension(298, 540));
        center.add(browser_bar, "grow, push");

        right.setMinimumSize(new Dimension(250, 540));
        right.setMaximumSize(new Dimension(250, 37500));
        tower_name.setToolTipText("Double click to remove tower if modules have been removed.");
        right.add(tower_name, "span, wrap");

        right.add(new JLabel(""), "wrap, span");
        right.add(new JLabel(""), "wrap, span");

        right.add(new JLabel("Capacitor"), "wrap, span");
        cap_bar.setMinimumSize(new Dimension(215, 40));
        right.add(cap_bar, "wrap, span");

        right.add(new JLabel("CPU"), "wrap, span");
        cpu_bar.setMinimumSize(new Dimension(215, 40));
        right.add(cpu_bar, "wrap, span");

        right.add(new JLabel("Shield:  "));
        right.add(shield, "wrap");

        right.add(new JLabel("Armor:  "));
        right.add(armor, "wrap");

        right.add(new JLabel(""), "wrap, span");
        right.add(new JLabel(""), "wrap, span");

        right.add(new JLabel("EM:  "));
        right.add(em, "wrap");

        right.add(new JLabel("TH:  "));
        right.add(th, "wrap");

        right.add(new JLabel("KN:  "));
        right.add(kn, "wrap");

        right.add(new JLabel("EX:  "));
        right.add(ex, "wrap");

        this.add(left, "dock west");
        this.add(center, "dock center");
        this.add(right, "dock east");
    }

    //getter - JLabel tower name
    public JLabel getTowerNameLabel()
    {
        return this.tower_name;
    }

    //listener - JLabel tower name
    public void towerLabelListner(MouseListener event)
    {
        this.tower_name.addMouseListener(event);
    }

    //getter - JList browser
    public JList getBrowserList()
    {
        return this.browser;
    }

    //listener - JList browser
    public void browserListListener(MouseListener event)
    {
        this.browser.addMouseListener(event);
    }

    //getter - JTree modules
    public JTree getModuleTree()
    {
        return this.modules;
    }

    //listener - JTree modules
    public void modulesTreeListener(MouseListener event)
    {
        this.modules.addMouseListener(event);
    }

    //getter - JComboBox towers
    public JComboBox getTowers()
    {
        return this.towers;
    }

    //lisetner - JComboBox towers
    public void towersBoxListener(ActionListener evnet)
    {
        this.towers.addActionListener(evnet);
    }

}

这是我的 UI 控制器

package env.controller;

import env.model.UI_Model;
import env.view.UI_View;
import java.awt.event.*;

import javax.swing.*;

public class UI_Controller
{    
    private UI_Model ui_model;
    private UI_View  ui_view;

    public UI_Controller(UI_Model model, UI_View view)
    {
        ui_model = model;
        ui_view  = view;

        ui_view.towersBoxListener(new towerSelectionListener());
        ui_view.modulesTreeListener(new modulesSelectionListener());
        ui_view.browserListListener(new browserSelectionListener());
        ui_view.towerLabelListner(new towerRemovalListener());
    }

    class towerRemovalListener implements MouseListener
    {
        @Override public void mouseClicked(MouseEvent e) 
        {
            if(e.getClickCount() == 2 && ui_model.getModulesCounter() == 0)
            {
                ui_view.getTowerNameLabel().setText(ui_model.reset_label());
                ui_model.retsetSelectionInfo();
            } else if (ui_model.getModulesCounter() != 0){
                JFrame dialog = new JFrame();
                JOptionPane.showMessageDialog(dialog, "Cannot remove tower whit modules still selected.",
                "Cannot remove tower !", JOptionPane.WARNING_MESSAGE);
            }
        }
        @Override public void mousePressed(MouseEvent e) {}
        @Override public void mouseReleased(MouseEvent e) {}
        @Override public void mouseEntered(MouseEvent e) {}
        @Override public void mouseExited(MouseEvent e) {}
    }

    class browserSelectionListener implements MouseListener
    {
        @Override public void mouseClicked(MouseEvent e) 
        {
            if(e.getClickCount() == 2)
            {
                String selection = ui_view.getBrowserList().getSelectedValue().toString();
                ui_model.removeFromList(selection);
                ui_view.getBrowserList().setModel(ui_model.getSelectedModules());
            }
        }
        @Override public void mousePressed(MouseEvent e) {}
        @Override public void mouseReleased(MouseEvent e) {}
        @Override public void mouseEntered(MouseEvent e) {}
        @Override public void mouseExited(MouseEvent e) {}
    }

    class modulesSelectionListener implements MouseListener
    {
        @Override public void mouseClicked(MouseEvent e) 
        {
            if(e.getClickCount() == 2 && ui_model.getSelectionInfo() != null)
            {
                String output = ui_view.getModuleTree().getLastSelectedPathComponent().toString();
                ui_model.addToList(output);
                ui_view.getBrowserList().setModel(ui_model.getSelectedModules());
            }
        }
        @Override public void mousePressed(MouseEvent e) {}
        @Override public void mouseReleased(MouseEvent e) {}
        @Override public void mouseEntered(MouseEvent e) {}
        @Override public void mouseExited(MouseEvent e) {}
    }

    class towerSelectionListener implements ActionListener
    {
        @Override public void actionPerformed(ActionEvent e) 
        {
            String output   = ui_view.getTowers().getSelectedItem().toString();
            if(ui_model.getSelectionInfo() == null)
            {
                if(ui_model.validateTower(output))
                {
                    ui_model.setSelectionInfo(output);
                    ui_view.getTowerNameLabel().setText(ui_model.getSelectionInfo());
                }
            } else {
                JFrame dialog = new JFrame();
                JOptionPane.showMessageDialog(dialog, "There is a already selected tower: "
                + ui_model.getSelectionInfo(), "Cannot select a new tower !",
                JOptionPane.WARNING_MESSAGE);
            }
        }
    }
}

这是我的用户界面模型:

package env.model;

import javax.swing.*;

public class UI_Model 
{
    private String is_tower_selected = null;
    private DefaultListModel selected_modules = new DefaultListModel();
    private int module_counter = 0;
    private final String reset_tower_name = "No tower selected";

    private int shield = 0;
    private int armor  = 0;
    private double em  = 0.0;
    private double th  = 0.0;
    private double kn  = 0.0;
    private double ex  = 0.0;

    public String reset_label()
    {
        return this.reset_tower_name;
    }

    public int getModulesCounter()
    {
        return this.module_counter;
    }

    public UI_Model()
    {

    }

    public DefaultListModel getSelectedModules()
    {
        return this.selected_modules;
    }

    public void removeFromList(String input)
    {
        this.selected_modules.removeElement(input);
        this.module_counter -= 1;
    }

    public void addToList(String output)
    {
        if(validateInput(output) == true)
        {
            this.selected_modules.addElement("   " + output);
            this.module_counter += 1;
        }
    }

    public String getSelectionInfo()
    {
        return this.is_tower_selected;
    }

    public void setSelectionInfo(String tower)
    {
        this.is_tower_selected = tower;
    }

    public void retsetSelectionInfo()
    {
        this.is_tower_selected = null;
    }

    public void outputSelection(String output)
    {
        System.out.println(output);
    }    

    public boolean validateTower(String input)
    {
        if(input.equals("Select a Control Tower "))
        {
            return false;
        }
        return true;
    }

    public boolean validateInput(String input)
    {
        if(input.contains("<html>") || input.equals("Starbase Modules"))
        {
            return false;
        }
        return true;
    }
}

非常感谢您到目前为止:) 现在的问题:

  1. 我正在尝试将 JProgressBar 组件实现到我的视图中,我已经创建了它的一个实例,但我对实现它的正确方法有点困惑,因为随着元素被添加到 JList 组件中,消耗的部分超出了 JProgressBar 的最大总量将会被更新。

  2. 在项目开始时,我被告知要在我的视图中实现 Observable 类,在我的模型中实现 Observer。但是,我被告知要提供一些我当时没有的代码以供参考。好吧,现在我有一些代码,但是我看不出这个 Observer / Observable 实现如何在我的情况下帮助我,或者特别是我的 JProgressBar 问题。我能得到一些关于如何在这段代码中实现 O/O 来帮助我的建议吗?

  3. 由于我无法将 BorderFactory.createEmptyBorder 应用于 JLabel 以在我的 JPanel 上的标签之间设置间距,因此我使用“right.add(new JLabel(""), "wrap, span")" 在如何替换它之间创建垂直间隙。是否有预定义的方法可以设置 JPanel 元素之间的间隙,或者我是否需要参考布局管理器。

欢迎任何关于修复、更改或替换的提示我知道我在这里放了很多数据,但我正在努力正确地学习这一点,我没有其他地方可以参考。

4

2 回答 2

4

你说

在项目开始时,我被告知要在我的视图中实现 Observable 类,在我的模型中实现 Observer。

但这对我来说听起来很倒退。视图最类似于Observer,而模型类似于Observable.可能你弄错了?

另外,检查一下这个类MouseAdapter——继承它而不是MouseListener直接实现会删掉很多无用的代码!

于 2012-01-03T02:31:43.013 回答
3
  1. 我不确定你在这里得到什么,除非你链接它们,它不会更新?

  2. 如果您在 UI_Model 类上扩展 Observable,请将 addToList() 更改为调用 setChanges(),然后调用 notifyObservers()。


 public void addToList(String output)
    {
        if (validateInput(output) == true)
        {
            this.selected_modules.addElement("   " + output);
            this.module_counter += 1;
            setChanged();
            notifyObservers();
        }
    }

然后在您的视图对象上实现观察者,然后将视图作为观察者添加到控制器中的模型中:

public UI_Controller(UI_Model model, UI_View view)
{
    ui_model = model;
    ui_view  = view;

    ui_model.addObserver(ui_view);

    ui_view.towersBoxListener(new towerSelectionListener());
    ui_view.modulesTreeListener(new modulesSelectionListener());
    ui_view.browserListListener(new browserSelectionListener());
    ui_view.towerLabelListner(new towerRemovalListener());
}
  1. 查看规范和其他各种来源,似乎 JLabel.setBorder(BorderFactory.createEmptyBorder(...)) 应该可以工作。
于 2012-01-03T02:54:18.687 回答