jace/src/main/java/jace/config/ConfigurationPanel.java

281 lines
12 KiB
Java

/*
* 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")
// <editor-fold defaultstate="collapsed" desc="Generated Code">//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)
);
}// </editor-fold>//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("<html><i>" + 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;
}
}