/* * Copyright (C) 2012 Brendan Robert (BLuRry) brendan.robert@gmail.com. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA */ package jace.config; import jace.apple2e.Apple2e; import jace.config.Configuration.ConfigNode; import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.io.File; import java.lang.reflect.Field; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JTextField; import javax.swing.JTree; /** * Configuration user interface. Not pretty but it works. * Created on Dec 16, 2010, 3:23:13 PM * @author Brendan Robert (BLuRry) brendan.robert@gmail.com */ public class ConfigurationPanel extends javax.swing.JPanel { public static void main(String... args) { new Apple2e(); Apple2e.getComputer().reconfigure(); Configuration.loadSettings(); JFrame f = new JFrame(); f.setContentPane(new ConfigurationPanel()); f.setSize(f.getContentPane().getPreferredSize()); f.validate(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } /** Creates new form ConfigurationPanel */ public ConfigurationPanel() { initComponents(); expandAll(configTree); } /** 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") // //GEN-BEGIN:initComponents private void initComponents() { configTreeScrollPane = new javax.swing.JScrollPane(); configTree = new javax.swing.JTree(); settingsPanel = new javax.swing.JPanel(); applyButton = new javax.swing.JButton(); saveButton = new javax.swing.JButton(); revertButton = new javax.swing.JButton(); setPreferredSize(new java.awt.Dimension(650, 480)); configTree.setModel(new Configuration.ConfigTreeModel()); configTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() { public void valueChanged(javax.swing.event.TreeSelectionEvent evt) { configTreeValueChanged(evt); } }); configTreeScrollPane.setViewportView(configTree); settingsPanel.setAlignmentX(0.0F); settingsPanel.setAlignmentY(0.0F); settingsPanel.setPreferredSize(new java.awt.Dimension(375, 480)); settingsPanel.setLayout(new java.awt.GridBagLayout()); applyButton.setText("Apply"); applyButton.setToolTipText("Apply current changes without saving"); applyButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { applyButtonActionPerformed(evt); } }); saveButton.setText("Save"); saveButton.setToolTipText("Apply settings and save"); saveButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { saveButtonActionPerformed(evt); } }); revertButton.setText("Revert"); revertButton.setToolTipText("Revert all settings to last saved values (hold SHIFT while clicking to revert to defaults)"); revertButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { revertButtonActionPerformed(evt); } }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(applyButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(saveButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(revertButton)) .addComponent(configTreeScrollPane, javax.swing.GroupLayout.PREFERRED_SIZE, 271, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(settingsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 438, Short.MAX_VALUE)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(configTreeScrollPane) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(applyButton) .addComponent(saveButton) .addComponent(revertButton)) .addContainerGap()) .addComponent(settingsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 0, Short.MAX_VALUE) ); }// //GEN-END:initComponents ConfigNode currentNode = null; private void configTreeValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_configTreeValueChanged settingsPanel.removeAll(); ConfigNode node = (ConfigNode) evt.getPath().getLastPathComponent(); if (currentNode == node) return; currentNode = node; if (node != null && node.subject != null && !node.getAllSettingNames().isEmpty()) { GridBagLayout l = (GridBagLayout) settingsPanel.getLayout(); GridBagConstraints c = new GridBagConstraints(); int y = 0; for (String s : node.getAllSettingNames()) { try { Field f = node.subject.getClass().getField(s); ConfigurableField annotation = f.getAnnotation(ConfigurableField.class); if (annotation == null) continue; JLabel label = new JLabel(annotation.name()); c.anchor = GridBagConstraints.FIRST_LINE_START; c.fill = GridBagConstraints.HORIZONTAL; c.gridwidth = 1; c.gridy = y++; c.gridx = 0; c.weightx = 0.0; c.insets = new Insets(2, 2, 2, 2); c.ipady = 2; settingsPanel.add(label,c); Component edit = generateEditComponent(node, s); edit.setSize(edit.getPreferredSize()); c.gridx = 1; c.weightx = 0.5; c.ipady = 0; c.insets = new Insets(0, 2, 2, 2); c.gridwidth = GridBagConstraints.REMAINDER; settingsPanel.add(edit,c); if (!annotation.description().equals("")) { c.gridy = y++; c.gridx = 0; c.gridwidth = 2; c.weightx = 0.0; JLabel desc = new JLabel("" + annotation.description()); c.insets = new Insets(1, 15, 7, 5); settingsPanel.add(desc, c); } } catch (NoSuchFieldException ex) { Logger.getLogger(ConfigurationPanel.class.getName()).log(Level.SEVERE, null, ex); } catch (SecurityException ex) { Logger.getLogger(ConfigurationPanel.class.getName()).log(Level.SEVERE, null, ex); } } } settingsPanel.validate(); settingsPanel.setVisible(true); settingsPanel.repaint(); }//GEN-LAST:event_configTreeValueChanged private void applyButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_applyButtonActionPerformed Configuration.applySettings(Configuration.BASE); configTree.updateUI(); expandAll(configTree); }//GEN-LAST:event_applyButtonActionPerformed private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed Configuration.saveSettings(); configTree.updateUI(); expandAll(configTree); }//GEN-LAST:event_saveButtonActionPerformed private void revertButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_revertButtonActionPerformed if ((evt.getModifiers() & evt.SHIFT_MASK) != 0) { revertDefaultsActionPerformed(evt); return; } Configuration.loadSettings(); configTree.updateUI(); expandAll(configTree); }//GEN-LAST:event_revertButtonActionPerformed private void revertDefaultsActionPerformed(java.awt.event.ActionEvent evt) { if (JOptionPane.showConfirmDialog(null, "Revert all settings to defaults?", "Revert to defaults?", JOptionPane.YES_NO_OPTION) != JOptionPane.YES_OPTION) return; Configuration.resetToDefaults(); } // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton applyButton; private javax.swing.JTree configTree; private javax.swing.JScrollPane configTreeScrollPane; private javax.swing.JButton revertButton; private javax.swing.JButton saveButton; private javax.swing.JPanel settingsPanel; // End of variables declaration//GEN-END:variables public void expandAll(JTree tree) { for (int row = 0; row < tree.getRowCount(); tree.expandRow(row++)); } private Component generateEditComponent(ConfigNode node, String s) { try { Field f = node.subject.getClass().getField(s); if (f.getType().isPrimitive()) { if (f.getType().equals(Boolean.TYPE)) { return new BooleanComponent(node, s); } else if (f.getType().equals(Integer.TYPE)) { return new IntegerComponent(node, s); } else if (f.getType().equals(Short.TYPE)) { return new IntegerComponent(node, s); } else if (f.getType().equals(Byte.TYPE)) { return new IntegerComponent(node, s); } else if (f.getType().equals(Long.TYPE)) { return new IntegerComponent(node, s); } else { return new StringComponent(node, s); } } else if (f.getType().equals(String.class)) { return new StringComponent(node, s); } else if (f.getType().equals(File.class)) { return new FileComponent(node, s); } else if (Class.class.isEnum()) { // TODO: Add enumeration support! } else if (ISelection.class.isAssignableFrom(f.getType())) { return new DynamicSelectComponent(node, s); } return new JTextField(); } catch (NoSuchFieldException ex) { Logger.getLogger(ConfigurationPanel.class.getName()).log(Level.SEVERE, null, ex); } catch (SecurityException ex) { Logger.getLogger(ConfigurationPanel.class.getName()).log(Level.SEVERE, null, ex); } return null; } }