package de.unisiegen.tpml.graphics.minimaltyping; import java.awt.Color; import java.awt.Container; import java.awt.Cursor; import java.awt.Dimension; import java.awt.FontMetrics; import java.awt.Point; import java.text.MessageFormat; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPopupMenu; import javax.swing.SwingUtilities; import de.unisiegen.tpml.core.ProofGuessException; import de.unisiegen.tpml.core.ProofNode; import de.unisiegen.tpml.core.ProofRule; import de.unisiegen.tpml.core.expressions.Identifier; import de.unisiegen.tpml.core.languages.LanguageTranslator; import de.unisiegen.tpml.core.minimaltyping.MinimalTypingProofModel; import de.unisiegen.tpml.core.minimaltyping.MinimalTypingProofNode; import de.unisiegen.tpml.core.minimaltyping.MinimalTypingTypesProofNode; import de.unisiegen.tpml.core.types.Type; import de.unisiegen.tpml.core.util.Theme; import de.unisiegen.tpml.graphics.Messages; import de.unisiegen.tpml.graphics.components.CompoundExpression; import de.unisiegen.tpml.graphics.components.LabelComponent; import de.unisiegen.tpml.graphics.components.MenuButton; import de.unisiegen.tpml.graphics.components.MenuButtonListener; import de.unisiegen.tpml.graphics.components.MenuEnterTypeItem; import de.unisiegen.tpml.graphics.components.MenuGuessItem; import de.unisiegen.tpml.graphics.components.MenuGuessTreeItem; import de.unisiegen.tpml.graphics.components.MenuRuleItem; import de.unisiegen.tpml.graphics.components.MenuTranslateItem; import de.unisiegen.tpml.graphics.components.TypeComponent; import de.unisiegen.tpml.graphics.outline.listener.OutlineMouseListener; import de.unisiegen.tpml.graphics.renderer.AbstractRenderer; import de.unisiegen.tpml.graphics.tree.TreeNodeComponent; /** * Graphical representation of a {@link MinimalTypingProofNode }.<br> * <br> * A usual look of a node may be given in the following pictur. It shows the * second node within the tree of the MinimalTyping of the Expression: * <code>let rec f = lambda x. if x = 0 then 1 else x * f (x-1) in f 3</code><br> * <img src="../../../../../../images/MinimalTypingnode.png" /><br> * <br> * This node is actualy build using 4 components. The following scheme * illustrates the layouting of the single components.<br> * <img src="../../../../../../images/MinimalTypingnode_scheme.png" /><br> * <br> * The first rectangle represents the {@link #indexLabel} The second rectanle * represents the entire {@link #compoundExpression} including the * typeenvironment. The last element in the first row is the typeLabel * containing the resulting type, it also is containing the <code>" :: "</code>. * If the node is not completly evaluated only the four dots are drawn.<br> * In the next row there is only one rectangle containing the rule. In the case * of the previous image the {@link #ruleLabel} is shown, but as long as the * node has not been evaluated with a rule there would be located the * {@link #ruleButton}.<br> * The bit of free space between the top and the bottom row aswell as between * the indexLabel and the expression is given in pixels in the {@link #spacing}. * <br> * Within the {@link MinimalTypingComponent} the * {@link de.unisiegen.tpml.graphics.renderer.TreeArrowRenderer} will be used to * draw the lines and the arrow of the tree. The TreeArrowRenderer uses * {@link TreeNodeComponent}s to located the points where the lines and the * arrow will be located. Therefore this component implements this interface. So * the method {@link #getLeftArrowConnection()} returns the point marked in red * in the scheme and the method {@link #getBottomArrowConnection()} return the * point marked in blue. Those points are absolut positions, not relative to * this component.<br> * <br> * The entire layouting or placing of the nodes of this component is done in the * method {@link #placeElements(int)}.<br> * * @author marcell * @author michael * * @see de.unisiegen.tpml.graphics.minimaltyping.MinimalTypingView * @see de.unisiegen.tpml.graphics.minimaltyping.MinimalTypingComponent * @see de.unisiegen.tpml.graphics.tree.TreeNodeComponent */ public class MinimalTypingNodeComponent extends JComponent implements TreeNodeComponent { /** * */ private static final long serialVersionUID = -6671706090992083026L; /** * The Model this node can work with to guess, enter type or do Coresyntax * transaltion */ private MinimalTypingProofModel proofModel; /** * The Origin {@link MinimalTypingProofNode} this node represents. */ private MinimalTypingProofNode proofNode; /** * The calculated dimension for this node in pixels. */ private Dimension dimension; /** * The spacing that should be set free between to components within the node. */ private int spacing; /** * The label containing the <i>(x)</i> text at the beginning. */ private JLabel indexLabel; /** * The {@link CompoundExpression} containing the expression of this node. */ private CompoundExpression < Identifier, Type > compoundExpression; /** * The first typeComponent containing the first type of this node */ private TypeComponent typeComponent; /** * The second typeComponent containing the second type of this node */ private TypeComponent typeComponent2; /** * The label component, between the two types. Means "<:" */ private LabelComponent labelComponent; /** * The label containing the "<:" */ private JLabel subTypeSymbol; /** * The Label shown between the type and the expression. It will be * " :: " */ private JLabel doubleColonLabel; /** * The String for the label */ private static final String doubleColonString = " :: "; /** * The {@link MenuButton} the user can use to do the actions. */ private MenuButton ruleButton; /*/** * The {@link JLabel} showing the resulting type of this node, once the node * has been evaluated. * private JLabel typeLabel;*/ /** * The {@link JLabel} showing the information about the rule, once the rule * has been evaluated. */ private JLabel ruleLabel; /** * The menuTranslate is one element within the menu. <br> * Needs to get handled separatly because it can be enabled and disabled * whether the expression is containing Syntactical Sugar. */ private MenuTranslateItem menuTranslateItem; /** * The translator will be used to determin whether the expression contains * syntactical sugor. */ private LanguageTranslator translator; /** * Constructor for a MinimalTypingNode<br> * <br> * All elements needed within the node will be created and added to the * component. Some of them will be hidden the {@link #ruleLabel}) because * they are not needed but they are always there.<br> * * @param node The origin ProofNode * @param model The model * @param pTranslator The translator of the model for the selected language */ public MinimalTypingNodeComponent ( MinimalTypingProofNode node, MinimalTypingProofModel model, LanguageTranslator pTranslator ) { super ( ); this.proofNode = node; this.proofModel = model; this.translator = pTranslator; this.dimension = new Dimension ( 0, 0 ); this.spacing = 10; this.subTypeSymbol = new JLabel( " " ); //$NON-NLS-1$ this.indexLabel = new JLabel ( ); this.indexLabel.addMouseListener ( new OutlineMouseListener ( this ) ); add ( this.indexLabel ); if ( this.proofNode.getEnvironment ( ) != null ) { // proofnode is an expression proof node this.compoundExpression = new CompoundExpression < Identifier, Type > ( ); this.compoundExpression.addMouseListener ( new OutlineMouseListener ( this ) ); add ( this.compoundExpression ); this.typeComponent = new TypeComponent ( ); this.typeComponent.addMouseListener ( new OutlineMouseListener ( this ) ); add ( this.typeComponent ); } else { // proof node is a type proof node //this.subtypeSymbol = " <: "; //$NON-NLS-1$ this.typeComponent = new TypeComponent ( ); this.typeComponent.addMouseListener ( new OutlineMouseListener ( this ) ); add ( this.typeComponent ); this.typeComponent.setText ( "" ); //$NON-NLS-1$ this.labelComponent = new LabelComponent ( ); add ( this.labelComponent ); this.typeComponent2 = new TypeComponent ( ); this.typeComponent2.addMouseListener ( new OutlineMouseListener ( this ) ); add ( this.typeComponent2 ); this.typeComponent2.setText ( "" ); //$NON-NLS-1$ } changeNode ( ); /* * Create both, the ruleButton for selecting the rule and the label, that * will be displayed later */ this.ruleButton = new MenuButton ( ); add ( this.ruleButton ); this.ruleButton.setVisible ( true ); this.ruleLabel = new JLabel ( ); add ( this.ruleLabel ); this.ruleLabel.setVisible ( false ); this.doubleColonLabel = new JLabel(); add(this.doubleColonLabel); this.doubleColonLabel.setFont(Theme.currentTheme().getFont()); this.doubleColonLabel.setForeground(Theme.currentTheme().getExpressionColor()); this.doubleColonLabel.setText(doubleColonString); /* * Create the PopupMenu for the menu button */ JPopupMenu menu = new JPopupMenu ( ); ProofRule[] rules = this.proofModel.getRules ( ); if ( rules.length > 0 ) { int group = rules[0].getGroup ( ); for ( ProofRule r : rules ) { if ( r.getGroup ( ) != group ) { menu.addSeparator ( ); } menu.add ( new MenuRuleItem ( r ) ); group = r.getGroup ( ); } } menu.addSeparator ( ); menu.add ( new MenuEnterTypeItem ( ) ); menu.add ( new MenuGuessItem ( ) ); menu.add ( new MenuGuessTreeItem ( ) ); menu.add ( this.menuTranslateItem = new MenuTranslateItem ( ) ); this.ruleButton.setMenu ( menu ); /* * Connect the handling of the ruleButton */ this.ruleButton.addMenuButtonListener ( new MenuButtonListener ( ) { public void menuClosed ( @SuppressWarnings ( "unused" ) MenuButton button ) { //Nothing to do } public void menuItemActivated ( @SuppressWarnings ( "unused" ) MenuButton button, final JMenuItem source ) { // setup a wait cursor for the toplevel ancestor final Container toplevel = getTopLevelAncestor ( ); final Cursor cursor = toplevel.getCursor ( ); toplevel.setCursor ( new Cursor ( Cursor.WAIT_CURSOR ) ); // avoid blocking the popup menu SwingUtilities.invokeLater ( new Runnable ( ) { @SuppressWarnings ( "synthetic-access" ) public void run ( ) { // handle the menu action MinimalTypingNodeComponent.this.handleMenuActivated ( source ); // wait for the repaint before resetting the cursor SwingUtilities.invokeLater ( new Runnable ( ) { public void run ( ) { // reset the cursor toplevel.setCursor ( cursor ); } } ); } } ); } } ); } /** * Causes the expression and the resultexpression to recalculate their layout. */ public void reset ( ) { this.compoundExpression.reset ( ); this.typeComponent.reset ( ); } /** * Sets the index that will be displayed in front of the node * * @param index The index */ public void setIndex ( int index ) { this.indexLabel.setText ( "(" + index + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ } /** * Causes the {@link #compoundExpression} to updated theire expression and * environment. */ public void changeNode ( ) { if ( this.proofNode.getEnvironment ( ) != null ) { this.compoundExpression.setExpression ( this.proofNode.getExpression ( ) ); this.compoundExpression.setEnvironment ( this.proofNode.getEnvironment ( ) ); this.typeComponent.setType ( this.proofNode.getType ( ) ); } else { MinimalTypingTypesProofNode typeNode = ( MinimalTypingTypesProofNode ) this.proofNode; this.typeComponent.setType ( typeNode.getType ( ) ); this.subTypeSymbol.setText ( "<:" ); //$NON-NLS-1$ this.labelComponent.setLabel ( this.subTypeSymbol ); this.typeComponent2.setType ( typeNode.getType2 ( ) ); } } /** * Places all elements one after another.<br> * <br> * First the label, the expression and the "::" will be placed, if the node is * already prooven the {@link #typeLabel} will be placed aswell. The * {@link #dimension} will be rescaled with every item that is placed and with * all items, the height of the dimension will set to the current maximum.<br> * <br> * When all item of the top row are placed the {@link #ruleButton}, * {@link #ruleLabel} or {@link #typeEnter} will be placed depending whether * the node is evaluated, it is not evaluated or the user previously selected * <i>Enter type</i>. * * @param maxWidth The maximum amount of pixels available to place the * elements. */ /** * Places all elements one after another.<br> * <br> * * @param pMaxWidth The maximum amount of pixels available to place the * elements. */ private void placeElements ( int pMaxWidth ) { int maxWidth = pMaxWidth; // get the size for the index at the beginning: (x) FontMetrics fm = AbstractRenderer.getTextFontMetrics ( ); Dimension labelSize = new Dimension ( fm.stringWidth ( this.indexLabel.getText ( ) ), fm.getHeight ( ) ); this.dimension.setSize ( labelSize.width, labelSize.height ); // there will be a bit spacing between the index label and the expression this.dimension.width += this.spacing; // the index shrinkens the max size for the expression maxWidth -= labelSize.width; Dimension labelComponentSize = new Dimension ( fm.stringWidth ( this.subTypeSymbol.getText ( ) ), fm.getHeight ( ) ); this.dimension.width += labelComponentSize.width + this.spacing; if ( this.proofNode.getEnvironment ( ) != null ) { // proofNode instance of expression proof node // get the needed size for the expression Dimension expSize = this.compoundExpression.getNeededSize ( maxWidth- AbstractRenderer.getTextFontMetrics().stringWidth(doubleColonString) ); this.dimension.width += expSize.width; this.dimension.width += AbstractRenderer.getTextFontMetrics().stringWidth(doubleColonString); this.dimension.height = Math.max ( expSize.height, this.dimension.height ); // get the neede size for the type Dimension typeSize = this.typeComponent.getNeededSize ( maxWidth ); this.dimension.width += typeSize.width; this.dimension.height = Math.max ( typeSize.height, this.dimension.height ); // now place the components int posX = 0; this.indexLabel.setBounds ( posX, 0, labelSize.width, this.dimension.height ); posX += labelSize.width + this.spacing; this.compoundExpression.setBounds ( posX, 0, expSize.width, this.dimension.height ); posX += expSize.width; // set the :: //this.doubleColonLabel.setBounds ( posX, AbstractRenderer.getFontLeading ( ), AbstractRenderer.getTextFontMetrics ( ).stringWidth ( doubleColonString ), expSize.height ); this.doubleColonLabel.setBounds(posX, 0, AbstractRenderer.getTextFontMetrics().stringWidth(doubleColonString), AbstractRenderer .getAbsoluteHeight()); posX += this.doubleColonLabel.getSize().width; this.typeComponent.setBounds ( posX, 0, typeSize.width, typeSize.height ); posX += typeSize.width; /* * Check whether this is node is evaluated. If it is evaluated only the * Label needs to get placed, if it is not evaluated yet the MenuButton * needs to get placed. */ posX = labelSize.width + this.spacing; if ( this.proofNode.isProven ( ) ) { // place the menu label this.ruleLabel.setText ( this.proofNode.getRule ( ).toString()); //$NON-NLS-1$ //$NON-NLS-2$ Dimension ruleLabelSize = this.ruleLabel.getPreferredSize ( ); this.ruleLabel.setBounds ( posX, this.dimension.height + this.spacing, ruleLabelSize.width, ruleLabelSize.height ); this.dimension.height += this.spacing + ruleLabelSize.height; this.dimension.width = Math.max ( this.dimension.width, ruleLabelSize.width + posX ); // display only the label not the button this.ruleLabel.setVisible ( true ); this.ruleButton.setVisible ( false ); } else { // place the menu button Dimension buttonSize = this.ruleButton.getNeededSize ( ); this.ruleButton .setBounds ( posX, this.dimension.height + this.spacing, buttonSize.width, buttonSize.height ); this.dimension.height += this.spacing + buttonSize.height; this.dimension.width = Math.max ( this.dimension.width, buttonSize.width + posX ); // display only the button not the label this.ruleLabel.setVisible ( false ); this.ruleButton.setVisible ( true ); } } else { // proofNode instance of type proof node // get the needed size for the expression Dimension expSize = this.typeComponent.getNeededSize ( maxWidth ); this.dimension.width += expSize.width; this.dimension.height = Math.max ( expSize.height, this.dimension.height ); // the result should never be wrapped so we use // the Integer.MAX_VALUE to prevent linewrapping Dimension resultSize = this.typeComponent2.getNeededSize ( Integer.MAX_VALUE ); this.dimension.width += resultSize.width; this.dimension.height = Math.max ( resultSize.height, this.dimension.height ); this.dimension.width += this.subTypeSymbol.getWidth ( ) + this.spacing; // now place the elements int posX = 0; this.indexLabel.setBounds ( posX, 0, labelSize.width, this.dimension.height ); posX += labelSize.width + this.spacing; this.typeComponent.setBounds ( posX, 0, expSize.width, this.dimension.height ); posX += expSize.width + this.spacing; this.labelComponent.setBounds ( posX, 0, labelComponentSize.width, this.dimension.height ); posX += labelComponentSize.width + this.spacing; this.typeComponent2.setBounds ( posX, 0, resultSize.width, this.dimension.height ); /* * Check whether this is node is evaluated. * * If it is evaluated only the Label needs to get placed, * if it is not evaluated yet the MenuButton needs to get placed. */ posX = labelSize.width + this.spacing; if ( this.proofNode.isProven ( ) ) { this.ruleLabel.setText ( "(" + this.proofNode.getRule ( ) + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ Dimension ruleLabelSize = this.ruleLabel.getPreferredSize ( ); this.ruleLabel.setBounds ( posX, this.dimension.height + this.spacing, ruleLabelSize.width, ruleLabelSize.height ); this.dimension.height += this.spacing + ruleLabelSize.height; this.dimension.width = Math.max ( this.dimension.width, ruleLabelSize.width + posX ); // display only the label not the button this.ruleLabel.setVisible ( true ); this.ruleButton.setVisible ( false ); } else { // place the menu button Dimension buttonSize = this.ruleButton.getNeededSize ( ); this.ruleButton .setBounds ( posX, this.dimension.height + this.spacing, buttonSize.width, buttonSize.height ); this.dimension.height += this.spacing + buttonSize.height; this.dimension.width = Math.max ( this.dimension.width, buttonSize.width + posX ); // display only the button not the label this.ruleLabel.setVisible ( false ); this.ruleButton.setVisible ( true ); } } } /* * Implementation of the eventhandling */ /** * Add a new {@link MinimalTypingNodeListener} * * @param listener the new listener to add */ public void addMinimalTypingNodeListener ( MinimalTypingNodeListener listener ) { this.listenerList.add ( MinimalTypingNodeListener.class, listener ); } /** * Remove a {@link MinimalTypingNodeListener} * * @param listener the listener to remove */ public void removeMinimalTypingNodeListener ( MinimalTypingNodeListener listener ) { this.listenerList.remove ( MinimalTypingNodeListener.class, listener ); } private void fireNodeChanged ( ) { Object[] listeners = this.listenerList.getListenerList ( ); for ( int i = 0; i < listeners.length; i += 2 ) { if ( listeners[i] != MinimalTypingNodeListener.class ) { continue; } ( ( MinimalTypingNodeListener ) listeners[i + 1] ).nodeChanged ( this ); } } private void fireRequestJumpToNode ( ProofNode node ) { Object[] listeners = this.listenerList.getListenerList ( ); for ( int i = 0; i < listeners.length; i += 2 ) { if ( listeners[i] != MinimalTypingNodeListener.class ) { continue; } ( ( MinimalTypingNodeListener ) listeners[i + 1] ).requestJumpToNode ( node ); } } /** * Handles every action, that is done via the menu of the {@link #ruleButton}.<br> * <br> * Because every item in the menu (except the Separatero :-) ) is one of our * own, the activated type of item can simply be identified by its class.<br> * * @param item */ private void handleMenuActivated ( JMenuItem item ) { if ( item instanceof MenuRuleItem ) { MenuRuleItem ruleItem = ( MenuRuleItem ) item; ProofRule rule = ruleItem.getRule ( ); try { this.proofModel.prove ( rule, this.proofNode ); this.ruleButton.setToolTipText ( null ); } catch ( Exception exc ) { // when the node could not be prooven with the selected // rule the menu button gets labeled with the given rule // and will be displayed in red this.ruleButton.setText ( "(" + rule.getName ( ) + ")" ); //$NON-NLS-1$ //$NON-NLS-2$ this.ruleButton.setTextColor ( Color.RED ); // determine the error text for the tooltip this.ruleButton.setToolTipText ( exc.getMessage ( ) ); } fireNodeChanged ( ); } else if ( item instanceof MenuTranslateItem ) { int answer = 1; if ( this.proofModel.containsSyntacticSugar ( this.proofNode, false ) ) { String[] answers = { Messages.getString ( "NodeComponent.0" ), Messages.getString ( "NodeComponent.1" ), Messages.getString ( "NodeComponent.2" ) }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ answer = JOptionPane.showOptionDialog ( getTopLevelAncestor ( ), Messages.getString ( "NodeComponent.3" ), //$NON-NLS-1$ Messages.getString ( "NodeComponent.4" ), //$NON-NLS-1$ JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, answers, answers[0] ); } switch ( answer) { case 0: this.proofModel.translateToCoreSyntax ( this.proofNode, false ); break; case 1: this.proofModel.translateToCoreSyntax ( this.proofNode, true ); break; case 2: break; } fireNodeChanged ( ); } else if ( item instanceof MenuGuessItem ) { try { this.proofModel.guess ( this.proofNode ); } catch ( final ProofGuessException e ) { fireRequestJumpToNode ( e.getNode ( ) ); SwingUtilities.invokeLater ( new Runnable ( ) { public void run ( ) { JOptionPane .showMessageDialog ( getTopLevelAncestor ( ), MessageFormat.format ( Messages.getString ( "NodeComponent.5" ), e.getMessage ( ) ), Messages.getString ( "NodeComponent.6" ), JOptionPane.ERROR_MESSAGE ); //$NON-NLS-1$ //$NON-NLS-2$ } } ); } fireNodeChanged ( ); } else if ( item instanceof MenuGuessTreeItem ) { try { this.proofModel.complete ( this.proofNode ); } catch ( final ProofGuessException e ) { //e.printStackTrace ( ); //e.getCause ( ).printStackTrace ( ); fireRequestJumpToNode ( e.getNode ( ) ); SwingUtilities.invokeLater ( new Runnable ( ) { public void run ( ) { JOptionPane .showMessageDialog ( getTopLevelAncestor ( ), MessageFormat.format ( Messages.getString ( "NodeComponent.7" ), e.getMessage ( ) ), Messages.getString ( "NodeComponent.8" ), JOptionPane.ERROR_MESSAGE ); //$NON-NLS-1$ //$NON-NLS-2$ } } ); } fireNodeChanged ( ); } } /* * Implementation of the TreeNodeComponent Interface */ /** * Performs an update for the Entire Node. All elements get rearanged based on * the given maximum with, the menu items will be checked if they are still * available. */ public Dimension update ( int maxWidth ) { placeElements ( maxWidth ); this.menuTranslateItem.setEnabled ( this.translator.containsSyntacticSugar ( this.proofNode.getExpression ( ), true ) ); return this.dimension; } /** * Returns the number of pixels the children should be displayed indentated. */ public int getIndentationWidth ( ) { // XXX: calculate the indentation return this.indexLabel.getWidth ( ); } /** * Returns the point at the bottom of the node where the layout should attach * the arrow. */ public Point getBottomArrowConnection ( ) { return new Point ( this.getX ( ) + this.indexLabel.getWidth ( ) / 2, this.getY ( ) + this.indexLabel.getHeight ( ) ); } /** * Returns the point at the left of the node where the layout should attach * the line to its parent. */ public Point getLeftArrowConnection ( ) { return new Point ( this.getX ( ), this.getY ( ) + this.indexLabel.getY ( ) + this.indexLabel.getHeight ( ) / 2 ); } /** * Just calls setBounds of the super class. */ @Override public void setBounds ( int x, int y, int width, int height ) { super.setBounds ( x, y, width, height ); } /** * Returns the typeLabel. * * @return The typeLabel. * @see #typeLabel */ public TypeComponent getTypeComponent ( ) { return this.typeComponent; } /** * Returns the proofNode. * * @return The proofNode. * @see #proofNode */ public MinimalTypingProofNode getProofNode ( ) { return this.proofNode; } /** * Returns the indexLabel. * * @return The indexLabel. * @see #indexLabel */ public JLabel getIndexLabel ( ) { return this.indexLabel; } /** * Returns the compoundExpression. * * @return The compoundExpression. * @see #compoundExpression */ public CompoundExpression < Identifier, Type > getCompoundExpression ( ) { return this.compoundExpression; } // // public void paintComponent (Graphics gc) // { // super.paintComponent (gc); // System.out.println("Auch Scheiße!!!"); // ShowBonds sb = new ShowBonds(); // sb.setType (this.proofNode.getType() ); // ToListenForMouseContainer tlfmc = new ToListenForMouseContainer(); // // //System.out.println ("Scheiße!"); // // typeRenderer.render (typePosition, 0,typeRenderer.getNeededSize (Integer.MAX_VALUE).width ,typeRenderer.getNeededSize (Integer.MAX_VALUE).height, this.getGraphics (), sb, tlfmc); // // // } /** * Get the second @link TypeComponent of this Component * * @return the second type component */ public TypeComponent getTypeComponent2 ( ) { return this.typeComponent2; } /** * * Set the mode for this component. * True means advanced, false means beginner. * */ public void setAdvanced ( ) { /* * Create the PopupMenu for the menu button */ JPopupMenu menu = new JPopupMenu ( ); ProofRule[] rules = this.proofModel.getRules ( ); if ( rules.length > 0 ) { int group = rules[0].getGroup ( ); for ( ProofRule r : rules ) { if ( r.getGroup ( ) != group ) { menu.addSeparator ( ); } menu.add ( new MenuRuleItem ( r ) ); group = r.getGroup ( ); } } menu.addSeparator ( ); menu.add ( new MenuGuessItem ( ) ); menu.add ( new MenuGuessTreeItem ( ) ); menu.add ( new MenuTranslateItem ( ) ); this.ruleButton.setMenu ( menu ); } }