我刚开始使用 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;
}
}
非常感谢您到目前为止:) 现在的问题:
我正在尝试将 JProgressBar 组件实现到我的视图中,我已经创建了它的一个实例,但我对实现它的正确方法有点困惑,因为随着元素被添加到 JList 组件中,消耗的部分超出了 JProgressBar 的最大总量将会被更新。
在项目开始时,我被告知要在我的视图中实现 Observable 类,在我的模型中实现 Observer。但是,我被告知要提供一些我当时没有的代码以供参考。好吧,现在我有一些代码,但是我看不出这个 Observer / Observable 实现如何在我的情况下帮助我,或者特别是我的 JProgressBar 问题。我能得到一些关于如何在这段代码中实现 O/O 来帮助我的建议吗?
由于我无法将 BorderFactory.createEmptyBorder 应用于 JLabel 以在我的 JPanel 上的标签之间设置间距,因此我使用“right.add(new JLabel(""), "wrap, span")" 在如何替换它之间创建垂直间隙。是否有预定义的方法可以设置 JPanel 元素之间的间隙,或者我是否需要参考布局管理器。
欢迎任何关于修复、更改或替换的提示我知道我在这里放了很多数据,但我正在努力正确地学习这一点,我没有其他地方可以参考。