/** * Copyright (C) 2007-2009, Jens Lehmann * * This file is part of DL-Learner. * * DL-Learner 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 3 of the License, or * (at your option) any later version. * * DL-Learner 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, see <http://www.gnu.org/licenses/>. * */ package org.dllearner.tools.protege; import static org.semanticweb.owlapi.model.AxiomType.DATA_PROPERTY_DOMAIN; import static org.semanticweb.owlapi.model.AxiomType.EQUIVALENT_CLASSES; import static org.semanticweb.owlapi.model.AxiomType.OBJECT_PROPERTY_DOMAIN; import static org.semanticweb.owlapi.model.AxiomType.OBJECT_PROPERTY_RANGE; import static org.semanticweb.owlapi.model.AxiomType.SUBCLASS_OF; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionListener; import java.net.URL; import java.util.ArrayList; import java.util.List; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextPane; import javax.swing.JToggleButton; import org.dllearner.core.EvaluatedAxiom; import org.dllearner.core.EvaluatedDescription; import org.dllearner.tools.protege.ActionHandler.Actions; import org.protege.editor.owl.OWLEditorKit; import org.semanticweb.owlapi.model.AxiomType; import org.semanticweb.owlapi.model.OWLAxiom; import org.semanticweb.owlapi.model.OWLDataPropertyDomainAxiom; import org.semanticweb.owlapi.model.OWLEntity; import org.semanticweb.owlapi.model.OWLObjectPropertyDomainAxiom; import org.semanticweb.owlapi.model.OWLObjectPropertyRangeAxiom; /** * This class is responsible for the view of the dllearner. It renders the * output for the user and is the graphical component of the plugin. * * @author Christian Koetteritzsch * */ public class DLLearnerView extends JPanel{ private static final long serialVersionUID = 624829578325729385L; //TODO: gucken wie geht private HyperLinkHandler hyperHandler; // this is the Component which shows the view of the dllearner private JComponent learner; // Accept button to add the learned concept to the owl private JButton addButton; // Runbutton to start the learning algorithm private JButton runButton; // This is the label for the advanced button. private JLabel advancedLabel; // Advanced Button to activate/deactivate the example select panel private JToggleButton advancedButton; // Action Handler that manages the Button actions private ActionHandler actionHandler; // Panel for the suggested concepts private SuggestClassPanel sugPanel; // Selection panel for the positive and negative examples private OptionPanel optionsPanel; // Picture for the advanced button when it is not toggled private ImageIcon icon; // Picture of the advanced button when it is toggled private JTextPane wikiPane; private ImageIcon toggledIcon; private ImageIcon helpIcon; private JTextPane hint; private JButton helpButton; private JPanel advancedPanel; private JPanel hintPanel; private boolean isInconsistent; // This is the Panel for more details of the suggested concept private MoreDetailForSuggestedConceptsPanel detail; private OWLEditorKit editorKit; private JScrollPane learnerScroll; private static final int SCROLL_SPEED = 10; private static final int SCROLL_WIDTH = 600; private static final int SCROLL_HEIGHT = 400; private boolean toogled = false; private SuggestClassPanelHandler sugPanelHandler; private StatusBar statusBar; public static final String HELP_BUTTON_STRING = "help"; public static final String ADD_BUTTON_STRING = "<html>Add</html>"; public static final String ADVANCED_BUTTON_STRING = "Advanced"; private static final String WIKI_STRING = "<html><font size=\"3\">See <a href=\"http://dl-learner.org/community/protege-plugin/\">DL-Learner plugin page</a> for an introduction.</font></html>"; private AxiomType axiomType; private String topicLabel; private OWLEntity entity; public DLLearnerView(OWLEditorKit editorKit, OWLEntity entity, AxiomType axiomType) { this.editorKit = editorKit; this.entity = entity; this.axiomType = axiomType; createUI(); } /** * This method returns the SuggestClassPanel. * @return SuggestClassPanel */ public SuggestClassPanel getSuggestClassPanel() { return sugPanel; } /** * This method returns the PosAndNegSelectPanel. * @return PosAndNegSelectPanel */ public OptionPanel getOptionsPanel() { return optionsPanel; } private void createUI(){ setLayout(new GridBagLayout()); GridBagConstraints c = new GridBagConstraints(); hyperHandler = new HyperLinkHandler(); actionHandler = new ActionHandler(this); learnerScroll = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); learnerScroll.setPreferredSize(new Dimension(SCROLL_WIDTH, SCROLL_HEIGHT)); learnerScroll.getVerticalScrollBar().setUnitIncrement(SCROLL_SPEED); JPanel addButtonPanel = new JPanel(new BorderLayout()); addButton = new JButton("<html>Add</html>"); addButton.setPreferredSize(new Dimension(70, 40)); addButton.setEnabled(false); addButton.setToolTipText("Add selected class expressions to current ontology."); c.gridx = 2; c.gridy = 1; c.weightx = 0.0; c.weighty = 0.0; c.gridwidth = 1; addButtonPanel.add("North", addButton); add(addButtonPanel, c); JPanel runButtonPanel = new JPanel(new FlowLayout()); runButton = new JButton(); runButton.setPreferredSize(new Dimension(260, 30)); runButton.setEnabled(false); runButton.setToolTipText("Start the learning algorithm."); runButtonPanel.add(BorderLayout.WEST, runButton); wikiPane = new JTextPane(); wikiPane.setContentType("text/html"); wikiPane.setBackground(learnerScroll.getBackground()); wikiPane.setEditable(false); wikiPane.setText(WIKI_STRING); wikiPane.addHyperlinkListener(hyperHandler); runButtonPanel.add(BorderLayout.EAST, wikiPane); c.anchor = GridBagConstraints.FIRST_LINE_START; c.gridx = 0; c.weightx = 0.0; c.weighty = 0.0; c.gridy = 0; c.gridwidth = 3; add(runButtonPanel, c); sugPanel = new SuggestClassPanel(editorKit); sugPanelHandler = new SuggestClassPanelHandler(this); sugPanel.getSuggestionsTable().getSelectionModel().addListSelectionListener(sugPanelHandler); c.fill = GridBagConstraints.BOTH; c.gridx = 0; c.gridy = 1; c.weightx = 1.0; c.weighty = 1.0; c.gridwidth = 2; add(sugPanel, c); statusBar = new StatusBar(); statusBar.setBackground(learnerScroll.getBackground()); showStatusBar(false); c.fill = GridBagConstraints.WEST; c.weightx = 0.0; c.weighty = 0.0; c.gridx = 0; c.gridy = 2; add(statusBar, c); hintPanel = new JPanel(new FlowLayout()); hint = new JTextPane(); hint.setBackground(learnerScroll.getBackground()); hint.setContentType("text/html"); hint.setEditable(false); hintPanel.add(BorderLayout.CENTER, hint); URL helpIconUrl = this.getClass().getResource("Help-16x16.png"); helpIcon = new ImageIcon(helpIconUrl); helpButton = new JButton(helpIcon); helpButton.setName("help"); helpButton.addActionListener(actionHandler); helpButton.setPreferredSize(new Dimension(30, 30)); helpButton.setVisible(false); hintPanel.add(BorderLayout.EAST, helpButton); c.fill = GridBagConstraints.BOTH; c.weightx = 0.0; c.weighty = 0.0; c.gridx = 0; c.gridy = 3; add(hintPanel, c); detail = new MoreDetailForSuggestedConceptsPanel(editorKit); // detail.unsetPanel(); detail.setVisible(false); c.fill = GridBagConstraints.VERTICAL; c.gridx = 0; c.gridy = 4; c.weightx = 0.0; c.weighty = 0.0; add(detail, c); advancedPanel = new JPanel(); URL iconUrl = this.getClass().getResource("arrow.gif"); icon = new ImageIcon(iconUrl); URL toggledIconUrl = this.getClass().getResource("arrow2.gif"); toggledIcon = new ImageIcon(toggledIconUrl); advancedLabel = new JLabel("<html>Advanced Settings</html>"); advancedPanel.add(advancedLabel); advancedButton = new JToggleButton(icon); advancedButton.setName("Advanced"); advancedButton.setIcon(icon); advancedButton.setSelected(false); advancedButton.setVisible(true); advancedButton.setSize(20, 20); advancedPanel.add(advancedButton); c.fill = GridBagConstraints.NONE; c.gridx = 0; c.weightx = 0.0; c.weighty = 0.0; c.gridy = 5; add(advancedPanel, c); optionsPanel = new OptionPanel(); optionsPanel.setVisible(false); c.fill = GridBagConstraints.BOTH; c.gridx = 0; c.gridy = 6; c.weightx = 0.0; c.weighty = 0.0; c.gridwidth = 3; add(optionsPanel, c); this.addAcceptButtonListener(this.actionHandler); this.addRunButtonListener(this.actionHandler); this.addAdvancedButtonListener(this.actionHandler); learnerScroll.setViewportView(this); } public void reset(){ // get the topic this view is 'talinking' about topicLabel = null; if(axiomType.equals(EQUIVALENT_CLASSES)) { topicLabel = "equivalent class expressions"; } else if(axiomType.equals(SUBCLASS_OF)) { topicLabel = "superclass expressions"; } else if(axiomType.equals(OBJECT_PROPERTY_DOMAIN)) { topicLabel = "object property domains"; } else if(axiomType.equals(OBJECT_PROPERTY_RANGE)) { topicLabel = "object property ranges"; } else if(axiomType.equals(DATA_PROPERTY_DOMAIN)) { topicLabel = "data property domains"; } // update label of run button runButton.setText("<html>suggest " + topicLabel + "</html>"); runButton.setActionCommand(Actions.LEARN.toString()); sugPanel.getSuggestionsTable().clear(); showGraphicalPanel(false); setHintMessage(""); setHelpButtonVisible(false); } public JComponent getView(){ return learnerScroll; } /** * This method sets the right icon for the advanced Panel. * @param toggled boolean */ public void setIconToggled(boolean toggled) { this.toogled = toggled; if (this.toogled) { advancedButton.setIcon(toggledIcon); // learnerPanel.setPreferredSize(new Dimension(WIDTH, OPTION_HEIGHT)); // learnerScroll.setPreferredSize(new Dimension(SCROLL_WIDTH, SCROLL_HEIGHT)); } if (!this.toogled) { advancedButton.setIcon(icon); // learnerPanel.setPreferredSize(new Dimension(WIDTH, HEIGHT)); // learnerScroll.setPreferredSize(new Dimension(SCROLL_WIDTH, SCROLL_HEIGHT)); } } /** * @return the axiomType */ public AxiomType getAxiomType() { return axiomType; } /** * @return the entity */ public OWLEntity getEntity() { return entity; } /** * This method sets the status bar visible when learning * is started. */ public void showStatusBar(boolean show) { statusBar.setVisible(show); } public void showGraphicalPanel(boolean show){ detail.setVisible(show); } /** * This Method changes the hint message. * @param message String hintmessage */ public void setHintMessage(String message) { hint.setText(message); } /** * This method returns the hint panel. * @return hint panel */ public JTextPane getHintPanel() { return hint; } /** * Sets the panel to select/deselect the examples visible/invisible. * @param visible boolean */ public void showOptionsPanel(boolean show) { optionsPanel.setVisible(show); } public void showHintMessagePanel(boolean show){ hintPanel.setVisible(show); } /** * Returns the AddButton. * @return JButton */ public JButton getAddButton() { return addButton; } /** * This method unsets all results after closing the plugin. */ public void dispose() throws Exception{ this.unsetEverything(); sugPanel.getSuggestionsTable().clear(); learner.removeAll(); sugPanel = null; } /** * Destroys everything in the view after the plugin is closed. */ public void unsetEverything() { runButton.setEnabled(true); learner.removeAll(); } /** * This Method returns the panel for more details for the chosen concept. * @return MoreDetailForSuggestedConceptsPanel */ public MoreDetailForSuggestedConceptsPanel getGraphicalPanel() { return detail; } public void setLearningEnabled(){ runButton.setEnabled(true); setHintMessage("<html><font size=\"3\">To get suggestions for " + topicLabel + "," + " please click the button above.</font></html>"); } public void showNoInstancesMessage() { String message = "<html><font size=\"3\" color=\"red\">There is no instance data for " + editorKit.getModelManager().getRendering(entity) + " available. Please insert some data first.</font></html>"; setHintMessage(message); } /** * This method sets if ontology is inconsistent or not. * @param isIncon boolean if ontology is consistent */ public void setIsInconsistent(boolean isIncon) { this.isInconsistent = isIncon; } /** * This method returns if the ontology is inconsistent. * @return boolean if ontology is inconsistent */ public boolean getIsInconsistent() { return isInconsistent; } /** * Adds Actionlistener to the run button. * @param a ActionListener */ public void addRunButtonListener(ActionListener a) { runButton.addActionListener(a); } /** * Adds Actionlistener to the add button. * @param a ActionListener */ public void addAcceptButtonListener(ActionListener a) { addButton.addActionListener(a); } /** * Adds Actionlistener to the advanced button. * @param a ActionListener */ public void addAdvancedButtonListener(ActionListener a) { advancedButton.addActionListener(a); } /** * This method sets the run button enable after learning. */ public void showAlgorithmTerminatedMessage() { this.showStatusBar(false); String message = "<html><font size=\"3\" color=\"black\">Learning successful. "; if(axiomType.equals(EQUIVALENT_CLASSES) || axiomType.equals(SUBCLASS_OF)) { message += "All expressions up to length " + (Manager.getInstance().getMinimumHorizontalExpansion()-1) + " and some expressions up to <br>length " + Manager.getInstance().getMaximumHorizontalExpansion() + " searched."; } hint.setForeground(Color.RED); if(isInconsistent) { message +="<font size=\"3\" color=\"red\"><br>Class expressions marked red will lead to an inconsistent ontology. <br>Please click on them to view detail information.</font></html>"; } else { message +="<br>To view details about why a class expression was suggested, please click on it.</font><html>"; } runButton.setEnabled(true); this.setHintMessage(message); } /** * This method returns the view of the plugin. * @return Plugin view */ public JComponent getLearnerView() { return learnerScroll; } /** * This method sets the help button visible. * @param isVisible boolean if help button is visible */ public void setHelpButtonVisible(boolean isVisible) { helpButton.setVisible(isVisible); } /** * This method returns the statusbar. * @return statusbar */ public StatusBar getStatusBar() { return statusBar; } public HyperLinkHandler getHyperLinkHandler() { return hyperHandler; } public void setBusy(boolean busy){ if(busy){ getLearnerView().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); } else { getLearnerView().setCursor(Cursor.getDefaultCursor()); } } public void setBusyTaskStarted(String taskName){ setBusy(true); setHelpButtonVisible(true); showStatusBar(true); statusBar.showProgress(true); statusBar.setMessage(taskName); } public void setBusyTaskEnded(){ setBusy(false); setHelpButtonVisible(false); showStatusBar(false); statusBar.showProgress(false); statusBar.setMessage(""); } public void setLearningStarted(){ setBusy(true); setHelpButtonVisible(true); showStatusBar(true); runButton.setEnabled(false); statusBar.setMaximumValue(Manager.getInstance().getMaxExecutionTimeInSeconds() * 2); statusBar.setMessage("Learning ..."); } public void setLearningFinished(){ statusBar.setProgress(0); setBusy(false); showAlgorithmTerminatedMessage(); } public void setRunButtonEnabled(boolean enabled){ runButton.setEnabled(enabled); } public void showHorizontalExpansionMessage(int min, int max){ StringBuffer sb = new StringBuffer(); sb.append("<html><font size=\"3\">Currently searching class expressions with length between "); sb.append(min); sb.append(" and "); sb.append(max); sb.append(".</font></html>"); setHintMessage(sb.toString()); } public void setSuggestions(List<? extends EvaluatedDescription> suggestions){ sugPanel.setSuggestions(suggestions); } public void showAxioms(List<EvaluatedAxiom<OWLAxiom>> evaluatedAxioms){ // currently we just convert axioms to descriptions List<EvaluatedDescription> evaluatedDescriptions = new ArrayList<EvaluatedDescription>(evaluatedAxioms.size()); for (EvaluatedAxiom<OWLAxiom> evaluatedAxiom : evaluatedAxioms) { if(axiomType.equals(OBJECT_PROPERTY_DOMAIN)) { evaluatedDescriptions.add( new EvaluatedDescription( ((OWLObjectPropertyDomainAxiom)evaluatedAxiom.getAxiom()).getDomain(), evaluatedAxiom.getScore())); } else if(axiomType.equals(OBJECT_PROPERTY_RANGE)) { evaluatedDescriptions.add( new EvaluatedDescription( ((OWLObjectPropertyRangeAxiom)evaluatedAxiom.getAxiom()).getRange(), evaluatedAxiom.getScore())); } else if(axiomType.equals(DATA_PROPERTY_DOMAIN)) { evaluatedDescriptions.add( new EvaluatedDescription( ((OWLDataPropertyDomainAxiom)evaluatedAxiom.getAxiom()).getDomain(), evaluatedAxiom.getScore())); } } sugPanel.setSuggestions(evaluatedDescriptions); } }