/* * Copyright 2014 Igor Maznitsa (http://www.igormaznitsa.com). * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.igormaznitsa.prol.easygui; import com.igormaznitsa.prol.easygui.AbstractProlEditor.PropertyLink; import java.awt.*; import java.awt.event.*; import java.util.ArrayList; import javax.swing.*; import javax.swing.event.*; import javax.swing.tree.*; /** * The class implements a small dialog window contains the tree which allows * user to change values of different IDE parts because it is a very specialized * auxiliary class, it is not described very precisely * * @author Igor Maznitsa (igor.maznitsa@igormaznitsa.com) */ public class OptionsDialog extends javax.swing.JDialog implements TreeSelectionListener, TreeModel { private static final long serialVersionUID = 6189268173338687096L; private final ArrayList<TreeModel> items; private final ArrayList<TreeModelListener> treeModelListeners; private static final class TreeRenderer extends DefaultTreeCellRenderer { private static final long serialVersionUID = 4008482488500265205L; private static final Icon ICON_CLOSE = UIUtils.loadIcon("folder_wrench"); private static final Icon ICON_OPEN = UIUtils.loadIcon("folder"); private static final Icon ICON_LEAF = UIUtils.loadIcon("wrench"); @Override public Icon getLeafIcon() { return ICON_LEAF; } @Override public Icon getClosedIcon() { return ICON_CLOSE; } @Override public Icon getOpenIcon() { return ICON_OPEN; } } /** * Creates new form OptionsDialog * * @param parent * @param items */ public OptionsDialog(final java.awt.Frame parent, final TreeModel[] items) { super(parent, true); initComponents(); treeModelListeners = new ArrayList<TreeModelListener>(); this.items = new ArrayList<TreeModel>(); for (final TreeModel model : items) { this.items.add(model); } optionsTree.setModel(this); optionsTree.setCellRenderer(new TreeRenderer()); optionsTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); optionsTree.addTreeSelectionListener(this); } /** * 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">//GEN-BEGIN:initComponents private void initComponents() { jScrollPane1 = new javax.swing.JScrollPane(); optionsTree = new javax.swing.JTree(); buttonEditOption = new javax.swing.JButton(); buttonCloseDialog = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setTitle("Options"); setLocationByPlatform(true); optionsTree.setRootVisible(false); optionsTree.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { optionsTreeMouseClicked(evt); } }); jScrollPane1.setViewportView(optionsTree); buttonEditOption.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/igormaznitsa/prol/easygui/icons/cog_edit.png"))); // NOI18N buttonEditOption.setText("Edit"); buttonEditOption.setToolTipText("Edit or change the selected option"); buttonEditOption.setEnabled(false); buttonEditOption.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { buttonEditOptionActionPerformed(evt); } }); buttonCloseDialog.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/igormaznitsa/prol/easygui/icons/cross.png"))); // NOI18N buttonCloseDialog.setText("Close"); buttonCloseDialog.setToolTipText("Close the dialog"); buttonCloseDialog.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { buttonCloseDialogActionPerformed(evt); } }); 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) .addComponent(jScrollPane1) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addComponent(buttonEditOption, javax.swing.GroupLayout.PREFERRED_SIZE, 112, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(buttonCloseDialog, javax.swing.GroupLayout.PREFERRED_SIZE, 135, javax.swing.GroupLayout.PREFERRED_SIZE))) .addContainerGap()) ); layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {buttonCloseDialog, buttonEditOption}); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 349, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(buttonEditOption) .addComponent(buttonCloseDialog)) .addContainerGap()) ); pack(); }// </editor-fold>//GEN-END:initComponents private void buttonCloseDialogActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonCloseDialogActionPerformed dispose(); }//GEN-LAST:event_buttonCloseDialogActionPerformed private void buttonEditOptionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonEditOptionActionPerformed final TreePath path = optionsTree.getSelectionPath(); if (path == null) { return; } final AbstractProlEditor.PropertyLink prop = (PropertyLink) path.getLastPathComponent(); final Object val = prop.getProperty(); if (val instanceof Font) { final FontChooserDialog dialog = new FontChooserDialog(this, "Tune the font for \'" + prop.toString() + "\'", (Font) val, "?-repeat,write('Hello world'),nl,fail.\r\n:-X is 2*2,write(X)."); dialog.setVisible(true); final Font font = dialog.getResult(); if (font != null) { prop.setProperty(font); } } else if (val instanceof Color) { final Color color = (Color) val; JColorChooser chooser = new JColorChooser(color); final boolean[] array = new boolean[1]; ActionListener actionListenerOk = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { array[0] = true; } }; JDialog colorChooser = JColorChooser.createDialog(this, "Choose color for \'" + prop.toString() + "\'", true, chooser, actionListenerOk, null); colorChooser.setVisible(true); if (array[0]) { prop.setProperty(chooser.getColor()); } } else if (val instanceof Boolean) { prop.setProperty((Boolean) (!(Boolean) val)); } firePropertyChanged(path); }//GEN-LAST:event_buttonEditOptionActionPerformed private void optionsTreeMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_optionsTreeMouseClicked final JTree tree = (JTree) evt.getSource(); int selRow = tree.getRowForLocation(evt.getX(), evt.getY()); final TreePath selPath = tree.getPathForLocation(evt.getX(), evt.getY()); if (selRow != -1) { if (evt.getClickCount() == 2) { if (buttonEditOption.isEnabled()) { buttonEditOption.doClick(); } } } }//GEN-LAST:event_optionsTreeMouseClicked // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton buttonCloseDialog; private javax.swing.JButton buttonEditOption; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JTree optionsTree; // End of variables declaration//GEN-END:variables @Override public void valueChanged(final TreeSelectionEvent e) { TreePath path = optionsTree.getSelectionPath(); if (path != null) { buttonEditOption.setEnabled(path.getLastPathComponent() instanceof AbstractProlEditor.PropertyLink); return; } buttonEditOption.setEnabled(false); } @Override public Object getRoot() { return this; } @Override public Object getChild(Object parent, int index) { if (this.equals(parent)) { return items.get(index); } else { return ((TreeModel) parent).getChild(parent, index); } } @Override public int getChildCount(Object parent) { if (this.equals(parent)) { return items.size(); } else { return ((TreeModel) parent).getChildCount(parent); } } @Override public boolean isLeaf(final Object node) { return node instanceof AbstractProlEditor.PropertyLink; } @Override public void valueForPathChanged(TreePath path, Object newValue) { } @Override public int getIndexOfChild(Object parent, Object child) { if (this.equals(parent)) { return items.indexOf(child); } else { return ((TreeModel) parent).getIndexOfChild(parent, child); } } private void firePropertyChanged(TreePath path) { for (TreeModelListener listener : treeModelListeners) { listener.treeNodesChanged(new TreeModelEvent(this, path)); } } @Override public void addTreeModelListener(TreeModelListener l) { treeModelListeners.add(l); } @Override public void removeTreeModelListener(TreeModelListener l) { treeModelListeners.remove(l); } }