From e716f9e63a654e51bc1c47143cd00d71e98be1c2 Mon Sep 17 00:00:00 2001
From: shendaras <shendaras>
Date: Sat, 10 Apr 2004 11:55:25 +0000
Subject: [PATCH] format (shendaras)

---
 installer/java/src/CliInstall.java |  75 +++--
 installer/java/src/FetchSeeds.java | 111 +++---
 installer/java/src/GUIInstall.java | 521 +++++++++++++++--------------
 3 files changed, 363 insertions(+), 344 deletions(-)

diff --git a/installer/java/src/CliInstall.java b/installer/java/src/CliInstall.java
index ed976194d1..81c8271e3e 100644
--- a/installer/java/src/CliInstall.java
+++ b/installer/java/src/CliInstall.java
@@ -1,3 +1,5 @@
+
+
 import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStreamReader;
@@ -7,64 +9,63 @@ public class CliInstall extends Install {
 
     private BufferedReader _in;
     private PrintStream _out;
-    
+
     public CliInstall() {
-	_out = System.out;
-	_in = new BufferedReader(new InputStreamReader(System.in));
+        _out = System.out;
+        _in = new BufferedReader(new InputStreamReader(System.in));
     }
 
     public void showStatus(String s) {
-	_out.println(s);
+        _out.println(s);
     }
-    
+
     public void showOptError(String s) {
-	_out.println(s);
+        _out.println(s);
     }
 
     public void handleOptInfo(String s) {
-	_out.println(s);
+        _out.println(s);
     }
 
     public void startOptCategory(String s) {
-	_out.println("* "+s+"\n");
+        _out.println("* " + s + "\n");
     }
 
-    public void finishOptions() {}
+    public void finishOptions() {
+    }
 
-    public void handleOption(int number, String question,
-			     String def, String type) {
-	Object value;
-	while(true) {
-	    String answer;
-	    _out.print(question+(def == null?"": (" ["+def+"]"))+": ");
-	    answer = readLine();
-	    if ("".equals(answer) && def != null) {
-		answer = def;
-	    }
-	    if (setOption(number,answer)) break;
-	}
+    public void handleOption(int number, String question, String def, String type) {
+        Object value;
+        while (true) {
+            String answer;
+            _out.print(question + (def == null ? "" : (" [" + def + "]")) + ": ");
+            answer = readLine();
+            if ("".equals(answer) && def != null) {
+                answer = def;
+            }
+            if (setOption(number, answer)) break;
+        }
     }
 
     public boolean confirmOption(String question, boolean defaultYes) {
-	_out.print(question);
-	return readBool(defaultYes);
+        _out.print(question);
+        return readBool(defaultYes);
     }
 
     private String readLine() {
-	try {
-	    return _in.readLine().trim();
-	} catch (IOException ex) {
-	    ex.printStackTrace();
-	    System.exit(1);
-	    return null;
-	}
+        try {
+            return _in.readLine().trim();
+        } catch (IOException ex) {
+            ex.printStackTrace();
+            System.exit(1);
+            return null;
+        }
     }
-    
+
     private boolean readBool(boolean defaultYes) {
-	String str = readLine().toLowerCase();
-	if ("".equals(str)) return defaultYes;
-	return "yes".equals(str) || "y".equals(str) || "true".equals(str)
-	    || "ok".equals(str) || "sure".equals(str)
-	    || "whatever".equals(str);
+        String str = readLine().toLowerCase();
+        if ("".equals(str)) return defaultYes;
+        return "yes".equals(str) || "y".equals(str) || "true".equals(str) || "ok".equals(str) || "sure".equals(str)
+               || "whatever".equals(str);
     }
-}
+}
\ No newline at end of file
diff --git a/installer/java/src/FetchSeeds.java b/installer/java/src/FetchSeeds.java
index 122f5e7e06..b716dabb20 100644
--- a/installer/java/src/FetchSeeds.java
+++ b/installer/java/src/FetchSeeds.java
@@ -28,66 +28,67 @@ public class FetchSeeds {
      * @return whether new seed nodes could be fetched
      */
     public static boolean fetchSeeds(File destination, String sourceURL) {
-	InputStream in = null;
-	try {
-	    URL source = new URL(sourceURL);
-	    URLConnection con = source.openConnection();
-	    in = con.getInputStream();
-	    BufferedReader br = new BufferedReader
-		(new InputStreamReader(in)); 
-	    String line;
-	    while ((line = br.readLine())!= null) {
-		int pos = line.indexOf(" <a href=\"routerInfo-");
-		if (pos == -1) continue;
-		line=line.substring(pos+10);
-		pos=line.indexOf("\"");
-		if (pos == -1) continue;
-		line=line.substring(0,pos);
-		fetchFile(new File(destination, line), sourceURL+line);
-		System.out.println(line);	
-	    }
-	    br.close();
-	    return true;
-	} catch (IOException ex) {
-	    System.err.println("Unable to fetch seeds from " + sourceURL + ": " + ex.getMessage());
-	    //ex.printStackTrace();
-	    return false;
-	} finally {
-	    if (in != null) try { in.close(); } catch (IOException ioe) {}
-	}
+        InputStream in = null;
+        try {
+            URL source = new URL(sourceURL);
+            URLConnection con = source.openConnection();
+            in = con.getInputStream();
+            BufferedReader br = new BufferedReader(new InputStreamReader(in));
+            String line;
+            while ((line = br.readLine()) != null) {
+                int pos = line.indexOf(" <a href=\"routerInfo-");
+                if (pos == -1) continue;
+                line = line.substring(pos + 10);
+                pos = line.indexOf("\"");
+                if (pos == -1) continue;
+                line = line.substring(0, pos);
+                fetchFile(new File(destination, line), sourceURL + line);
+                System.out.println(line);
+            }
+            br.close();
+            return true;
+        } catch (IOException ex) {
+            System.err.println("Unable to fetch seeds from " + sourceURL + ": " + ex.getMessage());
+            //ex.printStackTrace();
+            return false;
+        } finally {
+            if (in != null) try {
+                in.close();
+            } catch (IOException ioe) {
+            }
+        }
     }
 
-    public static void fetchFile(File destFile, String fileURL)
-	throws IOException {
-	URL url = new URL(fileURL);
-	InputStream in = url.openStream();
-	OutputStream out = new FileOutputStream(destFile);
-	byte[] buf = new byte[1024];
-	int len;
-	while ((len=in.read(buf)) != -1) {
-	    out.write(buf,0,len);
-	}
-	in.close();
-	out.flush();
-	out.close();
+    public static void fetchFile(File destFile, String fileURL) throws IOException {
+        URL url = new URL(fileURL);
+        InputStream in = url.openStream();
+        OutputStream out = new FileOutputStream(destFile);
+        byte[] buf = new byte[1024];
+        int len;
+        while ((len = in.read(buf)) != -1) {
+            out.write(buf, 0, len);
+        }
+        in.close();
+        out.flush();
+        out.close();
     }
 
     /**
      * test main method.
      */
-    public static void  main(String[] args) {
-	switch (args.length) {
-	    case 1:
-		fetchSeeds(new File(args[0]), "http://i2p.dnsalias.net/i2pdb/");
-		return;
-	    case 2:
-		fetchSeeds(new File(args[0]), args[1]);
-		return;
-	    default: 
-		System.out.println("Usage: FetchSeeds <outDir>");
-		System.out.println("    or FetchSeeds <outDir> <seedURL>");
-		System.out.println("The default seedURL is http://i2p.dnsalias.net/i2pdb/");
-		return;
-	}
+    public static void main(String[] args) {
+        switch (args.length) {
+        case 1:
+            fetchSeeds(new File(args[0]), "http://i2p.dnsalias.net/i2pdb/");
+            return;
+        case 2:
+            fetchSeeds(new File(args[0]), args[1]);
+            return;
+        default:
+            System.out.println("Usage: FetchSeeds <outDir>");
+            System.out.println("    or FetchSeeds <outDir> <seedURL>");
+            System.out.println("The default seedURL is http://i2p.dnsalias.net/i2pdb/");
+            return;
+        }
     }
-}
+}
\ No newline at end of file
diff --git a/installer/java/src/GUIInstall.java b/installer/java/src/GUIInstall.java
index b5fb872409..368a049ea7 100644
--- a/installer/java/src/GUIInstall.java
+++ b/installer/java/src/GUIInstall.java
@@ -1,3 +1,5 @@
+
+
 import java.awt.BorderLayout;
 import java.awt.Button;
 import java.awt.CardLayout;
@@ -24,315 +26,330 @@ import java.util.StringTokenizer;
 
 public class GUIInstall extends Install {
 
-    static final GridBagConstraints gbcLeft=new GridBagConstraints();
-    static final GridBagConstraints gbcRight=new GridBagConstraints();
-    static final GridBagConstraints gbcBottom=new GridBagConstraints();
+    static final GridBagConstraints gbcLeft = new GridBagConstraints();
+    static final GridBagConstraints gbcRight = new GridBagConstraints();
+    static final GridBagConstraints gbcBottom = new GridBagConstraints();
     static {
-	gbcLeft.anchor=GridBagConstraints.EAST;
-	gbcRight.fill=GridBagConstraints.HORIZONTAL;
-	gbcRight.gridwidth=GridBagConstraints.REMAINDER;
-	gbcRight.weightx=1.0;
-	gbcBottom.weighty=1.0;
-	gbcBottom.gridwidth=GridBagConstraints.REMAINDER;
-	gbcBottom.fill=GridBagConstraints.BOTH;
-	gbcBottom.insets=new Insets(4,4,4,4);
+        gbcLeft.anchor = GridBagConstraints.EAST;
+        gbcRight.fill = GridBagConstraints.HORIZONTAL;
+        gbcRight.gridwidth = GridBagConstraints.REMAINDER;
+        gbcRight.weightx = 1.0;
+        gbcBottom.weighty = 1.0;
+        gbcBottom.gridwidth = GridBagConstraints.REMAINDER;
+        gbcBottom.fill = GridBagConstraints.BOTH;
+        gbcBottom.insets = new Insets(4, 4, 4, 4);
     }
 
     public static void main(String[] args) {
-	new GUIInstall().runInstall();
+        new GUIInstall().runInstall();
     }
-    
+
     private InstallFrame frame;
-    boolean installing=false;
+    boolean installing = false;
     ArrayList categories = new ArrayList();
     InstallCategory currentCategory = null;
 
     public String handleSpliceParams(String s) {
-	// any better ideas?
-	return s;
+        // any better ideas?
+        return s;
     }
 
-
     public GUIInstall() {
-	frame = new InstallFrame();
+        frame = new InstallFrame();
     }
 
     public void showStatus(String s) {
-	if (!installing)
-	    throw new RuntimeException("Not installing yet!");
-	frame.showStatus(s);
+        if (!installing) throw new RuntimeException("Not installing yet!");
+        frame.showStatus(s);
     }
-    
+
     public void showOptError(String s) {
-	frame.showOptError(s);
+        frame.showOptError(s);
     }
 
     public void handleOptInfo(String s) {
-	currentCategory.addInfo(s);
+        currentCategory.addInfo(s);
     }
 
     public void startOptCategory(String s) {
-	currentCategory = new InstallCategory();
-	categories.add(currentCategory);
+        currentCategory = new InstallCategory();
+        categories.add(currentCategory);
     }
 
     public void finishOptions() {
-	frame.startInstall(categories);
-	System.out.println("Starting install...");
+        frame.startInstall(categories);
+        System.out.println("Starting install...");
     }
 
-    public void handleOption(int number, String question,
-			     String def, String type) {
-	currentCategory.addOption(number, question, def, type);
+    public void handleOption(int number, String question, String def, String type) {
+        currentCategory.addOption(number, question, def, type);
     }
 
     public boolean confirmOption(String question, boolean defaultYes) {
-	ConfirmFrame cf = new ConfirmFrame(frame, question, defaultYes);
-	return cf.getResult();
+        ConfirmFrame cf = new ConfirmFrame(frame, question, defaultYes);
+        return cf.getResult();
     }
 
     private class ConfirmFrame extends Dialog {
-	private boolean result;
-	private ConfirmFrame(Frame parent, String msg,
-			     boolean defaultYes) {
-	    super(parent,"Installer question",true);
-	    setBackground(Color.lightGray);
-	    setLayout(new BorderLayout());
-	    TextArea ta;
-	    Panel p;
-	    Button b1, b2;
-	    add("Center", ta = new TextArea(msg, 3, 80));
-	    ta.setEditable(false);
-	    add("South", p = new Panel(new FlowLayout()));
-	    p.add(b1 = new Button("Yes"));
-	    p.add(b2 = new Button("No"));
-	    ActionListener al = new ActionListener() {
-		    public void actionPerformed(ActionEvent evt) {
-			result = evt.getActionCommand().equals("Yes");
-			ConfirmFrame.this.dispose();
-		    }
-		};
-	    b1.addActionListener(al);
-	    b2.addActionListener(al);
-	    pack();
+        private boolean result;
+
+        private ConfirmFrame(Frame parent, String msg, boolean defaultYes) {
+            super(parent, "Installer question", true);
+            setBackground(Color.lightGray);
+            setLayout(new BorderLayout());
+            TextArea ta;
+            Panel p;
+            Button b1, b2;
+            add("Center", ta = new TextArea(msg, 3, 80));
+            ta.setEditable(false);
+            add("South", p = new Panel(new FlowLayout()));
+            p.add(b1 = new Button("Yes"));
+            p.add(b2 = new Button("No"));
+            ActionListener al = new ActionListener() {
+                public void actionPerformed(ActionEvent evt) {
+                    result = evt.getActionCommand().equals("Yes");
+                    ConfirmFrame.this.dispose();
+                }
+            };
+            b1.addActionListener(al);
+            b2.addActionListener(al);
+            pack();
 
             // java 1.4
-	    //setLocationRelativeTo(parent);
-	    show();
-	    (defaultYes?b1:b2).requestFocus();
-	}
-
-	private boolean getResult() {
-	    return result;
-	}
+            //setLocationRelativeTo(parent);
+            show();
+            (defaultYes ? b1 : b2).requestFocus();
+        }
+
+        private boolean getResult() {
+            return result;
+        }
     }
 
     private class InstallCategory extends ArrayList {
-	public void addInfo(String s) {
-	    add(new InfoOption(s));
-	}
-
-	public void addOption(int number, String question,
-			      String def, String type) {
-	    add(new RealOption(number, question, def, type));
-	}
+        public void addInfo(String s) {
+            add(new InfoOption(s));
+        }
+
+        public void addOption(int number, String question, String def, String type) {
+            add(new RealOption(number, question, def, type));
+        }
     }
 
     private interface InstallOption {
-	public Component getComponent1();
-	public Component getComponent2();
-	public boolean setValue();
-	public String getQuestion();
+        public Component getComponent1();
+
+        public Component getComponent2();
+
+        public boolean setValue();
+
+        public String getQuestion();
     }
-    
+
     private class InfoOption extends Panel implements InstallOption {
 
-	public InfoOption(String s) {
-	    super(new GridLayout(0,1,0,0));
-	    for(StringTokenizer st = new StringTokenizer(s,"\n");
-		st.hasMoreTokens();) {
-		add(new Label(st.nextToken()));
-	    }
-	}
-	public Component getComponent1() { return null;}
-	public Component getComponent2() { return this;}
-	public boolean setValue() {return true;}
-	public String getQuestion() { return "<no question>";}
+        public InfoOption(String s) {
+            super(new GridLayout(0, 1, 0, 0));
+            for (StringTokenizer st = new StringTokenizer(s, "\n"); st.hasMoreTokens();) {
+                add(new Label(st.nextToken()));
+            }
+        }
+
+        public Component getComponent1() {
+            return null;
+        }
+
+        public Component getComponent2() {
+            return this;
+        }
+
+        public boolean setValue() {
+            return true;
+        }
+
+        public String getQuestion() {
+            return "<no question>";
+        }
     }
 
     private class RealOption implements InstallOption {
 
-	private int number;
-	private String def, question;
-	private Label l;
-	private TextField t;
-	
-	public RealOption(int number, String question,
-			  String def, String type) {
-	    this.number = number;
-	    l = new Label(question);
-	    t = new TextField(def);
-	    this.def=def;
-	    this.question=question;
-	    // type is not needed yet
-	}
-
-	public void reset() {t.setText(def);}
-
-	public String getQuestion() { return question; }
-
-	public boolean setValue() {
-	    return GUIInstall.this.setOption(number, t.getText());
-	}
-	
-	public Component getComponent1() { return l;}
-	public Component getComponent2() { return t;}
-	
+        private int number;
+        private String def, question;
+        private Label l;
+        private TextField t;
+
+        public RealOption(int number, String question, String def, String type) {
+            this.number = number;
+            l = new Label(question);
+            t = new TextField(def);
+            this.def = def;
+            this.question = question;
+            // type is not needed yet
+        }
+
+        public void reset() {
+            t.setText(def);
+        }
+
+        public String getQuestion() {
+            return question;
+        }
+
+        public boolean setValue() {
+            return GUIInstall.this.setOption(number, t.getText());
+        }
+
+        public Component getComponent1() {
+            return l;
+        }
+
+        public Component getComponent2() {
+            return t;
+        }
+
     }
 
     private class InstallFrame extends Frame {
 
-	private int current = -1;
-	private Panel cats;
-	private CardLayout cl;
-	private boolean windowOpen = true;
-	private TextArea log;
-		
-	public InstallFrame() {
-	    super("I2P Installer");
-	    setBackground(Color.lightGray);
-	    Panel p;
-	    Button b;
-	    setLayout(new BorderLayout());
-	    add("Center", cats = new Panel(cl = new CardLayout()));
-	    cats.add("Start", p= new Panel(new BorderLayout()));
-	    p.add("Center", new Label("Loading installer..."));
-	    cats.add("Install", p= new Panel(new BorderLayout()));
-	    p.add("Center", log=new TextArea("Installing...\n\n"));
-	    log.setEditable(false);
-	    add("South", p = new Panel(new FlowLayout()));
-	    p.add(b = new Button("<< Back"));
-	    b.addActionListener(new ActionListener() {
-		    public void actionPerformed(ActionEvent evt) {
-			if (current > 0) {
-			    current --;
-			    cl.show(cats,""+current);
-			}
-		    }
-		});
-	    p.add(b = new Button("Next >>"));
-	    b.addActionListener(new ActionListener() {
-		    public void actionPerformed(ActionEvent evt) {
-			if (current != -1) {
-			    if (!saveCurrent()) return;
-			    current ++;
-			    if (current == categoryPanels.length) {
-				cl.show(cats,"Install");
-				current = -1;
-				synchronized(InstallFrame.this) {
-				    installing=true;
-				    windowOpen=false;
-				    InstallFrame.this.notify();
-				}
-			    } else {
-				cl.show(cats,""+current);
-			    }
-			}
-		    }
-		});
-	    p.add(b = new Button("Quit"));
-	    b.addActionListener(new ActionListener() {
-		    public void actionPerformed(ActionEvent evt) {
-			System.exit(0);
-		    }
-		});
-	    addWindowListener(new WindowAdapter() {
-		    public void windowClosing(WindowEvent evt) {
-			System.exit(0);
-		    }
-		});
-	    setSize(600,450);
+        private int current = -1;
+        private Panel cats;
+        private CardLayout cl;
+        private boolean windowOpen = true;
+        private TextArea log;
+
+        public InstallFrame() {
+            super("I2P Installer");
+            setBackground(Color.lightGray);
+            Panel p;
+            Button b;
+            setLayout(new BorderLayout());
+            add("Center", cats = new Panel(cl = new CardLayout()));
+            cats.add("Start", p = new Panel(new BorderLayout()));
+            p.add("Center", new Label("Loading installer..."));
+            cats.add("Install", p = new Panel(new BorderLayout()));
+            p.add("Center", log = new TextArea("Installing...\n\n"));
+            log.setEditable(false);
+            add("South", p = new Panel(new FlowLayout()));
+            p.add(b = new Button("<< Back"));
+            b.addActionListener(new ActionListener() {
+                public void actionPerformed(ActionEvent evt) {
+                    if (current > 0) {
+                        current--;
+                        cl.show(cats, "" + current);
+                    }
+                }
+            });
+            p.add(b = new Button("Next >>"));
+            b.addActionListener(new ActionListener() {
+                public void actionPerformed(ActionEvent evt) {
+                    if (current != -1) {
+                        if (!saveCurrent()) return;
+                        current++;
+                        if (current == categoryPanels.length) {
+                            cl.show(cats, "Install");
+                            current = -1;
+                            synchronized (InstallFrame.this) {
+                                installing = true;
+                                windowOpen = false;
+                                InstallFrame.this.notify();
+                            }
+                        } else {
+                            cl.show(cats, "" + current);
+                        }
+                    }
+                }
+            });
+            p.add(b = new Button("Quit"));
+            b.addActionListener(new ActionListener() {
+                public void actionPerformed(ActionEvent evt) {
+                    System.exit(0);
+                }
+            });
+            addWindowListener(new WindowAdapter() {
+                public void windowClosing(WindowEvent evt) {
+                    System.exit(0);
+                }
+            });
+            setSize(600, 450);
 
             // java 1.4
-	    //setLocationRelativeTo(null);
-	    show();
-	}
-
-	public void showStatus(String s) {
-	    log.append(s+"\n");
-	}
-	public void showOptError(String s) {
-	    if (current == -1) throw new RuntimeException("No options here!");
-	    categoryPanels[current].showError(s);
-	}
-
-	private CategoryPanel[] categoryPanels;
-	
-	public void startInstall(ArrayList categories) {
-	    Panel p;
-	    categoryPanels = new CategoryPanel[categories.size()];
-	    //build a panel for each category
-	    Iterator it = categories.iterator();
-	    for (int i=0; it.hasNext(); i++) {
-		cats.add(""+i, categoryPanels[i] =
-			 new CategoryPanel((InstallCategory)it.next()));
-	    }
-	    current = 0;
-	    cl.show(cats,"0");
-	    // wait till config is complete
-	    synchronized(this) {
-		while(windowOpen) {
-		    try {
-			wait();
-		    } catch (InterruptedException ex) {
-			ex.printStackTrace();
-		    }
-		}
-	    }
-	}
-
-	private boolean saveCurrent() {
-	    return categoryPanels[current].saveOptions();
-	}
+            //setLocationRelativeTo(null);
+            show();
+        }
+
+        public void showStatus(String s) {
+            log.append(s + "\n");
+        }
+
+        public void showOptError(String s) {
+            if (current == -1) throw new RuntimeException("No options here!");
+            categoryPanels[current].showError(s);
+        }
+
+        private CategoryPanel[] categoryPanels;
+
+        public void startInstall(ArrayList categories) {
+            Panel p;
+            categoryPanels = new CategoryPanel[categories.size()];
+            //build a panel for each category
+            Iterator it = categories.iterator();
+            for (int i = 0; it.hasNext(); i++) {
+                cats.add("" + i, categoryPanels[i] = new CategoryPanel((InstallCategory) it.next()));
+            }
+            current = 0;
+            cl.show(cats, "0");
+            // wait till config is complete
+            synchronized (this) {
+                while (windowOpen) {
+                    try {
+                        wait();
+                    } catch (InterruptedException ex) {
+                        ex.printStackTrace();
+                    }
+                }
+            }
+        }
+
+        private boolean saveCurrent() {
+            return categoryPanels[current].saveOptions();
+        }
     }
-	    
+
     private class CategoryPanel extends Panel {
 
-	private TextArea errorBox;
-	private InstallCategory ic;
-	
-	public CategoryPanel(InstallCategory ic) {
-	    super(new GridBagLayout());
-	    this.ic=ic;
-	    for (Iterator it = ic.iterator(); it.hasNext();) {
-		InstallOption io = (InstallOption) it.next();
-		Component c1 = io.getComponent1(),
-		    c2 = io.getComponent2();
-		if (c1 != null) add(c1, gbcLeft);
-		add(c2, gbcRight);
-	    }
-	    add (errorBox = new TextArea(), gbcBottom);
-	    errorBox.setEditable(false);
-	}
-
-	private InstallOption currentOption;
-	public boolean saveOptions() {
-	    errorBox.setText("Saving options...\n\n");
-	    for (Iterator it = ic.iterator(); it.hasNext();) {
-		InstallOption io = (InstallOption) it.next();
-		currentOption=io;
-		if (!io.setValue()) return false;
-		currentOption= null;
-	    }
-	    return true;
-	}
-
-	public void showError(String s) {
-	    if (currentOption==null) {
-		throw new RuntimeException("No option to test");
-	    }
-	    errorBox.append("While setting \""+currentOption.getQuestion()+
-			    "\":\n"+s+"\n\n");
-	}
+        private TextArea errorBox;
+        private InstallCategory ic;
+
+        public CategoryPanel(InstallCategory ic) {
+            super(new GridBagLayout());
+            this.ic = ic;
+            for (Iterator it = ic.iterator(); it.hasNext();) {
+                InstallOption io = (InstallOption) it.next();
+                Component c1 = io.getComponent1(), c2 = io.getComponent2();
+                if (c1 != null) add(c1, gbcLeft);
+                add(c2, gbcRight);
+            }
+            add(errorBox = new TextArea(), gbcBottom);
+            errorBox.setEditable(false);
+        }
+
+        private InstallOption currentOption;
+
+        public boolean saveOptions() {
+            errorBox.setText("Saving options...\n\n");
+            for (Iterator it = ic.iterator(); it.hasNext();) {
+                InstallOption io = (InstallOption) it.next();
+                currentOption = io;
+                if (!io.setValue()) return false;
+                currentOption = null;
+            }
+            return true;
+        }
+
+        public void showError(String s) {
+            if (currentOption == null) { throw new RuntimeException("No option to test"); }
+            errorBox.append("While setting \"" + currentOption.getQuestion() + "\":\n" + s + "\n\n");
+        }
     }
-}
+}
\ No newline at end of file
-- 
GitLab