/******************************************************************************* * Copyright (C) 2009-2011 Amir Hassan <amir@viel-zu.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ******************************************************************************/ package org.wooden.component; import java.awt.Color; import java.awt.Container; import java.awt.FlowLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.util.HashMap; import java.util.Vector; import javax.swing.AbstractButton; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSpinner; import javax.swing.JTextField; import javax.swing.filechooser.FileFilter; import javax.swing.text.JTextComponent; import org.wooden.util.Configuration; import org.wooden.util.StringTool; // Referenced classes of package org.wooden.component: // LayoutPane, FileSelector, ErrorDialog, ConfigurationChooser public abstract class ConfigurationPane extends LayoutPane implements ActionListener { private GridBagLayout layout; private JPanel actionContainer; private Box containers; private Box textfieldContainer; private Box lableContainer; private Box buttonContainer; private JButton commit; private JButton cancel; private JLabel status; private JMenuBar menuBar; private JMenu menuDatei; private JMenu menuRecent; private JMenuItem itemNew; private JMenuItem itemOpen; private JMenuItem itemSaveAs; private JMenuItem itemSave; private JMenuItem itemExit; private Object query_lock; private HashMap filequeries; private HashMap observedComponents; private FileFilter menufilter; private Configuration conf; private Vector recent; private File recentConfigurations; private boolean autoContinue; private boolean waiting; public ConfigurationPane() { this.layout = new GridBagLayout(); this.actionContainer = new JPanel(); this.containers = new Box(0); this.textfieldContainer = new Box(1); this.lableContainer = new Box(1); this.buttonContainer = new Box(1); this.commit = new JButton(); this.cancel = new JButton(); this.status = new JLabel(); this.menuBar = new JMenuBar(); this.menuDatei = new JMenu("Konfiguration"); this.menuRecent = new JMenu("Zuletzt ge\uFFFDffnet"); this.itemNew = new JMenuItem(); this.itemOpen = new JMenuItem(); this.itemSaveAs = new JMenuItem(); this.itemSave = new JMenuItem(); this.itemExit = new JMenuItem(); this.query_lock = new Object(); this.filequeries = new HashMap(); this.observedComponents = new HashMap(); this.recentConfigurations = new File("recent"); this.waiting = false; } public ConfigurationPane(File defaults) throws IOException { this(defaults, true); } public ConfigurationPane(File defaults, boolean autocontinuation) throws IOException { this.layout = new GridBagLayout(); this.actionContainer = new JPanel(); this.containers = new Box(0); this.textfieldContainer = new Box(1); this.lableContainer = new Box(1); this.buttonContainer = new Box(1); this.commit = new JButton(); this.cancel = new JButton(); this.status = new JLabel(); this.menuBar = new JMenuBar(); this.menuDatei = new JMenu("Konfiguration"); this.menuRecent = new JMenu("Zuletzt ge\uFFFDffnet"); this.itemNew = new JMenuItem(); this.itemOpen = new JMenuItem(); this.itemSaveAs = new JMenuItem(); this.itemSave = new JMenuItem(); this.itemExit = new JMenuItem(); this.query_lock = new Object(); this.filequeries = new HashMap(); this.observedComponents = new HashMap(); this.recentConfigurations = new File("recent"); this.waiting = false; this.recent = this.loadRecent(); this.updateRecent(); this.autoContinue = autocontinuation; if (defaults != null) this.conf = new Configuration(defaults); else this.conf = new Configuration(); try { this.jbInit(); } catch (Exception ex) { ex.printStackTrace(); } this.checkForContinuation(); this.addComponentListener(new LayoutPane.ResizeAdapter()); } @Override public void actionPerformed(ActionEvent e) { synchronized (this.query_lock) { Object src = e.getSource(); if (src instanceof JButton) { JButton b = (JButton) src; if (b == this.commit) this.applyConfiguration(); else this.exit(); if (this.waiting) this.query_lock.notifyAll(); } else if (src instanceof JMenuItem) { JMenuItem item = (JMenuItem) src; if (item == this.itemNew) this.new_dialog(); if (item == this.itemOpen) try { this.open_dialog(); } catch (Exception ex) { (new ErrorDialog("Couldn't open configuration", ex)).open(false); } else if (item == this.itemSaveAs) try { this.save_dialog(); } catch (Exception ex) { (new ErrorDialog("Couldn't save configuration", ex)).open(false); } else if (item == this.itemSave) try { this.saveConfiguration(true); } catch (Exception ex) { (new ErrorDialog("Couldn't save configuration", ex)).open(false); } else if (item == this.itemExit) this.exit(); else try { File c = new File(item.getText()); if (c.exists()) this.openConfiguration(c); else throw new IOException((new StringBuilder("File not found: ")) .append(c.getAbsolutePath()).toString()); } catch (IOException ex1) { this.setStatus(ex1.getMessage()); } } } } public void addCustomActionButton(JButton btn, int pos) { this.actionContainer.add(btn, pos); } public void addFileSelector(String name, File defaultPath) { this.addFileSelector(name, defaultPath, null); } public void addFileSelector(String name, File defaultPath, FileFilter filter) { FileSelector fq = new FileSelector(name, defaultPath, filter, this); this.filequeries.put(name, fq); this.lableContainer.add(fq.label()); this.textfieldContainer.add(fq.textfield()); this.buttonContainer.add(fq.button()); this.updateLayout(); } @Override public LayoutPane addLayoutComponent(String name, JComponent cmp, int line) { return this.addLayoutComponent(name, cmp, line, true); } public LayoutPane addLayoutComponent(String name, JComponent cmp, int line, boolean observeData) { if (observeData) this.observedComponents.put(name, cmp); return super.addLayoutComponent(name, cmp, line); } public LayoutPane addLayoutComponent(String name, JComponent cmp, int line, double weightx, double weighty, boolean observeData) { if (observeData) this.observedComponents.put(name, cmp); return super.addLayoutComponent(name, cmp, line, weightx, weighty); } public LayoutPane addLayoutComponent(String name, JComponent cmp, int line, GridBagConstraints constraints, boolean observeData) { if (observeData) this.observedComponents.put(name, cmp); return super.addLayoutComponent(name, cmp, line, constraints); } private void addRecent(File f) throws IOException { String name = f.getAbsolutePath(); if (!this.recent.contains(name)) { if (this.recent.size() == 5) this.recent.remove(4); this.recent.add(name); this.saveRecent(); } } public void allowContinuation(boolean allow) { this.commit.setEnabled(allow); } public void applyConfiguration() { FileSelector arrFileQueries[] = (FileSelector[]) this.filequeries.values() .toArray(new FileSelector[0]); String arrCustomKeys[] = (String[]) this.observedComponents.keySet() .toArray(new String[0]); for (FileSelector arrFileQuerie : arrFileQueries) this.conf.putProperty(arrFileQuerie.name(), arrFileQuerie.textfield() .getText()); for (String arrCustomKey : arrCustomKeys) { String text = this.gatherText((JComponent) this.observedComponents .get(arrCustomKey)); if (text != null) this.conf.putProperty(arrCustomKey, text); } } public void checkForContinuation() { if (!this.autoContinue) return; try { this.applyConfiguration(); this.test(); this.allowContinuation(true); } catch (IllegalArgumentException ex) { this.allowContinuation(false); } } public void close(boolean save) throws IOException { if (save) this.saveConfiguration(true); this.setVisible(false); } private void exit() { System.exit(0); } public void fillForm() { FileSelector arrFileQueries[] = (FileSelector[]) this.filequeries.values() .toArray(new FileSelector[0]); String arrCustomKeys[] = (String[]) this.observedComponents.keySet() .toArray(new String[0]); for (FileSelector arrFileQuerie : arrFileQueries) arrFileQuerie.textfield().setText( StringTool.eliminateNull(this.conf.getString(arrFileQuerie.name(), false))); for (String arrCustomKey : arrCustomKeys) this.setText((JComponent) this.observedComponents.get(arrCustomKey), StringTool.eliminateNull(this.conf.getString(arrCustomKey, false))); } private String gatherText(JComponent cmp) { if (cmp instanceof JTextComponent) return ((JTextComponent) cmp).getText(); if (cmp instanceof JLabel) return ((JLabel) cmp).getText(); if (cmp instanceof JSpinner) return ((JSpinner) cmp).getValue().toString(); if (cmp instanceof AbstractButton) return ((AbstractButton) cmp).getText(); if (cmp instanceof JScrollPane) return this.gatherText((JComponent) ((JScrollPane) cmp).getViewport() .getView()); else return null; } public JButton getActionButton(int pos) { return (JButton) this.actionContainer.getComponent(pos); } public Container getActionContainer() { return this.actionContainer; } public Configuration getConfiguration() { return this.conf; } public JMenuBar getConfigurationMenuBar() { return this.menuBar; } private void jbInit() throws Exception { this.lableContainer.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 5)); this.textfieldContainer.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); this.buttonContainer.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 0)); this.status.setFont(this.commit.getFont()); this.status.setBorder(BorderFactory.createEtchedBorder()); this.status.setHorizontalAlignment(0); this.status.setHorizontalTextPosition(0); this.status.setVisible(true); this.commit.setText("OK"); this.commit.addActionListener(this); this.cancel.setText("Cancel"); this.cancel.addActionListener(this); this.actionContainer.setLayout(new FlowLayout()); this.setLayout(this.layout); this.itemNew.setText("Neu"); this.itemOpen.setText("\uFFFDffnen"); this.itemSaveAs.setText("Speichern unter"); this.itemSave.setText("Speichern"); this.itemExit.setText("Beenden"); this.containers.add(this.lableContainer); this.containers.add(this.textfieldContainer); this.containers.add(this.buttonContainer); this.actionContainer.add(this.commit); this.actionContainer.add(this.cancel); GridBagConstraints constraints = new GridBagConstraints(); constraints.gridheight = 1; constraints.gridwidth = 0; constraints.weightx = 1.0D; constraints.weighty = 0.0D; constraints.fill = 1; this.layout.addLayoutComponent(this.containers, constraints); this.layout.addLayoutComponent(this.actionContainer, constraints); this.layout.addLayoutComponent(this.status, constraints); this.add(this.containers, null); this.add(this.actionContainer, null); this.add(this.status, null); this.menuBar.add(this.menuDatei); this.itemNew.addActionListener(this); this.itemOpen.addActionListener(this); this.itemSaveAs.addActionListener(this); this.itemSave.addActionListener(this); this.itemExit.addActionListener(this); this.menuDatei.add(this.itemNew); this.menuDatei.add(this.itemOpen); this.menuDatei.add(this.itemSave); this.menuDatei.add(this.itemSaveAs); this.menuDatei.add(this.menuRecent); this.menuDatei.add(this.itemExit); this.setStatus("Configuration not set..."); this.updateLayout(); } private Vector loadRecent() throws IOException { Vector r = new Vector(); if (!this.recentConfigurations.exists()) { this.recentConfigurations.createNewFile(); } else { BufferedReader in = new BufferedReader(new FileReader( this.recentConfigurations)); String line; while ((line = in.readLine()) != null) r.add(line); in.close(); } return r; } private void new_dialog() { this.conf = new Configuration(); try { this.fillForm(); } catch (IllegalArgumentException ex) { this.setStatus(ex.getMessage()); } } private void open_dialog() throws IOException { File f = (new ConfigurationChooser(this.findRootFrame(), null, 0, this.menufilter)).open(); this.openConfiguration(f); } public void openConfiguration(File f) throws IOException { if (f != null) { this.addRecent(f); this.updateRecent(); this.conf = new Configuration(f); try { this.fillForm(); this.test(); this.setStatus("Configuration set"); } catch (IllegalArgumentException ex) { this.setStatus(ex.getMessage()); } } this.updateLayout(); } public void queryConfiguration() throws IllegalArgumentException { if (!this.isVisible()) throw new IllegalStateException("ConfigurationPane is not visible"); synchronized (this.query_lock) { this.waiting = true; try { this.query_lock.wait(); } catch (InterruptedException interruptedexception) {} this.waiting = false; } } public void removeActionButton(int pos) { this.actionContainer.remove(pos); } private void save_dialog() throws IOException { File c = this.getConfiguration().getConfigurationFile(); String actualFile; if (c == null) actualFile = (new File("./")).getAbsolutePath(); else actualFile = c.getAbsolutePath(); File f = (new ConfigurationChooser(this.findRootFrame(), new JTextField( actualFile), 1, this.menufilter)).open(); this.saveConfiguration(f, false); } public void saveConfiguration(boolean dialogOnFail) throws IOException { this.saveConfiguration(this.getConfiguration().getConfigurationFile(), dialogOnFail); } public void saveConfiguration(File f, boolean dialogOnFail) throws IOException { if (f != null) this.getConfiguration().saveConfiguration(f); else if (dialogOnFail) this.save_dialog(); } private void saveRecent() throws IOException { BufferedWriter out = new BufferedWriter(new FileWriter( this.recentConfigurations)); String arrRecent[] = (String[]) this.recent.toArray(new String[0]); for (String element : arrRecent) { out.write(element); out.newLine(); } out.close(); } public void setActionComponentColor(Color fore, Color back) { this.setRecursiveColor(this.actionContainer, fore, back); } public void setActionContainerColor(Color fore, Color back) { if (back != null) this.actionContainer.setBackground(back); if (fore != null) this.actionContainer.setForeground(fore); } public void setDefaultActionText(String commit, String abort) { this.commit.setText(commit); this.cancel.setText(abort); } public void setFileSelectorColor(Color lbl_fore, Color lbl_back, Color txt_fore, Color txt_back, Color btn_fore, Color btn_back) { FileSelector arrFileSelector[] = (FileSelector[]) this.filequeries.values() .toArray(new FileSelector[0]); for (FileSelector f : arrFileSelector) { if (btn_back != null) f.button().setBackground(btn_back); if (btn_fore != null) f.button().setForeground(btn_fore); if (lbl_back != null) f.label().setBackground(lbl_back); if (lbl_fore != null) f.label().setForeground(lbl_fore); if (txt_back != null) f.textfield().setBackground(txt_back); if (txt_fore != null) f.textfield().setForeground(txt_fore); } } public void setStatus(String message) { this.status.setText(message); this.updateLayout(); } public void setStatusColor(Color fore, Color back) { if (back != null) this.status.setBackground(back); if (fore != null) this.status.setForeground(fore); } private void setText(JComponent cmp, String text) { if (cmp instanceof JTextComponent) ((JTextComponent) cmp).setText(text); else if (cmp instanceof JLabel) ((JLabel) cmp).setText(text); else if (cmp instanceof JSpinner) ((JSpinner) cmp).setValue(text); else if (cmp instanceof AbstractButton) ((AbstractButton) cmp).setText(text); } @Override public void setVisible(boolean visible) { super.setVisible(visible); } public void showMenu(FileFilter mfilter) { this.menufilter = mfilter; } public void showStatus(boolean show) { this.status.setVisible(show); } public abstract void test() throws IllegalArgumentException; private void updateRecent() throws IOException { if (this.recent.size() > 0) { String arrRecent[] = (String[]) this.recent.toArray(new String[0]); this.menuRecent.setVisible(true); this.menuRecent.removeAll(); for (String element : arrRecent) { JMenuItem item = new JMenuItem(element); item.addActionListener(this); this.menuRecent.add(item); } } else { this.menuRecent.setVisible(false); } } }