package nbtool.gui.utilitypanes; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.Map; import java.util.Set; import javax.swing.DefaultComboBoxModel; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JTree; import javax.swing.UIManager; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.TreeCellRenderer; import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; import nbtool.data.ViewProfile; import nbtool.data.ViewProfile.ViewState; import nbtool.gui.logviews.misc.ViewParent; import nbtool.util.Events; import nbtool.util.ToolSettings; import nbtool.util.UserSettings; import static nbtool.util.Debug.*; public class LogToViewUtility extends UtilityParent { public LogToViewUtility() { super(); } private LogToViewFrame display = null; @Override public JFrame supplyDisplay() { if (display == null) { return (display = new LogToViewFrame()); } return display; } @Override public String purpose() { return "Manage views displayed for a given log"; } @Override public char preferredMemnonic() { return 'l'; } /* NEW STUFF */ public class LogToViewFrame extends javax.swing.JFrame implements TreeModel, MouseListener, KeyListener { private final Object root = new Object(); protected ViewProfile vp = ViewProfile.DEFAULT_PROFILE; @Override public Object getRoot() { return root; } @Override public Object getChild(Object parent, int index) { if (parent == root) { return ViewProfile.TYPES[index]; } int i2 = Arrays.asList(ViewProfile.TYPES).indexOf(parent); return vp.states[i2][index]; } @Override public int getChildCount(Object parent) { if (parent == root) return ViewProfile.TYPES.length; int i2 = Arrays.asList(ViewProfile.TYPES).indexOf(parent); return vp.states[i2].length; } @Override public boolean isLeaf(Object node) { return (node instanceof ViewState); } @Override public void valueForPathChanged(TreePath path, Object newValue) { throw new Error("modification not allowed."); } @Override public int getIndexOfChild(Object parent, Object child) { if (parent == root) { return Arrays.asList(ViewProfile.TYPES).indexOf(child); } return Arrays.asList((ViewState[]) parent).indexOf(child); } private ArrayList<TreeModelListener> listeners = new ArrayList<TreeModelListener>(); public void addTreeModelListener(TreeModelListener l) { listeners.add(l); } public void removeTreeModelListener(TreeModelListener l) { listeners.remove(l); } /*Rendering code from "Definitive Guide to Swing for Java 2, Second Edition"*/ private class LTVCellRenderer implements TreeCellRenderer { private JCheckBox leafRenderer = new JCheckBox(); private DefaultTreeCellRenderer nonLeafRenderer = new DefaultTreeCellRenderer(); Color selectionForeground, selectionBackground, textForeground, textBackground; LTVCellRenderer(){ Font fontValue; fontValue = UIManager.getFont("Tree.font"); if (fontValue != null) { leafRenderer.setFont(fontValue); } Boolean booleanValue = (Boolean) UIManager .get("Tree.drawsFocusBorderAroundIcon"); leafRenderer.setFocusPainted((booleanValue != null) && (booleanValue.booleanValue())); selectionForeground = UIManager.getColor("Tree.selectionForeground"); selectionBackground = UIManager.getColor("Tree.selectionBackground"); textForeground = UIManager.getColor("Tree.textForeground"); textBackground = UIManager.getColor("Tree.textBackground"); } @Override public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { Component returnValue; if (leaf) { assert(value instanceof ViewState); ViewState vs = (ViewState) value; leafRenderer.setText(vs.toString()); leafRenderer.setSelected(vs.showing); leafRenderer.setEnabled(tree.isEnabled()); if (selected) { leafRenderer.setForeground(selectionForeground); leafRenderer.setBackground(selectionBackground); } else { leafRenderer.setForeground(textForeground); leafRenderer.setBackground(textBackground); } returnValue = leafRenderer; } else { returnValue = nonLeafRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); } return returnValue; } } @Override public void mouseClicked(MouseEvent e) { TreePath tp = tree.getClosestPathForLocation(e.getX(), e.getY()); if (tp.getLastPathComponent() != null && tp.getLastPathComponent() instanceof ViewState) { ViewState changed = (ViewState) tp.getLastPathComponent(); changed.showing = !changed.showing; TreeModelEvent tme = new TreeModelEvent(this, tp.getParentPath(), new int[0], new Object[]{changed}); for (TreeModelListener l : listeners) { l.treeNodesChanged(tme); } } } @Override public void mousePressed(MouseEvent e) {} @Override public void mouseReleased(MouseEvent e) {} @Override public void mouseEntered(MouseEvent e) {} @Override public void mouseExited(MouseEvent e) {} @Override public void keyTyped(KeyEvent e) { TreePath path = tree.getSelectionPath(); int toIndex = Character.getNumericValue(e.getKeyChar()) - 1; if (path == null || toIndex < 0 || toIndex > 8) { return; } if (path.getPathCount() == 3) { ViewState vs = (ViewState) path.getPathComponent(2); String type = (String) path.getPathComponent(1); int tindex = Arrays.asList(ViewProfile.TYPES).indexOf(type); int fromIndex = Arrays.asList(vp.states[tindex]).indexOf(vs); if (toIndex < vp.states[tindex].length) { info("swapping %s %d to %d", type, fromIndex, toIndex); vp.states[tindex][fromIndex] = vp.states[tindex][toIndex]; vp.states[tindex][toIndex] = vs; TreeModelEvent tme = new TreeModelEvent(this, new Object[]{root, type}); for (TreeModelListener l : listeners) { l.treeStructureChanged(tme); } } } } @Override public void keyPressed(KeyEvent e) {} @Override public void keyReleased(KeyEvent e) {} private void resetProfileBoxModel() { Collection<ViewProfile> set = ViewProfile.PROFILES.values(); profileComboBox.setModel(new DefaultComboBoxModel<>( set.toArray(new ViewProfile[0]))); if (set.contains(vp)) { profileComboBox.setSelectedItem(vp); } else { ViewProfile def = ViewProfile.DEFAULT_PROFILE; profileComboBox.setSelectedItem(def); } } private void profileComboBoxActionPerformed(java.awt.event.ActionEvent evt) { ViewProfile sel = (ViewProfile) profileComboBox.getSelectedItem(); if (sel == null) return; vp = sel; profileChanged(); } private void deleteAction() { if (vp == ViewProfile.DEFAULT_PROFILE) { JOptionPane.showMessageDialog(this, String.format("cannot delete default profile")); } else { ViewProfile.PROFILES.remove(vp.name); vp = ViewProfile.DEFAULT_PROFILE; resetProfileBoxModel(); profileChanged(); Events.GViewProfileSetChanged.generate(this); } } private void createAction() { String name = nameField.getText(); if (name.isEmpty() || name.equals(ViewProfile.DEFAULT_PROFILE_NAME)) { JOptionPane.showMessageDialog(this, String.format("cannot use that name: {%s}", name)); return; } vp = ViewProfile.addWithName(name); resetProfileBoxModel(); profileChanged(); Events.GViewProfileSetChanged.generate(this); } private void profileChanged() { TreeModelEvent tme = new TreeModelEvent(this, new Object[]{root}); for (TreeModelListener l : listeners) { l.treeStructureChanged(tme); } } /** * Creates new form LogToViewFrame */ public LogToViewFrame() { initComponents(); tree.setEditable(false); tree.setRootVisible(false); tree.setScrollsOnExpand(true); tree.addMouseListener(this); tree.addKeyListener(this); tree.setCellRenderer(new LTVCellRenderer()); tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); tree.setDragEnabled(false); resetProfileBoxModel(); createButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { createAction(); } }); deleteButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { deleteAction(); } }); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code"> private void initComponents() { profileComboBox = new javax.swing.JComboBox<>(); deleteButton = new javax.swing.JButton(); createButton = new javax.swing.JButton(); jScrollPane1 = new javax.swing.JScrollPane(); tree = new javax.swing.JTree(this); nameField = new javax.swing.JTextField(); profileComboBox.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { profileComboBoxActionPerformed(evt); } }); deleteButton.setText("delete this"); createButton.setText("create new"); jScrollPane1.setViewportView(tree); nameField.setText("a name"); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(jScrollPane1) .addContainerGap()) .addGroup(layout.createSequentialGroup() .addComponent(profileComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, 228, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 147, Short.MAX_VALUE) .addComponent(createButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(nameField, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 73, Short.MAX_VALUE) .addComponent(deleteButton)))) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(profileComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(deleteButton) .addComponent(createButton) .addComponent(nameField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 315, Short.MAX_VALUE) .addContainerGap()) ); pack(); }// </editor-fold> // Variables declaration - do not modify private javax.swing.JButton createButton; private javax.swing.JButton deleteButton; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTextField nameField; private javax.swing.JComboBox<ViewProfile> profileComboBox; private javax.swing.JTree tree; // End of variables declaration } }