I just started doing Java Swing applications using MVC pattern and so far i found it has simplified my work a lot and solved quite a few problems. Now i have a few questions that bug me or dont now how to resolve:
Here is my UI VIEW:
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);
}
}
Here is my UI CONTROLLER
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);
}
}
}
}
Here is my UI MODEL:
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;
}
}
Thanks a lot if you came so far : ) Now for the questions:
I am trying to implement JProgressBar component to my view i have created an instance of it but i am a bit confused on what is the proper way to implement it because as elements are added to JList components the consumed part out of total maximum amount of JProgressBar will be updated.
At the start of the project i have been told to implement Observable class to my view and Observer to my model. However i was told to provide some code that i didnt have at that time for a reference. Well now i have some code however i do not see how this Observer / Observable implementation could help me in my case or whit my JProgressBar problem in particular. Can i get some suggestions on how implementing O/O can help me out in this code.
Since i cannot apply BorderFactory.createEmptyBorder to JLabel to make spacing between labels on my JPanel i use "right.add(new JLabel(""), "wrap, span")" to create a vertical gap between how can i substitute this. Is there a pre-defined method that can set the gap between the JPanel elements or do i need to refer to the Layout Manager.
Any tips on what to fix, change or replace are welcomed i know i putted a lot of data here but i am trying to learn this properly and i dont have another place to refer to.