package vg.modules.search;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Map;
import java.util.Set;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import vg.core.IGraphView;
import vg.core.VisualGraph;
import vg.core.graph.GraphNode;
import vg.core.plugin.PluginParameter;
import vg.core.storableGraph.StorableSubGraph;
import vg.modules.search.components.FirstPanel;
import vg.modules.search.components.SecondPanel;
/**
* This class implements ISearchPanel interface.
* @author tzolotuhin
*/
public class SearchPanel extends JFrame implements FBSearchPanel {
private static final long serialVersionUID = 1L;
// init variable
private boolean init = false;
//-------------------------------------------------------------------------
private JPanel view;
private FirstPanel firstPanel;
private SecondPanel secondPanel;
private JButton searchButton, cancelButton, backButton;
private SearchPanelModel model;
private final PluginParameter param;
// Mutexes
private Object fbspMutex; // feedBackSearchPanel mutex
private Object spMutex; // searchPanel mutex
// Window settings
private final static String DEF_WINDOWS_SIZE_X = "SEARCH_PLUGIN_WindowSizeX";
private final static String DEF_WINDOWS_SIZE_Y = "SEARCH_PLUGIN_WindowSizeY";
private final static String DEF_WINDOWS_POS_X = "SEARCH_PLUGIN_WindowPosX";
private final static String DEF_WINDOWS_POS_Y = "SEARCH_PLUGIN_WindowPosY";
private Integer windowSizeX, windowSizeY;
private Integer windowPosX, windowPosY;
/**
* Constructor.
* @param title - title of frame.
* @param parameter - connection with model and user interface.
*/
public SearchPanel(final String title, final PluginParameter parameter) {
super(title);
this.param = parameter;
// Creating of mutexes
this.spMutex = new Object();
this.fbspMutex = new Object();
this.model = new SearchPanelModel(this);
}
/**
* This method adds new graph to model.
* @param id - id of graph in data base.
* @param name - name of graph.
*/
public void addGraph(int id, String name) {
synchronized (spMutex) {
this.model.addGraph(id, name);
if(init) {
this.firstPanel.addGraph(id, name);
}
}
}
/**
* This method changes current view.
* @param igv - current view.
*/
public void changeView(final IGraphView igv) {
synchronized (spMutex) {
this.model.changeView(igv);
}
}
/**
* This method opens search plugin.
*/
public void open() {
synchronized (spMutex) {
if(!init) {
init();
Map<Integer, String>map = this.model.getGraphs();
if(map != null) {
for(Integer buf : map.keySet()) {
this.firstPanel.addGraph(buf, map.get(buf));
}
}
}
this.model.setClose(false);
}
}
/**
* This method closes search plugin.
*/
public void close() {
synchronized (spMutex) {
this.model.setClose(true);
}
}
/**
* This method updates ui theme.
*/
public void updateUITheme() {
synchronized (spMutex) {
if(init) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
SwingUtilities.updateComponentTreeUI(SearchPanel.this);
SwingUtilities.updateComponentTreeUI(SearchPanel.this.backButton);
SwingUtilities.updateComponentTreeUI(SearchPanel.this.searchButton);
SwingUtilities.updateComponentTreeUI(SearchPanel.this.cancelButton);
}
});
this.firstPanel.updateUITheme();
this.secondPanel.updateUITheme();
}
}
}
public void reset() {
synchronized (spMutex) {
this.firstPanel.reset();
this.model.changeView(null);
}
}
///////////////////////////////////////////////////////////////////////////
// IMPLEMENTATION OF FBSEARCHPANEL
///////////////////////////////////////////////////////////////////////////
/**
* This method makes activity search button.
*/
public void setSearchEnable(final boolean state) {
synchronized (fbspMutex) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
SearchPanel.this.searchButton.setEnabled(state);
}
});
}
}
/**
* This method returns vertex additional attributes.
*/
public Set<String> getVertexAdditionalAttributes() {
synchronized (fbspMutex) {
return(this.secondPanel.getVertexAdditionalAttributes());
}
}
/**
* This method sets option mode.
*/
public void setOptionMode(final int option) {
synchronized (fbspMutex) {
this.secondPanel.setOptionMode(option);
}
}
/**
* This method sets current subgraph for first panel.
*/
public void setCurrentSubGraph(final StorableSubGraph ssg) {
synchronized (fbspMutex) {
if(init) {
this.firstPanel.setCurrentSubGraph(ssg);
}
}
}
/**
* This method opens search plugin from model.
*/
public void openFromModel() {
synchronized (fbspMutex) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
buildFirstPanel();
SearchPanel.this.setVisible(true);
}
});
}
}
/**
* This method closes search plugin from model.
*/
public void closeFromModel() {
synchronized (fbspMutex) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
SearchPanel.this.setVisible(false);
}
});
}
}
/**
* This method realizes action for search button.
*/
public void search() {
synchronized (fbspMutex) {
this.firstPanel.search();
Set<Integer>vertexIdList = this.firstPanel.getSelectedVertexIdList();
GraphNode rootNode = this.firstPanel.getRootNode();
Set<String> vertexAttributes = this.firstPanel.getVertexAttributes();
this.secondPanel.buildTree(rootNode, vertexIdList, vertexAttributes);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
buildSecondPanel();
SearchPanel.this.view.updateUI();
}
});
}
}
public synchronized void back() {
synchronized (fbspMutex) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
buildFirstPanel();
SearchPanel.this.view.updateUI();
}
});
}
}
///////////////////////////////////////////////////////////////////////////
// PRIVATE METHODS
///////////////////////////////////////////////////////////////////////////
private void buildFirstPanel() {
this.view.removeAll();
GridBagConstraints gbc = new GridBagConstraints(0,0, 2,1, 1,1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0,0);
this.view.add(this.firstPanel.getView(), gbc);
gbc = new GridBagConstraints(0,1, 1,1, 1,0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0,0);
this.view.add(this.cancelButton, gbc);
gbc = new GridBagConstraints(1,1, 1,1, 0,0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0,0);
this.view.add(this.searchButton, gbc);
gbc = null;
}
private void buildSecondPanel() {
this.view.removeAll();
GridBagConstraints gbc = new GridBagConstraints(0,0, 1,1, 1,1, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0,0);
this.view.add(this.secondPanel.getView(), gbc);
gbc = new GridBagConstraints(0,1, 1,1, 1,0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0,0);
this.view.add(this.backButton, gbc);
gbc = null;
}
private void init() {
this.init = true;
this.view = new JPanel(new GridBagLayout());
// Creating of window
this.loadWindowOptions();
this.setSize(this.windowSizeX, this.windowSizeY);
this.setLocation(this.windowPosX, this.windowPosY);
this.setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
this.setLayout(new GridLayout(1, 1));
this.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent e) {
super.componentResized(e);
Component c = (Component)e.getSource();
Integer sizeX = c.getSize().width;
Integer sizeY = c.getSize().height;
VisualGraph.config.setProperty(DEF_WINDOWS_SIZE_X, sizeX.toString());
VisualGraph.config.setProperty(DEF_WINDOWS_SIZE_Y, sizeY.toString());
}
public void componentMoved(ComponentEvent e) {
super.componentMoved(e);
Component c = (Component)e.getSource();
Integer posX = c.getLocation().x;
Integer posY = c.getLocation().y;
VisualGraph.config.setProperty(DEF_WINDOWS_POS_X, posX.toString());
VisualGraph.config.setProperty(DEF_WINDOWS_POS_Y, posY.toString());
}
});
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
super.windowClosed(e);
close();
}
});
this.cancelButton = new JButton("Cancel");
this.cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
close();
}
});
this.searchButton = new JButton("Search");
this.searchButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
SearchPanel.this.model.search();
}
});
this.backButton = new JButton("Back");
this.backButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
SearchPanel.this.model.back();
}
});
//create first and second panels
this.firstPanel = new FirstPanel(this.param, this.model);
this.secondPanel = new SecondPanel(this.param, this.model);
this.add(this.view);
buildFirstPanel();
this.setVisible(false);
this.view.updateUI();
}
/**
* Load window options.
*/
private void loadWindowOptions() {
String wSizeStrX = VisualGraph.config.getProperty(DEF_WINDOWS_SIZE_X);
String wSizeStrY = VisualGraph.config.getProperty(DEF_WINDOWS_SIZE_Y);
String wPosStrX = VisualGraph.config.getProperty(DEF_WINDOWS_POS_X);
String wPosStrY = VisualGraph.config.getProperty(DEF_WINDOWS_POS_Y);
//set size X(width of window)
if(wSizeStrX == null) {
this.windowSizeX = 800;
VisualGraph.config.setProperty(DEF_WINDOWS_SIZE_X, this.windowSizeX.toString());
} else {
try {
this.windowSizeX = new Integer(wSizeStrX);
} catch(NumberFormatException ex) {
this.windowSizeX = 800;
VisualGraph.config.setProperty(DEF_WINDOWS_SIZE_X, this.windowSizeX.toString());
}
}
//set size Y(height of window)
if(wSizeStrY == null) {
this.windowSizeY = 600;
VisualGraph.config.setProperty(DEF_WINDOWS_SIZE_Y, this.windowSizeY.toString());
} else {
try {
this.windowSizeY = new Integer(wSizeStrY);
} catch(NumberFormatException ex) {
this.windowSizeY = 600;
VisualGraph.config.setProperty(DEF_WINDOWS_SIZE_Y, this.windowSizeY.toString());
}
}
//set position X
if(wPosStrX == null) {
this.windowPosX = 200;
VisualGraph.config.setProperty(DEF_WINDOWS_POS_X, this.windowPosX.toString());
} else {
try {
this.windowPosX = new Integer(wPosStrX);
} catch(NumberFormatException ex) {
this.windowPosX = 800;
VisualGraph.config.setProperty(DEF_WINDOWS_POS_X, this.windowPosX.toString());
}
}
//set position Y
if(wPosStrY == null) {
this.windowPosY = 200;
VisualGraph.config.setProperty(DEF_WINDOWS_POS_Y, this.windowPosY.toString());
} else {
try {
this.windowPosY = new Integer(wPosStrY);
} catch(NumberFormatException ex) {
this.windowPosY = 800;
VisualGraph.config.setProperty(DEF_WINDOWS_POS_Y, this.windowPosY.toString());
}
}
}
}