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 }