PreferencesDialog.java
001 /* This file is part of the project "Hilbert II" - http://www.qedeq.org
002  *
003  * Copyright 2000-2013,  Michael Meyling <mime@qedeq.org>.
004  *
005  * "Hilbert II" is free software; you can redistribute
006  * it and/or modify it under the terms of the GNU General Public
007  * License as published by the Free Software Foundation; either
008  * version 2 of the License, or (at your option) any later version.
009  *
010  * This program is distributed in the hope that it will be useful,
011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013  * GNU General Public License for more details.
014  */
015 
016 package org.qedeq.gui.se.pane;
017 
018 import java.awt.Component;
019 import java.awt.Container;
020 import java.awt.Dimension;
021 import java.awt.GridLayout;
022 import java.awt.event.ActionEvent;
023 import java.awt.event.ActionListener;
024 import java.io.File;
025 import java.io.IOException;
026 
027 import javax.swing.BorderFactory;
028 import javax.swing.Box;
029 import javax.swing.BoxLayout;
030 import javax.swing.JButton;
031 import javax.swing.JCheckBox;
032 import javax.swing.JComboBox;
033 import javax.swing.JComponent;
034 import javax.swing.JDialog;
035 import javax.swing.JFileChooser;
036 import javax.swing.JFrame;
037 import javax.swing.JLabel;
038 import javax.swing.JOptionPane;
039 import javax.swing.JPanel;
040 import javax.swing.JScrollPane;
041 import javax.swing.JTabbedPane;
042 import javax.swing.JTextArea;
043 import javax.swing.JTextField;
044 import javax.swing.ScrollPaneConstants;
045 import javax.swing.filechooser.FileFilter;
046 
047 import org.qedeq.base.io.IoUtility;
048 import org.qedeq.base.trace.Trace;
049 import org.qedeq.base.utility.EqualsUtility;
050 import org.qedeq.base.utility.StringUtility;
051 import org.qedeq.gui.se.util.GuiHelper;
052 import org.qedeq.kernel.bo.KernelContext;
053 
054 import com.jgoodies.forms.builder.ButtonBarBuilder;
055 import com.jgoodies.forms.builder.DefaultFormBuilder;
056 import com.jgoodies.forms.layout.FormLayout;
057 
058 /**
059  * Configures the application.
060  *
061  @author  Michael Meyling
062  */
063 
064 public class PreferencesDialog extends JDialog {
065 
066     /** This class. */
067     private static final Class CLASS = PreferencesDialog.class;
068 
069     /** Timeout for making a TCP/IP connection. */
070     private JTextField connectionTimeoutTextField;
071 
072     /** Timeout for reading from a TCP/IP connection. */
073     private JTextField readTimeoutTextField;
074 
075     /** Automatic scroll of log pane. */
076     private JCheckBox automaticLogScrollCB;
077 
078     /** Automatic reload of all modules that were successfully checked in last session. */
079     private JCheckBox autoReloadLastSessionCheckedCB;
080 
081     /** List of icon sizes. */
082     private JComboBox iconSizeCB;
083 
084     /** Look and feel of the application. */
085     private JComboBox lookAndFeelCB;
086 
087 //    /** Response with a message box. */
088 //    private JCheckBox directResponseCB;
089 
090     /** Automatic start of default HTML browser after HTML generation. */
091     private JCheckBox autoStartHtmlBrowserCB;
092 
093     /** Enable detail trace. Detail level are configurated within the logging environment.
094      * (E.g. within log4j.xml.)*/
095     private JCheckBox traceOnCB;
096 
097     /** QEDEQ module buffer directory. */
098     private JTextArea moduleBufferTextArea;
099 
100     /** Generation directory. */
101     private JTextArea generationPathTextArea;
102 
103     /** Directory for new local modules. */
104     private JTextArea localModulesPathTextArea;
105 
106     /** HTTP proxy host.*/
107     private JTextField httpProxyHostTextField;
108 
109     /** HTTP proxy port. */
110     private JTextField httpProxyPortTextField;
111 
112     /** HTTP non proxy hosts. */
113     private JTextField httpNonProxyHostsTextField;
114 
115     /**
116      * Creates new Panel.
117      *
118      @param   parent  Parent frame.
119      */
120     public PreferencesDialog(final JFrame parent) {
121         super(parent, "Preferences");
122         final String method = "Constructor";
123         Trace.begin(CLASS, this, method);
124         try {
125             setModal(true);
126             setDefaultCloseOperation(DISPOSE_ON_CLOSE);
127             setupView();
128             updateView();
129         catch (Throwable e) {
130             Trace.fatal(CLASS, this, "Initalization of PreferencesDialog failed.", method, e);
131         finally {
132             Trace.end(CLASS, this, method);
133         }
134     }
135 
136     /**
137      * Assembles Timeout settings panel.
138      *
139      @return  Timeout settings panel.
140      */
141     private JComponent buildTimeoutPanel() {
142         FormLayout layout = new FormLayout(
143         "right:pref, 5dlu, fill:50dlu");    // columns
144 
145         DefaultFormBuilder builder = new DefaultFormBuilder(layout);
146         builder.setBorder(BorderFactory.createEmptyBorder(0000));
147         builder.getPanel().setOpaque(false);
148 
149         builder.append("Connection Timeout");
150         connectionTimeoutTextField = createTextField("" + QedeqGuiConfig.getInstance().getConnectionTimeout()true);
151         connectionTimeoutTextField.setToolTipText("Sets a specified timeout value, in milliseconds, to be used when"
152             " opening a communications link a remote QEDEQ module. If the timeout expires before the connection can"
153             " be established, an error occurs. A timeout of zero is interpreted as an infinite timeout.");
154         builder.append(connectionTimeoutTextField);
155 
156         builder.append("Read Timeout");
157         readTimeoutTextField = createTextField("" + QedeqGuiConfig.getInstance().getReadTimeout() true);
158         readTimeoutTextField.setToolTipText("Sets the read timeout to a specified timeout, in milliseconds. A"
159            " non-zero value specifies the timeout when reading from Input stream when a connection is established"
160            " to a resource. If the timeout expires before there is data available for read, an error occurs. A"
161            " timeout of zero is interpreted as an infinite timeout.");
162         builder.append(readTimeoutTextField);
163         return GuiHelper.addSpaceAndTitle(builder.getPanel()"Timeouts");
164     }
165 
166     /**
167      * Assembles proxy settings panel.
168      *
169      @return  Proxy settings panel.
170      */
171     private JComponent buildProxyPanel() {
172 
173         if (IoUtility.isWebStarted()) {
174             JPanel panel = new JPanel();
175             JTextArea label = new JTextArea("This application is webstarted. For changing the"
176                 " proxy settings see for example \"Sun Java Plugin Control Panel / General /"
177                 " Network Settings\".");
178             label.setWrapStyleWord(true);
179             label.setLineWrap(true);
180             label.setEditable(false);
181             panel.add(label);
182             panel.setLayout(new GridLayout(01));
183             JPanel withSpace = new JPanel();
184                 withSpace.add(panel);
185                 withSpace.setLayout(new GridLayout(01));
186                 JPanel withTitle = new JPanel();
187                 withTitle.setBorder(BorderFactory.createTitledBorder("Proxy Settings"));
188                 withTitle.add(withSpace);
189                 withTitle.setLayout(new GridLayout(01));
190                 return withTitle;
191         else {
192             FormLayout layout = new FormLayout(
193                 "left:pref, 5dlu, fill:pref:grow");    // columns
194 
195             DefaultFormBuilder builder = new DefaultFormBuilder(layout);
196             builder.setBorder(BorderFactory.createEmptyBorder(0000));
197             builder.getPanel().setOpaque(false);
198 
199             builder.append("HTTP proxy host");
200             httpProxyHostTextField = createTextField(QedeqGuiConfig.getInstance().getHttpProxyHost()true);
201             httpProxyHostTextField.setToolTipText("Proxy server for the http protocol.");
202             builder.append(httpProxyHostTextField);
203 
204             builder.append("HTTP proxy port");
205             httpProxyPortTextField = createTextField(QedeqGuiConfig.getInstance().getHttpProxyPort()true);
206             httpProxyPortTextField.setToolTipText("Proxy server port for the http protocol.");
207             builder.append(httpProxyPortTextField);
208 
209             builder.append("HTTP non proxy hosts");
210             httpNonProxyHostsTextField = createTextField(StringUtility.replace(QedeqGuiConfig.getInstance()
211                 .getHttpNonProxyHosts()"|"",")true);
212             builder.append(httpNonProxyHostsTextField);
213             httpNonProxyHostsTextField.setToolTipText("Lists the hosts which should be connected to directly and"
214                 " not through the proxy server. The value can be a comma separated list of hosts, and in addition"
215                 " a wildcard character (*) can be used for matching. For example: *.foo.com,localhost");
216 
217             return GuiHelper.addSpaceAndTitle(builder.getPanel()"Proxy Settings");
218         }
219     }
220 
221     /**
222      * Assembles path settings panel.
223      *
224      @return  Created panel.
225      */
226     private JComponent buildPathsPanel() {
227         FormLayout layout = new FormLayout(
228 //            "fill:200dlu:grow, 5dlu, right:pref");    // columns
229             "left:pref, fill:5dlu:grow, right:pref");    // columns
230 
231         DefaultFormBuilder builder = new DefaultFormBuilder(layout);
232         builder.setBorder(BorderFactory.createEmptyBorder(0000));
233         builder.getPanel().setOpaque(false);
234 
235         builder.append("Path for QEDEQ module file buffer");
236         moduleBufferTextArea = new JTextArea(QedeqGuiConfig.getInstance().getBufferDirectory().getPath());
237         moduleBufferTextArea.setEditable(false);
238         moduleBufferTextArea.setLineWrap(false);
239         final JButton chooseBufferLocation = new JButton("Choose");
240         builder.append(chooseBufferLocation);
241         builder.append(wrapWithScrollPane(moduleBufferTextArea)3);
242         chooseBufferLocation.setEnabled(true);
243 //        chooseBufferLocation.setBounds(33 + 600 - 90, 180 + y, 90, 21);
244         chooseBufferLocation.addActionListener(new ActionListener() {
245             public void actionPerformed(final ActionEvent actionEvent) {
246                 try {
247                     QedeqGuiConfig.getInstance().getBufferDirectory().mkdirs();
248                     JFileChooser chooser = new JFileChooser(QedeqGuiConfig.getInstance().getBufferDirectory());
249                     FileFilter filter = new FileFilter() {
250                         public boolean accept(final File f) {
251                             if (f.isDirectory()) {
252                                 return true;
253                             }
254                             return false;
255                         }
256 
257                         // description of this filter
258                         public String getDescription() {
259                             return "Directory";
260                         }
261                     };
262 
263                     chooser.setFileFilter(filter);
264                     chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
265                     final int returnVal = chooser.showOpenDialog(PreferencesDialog.this);
266 
267                     if (returnVal == JFileChooser.APPROVE_OPTION) {
268                         moduleBufferTextArea.setText(chooser.getSelectedFile().getPath());
269                     }
270                 catch (Exception e) {
271                      JOptionPane.showMessageDialog(PreferencesDialog.this, e.getMessage()"Alert",
272                      JOptionPane.ERROR_MESSAGE);
273                 }
274             }
275         });
276 
277 
278         builder.append("Path for generated files");
279         generationPathTextArea = new JTextArea(QedeqGuiConfig.getInstance().getGenerationDirectory().getPath());
280         generationPathTextArea.setEditable(false);
281         final JButton chooseGenerationLocation = new JButton("Choose");
282         builder.append(chooseGenerationLocation);
283         builder.append(wrapWithScrollPane(generationPathTextArea)3);
284         chooseGenerationLocation.setEnabled(true);
285 //        chooseGenerationLocation.setBounds(33 + 600 - 90, 250 + y, 90, 21);
286         chooseGenerationLocation.addActionListener(new  ActionListener() {
287             public void actionPerformed(final ActionEvent actionEvent) {
288                 try {
289                     QedeqGuiConfig.getInstance().getGenerationDirectory().mkdirs();
290                     JFileChooser chooser = new JFileChooser(QedeqGuiConfig.getInstance().getGenerationDirectory());
291                     FileFilter filter = new FileFilter() {
292                         public boolean accept(final File f) {
293                             if (f.isDirectory()) {
294                                 return true;
295                             }
296                             return false;
297                         }
298 
299                         // description of this filter
300                         public String getDescription() {
301                             return "Directory";
302                         }
303                     };
304                     chooser.setFileFilter(filter);
305                     chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
306                     final int returnVal = chooser.showOpenDialog(PreferencesDialog.this);
307 
308                     if (returnVal == JFileChooser.APPROVE_OPTION) {
309                         generationPathTextArea.setText(chooser.getSelectedFile().getPath());
310                     }
311                 catch (Exception e) {
312                      JOptionPane.showMessageDialog(PreferencesDialog.this, e.getMessage()"Alert",
313                      JOptionPane.ERROR_MESSAGE);
314                 }
315             }
316         });
317 
318 
319         builder.append("Path for newly created module files");
320         localModulesPathTextArea = new JTextArea(QedeqGuiConfig.getInstance().getLocalModulesDirectory().getPath());
321         localModulesPathTextArea.setEditable(false);
322         final JButton chooselocalModulesLocation = new JButton("Choose");
323         builder.append(chooselocalModulesLocation);
324         builder.append(wrapWithScrollPane(localModulesPathTextArea)3);
325         chooselocalModulesLocation.setEnabled(true);
326         chooselocalModulesLocation.addActionListener(new ActionListener() {
327             public void actionPerformed(final ActionEvent actionEvent) {
328                 try {
329                     QedeqGuiConfig.getInstance().getLocalModulesDirectory().mkdirs();
330                     JFileChooser chooser = new JFileChooser(QedeqGuiConfig.getInstance().getLocalModulesDirectory());
331                     FileFilter filter = new FileFilter() {
332                         public boolean accept(final File f) {
333                             if (f.isDirectory()) {
334                                 return true;
335                             }
336                             return false;
337                         }
338                         // description of this filter
339                         public String getDescription() {
340                             return "Directory";
341                         }
342                     };
343                     chooser.setFileFilter(filter);
344                     chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
345                     final int returnVal = chooser.showOpenDialog(PreferencesDialog.this);
346                     if (returnVal == JFileChooser.APPROVE_OPTION) {
347                         localModulesPathTextArea.setText(chooser.getSelectedFile().getPath());
348                     }
349                 catch (Exception e) {
350                      JOptionPane.showMessageDialog(PreferencesDialog.this, e.getMessage()"Alert",
351                      JOptionPane.ERROR_MESSAGE);
352                 }
353             }
354         });
355 
356         return GuiHelper.addSpaceAndTitle(builder.getPanel()"Paths");
357     }
358 
359     /**
360      * Assembles checkbox settings panel.
361      *
362      @return  Created panel.
363      */
364     private JComponent buildBinaryOptionPanel() {
365         FormLayout layout = new FormLayout(
366         "left:pref");    // columns
367 
368         DefaultFormBuilder builder = new DefaultFormBuilder(layout);
369         builder.setBorder(BorderFactory.createEmptyBorder(0000));
370         builder.getPanel().setOpaque(false);
371 
372         autoReloadLastSessionCheckedCB = new JCheckBox(" Auto loading of in last session successfully checked modules",
373             QedeqGuiConfig.getInstance().isAutoReloadLastSessionChecked());
374         builder.append(autoReloadLastSessionCheckedCB);
375 
376 //        directResponseCB = new JCheckBox(" Direct message response for actions",
377 //            QedeqGuiConfig.getInstance().isDirectResponse());
378 //        builder.append(directResponseCB);
379 
380         automaticLogScrollCB = new JCheckBox(" Automatic Scroll of Log Window",
381             QedeqGuiConfig.getInstance().isAutomaticLogScroll());
382         builder.append(automaticLogScrollCB);
383 
384         autoStartHtmlBrowserCB = new JCheckBox(" Auto start web browser after HTML generation",
385             QedeqGuiConfig.getInstance().isAutoStartHtmlBrowser());
386         builder.append(autoStartHtmlBrowserCB);
387 
388         traceOnCB = new JCheckBox(" Enable trace output generation. Must be on to configure detailed log.",
389                 QedeqGuiConfig.getInstance().isTraceOn());
390             builder.append(traceOnCB);
391 
392         return GuiHelper.addSpaceAndTitle(builder.getPanel()"Miscellaneous Switches");
393     }
394 
395     /**
396      * Assembles GUI size settings panel.
397      *
398      @return  Created panel.
399      */
400     private JComponent buildSizeOptionPanel() {
401         FormLayout layout = new FormLayout(
402         "right:pref, 5dlu, fill:50dlu");    // columns
403 
404         DefaultFormBuilder builder = new DefaultFormBuilder(layout);
405         builder.setBorder(BorderFactory.createEmptyBorder(0000));
406         builder.getPanel().setOpaque(false);
407 
408         iconSizeCB = new JComboBox(new String[]  {"16x16""22x22""32x32"});
409         iconSizeCB.setSelectedItem(QedeqGuiConfig.getInstance().getIconSize());
410         builder.append("Icon size", iconSizeCB);
411         return GuiHelper.addSpaceAndTitle(builder.getPanel()"Sizes");
412     }
413 
414     /**
415      * Assembles Look and Feel settings panel.
416      *
417      @return  Created panel.
418      */
419     private JComponent buildLookAndFeelPanel() {
420         FormLayout layout = new FormLayout(
421         "right:pref, 5dlu, fill:150dlu");    // columns
422 
423         DefaultFormBuilder builder = new DefaultFormBuilder(layout);
424         builder.setBorder(BorderFactory.createEmptyBorder(0000));
425         builder.getPanel().setOpaque(false);
426 
427         lookAndFeelCB = new JComboBox(new String[] {"PlasticXP""Plastic",
428             "Plastic3D""Windows""Metal"});
429         lookAndFeelCB.setEditable(true);
430         lookAndFeelCB.setSelectedItem(QedeqGuiConfig.getInstance().getLookAndFeel());
431         builder.append("Look & Feel", lookAndFeelCB);
432         return GuiHelper.addSpaceAndTitle(builder.getPanel()"Look and Feel");
433     }
434 
435     /**
436      * Assembles the GUI components of the panel.
437      */
438     public final void setupView() {
439         final Container content = getContentPane();
440         content.setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
441 
442         final JPanel allOptions = new JPanel();
443         allOptions.setBorder(GuiHelper.getEmptyBorder());
444         allOptions.setLayout(new BoxLayout(allOptions, BoxLayout.Y_AXIS));
445         allOptions.add(buildBinaryOptionPanel());
446         allOptions.add(Box.createVerticalStrut(GuiHelper.getEmptyBorderPixelsY()));
447         allOptions.add(buildPathsPanel());
448         allOptions.add(Box.createVerticalStrut(GuiHelper.getEmptyBorderPixelsY()));
449         allOptions.add(buildTimeoutPanel());
450         final JComponent proxyPanel = buildProxyPanel();
451         allOptions.add(Box.createVerticalStrut(GuiHelper.getEmptyBorderPixelsY()));
452         allOptions.add(buildProxyPanel());
453 
454         final JPanel graphicOptions = new JPanel();
455         graphicOptions.setBorder(GuiHelper.getEmptyBorder());
456         graphicOptions.setLayout(new BoxLayout(graphicOptions, BoxLayout.Y_AXIS));
457         graphicOptions.add(new JLabel("Most options require a restart of the application!"));
458         graphicOptions.add(buildLookAndFeelPanel());
459         graphicOptions.add(Box.createVerticalStrut(GuiHelper.getEmptyBorderPixelsY()));
460         graphicOptions.add(buildSizeOptionPanel());
461         graphicOptions.add(Box.createVerticalGlue());
462 
463         final JTabbedPane tabbedPane = new JTabbedPane();
464         tabbedPane.setOpaque(false);
465         tabbedPane.addTab("Main Options", allOptions);
466         tabbedPane.addTab("Gui Options", graphicOptions);
467 
468         content.add(tabbedPane);
469 
470         content.add(GuiHelper.addSpaceAndAlignRight(createButtonPanel()));
471 
472         // let the container calculate the ideal size
473         pack();
474 
475         final Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
476         setBounds((screenSize.width - getWidth()) 2(screenSize.height - getHeight()) 2,
477             getWidth(), getHeight() (IoUtility.isWebStarted() ? proxyPanel.getHeight()
478             20    // TODO 20101228 m31: hard coded pixel size
479             0));
480     }
481 
482     /**
483      * Create button panel.
484      *
485      @return  Main buttons.
486      */
487     private JPanel createButtonPanel() {
488         ButtonBarBuilder bbuilder = ButtonBarBuilder.createLeftToRightBuilder();
489 
490         JButton ok = new JButton("OK");
491         ok.addActionListener(new  ActionListener() {
492             public void actionPerformed(final ActionEvent actionEvent) {
493                 PreferencesDialog.this.save();
494                 PreferencesDialog.this.dispose();
495             }
496         });
497 
498         JButton cancel = new JButton("Cancel");
499         cancel.addActionListener(new  ActionListener() {
500             public void actionPerformed(final ActionEvent actionEvent) {
501                 PreferencesDialog.this.dispose();
502             }
503         });
504 
505         bbuilder.addGriddedButtons(new JButton[]{cancel, ok});
506 
507         final JPanel buttons = bbuilder.getPanel();
508         return buttons;
509     }
510 
511     /**
512      * Update from model.
513      */
514     public void updateView() {
515         invalidate();
516         repaint();
517     }
518 
519     private JTextField createTextField(final String selectedText, final boolean editable) {
520         JTextField combo = new JTextField(selectedText);
521         combo.setEditable(editable);
522         return combo;
523     }
524 
525     private Component wrapWithScrollPane(final Component c) {
526         return new JScrollPane(c,
527             ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
528             ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
529     }
530 
531     boolean changed() {
532         boolean result = false;
533         result = result || (EqualsUtility.equals(moduleBufferTextArea.getText(),
534             QedeqGuiConfig.getInstance().getBufferDirectory()));
535         result = result || (EqualsUtility.equals(generationPathTextArea.getText(),
536                 QedeqGuiConfig.getInstance().getGenerationDirectory()));
537         result = result || (EqualsUtility.equals(localModulesPathTextArea.getText(),
538                 QedeqGuiConfig.getInstance().getLocalModulesDirectory()));
539         result = result || (automaticLogScrollCB.isSelected()
540                 == QedeqGuiConfig.getInstance().isAutomaticLogScroll());
541 //        result = result || (directResponseCB.isSelected()
542 //                == QedeqGuiConfig.getInstance().isDirectResponse());
543         result = result || (autoReloadLastSessionCheckedCB.isSelected()
544                 == QedeqGuiConfig.getInstance().isAutoReloadLastSessionChecked());
545         result = result || (autoStartHtmlBrowserCB.isSelected()
546                 == QedeqGuiConfig.getInstance().isAutoStartHtmlBrowser());
547         result = result || (traceOnCB.isSelected()
548                 == QedeqGuiConfig.getInstance().isTraceOn());
549         result = result || (EqualsUtility.equals(iconSizeCB.getSelectedItem(),
550                 QedeqGuiConfig.getInstance().getIconSize()));
551         result = result || (EqualsUtility.equals(lookAndFeelCB.getSelectedItem(),
552                 QedeqGuiConfig.getInstance().getLookAndFeel()));
553         if (KernelContext.getInstance().isSetConnectionTimeOutSupported()) {
554             result = result || EqualsUtility.equals(connectionTimeoutTextField.getText(),
555                     "" + QedeqGuiConfig.getInstance().getConnectionTimeout());
556         }
557         if (KernelContext.getInstance().isSetReadTimeoutSupported()) {
558             result = result || EqualsUtility.equals(readTimeoutTextField.getText(),
559                     "" + QedeqGuiConfig.getInstance().getReadTimeout());
560         }
561         if (!IoUtility.isWebStarted()) {
562             result = result || EqualsUtility.equals(httpProxyHostTextField.getText(),
563                     QedeqGuiConfig.getInstance().getHttpProxyHost());
564             result = result || EqualsUtility.equals(httpProxyPortTextField.getText(),
565                     QedeqGuiConfig.getInstance().getHttpProxyPort());
566             result = result || EqualsUtility.equals(httpNonProxyHostsTextField.getText(),
567                     QedeqGuiConfig.getInstance().getHttpNonProxyHosts());
568         }
569         return result;
570     }
571 
572     void save() {
573         if (changed()) {
574             try {
575                 QedeqGuiConfig.getInstance().setBufferDirectory(new File(moduleBufferTextArea.getText()));
576                 QedeqGuiConfig.getInstance().setGenerationDirectory(new File(generationPathTextArea.getText()));
577                 QedeqGuiConfig.getInstance().setLocalModulesDirectory(new File(localModulesPathTextArea.getText()));
578                 QedeqGuiConfig.getInstance().setAutomaticLogScroll(automaticLogScrollCB.isSelected());
579 //                QedeqGuiConfig.getInstance().setDirectResponse(directResponseCB.isSelected());
580                 QedeqGuiConfig.getInstance().setAutoReloadLastSessionChecked(
581                     autoReloadLastSessionCheckedCB.isSelected());
582                 QedeqGuiConfig.getInstance().setAutoStartHtmlBrowser(autoStartHtmlBrowserCB.isSelected());
583                 QedeqGuiConfig.getInstance().setTraceOn(traceOnCB.isSelected());
584                 Trace.setTraceOn(traceOnCB.isSelected());   // TODO 20101122 m31: is this the correct position
585                                                             // to set this flag
586                 if (KernelContext.getInstance().isSetConnectionTimeOutSupported()) {
587                     QedeqGuiConfig.getInstance().setConnectionTimeout(Integer.parseInt(
588                         connectionTimeoutTextField.getText()));
589                 }
590                 if (KernelContext.getInstance().isSetReadTimeoutSupported()) {
591                     QedeqGuiConfig.getInstance().setReadTimeout(Integer.parseInt(readTimeoutTextField.getText()));
592                 }
593                 if (!IoUtility.isWebStarted()) {
594                     QedeqGuiConfig.getInstance().setHttpProxyHost(httpProxyHostTextField.getText().trim());
595                     QedeqGuiConfig.getInstance().setHttpProxyPort(httpProxyPortTextField.getText().trim());
596                     StringBuffer httpNonProxyHosts = new StringBuffer(httpNonProxyHostsTextField.getText().trim());
597                     StringUtility.replace(httpNonProxyHosts, " ""|");
598                     StringUtility.replace(httpNonProxyHosts, "\t""|");
599                     StringUtility.replace(httpNonProxyHosts, "\r""|");
600                     StringUtility.replace(httpNonProxyHosts, ",""|");
601                     StringUtility.replace(httpNonProxyHosts, ";""|");
602                     StringUtility.replace(httpNonProxyHosts, "||""|");
603                     QedeqGuiConfig.getInstance().setHttpNonProxyHosts(httpNonProxyHosts.toString());
604                 }
605                 QedeqGuiConfig.getInstance().setIconSize(String.valueOf(iconSizeCB.getSelectedItem()));
606                 QedeqGuiConfig.getInstance().setLookAndFeel(String.valueOf(lookAndFeelCB.getSelectedItem()));
607             catch (RuntimeException e) {
608                 JOptionPane.showMessageDialog(this, e.getMessage()"Error",
609                     JOptionPane.ERROR_MESSAGE);
610             }
611 
612             try {
613                 QedeqGuiConfig.getInstance().store();
614             catch (IOException e) {
615                 Trace.fatal(CLASS, this, "save""couldn't save preferences", e);
616                 JOptionPane.showMessageDialog(this, "Couldn't save preferences""Error", JOptionPane.ERROR_MESSAGE);
617             }
618         }
619     }
620 
621 }