rewrote project dialog, for easier import and management of cooja projects
This commit is contained in:
parent
56a3a71108
commit
b229e9aa59
3 changed files with 647 additions and 419 deletions
|
@ -24,7 +24,7 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* $Id: GUI.java,v 1.168 2010/04/26 08:19:32 fros4943 Exp $
|
||||
* $Id: GUI.java,v 1.169 2010/05/19 17:32:54 fros4943 Exp $
|
||||
*/
|
||||
|
||||
package se.sics.cooja;
|
||||
|
@ -419,7 +419,7 @@ public class GUI extends Observable {
|
|||
if (isVisualized()) {
|
||||
JOptionPane.showMessageDialog(GUI.getTopParentContainer(),
|
||||
"Default projects could not load, reconfigure project directories:" +
|
||||
"\n\tMenu->Settings->Manage project directories" +
|
||||
"\n\tMenu->Settings->COOJA projects" +
|
||||
"\n\nSee console for stack trace with more information.",
|
||||
"Project loading error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
|
@ -898,7 +898,7 @@ public class GUI extends Observable {
|
|||
menuItem.setToolTipText("Not available in applet version");
|
||||
}
|
||||
|
||||
menuItem = new JMenuItem("Manage project directories");
|
||||
menuItem = new JMenuItem("COOJA projects");
|
||||
menuItem.setActionCommand("manage projects");
|
||||
menuItem.addActionListener(guiEventHandler);
|
||||
menu.add(menuItem);
|
||||
|
@ -2878,7 +2878,7 @@ public class GUI extends Observable {
|
|||
if (isVisualized()) {
|
||||
JOptionPane.showMessageDialog(GUI.getTopParentContainer(),
|
||||
"Configured projects could not load, reconfigure project directories:" +
|
||||
"\n\tMenu->Settings->Manage project directories" +
|
||||
"\n\tMenu->Settings->COOJA projects" +
|
||||
"\n\nSee console for stack trace with more information.",
|
||||
"Project loading error", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2006, Swedish Institute of Computer Science.
|
||||
* Copyright (c) 2010, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -26,24 +26,29 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: ProjectDirectoriesDialog.java,v 1.12 2010/02/03 10:19:58 fros4943 Exp $
|
||||
* $Id: ProjectDirectoriesDialog.java,v 1.13 2010/05/19 17:32:53 fros4943 Exp $
|
||||
*/
|
||||
|
||||
package se.sics.cooja.dialogs;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dialog;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Frame;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.List;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -52,13 +57,28 @@ import java.util.Enumeration;
|
|||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.BoxLayout;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.JTree;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.event.TreeModelListener;
|
||||
import javax.swing.event.TreeSelectionEvent;
|
||||
import javax.swing.event.TreeSelectionListener;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.DefaultTreeCellRenderer;
|
||||
import javax.swing.tree.DefaultTreeModel;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
|
@ -66,31 +86,31 @@ import se.sics.cooja.GUI;
|
|||
import se.sics.cooja.ProjectConfig;
|
||||
|
||||
/**
|
||||
* This dialog allows a user to manage the project directory configurations. Project
|
||||
* directories can be added, removed or reordered. The resulting
|
||||
* configuration can also be viewed.
|
||||
*
|
||||
* This dialog reads from the external project configuration files in each project
|
||||
* directory, as well as from any specified default configuration files.
|
||||
* This dialog allows a user to manage COOJA projects: extensions to COOJA that
|
||||
* provide new functionality such as radio mediums, plugins, and mote types.
|
||||
*
|
||||
* @author Fredrik Osterlind
|
||||
*/
|
||||
public class ProjectDirectoriesDialog extends JDialog {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final long serialVersionUID = 1896348946753376556L;
|
||||
private static Logger logger = Logger.getLogger(ProjectDirectoriesDialog.class);
|
||||
|
||||
private GUI gui;
|
||||
|
||||
private File[] projects = null;
|
||||
private List projectsList = new List();
|
||||
private JTable table = null;
|
||||
private DirectoryTreePanel treePanel = null;
|
||||
|
||||
private ArrayList<File> currentProjects = new ArrayList<File>();
|
||||
private File[] finalProjects = null;
|
||||
|
||||
/**
|
||||
* Allows editing the project directories list by adding new,
|
||||
* reordering or removing project directories.
|
||||
* Shows a blocking configuration dialog.
|
||||
* Returns a list of new COOJA project directories, or null if canceled by the user.
|
||||
*
|
||||
* @param parent Parent container
|
||||
* @param currentProjects Current project directories
|
||||
* @return The new project directories, or null if dialog was aborted
|
||||
* @param gui COOJA
|
||||
* @param currentProjects Current project configuration
|
||||
* @return New COOJA projects, or null
|
||||
*/
|
||||
public static File[] showDialog(Container parent, GUI gui, File[] currentProjects) {
|
||||
if (GUI.isVisualizedInApplet()) {
|
||||
|
@ -98,37 +118,118 @@ public class ProjectDirectoriesDialog extends JDialog {
|
|||
}
|
||||
|
||||
ProjectDirectoriesDialog dialog = new ProjectDirectoriesDialog((Window) parent, currentProjects);
|
||||
|
||||
dialog.gui = gui;
|
||||
dialog.setLocationRelativeTo(parent);
|
||||
|
||||
dialog.setVisible(true);
|
||||
|
||||
return dialog.projects;
|
||||
return dialog.finalProjects;
|
||||
}
|
||||
|
||||
private ProjectDirectoriesDialog(Container parent, File[] projects) {
|
||||
super(
|
||||
parent instanceof Dialog?(Dialog)parent:
|
||||
parent instanceof Window?(Window)parent:
|
||||
(Frame)parent, "Manage Project Directories", ModalityType.APPLICATION_MODAL);
|
||||
(Frame)parent, "COOJA projects", ModalityType.APPLICATION_MODAL);
|
||||
|
||||
JPanel mainPane = new JPanel();
|
||||
mainPane.setLayout(new BoxLayout(mainPane, BoxLayout.Y_AXIS));
|
||||
table = new JTable(new AbstractTableModel() {
|
||||
private static final long serialVersionUID = 591599455927509191L;
|
||||
public int getColumnCount() {
|
||||
return 2;
|
||||
}
|
||||
public int getRowCount() {
|
||||
return currentProjects.size();
|
||||
}
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
if (columnIndex == 0) {
|
||||
return rowIndex+1;
|
||||
}
|
||||
|
||||
if (!currentProjects.get(rowIndex).exists()) {
|
||||
return currentProjects.get(rowIndex) + " (directory not found)";
|
||||
}
|
||||
if (!new File(currentProjects.get(rowIndex), GUI.PROJECT_CONFIG_FILENAME).exists()) {
|
||||
return currentProjects.get(rowIndex) + " (no " + GUI.PROJECT_CONFIG_FILENAME + " found)";
|
||||
}
|
||||
|
||||
return currentProjects.get(rowIndex);
|
||||
}
|
||||
});
|
||||
table.setTableHeader(null);
|
||||
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
if (table.getSelectedRow() < 0) {
|
||||
return;
|
||||
}
|
||||
selectTreeProject(currentProjects.get(table.getSelectedRow()));
|
||||
}
|
||||
});
|
||||
table.getColumnModel().getColumn(0).setPreferredWidth(30);
|
||||
table.getColumnModel().getColumn(0).setMaxWidth(30);
|
||||
table.getColumnModel().getColumn(1).setCellRenderer(new DefaultTableCellRenderer() {
|
||||
private static final long serialVersionUID = 7224219223448831880L;
|
||||
public Component getTableCellRendererComponent(JTable table,
|
||||
Object value, boolean isSelected, boolean hasFocus, int row,
|
||||
int column) {
|
||||
if (!new File(currentProjects.get(row), GUI.PROJECT_CONFIG_FILENAME).exists()) {
|
||||
setBackground(Color.RED);
|
||||
} else {
|
||||
setBackground(Color.WHITE);
|
||||
}
|
||||
|
||||
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus,
|
||||
row, column);
|
||||
}
|
||||
});
|
||||
|
||||
/* Add current projects */
|
||||
for (File projectDir : projects) {
|
||||
addProjectDir(projectDir);
|
||||
}
|
||||
|
||||
Box mainPane = Box.createVerticalBox();
|
||||
Box buttonPane = Box.createHorizontalBox();
|
||||
JPanel smallPane;
|
||||
JButton button;
|
||||
|
||||
// BOTTOM BUTTON PART
|
||||
JPanel buttonPane = new JPanel();
|
||||
buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.X_AXIS));
|
||||
buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
|
||||
|
||||
/* Lower buttons */
|
||||
{
|
||||
buttonPane.setBorder(BorderFactory.createEmptyBorder(0,3,3,3));
|
||||
buttonPane.add(Box.createHorizontalGlue());
|
||||
|
||||
button = new JButton("View merged config");
|
||||
button.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
ProjectConfig config;
|
||||
try {
|
||||
config = new ProjectConfig(true);
|
||||
} catch (FileNotFoundException ex) {
|
||||
logger.fatal("Could not find default project config file: " + GUI.PROJECT_DEFAULT_CONFIG_FILENAME);
|
||||
return;
|
||||
} catch (IOException ex) {
|
||||
logger.fatal("Error when reading default project config file: " + GUI.PROJECT_DEFAULT_CONFIG_FILENAME);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Merge configs */
|
||||
for (File project : getProjects()) {
|
||||
try {
|
||||
config.appendProjectDir(project);
|
||||
} catch (Exception ex) {
|
||||
logger.fatal("Error when merging configurations: " + ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ConfigViewer.showDialog(ProjectDirectoriesDialog.this, config);
|
||||
}
|
||||
});
|
||||
buttonPane.add(button);
|
||||
buttonPane.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
|
||||
button = new JButton("Cancel");
|
||||
button.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
ProjectDirectoriesDialog.this.projects = null;
|
||||
ProjectDirectoriesDialog.this.finalProjects = null;
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
|
@ -142,12 +243,12 @@ public class ProjectDirectoriesDialog extends JDialog {
|
|||
Object[] options = { "Ok", "Cancel" };
|
||||
|
||||
String newDefaultProjectDirs = "";
|
||||
for (String directory : projectsList.getItems()) {
|
||||
for (File f: currentProjects) {
|
||||
if (newDefaultProjectDirs != "") {
|
||||
newDefaultProjectDirs += ";";
|
||||
}
|
||||
|
||||
newDefaultProjectDirs += gui.createPortablePath(new File(directory)).getPath();
|
||||
newDefaultProjectDirs += gui.createPortablePath(f).getPath();
|
||||
}
|
||||
newDefaultProjectDirs = newDefaultProjectDirs.replace('\\', '/');
|
||||
|
||||
|
@ -174,208 +275,485 @@ public class ProjectDirectoriesDialog extends JDialog {
|
|||
button = new JButton("OK");
|
||||
button.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
ArrayList<File> newProjects = new ArrayList<File>();
|
||||
for (String directory : projectsList.getItems()) {
|
||||
newProjects.add(new File(directory));
|
||||
}
|
||||
ProjectDirectoriesDialog.this.projects = newProjects.toArray(new File[0]);
|
||||
ProjectDirectoriesDialog.this.finalProjects = currentProjects.toArray(new File[0]);
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
buttonPane.add(button);
|
||||
this.getRootPane().setDefaultButton(button);
|
||||
}
|
||||
|
||||
// LIST PART
|
||||
JPanel listPane = new JPanel();
|
||||
listPane.setLayout(new BoxLayout(listPane, BoxLayout.X_AXIS));
|
||||
listPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||
/* Center: Tree and list*/
|
||||
{
|
||||
JPanel listPane = new JPanel(new BorderLayout());
|
||||
|
||||
JPanel listPane2 = new JPanel();
|
||||
listPane2.setLayout(new BoxLayout(listPane2, BoxLayout.Y_AXIS));
|
||||
listPane.add(BorderLayout.WEST, treePanel = new DirectoryTreePanel(this));
|
||||
listPane.add(BorderLayout.CENTER, new JScrollPane(table));
|
||||
|
||||
listPane2.add(projectsList);
|
||||
|
||||
listPane.add(listPane2);
|
||||
|
||||
smallPane = new JPanel();
|
||||
smallPane.setLayout(new BoxLayout(smallPane, BoxLayout.Y_AXIS));
|
||||
|
||||
button = new JButton("Move up");
|
||||
smallPane = new JPanel(new BorderLayout());
|
||||
Icon icon = UIManager.getLookAndFeelDefaults().getIcon("Table.ascendingSortIcon");
|
||||
if (icon == null) {
|
||||
button = new JButton("Up");
|
||||
} else {
|
||||
button = new JButton(icon);
|
||||
}
|
||||
button.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
int selectedIndex = projectsList.getSelectedIndex();
|
||||
int selectedIndex = table.getSelectedRow();
|
||||
if (selectedIndex <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
File file = new File(projectsList.getItem(selectedIndex));
|
||||
|
||||
removeProjectDir(selectedIndex);
|
||||
File file = currentProjects.get(selectedIndex);
|
||||
removeProjectDir(file);
|
||||
addProjectDir(file, selectedIndex - 1);
|
||||
projectsList.select(selectedIndex - 1);
|
||||
table.getSelectionModel().setSelectionInterval(selectedIndex - 1, selectedIndex - 1);
|
||||
}
|
||||
});
|
||||
smallPane.add(button);
|
||||
|
||||
button = new JButton("Move down");
|
||||
smallPane.add(BorderLayout.NORTH, button);
|
||||
icon = UIManager.getLookAndFeelDefaults().getIcon("Table.descendingSortIcon");
|
||||
if (icon == null) {
|
||||
button = new JButton("Down");
|
||||
} else {
|
||||
button = new JButton(icon);
|
||||
}
|
||||
button.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
int selectedIndex = projectsList.getSelectedIndex();
|
||||
int selectedIndex = table.getSelectedRow();
|
||||
if (selectedIndex < 0) {
|
||||
return;
|
||||
}
|
||||
if (selectedIndex >= projectsList.getItemCount() - 1) {
|
||||
if (selectedIndex >= currentProjects.size() - 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
File file = new File(projectsList.getItem(selectedIndex));
|
||||
removeProjectDir(selectedIndex);
|
||||
File file = currentProjects.get(selectedIndex);
|
||||
removeProjectDir(file);
|
||||
addProjectDir(file, selectedIndex + 1);
|
||||
projectsList.select(selectedIndex + 1);
|
||||
table.getSelectionModel().setSelectionInterval(selectedIndex + 1, selectedIndex + 1);
|
||||
}
|
||||
});
|
||||
smallPane.add(button);
|
||||
|
||||
smallPane.add(Box.createRigidArea(new Dimension(10, 10)));
|
||||
|
||||
button = new JButton("Remove");
|
||||
button.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (projectsList.getSelectedIndex() < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
removeProjectDir(projectsList.getSelectedIndex());
|
||||
}
|
||||
});
|
||||
smallPane.add(button);
|
||||
|
||||
listPane.add(smallPane);
|
||||
|
||||
// ADD/REMOVE PART
|
||||
JPanel addRemovePane = new JPanel();
|
||||
addRemovePane.setLayout(new BoxLayout(addRemovePane, BoxLayout.X_AXIS));
|
||||
addRemovePane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
|
||||
|
||||
button = new JButton("View resulting config");
|
||||
button.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
ProjectConfig config;
|
||||
try {
|
||||
// Create default configuration
|
||||
config = new ProjectConfig(true);
|
||||
} catch (FileNotFoundException ex) {
|
||||
logger.fatal("Could not find default project config file: "
|
||||
+ GUI.PROJECT_DEFAULT_CONFIG_FILENAME);
|
||||
return;
|
||||
} catch (IOException ex) {
|
||||
logger.fatal("Error when reading default project config file: "
|
||||
+ GUI.PROJECT_DEFAULT_CONFIG_FILENAME);
|
||||
return;
|
||||
}
|
||||
|
||||
// Add the project directory configurations
|
||||
for (String projectDir : projectsList.getItems()) {
|
||||
try {
|
||||
config.appendProjectDir(new File(projectDir));
|
||||
} catch (Exception ex) {
|
||||
logger.fatal("Error when merging configurations: " + ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Show merged configuration
|
||||
ConfigViewer.showDialog(ProjectDirectoriesDialog.this, config);
|
||||
}
|
||||
});
|
||||
addRemovePane.add(button);
|
||||
|
||||
addRemovePane.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
|
||||
button = new JButton("Enter path manually");
|
||||
button.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
ProjectDirectoryInputDialog pathDialog = new ProjectDirectoryInputDialog(ProjectDirectoriesDialog.this);
|
||||
pathDialog.pack();
|
||||
|
||||
pathDialog.setLocationRelativeTo(ProjectDirectoriesDialog.this);
|
||||
pathDialog.setVisible(true);
|
||||
|
||||
File projectPath = pathDialog.getProjectDirectory();
|
||||
if (projectPath != null) {
|
||||
addProjectDir(projectPath);
|
||||
}
|
||||
}
|
||||
});
|
||||
addRemovePane.add(button);
|
||||
|
||||
addRemovePane.add(Box.createRigidArea(new Dimension(10, 0)));
|
||||
|
||||
button = new JButton("Browse");
|
||||
button.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JFileChooser fc = new JFileChooser();
|
||||
fc.setCurrentDirectory(new java.io.File(GUI.getExternalToolsSetting("PATH_CONTIKI")));
|
||||
fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
|
||||
fc.setDialogTitle("Select project directory");
|
||||
|
||||
if (fc.showOpenDialog(ProjectDirectoriesDialog.this) == JFileChooser.APPROVE_OPTION) {
|
||||
File dir = fc.getSelectedFile();
|
||||
String selectedPath = null;
|
||||
try {
|
||||
selectedPath = dir.getCanonicalPath().replace('\\', '/');
|
||||
String contikiPath =
|
||||
new File(GUI.getExternalToolsSetting("PATH_CONTIKI", null)).
|
||||
getCanonicalPath().replace('\\', '/');
|
||||
if (contikiPath != null && selectedPath.startsWith(contikiPath)) {
|
||||
selectedPath = selectedPath.replaceFirst(
|
||||
contikiPath, GUI.getExternalToolsSetting("PATH_CONTIKI"));
|
||||
}
|
||||
addProjectDir(new File(selectedPath));
|
||||
} catch (IOException ex) {
|
||||
logger.fatal("Error in path extraction: " + ex);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
addRemovePane.add(button);
|
||||
|
||||
// Add components
|
||||
Container contentPane = getContentPane();
|
||||
smallPane.add(BorderLayout.SOUTH, button);
|
||||
listPane.add(BorderLayout.EAST, smallPane);
|
||||
mainPane.setBackground(Color.WHITE);
|
||||
mainPane.add(listPane);
|
||||
mainPane.add(addRemovePane);
|
||||
contentPane.add(mainPane, BorderLayout.CENTER);
|
||||
contentPane.add(buttonPane, BorderLayout.SOUTH);
|
||||
|
||||
for (File projectDir : projects) {
|
||||
addProjectDir(projectDir);
|
||||
}
|
||||
pack();
|
||||
}
|
||||
|
||||
private void addProjectDir(File projectDir) {
|
||||
addProjectDir(projectDir, projectsList.getItemCount());
|
||||
JPanel topPanel = new JPanel(new BorderLayout());
|
||||
topPanel.add(BorderLayout.CENTER, new JLabel(" A COOJA project depends on a cooja.config file, and extends COOJA with radio mediums, mote types, plugins etc."));
|
||||
topPanel.setBackground(Color.WHITE);
|
||||
getContentPane().add(BorderLayout.NORTH, topPanel);
|
||||
getContentPane().add(BorderLayout.CENTER, mainPane);
|
||||
getContentPane().add(BorderLayout.SOUTH, buttonPane);
|
||||
setSize(700, 500);
|
||||
}
|
||||
|
||||
private void addProjectDir(File projectDir, int index) {
|
||||
// Check that file exists, is a directory and contains the correct files
|
||||
public File[] getProjects() {
|
||||
return currentProjects.toArray(new File[0]);
|
||||
}
|
||||
protected void addProjectDir(File projectDir) {
|
||||
currentProjects.add(projectDir);
|
||||
((AbstractTableModel)table.getModel()).fireTableDataChanged();
|
||||
}
|
||||
protected void addProjectDir(File projectDir, int index) {
|
||||
currentProjects.add(index, projectDir);
|
||||
((AbstractTableModel)table.getModel()).fireTableDataChanged();
|
||||
}
|
||||
protected void removeProjectDir(int index) {
|
||||
currentProjects.remove(index);
|
||||
((AbstractTableModel)table.getModel()).fireTableDataChanged();
|
||||
}
|
||||
protected void removeProjectDir(File dir) {
|
||||
currentProjects.remove(dir);
|
||||
((AbstractTableModel)table.getModel()).fireTableDataChanged();
|
||||
}
|
||||
private int getProjectListIndex(File dir) {
|
||||
return currentProjects.indexOf(dir);
|
||||
}
|
||||
public void selectListProject(File dir) {
|
||||
int i = getProjectListIndex(dir);
|
||||
if (i >= 0) {
|
||||
table.getSelectionModel().setSelectionInterval(i, i);
|
||||
}
|
||||
}
|
||||
public void selectTreeProject(File dir) {
|
||||
treePanel.selectProject(dir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a directory tree, and allows for selecting directories with a cooja.config file.
|
||||
*
|
||||
* @author Fredrik Osterlind
|
||||
*/
|
||||
class DirectoryTreePanel extends JPanel {
|
||||
private static final long serialVersionUID = -6852893350326771136L;
|
||||
private static Logger logger = Logger.getLogger(DirectoryTreePanel.class);
|
||||
|
||||
private ProjectDirectoriesDialog parent;
|
||||
private JTree tree;
|
||||
private DefaultMutableTreeNode treeRoot;
|
||||
public DirectoryTreePanel(ProjectDirectoriesDialog parent) {
|
||||
super(new BorderLayout());
|
||||
this.parent = parent;
|
||||
|
||||
/* Build directory tree */
|
||||
treeRoot = new DefaultMutableTreeNode("My Computer");
|
||||
tree = new JTree(treeRoot);
|
||||
tree.setRootVisible(false);
|
||||
tree.setShowsRootHandles(true);
|
||||
tree.expandRow(0);
|
||||
tree.setCellRenderer(new DefaultTreeCellRenderer() {
|
||||
private static final long serialVersionUID = 280434957859560569L;
|
||||
private Icon unselectedIcon = new CheckboxIcon(null);
|
||||
private Icon selectedIcon = new CheckboxIcon(new Color(0, 255, 0, 128));
|
||||
private Icon errorIcon = new CheckboxIcon(new Color(255, 0, 0, 128));
|
||||
private Font boldFont = null;
|
||||
private Font normalFont = null;
|
||||
public Component getTreeCellRendererComponent(JTree tree,
|
||||
Object value, boolean sel, boolean expanded, boolean leaf,
|
||||
int row, boolean hasFocus) {
|
||||
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf,
|
||||
row, hasFocus);
|
||||
if (value instanceof DefaultMutableTreeNode) {
|
||||
value = ((DefaultMutableTreeNode) value).getUserObject();
|
||||
}
|
||||
if (!(value instanceof ProjectDirectory)) {
|
||||
return this;
|
||||
}
|
||||
ProjectDirectory td = (ProjectDirectory) value;
|
||||
|
||||
if (boldFont == null) {
|
||||
normalFont = getFont();
|
||||
boldFont = getFont().deriveFont( Font.BOLD );
|
||||
}
|
||||
|
||||
/* Style */
|
||||
setFont(normalFont);
|
||||
if (td.isProject()) {
|
||||
if (td.containsConfig()) {
|
||||
setIcon(selectedIcon);
|
||||
} else {
|
||||
/* Error: no cooja.config */
|
||||
setIcon(errorIcon);
|
||||
setFont(boldFont);
|
||||
}
|
||||
} else if (td.containsConfig()) {
|
||||
setIcon(unselectedIcon);
|
||||
} else if (td.subtreeContainsProject()) {
|
||||
setFont(boldFont);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
class CheckboxIcon implements Icon {
|
||||
Icon icon = (Icon) UIManager.get("CheckBox.icon");
|
||||
Color color;
|
||||
public CheckboxIcon(Color color) {
|
||||
this.color = color;
|
||||
}
|
||||
public int getIconHeight() {
|
||||
return icon.getIconHeight();
|
||||
}
|
||||
public int getIconWidth() {
|
||||
return icon.getIconWidth();
|
||||
}
|
||||
public void paintIcon(Component c, Graphics g, int x, int y) {
|
||||
icon.paintIcon(c, g, x, y);
|
||||
if (color != null) {
|
||||
g.setColor(color);
|
||||
g.fillRect(x, y, icon.getIconWidth(), icon.getIconHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
tree.setModel(new COOJAProjectTreeModel(treeRoot));
|
||||
tree.addMouseListener(new MouseAdapter() {
|
||||
public void mousePressed(MouseEvent e) {
|
||||
TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
|
||||
if (selPath == null) {
|
||||
return;
|
||||
}
|
||||
if (e.getClickCount() != 1) {
|
||||
return;
|
||||
}
|
||||
Object o = selPath.getLastPathComponent();
|
||||
if (!(o instanceof DefaultMutableTreeNode)) {
|
||||
return;
|
||||
}
|
||||
if (!(((DefaultMutableTreeNode) o).getUserObject() instanceof ProjectDirectory)) {
|
||||
return;
|
||||
}
|
||||
ProjectDirectory pd = (ProjectDirectory) ((DefaultMutableTreeNode) o).getUserObject();
|
||||
Rectangle r = tree.getPathBounds(selPath);
|
||||
int delta = e.getX() - r.x;
|
||||
if (delta > 18 /* XXX Icon width */) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pd.isProject()) {
|
||||
/* Remove project */
|
||||
DirectoryTreePanel.this.parent.removeProjectDir(pd.dir);
|
||||
DirectoryTreePanel.this.parent.repaint();
|
||||
} else if (pd.containsConfig()) {
|
||||
/* Add project */
|
||||
DirectoryTreePanel.this.parent.addProjectDir(pd.dir);
|
||||
DirectoryTreePanel.this.parent.repaint();
|
||||
}
|
||||
}
|
||||
});
|
||||
tree.addTreeSelectionListener(new TreeSelectionListener() {
|
||||
public void valueChanged(TreeSelectionEvent e) {
|
||||
TreePath selPath = e.getPath();
|
||||
if (selPath == null) {
|
||||
return;
|
||||
}
|
||||
Object o = selPath.getLastPathComponent();
|
||||
if (!(o instanceof DefaultMutableTreeNode)) {
|
||||
return;
|
||||
}
|
||||
if (!(((DefaultMutableTreeNode) o).getUserObject() instanceof ProjectDirectory)) {
|
||||
return;
|
||||
}
|
||||
ProjectDirectory pd = (ProjectDirectory) ((DefaultMutableTreeNode) o).getUserObject();
|
||||
if (pd.isProject()) {
|
||||
DirectoryTreePanel.this.parent.selectListProject(pd.dir);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/* Try expand current COOJA projects */
|
||||
for (File projectDir: parent.getProjects()) {
|
||||
if (!projectDir.exists()) {
|
||||
logger.fatal("Can't find project directory: " + projectDir);
|
||||
logger.fatal("Project directory not found: " + projectDir);
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
String projectCanonical = projectDir.getCanonicalPath();
|
||||
TreePath tp = new TreePath(tree.getModel().getRoot());
|
||||
tp = buildTreePath(projectCanonical, treeRoot, tp, tree);
|
||||
/*logger.info("Expanding: " + tp);*/
|
||||
if (tp != null) {
|
||||
tree.expandPath(tp.getParentPath());
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
logger.warn("Error when expanding projects: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
add(BorderLayout.CENTER, new JScrollPane(tree));
|
||||
}
|
||||
|
||||
public void selectProject(File dir) {
|
||||
/* Expand view */
|
||||
try {
|
||||
String projectCanonical = dir.getCanonicalPath();
|
||||
TreePath tp = new TreePath(tree.getModel().getRoot());
|
||||
tp = buildTreePath(projectCanonical, treeRoot, tp, tree);
|
||||
/*logger.info("Expanding: " + tp);*/
|
||||
if (tp != null) {
|
||||
tree.setSelectionPath(tp);
|
||||
tree.scrollPathToVisible(tp);
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
logger.warn("Error when expanding projects: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static TreePath buildTreePath(String projectCanonical, DefaultMutableTreeNode parent, TreePath tp, JTree tree)
|
||||
throws IOException {
|
||||
/* Force filesystem listing */
|
||||
tree.getModel().getChildCount(parent);
|
||||
|
||||
for (int i=0; i < tree.getModel().getChildCount(parent); i++) {
|
||||
DefaultMutableTreeNode child = (DefaultMutableTreeNode) tree.getModel().getChild(parent, i);
|
||||
Object userObject = child.getUserObject();
|
||||
if (!(userObject instanceof ProjectDirectory)) {
|
||||
logger.fatal("Bad tree element: " + userObject.getClass());
|
||||
continue;
|
||||
}
|
||||
ProjectDirectory td = (ProjectDirectory) userObject;
|
||||
String treeCanonical = td.dir.getCanonicalPath();
|
||||
|
||||
if (projectCanonical.startsWith(treeCanonical)) {
|
||||
tp = tp.pathByAddingChild(child);
|
||||
if (projectCanonical.equals(treeCanonical)) {
|
||||
return tp;
|
||||
}
|
||||
|
||||
return buildTreePath(projectCanonical, child, tp, tree);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class ProjectDirectory {
|
||||
File dir = null;
|
||||
File[] subdirs = null;
|
||||
|
||||
public ProjectDirectory(File file) {
|
||||
this.dir = file;
|
||||
}
|
||||
|
||||
boolean isProject() {
|
||||
for (File project: parent.getProjects()) {
|
||||
if (project.equals(dir)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
boolean containsConfig() {
|
||||
return new File(dir, GUI.PROJECT_CONFIG_FILENAME).exists();
|
||||
}
|
||||
boolean subtreeContainsProject() {
|
||||
try {
|
||||
String dirCanonical = dir.getCanonicalPath();
|
||||
for (File project: parent.getProjects()) {
|
||||
if (!project.exists()) {
|
||||
continue;
|
||||
}
|
||||
String projectCanonical = project.getCanonicalPath();
|
||||
if (projectCanonical.startsWith(dirCanonical)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public String toString() {
|
||||
if (dir.getName() == null || dir.getName().equals("")) {
|
||||
return dir.getAbsolutePath();
|
||||
}
|
||||
return dir.getName();
|
||||
}
|
||||
}
|
||||
private class COOJAProjectTreeModel extends DefaultTreeModel {
|
||||
private static final long serialVersionUID = -4673855124090194313L;
|
||||
|
||||
private DefaultMutableTreeNode computerNode;
|
||||
|
||||
public COOJAProjectTreeModel(DefaultMutableTreeNode computerNode) {
|
||||
super(computerNode);
|
||||
this.computerNode = computerNode;
|
||||
|
||||
/* List roots */
|
||||
File[] devices = File.listRoots();
|
||||
if (devices == null) {
|
||||
logger.fatal("Could not list filesystem");
|
||||
return;
|
||||
}
|
||||
if (!projectDir.isDirectory()) {
|
||||
logger.fatal("Specified path is not a directory: " + projectDir);
|
||||
return;
|
||||
for (File device: devices) {
|
||||
DefaultMutableTreeNode deviceNode = new DefaultMutableTreeNode(new ProjectDirectory(device));
|
||||
computerNode.add(deviceNode);
|
||||
}
|
||||
}
|
||||
public Object getRoot() {
|
||||
return computerNode.getUserObject();
|
||||
}
|
||||
public boolean isLeaf(Object node) {
|
||||
if ((node instanceof DefaultMutableTreeNode)) {
|
||||
node = ((DefaultMutableTreeNode)node).getUserObject();
|
||||
}
|
||||
if (!(node instanceof ProjectDirectory)) {
|
||||
/* Computer node */
|
||||
return false;
|
||||
}
|
||||
ProjectDirectory td = ((ProjectDirectory)node);
|
||||
|
||||
return td.dir.isFile();
|
||||
}
|
||||
public int getChildCount(Object parent) {
|
||||
if ((parent instanceof DefaultMutableTreeNode)) {
|
||||
parent = ((DefaultMutableTreeNode)parent).getUserObject();
|
||||
}
|
||||
if (!(parent instanceof ProjectDirectory)) {
|
||||
/* Computer node */
|
||||
return computerNode.getChildCount();
|
||||
}
|
||||
ProjectDirectory td = ((ProjectDirectory)parent);
|
||||
|
||||
File[] children;
|
||||
if (td.subdirs != null) {
|
||||
children = td.subdirs;
|
||||
} else {
|
||||
children = td.dir.listFiles(DIRECTORIES);
|
||||
td.subdirs = children;
|
||||
}
|
||||
if (children == null) {
|
||||
return 0;
|
||||
}
|
||||
return children.length;
|
||||
}
|
||||
public Object getChild(Object parent, int index) {
|
||||
if ((parent instanceof DefaultMutableTreeNode)) {
|
||||
parent = ((DefaultMutableTreeNode)parent).getUserObject();
|
||||
}
|
||||
if (!(parent instanceof ProjectDirectory)) {
|
||||
/* Computer node */
|
||||
return computerNode.getChildAt(index);
|
||||
}
|
||||
ProjectDirectory td = ((ProjectDirectory)parent);
|
||||
|
||||
File[] children;
|
||||
if (td.subdirs != null) {
|
||||
children = td.subdirs;
|
||||
} else {
|
||||
children = td.dir.listFiles(DIRECTORIES);
|
||||
td.subdirs = children;
|
||||
}
|
||||
if ((children == null) || (index >= children.length)) {
|
||||
return null;
|
||||
}
|
||||
return new DefaultMutableTreeNode(new ProjectDirectory(children[index]));
|
||||
}
|
||||
public int getIndexOfChild(Object parent, Object child) {
|
||||
if ((parent instanceof DefaultMutableTreeNode)) {
|
||||
parent = ((DefaultMutableTreeNode)parent).getUserObject();
|
||||
}
|
||||
if (!(parent instanceof ProjectDirectory)) {
|
||||
/* Computer node */
|
||||
for(int i=0; i < computerNode.getChildCount(); i++) {
|
||||
if (computerNode.getChildAt(i).equals(child)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
ProjectDirectory td = ((ProjectDirectory)parent);
|
||||
|
||||
File[] children;
|
||||
if (td.subdirs != null) {
|
||||
children = td.subdirs;
|
||||
} else {
|
||||
children = td.dir.listFiles(DIRECTORIES);
|
||||
td.subdirs = children;
|
||||
}
|
||||
if (children == null) {
|
||||
return -1;
|
||||
}
|
||||
if (child instanceof DefaultMutableTreeNode) {
|
||||
child = ((DefaultMutableTreeNode)child).getUserObject();
|
||||
}
|
||||
File subDir = ((ProjectDirectory)child).dir;
|
||||
for(int i = 0; i < children.length; i++) {
|
||||
if (subDir.equals(children[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
projectsList.add(projectDir.getPath(), index);
|
||||
}
|
||||
public void valueForPathChanged(TreePath path, Object newvalue) {}
|
||||
public void addTreeModelListener(TreeModelListener l) {}
|
||||
public void removeTreeModelListener(TreeModelListener l) {}
|
||||
|
||||
private void removeProjectDir(int index) {
|
||||
projectsList.remove(index);
|
||||
private final FileFilter DIRECTORIES = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
if (file.isDirectory()) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -491,7 +869,5 @@ class ConfigViewer extends JDialog {
|
|||
if (maxSize != null && (getSize().height > maxSize.height)) {
|
||||
setSize(getSize().width, maxSize.height);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,148 +0,0 @@
|
|||
package se.sics.cooja.dialogs;
|
||||
|
||||
import java.beans.*;
|
||||
import java.io.File;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
class ProjectDirectoryInputDialog extends JDialog implements ActionListener, PropertyChangeListener {
|
||||
private static Logger logger = Logger.getLogger(ProjectDirectoryInputDialog.class);
|
||||
|
||||
private File projectDirectoryPath = null;
|
||||
private JTextField textField;
|
||||
|
||||
private JOptionPane optionPane;
|
||||
|
||||
private String buttonAdd = "Add";
|
||||
private String buttonCancel = "Cancel";
|
||||
|
||||
public ProjectDirectoryInputDialog(Window window) {
|
||||
super(window, ModalityType.APPLICATION_MODAL);
|
||||
setupDialog();
|
||||
}
|
||||
public ProjectDirectoryInputDialog(Dialog dialog) {
|
||||
super(dialog, ModalityType.APPLICATION_MODAL);
|
||||
setupDialog();
|
||||
}
|
||||
public ProjectDirectoryInputDialog(Frame frame) {
|
||||
super(frame, ModalityType.APPLICATION_MODAL);
|
||||
setupDialog();
|
||||
}
|
||||
|
||||
public void setupDialog() {
|
||||
setTitle("Enter path");
|
||||
|
||||
textField = new JTextField(10);
|
||||
textField.getDocument().addDocumentListener(new DocumentListener() {
|
||||
public void insertUpdate(DocumentEvent e) {
|
||||
pathChanged();
|
||||
}
|
||||
public void removeUpdate(DocumentEvent e) {
|
||||
pathChanged();
|
||||
}
|
||||
public void changedUpdate(DocumentEvent e) {
|
||||
pathChanged();
|
||||
}
|
||||
});
|
||||
|
||||
Object[] objects = {"Enter path to project directory", textField};
|
||||
Object[] options = {buttonAdd, buttonCancel};
|
||||
|
||||
optionPane = new JOptionPane(objects,
|
||||
JOptionPane.QUESTION_MESSAGE,
|
||||
JOptionPane.YES_NO_OPTION,
|
||||
null,
|
||||
options,
|
||||
options[0]);
|
||||
|
||||
setContentPane(optionPane);
|
||||
|
||||
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
|
||||
addWindowListener(new WindowAdapter() {
|
||||
public void windowClosing(WindowEvent we) {
|
||||
optionPane.setValue(new Integer(
|
||||
JOptionPane.CLOSED_OPTION));
|
||||
}
|
||||
});
|
||||
|
||||
addComponentListener(new ComponentAdapter() {
|
||||
public void componentShown(ComponentEvent ce) {
|
||||
textField.requestFocusInWindow();
|
||||
}
|
||||
});
|
||||
|
||||
textField.addActionListener(this);
|
||||
optionPane.addPropertyChangeListener(this);
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
pathChanged();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public File getProjectDirectory() {
|
||||
return projectDirectoryPath;
|
||||
}
|
||||
|
||||
private void pathChanged() {
|
||||
String newPath = textField.getText();
|
||||
File projectDir = new File(newPath);
|
||||
if (!projectDir.exists()) {
|
||||
textField.setBackground(Color.RED);
|
||||
textField.setToolTipText("Directory does not exist");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!projectDir.isDirectory()) {
|
||||
textField.setBackground(Color.RED);
|
||||
textField.setToolTipText("Not a directory");
|
||||
return;
|
||||
}
|
||||
|
||||
// if (!new File(projectDir, GUI.PROJECT_CONFIG_FILENAME).exists()) {
|
||||
// textField.setBackground(Color.LIGHT_GRAY);
|
||||
// textField.setToolTipText("No configuration file found");
|
||||
// return;
|
||||
// }
|
||||
|
||||
textField.setBackground(Color.WHITE);
|
||||
textField.setToolTipText("");
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
optionPane.setValue(buttonAdd);
|
||||
}
|
||||
|
||||
public void propertyChange(PropertyChangeEvent e) {
|
||||
String prop = e.getPropertyName();
|
||||
if (isVisible() && (e.getSource() == optionPane)
|
||||
&& (JOptionPane.VALUE_PROPERTY.equals(prop) ||
|
||||
JOptionPane.INPUT_VALUE_PROPERTY.equals(prop))) {
|
||||
Object value = optionPane.getValue();
|
||||
|
||||
if (value == JOptionPane.UNINITIALIZED_VALUE) {
|
||||
return;
|
||||
}
|
||||
|
||||
optionPane.setValue(
|
||||
JOptionPane.UNINITIALIZED_VALUE);
|
||||
|
||||
if (buttonAdd.equals(value)) {
|
||||
projectDirectoryPath = new File(textField.getText());
|
||||
close();
|
||||
} else {
|
||||
projectDirectoryPath = null;
|
||||
close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
textField.setText(null);
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue