001    /**
002     * Copyright (C) 2007-2008, Jens Lehmann
003     *
004     * This file is part of DL-Learner.
005     * 
006     * DL-Learner is free software; you can redistribute it and/or modify
007     * it under the terms of the GNU General Public License as published by
008     * the Free Software Foundation; either version 3 of the License, or
009     * (at your option) any later version.
010     *
011     * DL-Learner is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014     * GNU General Public License for more details.
015     *
016     * You should have received a copy of the GNU General Public License
017     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
018     *
019     */
020    package org.dllearner.gui;
021    
022    import java.awt.BorderLayout;
023    import java.awt.event.ActionEvent;
024    import java.awt.event.ActionListener;
025    import java.util.LinkedList;
026    import java.util.List;
027    
028    import javax.swing.JButton;
029    import javax.swing.JComboBox;
030    import javax.swing.JPanel;
031    
032    import org.dllearner.core.Component;
033    import org.dllearner.core.KnowledgeSource;
034    import org.dllearner.core.LearningAlgorithm;
035    import org.dllearner.core.LearningProblem;
036    import org.dllearner.core.LearningProblemUnsupportedException;
037    import org.dllearner.core.ReasonerComponent;
038    
039    /**
040     * Class displaying a component (and its options).
041     * 
042     * @author Jens Lehmann
043     * 
044     */
045    public class ComponentPanel extends JPanel implements ActionListener {
046    
047            private static final long serialVersionUID = -7678275020058043937L;
048    
049            private Config config;
050            private StartGUI startGUI;
051            private List<Class<? extends Component>> selectableComponents;
052            private OptionPanel optionPanel;
053            private Class<? extends Component> panelClass;
054            private Component currentComponent;
055    
056            // GUI elements
057            private JButton clearButton;
058            private JComboBox comboBox = new JComboBox();
059    
060            /**
061             * Calls this(config, startGUI, panelClass, defaultComponent,null).
062             * 
063             * @param config
064             *            See main constructor.
065             * @param startGUI
066             *            See main constructor.
067             * @param panelClass
068             *            See main constructor.
069             * @param defaultComponent
070             *            See main constructor.
071             */
072            ComponentPanel(final Config config, StartGUI startGUI, Class<? extends Component> panelClass,
073                            Class<? extends Component> defaultComponent) {
074                    this(config, startGUI, panelClass, defaultComponent, null);
075            }
076    
077            /**
078             * Constructs a panel for configuring a component.
079             * 
080             * @param config
081             *            Central configuration handler.
082             * @param startGUI
083             *            Central GUI class.
084             * @param panelClass
085             *            Class of this panel, e.g. one of KnowledgeSource.class,
086             *            ReasonerComponent.class, ...
087             * @param defaultComponent
088             *            The default component, e.g. OWLFile.class.
089             * @param ignoredComponents
090             *            Components of DL-Learner, which should not be displayed.
091             */
092            ComponentPanel(final Config config, StartGUI startGUI, Class<? extends Component> panelClass,
093                            Class<? extends Component> defaultComponent,
094                            List<Class<? extends Component>> ignoredComponents) {
095                    super(new BorderLayout());
096    
097                    this.config = config;
098                    this.startGUI = startGUI;
099                    this.panelClass = panelClass;
100    
101                    // get all classes of the correct type
102                    selectableComponents = new LinkedList<Class<? extends Component>>();
103                    if (panelClass == KnowledgeSource.class) {
104                            selectableComponents.addAll(config.getComponentManager().getKnowledgeSources());
105                    } else if (panelClass == ReasonerComponent.class) {
106                            selectableComponents.addAll(config.getComponentManager().getReasonerComponents());
107                    } else if (panelClass == LearningProblem.class) {
108                            selectableComponents.addAll(config.getComponentManager().getLearningProblems());
109                    } else if (panelClass == LearningAlgorithm.class) {
110                            selectableComponents.addAll(config.getComponentManager().getLearningAlgorithms());
111                    }
112    
113                    // set default component class (move it to first position)
114                    selectableComponents.remove(defaultComponent);
115                    selectableComponents.add(0, defaultComponent);
116    
117                    // remove ignored component classes
118                    if (ignoredComponents != null) {
119                            selectableComponents.removeAll(ignoredComponents);
120                    }
121    
122                    // create combo box
123                    for (int i = 0; i < selectableComponents.size(); i++) {
124                            comboBox.addItem(config.getComponentManager().getComponentName(
125                                            selectableComponents.get(i)));
126                            // comboBox.addItem(selectableComponents.get(i));
127                    }
128                    comboBox.addActionListener(this);
129    
130                    clearButton = new JButton("Reset to Default Values");
131                    clearButton.addActionListener(this);
132    
133                    // create upper panel
134                    JPanel choosePanel = new JPanel();
135                    choosePanel.add(comboBox);
136                    // choosePanel.add(new JLabel(" "));
137                    choosePanel.add(clearButton);
138    
139                    // we create a new default component
140                    currentComponent = newInstance(defaultComponent);
141                    optionPanel = new OptionPanel(config, currentComponent);
142    
143                    add(choosePanel, BorderLayout.NORTH);
144                    add(optionPanel, BorderLayout.CENTER);
145    
146            }
147    
148            @Override
149            public void actionPerformed(ActionEvent e) {
150                    if (e.getSource() == comboBox) {
151                            // change component and update option panel
152                            Class<? extends Component> c = selectableComponents.get(comboBox.getSelectedIndex());
153                            currentComponent = changeInstance(c);
154                            updateOptionPanel();
155                            // if the component does not have mandatory values, we can
156                            // enable the following tabs
157                            config.enableComponentsIfPossible();
158                            startGUI.updateTabs();
159                    } else if (e.getSource() == clearButton) {
160                            // clearing everything corresponds to changing to an unconfigured
161                            // component of the same type
162                            currentComponent = changeInstance(currentComponent.getClass());
163                            updateOptionPanel();
164                    }
165            }
166    
167            /**
168             * Update according to (possibly changed) config.
169             */
170            public void update() {
171                    // detect current component
172                    if (panelClass == KnowledgeSource.class) {
173                            currentComponent = config.getKnowledgeSource();
174                    } else if (panelClass == ReasonerComponent.class) {
175                            currentComponent = config.getReasoner();
176                    } else if (panelClass == LearningProblem.class) {
177                            currentComponent = config.getLearningProblem();
178                    } else if (panelClass == LearningAlgorithm.class) {
179                            currentComponent = config.getLearningAlgorithm();
180                    }
181                    // select component without sending an event;
182                    // we need to disable events send by JComboBox
183                    comboBox.removeActionListener(this);
184                    String val = config.getComponentManager().getComponentName(currentComponent.getClass());
185                    comboBox.setSelectedItem(val);
186                    comboBox.addActionListener(this);
187    
188                    // update option panel accordingly
189                    updateOptionPanel();
190            }
191    
192            /**
193             * Updates the option panel.
194             */
195            public void updateOptionPanel() {
196                    optionPanel.rebuild(currentComponent);
197            }
198    
199            /**
200             * Method performing actions when panel is activated.
201             */
202            public void panelActivated() {
203                    // hook method, which does nothing yet
204            }
205    
206            // creates an instance of the specified component class
207            @SuppressWarnings("unchecked")
208            private Component newInstance(Class<? extends Component> clazz) {
209                    Component newComponent = null;
210                    if (KnowledgeSource.class.isAssignableFrom(clazz)) {
211                            newComponent = config.newKnowledgeSource((Class<KnowledgeSource>) clazz);
212                    } else if (ReasonerComponent.class.isAssignableFrom(clazz)) {
213                            newComponent = config.newReasoner((Class<ReasonerComponent>) clazz);
214                    } else if (LearningProblem.class.isAssignableFrom(clazz)) {
215                            newComponent = config.newLearningProblem((Class<LearningProblem>) clazz);
216                    } else if (LearningAlgorithm.class.isAssignableFrom(clazz)) {
217                            try {
218                                    newComponent = config.newLearningAlgorithm((Class<LearningAlgorithm>) clazz);
219                            } catch (LearningProblemUnsupportedException e) {
220                                    // TODO status message
221                                    e.printStackTrace();
222                            }
223                    }
224                    return newComponent;
225            }
226    
227            // changes current component to an instance of the specified class
228            @SuppressWarnings("unchecked")
229            private Component changeInstance(Class<? extends Component> clazz) {
230                    Component newComponent = null;
231                    if (KnowledgeSource.class.isAssignableFrom(clazz)) {
232                            newComponent = config.changeKnowledgeSource((Class<KnowledgeSource>) clazz);
233                    } else if (ReasonerComponent.class.isAssignableFrom(clazz)) {
234                            newComponent = config.changeReasoner((Class<ReasonerComponent>) clazz);
235                    } else if (LearningProblem.class.isAssignableFrom(clazz)) {
236                            newComponent = config.changeLearningProblem((Class<LearningProblem>) clazz);
237                    } else if (LearningAlgorithm.class.isAssignableFrom(clazz)) {
238                            try {
239                                    newComponent = config.changeLearningAlgorithm((Class<LearningAlgorithm>) clazz);
240                            } catch (LearningProblemUnsupportedException e) {
241                                    // TODO status message
242                                    e.printStackTrace();
243                            }
244                    }
245                    return newComponent;
246            }
247    
248            /**
249             * @return the currentComponent
250             */
251            public Component getCurrentComponent() {
252                    return currentComponent;
253            }
254    
255    }