package ilarkesto.mda.swingeditor;
import ilarkesto.core.logging.Log;
import ilarkesto.mda.model.Node;
import ilarkesto.mda.model.RuleSet;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collections;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
public class NodeListPanel extends JPanel {
private static final Log LOG = Log.get(NodeListPanel.class);
private SwingModelHelper swingModelHelper;
private Node node;
private Observer observer;
private JScrollPane scroller;
private JTable table;
private NodesModel tableModel;
private JPanel toolbar;
private JButton addButton;
private JButton removeButton;
private JButton editButton;
public NodeListPanel(SwingModelHelper swingModelHelper) {
this.swingModelHelper = swingModelHelper;
setLayout(new BorderLayout());
add(createToolbar(), BorderLayout.NORTH);
add(createTable(), BorderLayout.CENTER);
}
public void addNode() {
Node newNode = swingModelHelper.addNode(node, getSelectedNode());
if (newNode == null) return;
tableModel.update();
selectNode(newNode);
}
public void editNode() {
Node selectedNode = getSelectedNode();
if (selectedNode == null) return;
swingModelHelper.editNode(selectedNode);
tableModel.update();
selectNode(selectedNode);
}
public void removeNode() {
Node selectedNode = getSelectedNode();
if (selectedNode == null) return;
swingModelHelper.removeNode(selectedNode);
tableModel.update();
}
public void selectNode(Node nodeToSelect) {
int index = tableModel.nodes.indexOf(nodeToSelect);
if (index < 0) return;
table.getSelectionModel().setSelectionInterval(index, index);
}
public void setNode(Node node) {
this.node = node;
tableModel.update();
}
private Component createToolbar() {
addButton = new JButton("+");
addButton.setToolTipText("Create new node.");
addButton.addActionListener(new AddActionListener());
removeButton = new JButton("-");
removeButton.setToolTipText("Delete selected node.");
removeButton.addActionListener(new RemoveActionListener());
editButton = new JButton("edit");
editButton.setToolTipText("Edit value of selected node.");
editButton.addActionListener(new EditActionListener());
toolbar = new JPanel(new FlowLayout(FlowLayout.LEFT));
toolbar.add(addButton);
toolbar.add(editButton);
toolbar.add(removeButton);
updateToolbar(null);
return toolbar;
}
private void updateToolbar(Node selectedNode) {
RuleSet ruleSet = swingModelHelper.getModellingSession().getRuleSet();
addButton.setEnabled(node == null || ruleSet.containsAllowedChildTypes(node));
removeButton.setEnabled(selectedNode != null);
editButton.setEnabled(selectedNode != null);
}
private Component createTable() {
tableModel = new NodesModel();
table = new JTable(tableModel);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setColumnSelectionAllowed(false);
table.getSelectionModel().addListSelectionListener(new SelectionListener());
table.setShowGrid(false);
table.setShowHorizontalLines(true);
table.getColumnModel().getColumn(0).setPreferredWidth(30);
scroller = new JScrollPane(table);
scroller.setPreferredSize(new Dimension(200, 200));
scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
return scroller;
}
public Node getSelectedNode() {
int selectedRow = table.getSelectedRow();
return selectedRow < 0 ? null : tableModel.nodes.get(selectedRow);
}
public void setObserver(Observer observer) {
this.observer = observer;
}
@Override
public String toString() {
return "NodeListPanel(" + node + ")";
}
private class RemoveActionListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
removeNode();
}
}
private class EditActionListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
editNode();
}
}
private class AddActionListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
addNode();
}
}
public static interface Observer {
void onNodeSelectionChanged(NodeListPanel nodeListPanel, Node selectedNode);
}
private class SelectionListener implements ListSelectionListener {
@Override
public void valueChanged(ListSelectionEvent evt) {
if (evt.getValueIsAdjusting()) return;
Node selectedNode = getSelectedNode();
LOG.debug("selection changed:", selectedNode);
updateToolbar(selectedNode);
if (observer != null) observer.onNodeSelectionChanged(NodeListPanel.this, selectedNode);
}
}
private class NodesModel extends AbstractTableModel {
private List<Node> nodes = Collections.emptyList();
public void update() {
nodes = node.getChildren();
Collections.sort(nodes);
fireTableDataChanged();
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Node node = nodes.get(rowIndex);
switch (columnIndex) {
case 0:
return node.getType();
default:
return node.getValue();
}
}
@Override
public int getRowCount() {
return nodes.size();
}
@Override
public int getColumnCount() {
return 2;
}
@Override
public String getColumnName(int column) {
switch (column) {
case 0:
return "Type";
default:
return "Value";
}
}
}
}