/** * For each port of the given entity, if the port's derived level is greater than 0 (i.e., it is * created automatically by the entity), store the persistent attributes of the port in a "port" * XML element. * * @param entity The entity whose ports are looked at. * @param output The output writer. * @param depth The depth for the MoML output. * @exception IOException If the output writer cannot be written to. */ public static void exportPortProperties(GTEntity entity, Writer output, int depth) throws IOException { if (entity instanceof Entity) { Entity ptEntity = (Entity) entity; for (Object portObject : ptEntity.portList()) { Port port = (Port) portObject; if (port.getDerivedLevel() == 0) { continue; } boolean outputStarted = false; for (Object attributeObject : port.attributeList()) { Attribute attribute = (Attribute) attributeObject; if (attribute.isPersistent()) { if (!outputStarted) { output.write( StringUtilities.getIndentPrefix(depth) + "<port name=\"" + port.getName() + "\">\n"); outputStarted = true; } attribute.exportMoML(output, depth + 1); } } if (outputStarted) { output.write(StringUtilities.getIndentPrefix(depth) + "</port>\n"); } } } }
/** * Get the children of the given object. The children can be either attributes, ports, entities, * or relations if permitted by the arguments. * * @param object The object. * @param includeAttributes Whether the children can be attributes. * @param includePorts Whether the children can be ports. * @param includeEntities Whether the children can be entities. * @param includeRelations Whether the children can be relations. * @return The collection of children. */ public static Collection<NamedObj> getChildren( NamedObj object, boolean includeAttributes, boolean includePorts, boolean includeEntities, boolean includeRelations) { Collection<NamedObj> collection = new CombinedCollection<NamedObj>(); if (includeAttributes) { collection.addAll(object.attributeList()); } if (includePorts && object instanceof Entity) { Entity entity = (Entity) object; collection.addAll(entity.portList()); } if (object instanceof CompositeEntity) { CompositeEntity entity = (CompositeEntity) object; if (includeEntities) { collection.addAll(entity.entityList()); } if (includeRelations) { collection.addAll(entity.relationList()); } } return collection; }
private void _inferFiringCounts(SymbolicScheduleElement element, String expression) throws IllegalActionException, NameDuplicationException { String recursiveExpression; if (expression == null) { recursiveExpression = element.expression(); } else { recursiveExpression = expression + "*" + element.expression(); } if (element instanceof SymbolicFiring) { SymbolicFiring firing = (SymbolicFiring) element; Entity actor = (Entity) firing.getActor(); Variable parameter = (Variable) actor.getAttribute("firingsPerIteration"); if (parameter == null) { parameter = new Parameter(actor, "firingsPerIteration"); parameter.setVisibility(Settable.NOT_EDITABLE); parameter.setPersistent(false); } parameter.setExpression(recursiveExpression); } else if (element instanceof SymbolicSchedule) { SymbolicSchedule schedule = (SymbolicSchedule) element; for (Iterator i = schedule.iterator(); i.hasNext(); ) { _inferFiringCounts((SymbolicScheduleElement) i.next(), recursiveExpression); } } else { throw new RuntimeException("Unexpected Schedule Element"); } }
// ///////////////////////////////////////////////////////////////// // // private methods //// // Recursively compute the set of free variables for all actors // deeply contained in the given model. private Set _freeVariables(Entity model) throws IllegalActionException { // First get the free variables of contained actors. Set set = new HashSet(); if (model instanceof CompositeEntity) { for (Iterator entities = ((CompositeEntity) model).entityList().iterator(); entities.hasNext(); ) { Entity entity = (Entity) entities.next(); set.addAll(_freeVariables(entity)); } } // Next, compute the set of variable names defined in this container. Set variableNames = new HashSet(); for (Iterator variables = model.attributeList(Variable.class).iterator(); variables.hasNext(); ) { Variable variable = (Variable) variables.next(); variableNames.add(variable.getName()); } variableNames = Collections.unmodifiableSet(variableNames); // Free variables of contained actors that are defined in this // container are not free variables of this container. set.removeAll(variableNames); // Iterate over all the variables of this container, and add in // any free variables they reference. PtParser parser = new PtParser(); ParseTreeFreeVariableCollector collector = new ParseTreeFreeVariableCollector(); for (Iterator variables = model.attributeList(Variable.class).iterator(); variables.hasNext(); ) { Variable variable = (Variable) variables.next(); String expression = variable.getExpression(); ASTPtRootNode root; if (variable.isStringMode()) { root = parser.generateStringParseTree(expression); } else { root = parser.generateParseTree(expression); } Set freeIdentifiers = new HashSet(collector.collectFreeVariables(root)); // Identifiers that reference other variables in the same container // are bound, not free. Set tempSet = new HashSet(variableNames); tempSet.remove(variable.getName()); freeIdentifiers.removeAll(tempSet); set.addAll(freeIdentifiers); } _entityToFreeVariableNameSet.put(model, set); return set; }
/** * Return the computed free variables for the given entity. * * @param entity An entity, which must be deeply contained by the model for which this analysis * was created. * @return The computed free variables for the given entity. * @exception RuntimeException If the free variables for the entity have not already been * computed. */ public Set getFreeVariables(Entity entity) { Set freeVariables = (Set) _entityToFreeVariableNameSet.get(entity); if (freeVariables == null) { throw new RuntimeException("Entity " + entity.getFullName() + " has not been analyzed."); } return Collections.unmodifiableSet(freeVariables); }
/** * @param container * @param name * @param mode * @param isInput * @param isOutput * @throws IllegalActionException * @throws NameDuplicationException */ public Port(Entity container, String name, PortMode mode, boolean isInput, boolean isOutput) throws IllegalActionException, NameDuplicationException { // we explicitly do not call the default matching super() constructor // with a container param etc, as this leads to initialization/construction ordering problems... // the code below ensures that the port is completely initialized // before it "declares" itself to its container super(container.workspace()); setName(name); setMode(mode); setInput(isInput); setOutput(isOutput); setTypeEquals(PasserelleType.PASSERELLE_MSG_TYPE); setMultiport(true); statistics = new PortStatistics(this); setContainer(container); }
/** * Return the parameterized scheduling sequence. An exception will be thrown if the graph is not * schedulable. * * @return A schedule of the deeply contained opaque entities in the firing order. * @exception NotSchedulableException If a parameterized schedule cannot be derived for the model. * @exception IllegalActionException If the rate parameters of the model are not correct, or the * computed rates for external ports are not correct. */ @SuppressWarnings("unused") protected Schedule _getSchedule() throws NotSchedulableException, IllegalActionException { PSDFDirector director = (PSDFDirector) getContainer(); CompositeActor model = (CompositeActor) director.getContainer(); // Get the vectorization factor. String vectorizationFactorExpression = "1"; String vectorizationName = director.vectorizationFactor.getName(model); vectorizationFactorExpression = vectorizationName.replaceAll("\\.", "::"); if (vectorizationFactorExpression.indexOf(" ") != -1) { throw new InternalErrorException( "The vectorizationFactor " + "PSDFDirector parameter must " + "not have spaces in its value. The original value " + "was \"" + vectorizationName + "\". Try changing the name of " + "director."); } PSDFGraphReader graphReader = new PSDFGraphReader(); PSDFGraph graph = (PSDFGraph) graphReader.convert(model); _debug("PSDF graph = \n" + graph.toString()); if (_debugFlag) { graph.printEdgeRateExpressions(); } PSDFAPGANStrategy strategy = new PSDFAPGANStrategy(graph); ptolemy.graph.sched.Schedule graphSchedule = strategy.schedule(); _debug("P-APGAN schedule = \n" + graphSchedule.toString()); SymbolicScheduleElement resultSchedule = _expandAPGAN(graph, strategy.getClusterManager().getRootNode(), strategy); resultSchedule.setIterationCount(vectorizationFactorExpression); _debug("Final schedule = \n" + resultSchedule.toString()); if (_debugging) { _debug("The buffer size map:\n"); Iterator relations = _bufferSizeMap.keySet().iterator(); while (relations.hasNext()) { Relation relation = (Relation) relations.next(); _debug(relation.getName() + ": " + _bufferSizeMap.get(relation) + "\n"); } } _saveBufferSizes(_bufferSizeMap); // Crazy hack to infer firing counts for each actor. try { _inferFiringCounts(resultSchedule, null); } catch (NameDuplicationException ex) { throw new NotSchedulableException(new LinkedList(), ex, "Error recording firing counts"); } // Crazy hack to Infer port production: FIXME: This should be // done as part of the APGAN expansion where the rates of // external ports are unknown The reason is that it will make // rate information propagate from an actor input port to // another actors input port that are connected on the inside // to the same external input port. See // BaseSDFScheduler.setContainerRates. Iterator ports = model.portList().iterator(); while (ports.hasNext()) { IOPort port = (IOPort) ports.next(); if (_debugging && VERBOSE) { _debug("External Port " + port.getName()); } if (port.isInput() && port.isOutput()) { throw new NotSchedulableException( port, "External port is both an input and an output, " + "which is not allowed in SDF."); } else if (port.isInput()) { List sinks = port.insideSinkPortList(); if (sinks.size() > 0) { IOPort connectedPort = (IOPort) sinks.get(0); Entity entity = (Entity) connectedPort.getContainer(); String name = connectedPort.getName(model); String identifier = name.replaceAll("\\.", "::"); String sinkExpression; Variable sinkRateVariable = DFUtilities.getRateVariable(connectedPort, "tokenConsumptionRate"); if (sinkRateVariable == null) { sinkExpression = "1"; } else { sinkExpression = identifier + "::" + sinkRateVariable.getName(); } String expression = sinkExpression + " * " + entity.getName() + "::firingsPerIteration"; DFUtilities.setExpressionIfNotDefined(port, "tokenConsumptionRate", expression); if (_debugging && VERBOSE) { _debug("Setting tokenConsumptionRate to " + expression); } } } else if (port.isOutput()) { List sources = port.insideSourcePortList(); if (sources.size() > 0) { IOPort connectedPort = (IOPort) sources.get(0); Entity entity = (Entity) connectedPort.getContainer(); String name = connectedPort.getName(model); String identifier = name.replaceAll("\\.", "::"); Variable sourceRateVariable = DFUtilities.getRateVariable(connectedPort, "tokenProductionRate"); String sourceExpression; if (sourceRateVariable == null) { sourceExpression = "1"; } else { sourceExpression = identifier + "::" + sourceRateVariable.getName(); } String expression = sourceExpression + " * " + entity.getName() + "::firingsPerIteration"; DFUtilities.setExpressionIfNotDefined(port, "tokenProductionRate", expression); if (_debugging && VERBOSE) { _debug("Setting tokenProductionRate to " + expression); } } // Infer init production. // Note that this is a very simple type of inference... // However, in general, we don't want to try to // flatten this model... // Iterator connectedPorts = // port.insideSourcePortList().iterator(); // IOPort foundOutputPort = null; // int inferredRate = 0; // while (connectedPorts.hasNext()) { // IOPort connectedPort = (IOPort) connectedPorts.next(); // int newRate; // if (connectedPort.isOutput()) { // newRate = // DFUtilities.getTokenInitProduction(connectedPort); // } else { // newRate = 0; // } // // If we've already set the rate, then check that the // // rate for any other internal port is correct. // if (foundOutputPort != null && // newRate != inferredRate) { // throw new NotSchedulableException( // "External output port " + port // + " is connected on the inside to ports " // + "with different initial production: " // + foundOutputPort + " and " // + connectedPort); // } // foundOutputPort = connectedPort; // inferredRate = newRate; // } // DFUtilities._setIfNotDefined( // port, "tokenInitProduction", inferredRate); // if (_debugging && VERBOSE) { // _debug("Setting tokenInitProduction to " // + inferredRate); // } } else { throw new NotSchedulableException( port, "External port is neither an input and an output, " + "which is not allowed in SDF."); } } // Set the schedule to be valid. setValid(true); if (resultSchedule instanceof Schedule) { return (Schedule) resultSchedule; } else { // Must be ScheduleElement. Schedule schedule = new Schedule(); schedule.add((ScheduleElement) resultSchedule); return schedule; } }
/** * Create a refinement for the given state. * * @param state The state that will contain the new refinement. * @param name The name of the composite entity that stores the refinement. * @param template The template used to create the refinement, or null if template is not used. * @param className The class name for the refinement, which is used when template is null. * @param configuration The configuration that is used to open the refinement (as a look-inside * action) after it is created, or null if it is not needed to open the refinement. * @exception IllegalActionException If error occurs while creating the refinement. */ public void addRefinement( State state, final String name, Entity template, String className, final Configuration configuration) throws IllegalActionException { Attribute allowRefinement = state.getAttribute("_allowRefinement"); if (allowRefinement instanceof Parameter && !((BooleanToken) ((Parameter) allowRefinement).getToken()).booleanValue()) { throw new IllegalActionException(state, "State does not support " + "refinement."); } final CompositeEntity container = (CompositeEntity) getContainer(); if (container == null) { throw new IllegalActionException(state, "State container has no " + "container!"); } if (container.getEntity(name) != null) { throw new IllegalActionException( state, "There is already a " + "refinement with name " + name + "."); } String currentRefinements = state.refinementName.getExpression(); if ((currentRefinements == null) || currentRefinements.equals("")) { currentRefinements = name; } else { currentRefinements = currentRefinements.trim() + ", " + name; } String moml; // The MoML we create depends on whether the configuration // specified a set of prototype refinements. if (template != null) { String templateDescription = template.exportMoML(name); moml = "<group>" + templateDescription + "<entity name=\"" + state.getName(container) + "\"><property name=\"refinementName\" value=\"" + currentRefinements + "\"/></entity></group>"; } else { moml = "<group><entity name=\"" + name + "\" class=\"" + className + "\"/>" + "<entity name=\"" + state.getName(container) + "\"><property name=\"refinementName\" value=\"" + currentRefinements + "\"/></entity></group>"; } MoMLChangeRequest change = new MoMLChangeRequest(state, container, moml) { protected void _execute() throws Exception { super._execute(); // Mirror the ports of the container in the refinement. // Note that this is done here rather than as part of // the MoML because we have set protected variables // in the refinement to prevent it from trying to again // mirror the changes in the container. // The following entity is newly created refinement. Entity entity = container.getEntity(name); // Get the initial port configuration from the container. Iterator ports = container.portList().iterator(); while (ports.hasNext()) { Port port = (Port) ports.next(); try { if (entity instanceof RefinementActor) { // Prevent the newly created refinement from // creating a port in its container. ((RefinementActor) entity).setMirrorDisable(1); } String name = port.getName(); Port newPort = entity.getPort(name); if (newPort == null) { newPort = entity.newPort(port.getName()); } if (newPort instanceof RefinementPort && port instanceof IOPort) { try { ((RefinementPort) newPort).setMirrorDisable(true); if (((IOPort) port).isInput()) { ((RefinementPort) newPort).setInput(true); } if (((IOPort) port).isOutput()) { ((RefinementPort) newPort).setOutput(true); } if (((IOPort) port).isMultiport()) { ((RefinementPort) newPort).setMultiport(true); } // Copy the location to the new port if any. // (tfeng 08/29/08) if (container instanceof ModalModel) { FSMActor controller = ((ModalModel) container).getController(); if (controller != null && controller != container) { Port controllerPort = controller.getPort(port.getName()); if (controllerPort != null) { Location location = (Location) controllerPort.getAttribute("_location", Location.class); if (location != null) { location = (Location) location.clone(newPort.workspace()); location.setContainer(newPort); } } } } } finally { ((RefinementPort) newPort).setMirrorDisable(false); } } } finally { if (entity instanceof RefinementActor) { ((RefinementActor) entity).setMirrorDisable(0); } } } if (configuration != null) { // Look inside. configuration.openInstance(entity); } } }; container.requestChange(change); }
/** * Create a new port with the specified name in the container of this controller, which in turn * creates a port in this controller and all the refinements. This method is write-synchronized on * the workspace. * * @param name The name to assign to the newly created port. * @return The new port. * @exception NameDuplicationException If the entity already has a port with the specified name. */ public Port newPort(String name) throws NameDuplicationException { try { _workspace.getWriteAccess(); ModalModel container = (ModalModel) getContainer(); if (_mirrorDisable == 1 || container == null) { // We are mirroring a change above in the hierarchy // (or there is no above in the hierarchy), // so we should not mirror this change upwards. // But we should mirror it downwards. ModalRefinementPort port = new ModalRefinementPort(this, name); // Create the links on the outside of the new port. if (container != null) { String relationName = name + "Relation"; Relation relation = container.getRelation(relationName); if (relation == null) { relation = container.newRelation(relationName); Port containerPort = container.getPort(name); containerPort.link(relation); } port.link(relation); } // Mirror the change downwards in the hierarchy. Iterator entities = entityList().iterator(); while (entities.hasNext()) { Entity entity = (Entity) entities.next(); if (entity instanceof RefinementActor) { if (entity.getPort(name) == null) { try { ((RefinementActor) entity).setMirrorDisable(1); entity.newPort(name); } finally { ((RefinementActor) entity).setMirrorDisable(0); } } } } return port; } else { // We are originating the change, or it originated from // below us in the hierarchy, and hence should delegate // it upwards. This will cause this newPort() method // to be called again by the container after it has // created its own port. That will result in the code // above executing because it will set _mirrorPort to 1 // on this port before doing the call. ModalRefinementPort containerPort = container == null ? null : (ModalRefinementPort) container.getPort(name); if (containerPort == null) { // The container does not have a mirror port. // Delegate upwards. // Note that this will result in the container // creating the port here by calling this // newPort() method. It will set my // _mirrorDisable to 1 before doing that, // and set it back to 0 after. container.newPort(name); return getPort(name); } else { // The container already has a mirror port, so // we cannot use it to create our port. // This can happen if the container was created first // and populated with its ports before this refinement // was created. ModalRefinementPort port = new ModalRefinementPort(this, name); // Create the link on the outside of the port. String relationName = name + "Relation"; Relation relation = container.getRelation(relationName); // The container should already have this relation, // but in case not, we create it. if (relation == null) { relation = container.newRelation(relationName); containerPort.link(relation); } port.link(relation); // Mirror the change downwards in the hierarchy. Iterator entities = entityList().iterator(); while (entities.hasNext()) { Entity entity = (Entity) entities.next(); if (entity instanceof RefinementActor) { if (entity.getPort(name) == null) { try { ((RefinementActor) entity).setMirrorDisable(1); entity.newPort(name); } finally { ((RefinementActor) entity).setMirrorDisable(0); } } } } return port; } } } catch (IllegalActionException ex) { // This exception should not occur, so we throw a runtime // exception. throw new InternalErrorException( "ModalRefinement.newPort: Internal error: " + ex.getMessage()); } finally { _mirrorDisable = 0; _workspace.doneWriting(); } }
/** * Construct an attribute with the given name contained by the specified container. The container * argument must not be null, or a NullPointerException will be thrown. This attribute will use * the workspace of the container for synchronization and version counts. If the name argument is * null, then the name is set to the empty string. Increment the version of the workspace. * * @param container The container. * @param name The name of this attribute. * @exception IllegalActionException If the attribute is not of an acceptable class for the * container, or if the name contains a period. * @exception NameDuplicationException If the name coincides with an attribute already in the * container. */ public IDAttribute(Entity container, String name) throws IllegalActionException, NameDuplicationException { super(container, name); // name for the model this.name = new StringAttribute(this, "name"); this.name.setExpression(container.getName()); // This should not be persistent, in case the name changes outside // of this parameter. this.name.setPersistent(false); // This should not be editable, since the name is set by saveAs. this.name.setVisibility(Settable.NOT_EDITABLE); // FIXME: Need to listen for changes to the name. // How to do that? // The current design is also a solution in that the name of this // attribute and model must be consistent with the name of the file. // boolean isClass = false; // if (container instanceof InstantiableNamedObj) { /* isClass = */ ((InstantiableNamedObj) container).isClassDefinition(); // } String className = container.getClassName(); baseClass = new StringAttribute(this, "baseClass"); baseClass.setExpression(className); // This should not be persistent, because the base class // is set already, generally. baseClass.setPersistent(false); // Cannot change the base class. baseClass.setVisibility(Settable.NOT_EDITABLE); URIAttribute modelURI = (URIAttribute) container.getAttribute("_uri", URIAttribute.class); if (modelURI != null) { StringAttribute definedIn = new StringAttribute(this, "definedIn"); definedIn.setExpression(modelURI.getURI().toString()); definedIn.setPersistent(false); definedIn.setVisibility(Settable.NOT_EDITABLE); } // The date when this model is created. // Actually, it is the date when this attribute is created. // We assume that when the model is created, this attribute // is also created. // We may force this to happen.:-) Further more, we may force // that only the top level contains an model ID. created = new StringAttribute(this, "created"); created.setExpression(DateFormat.getDateTimeInstance().format(new Date())); created.setVisibility(Settable.NOT_EDITABLE); created.setPersistent(true); // The date when this model is modified. // Everytime the model gets modified, the updateContent method // defined below is called and the lastUpdated attribute gets // updated. lastUpdated = new StringAttribute(this, "lastUpdated"); _updateDate(); lastUpdated.setVisibility(Settable.NOT_EDITABLE); lastUpdated.setPersistent(true); // The name of the author who creates the model. // This attribute can not be changed so that the // intellectual property (IP) is preserved. author = new StringAttribute(this, "author"); author.setVisibility(Settable.NOT_EDITABLE); String userName = null; try { userName = StringUtilities.getProperty("user.name"); } catch (Exception ex) { System.out.println( "Warning, in IDAttribute, failed to read " + "'user.name' property (-sandbox or applets always cause " + "this)"); } if (userName != null) { author.setExpression(userName); } author.setPersistent(true); // The names of the contributors who modify the model. contributors = new StringAttribute(this, "contributors"); String contributorsNames = ""; contributors.setExpression(contributorsNames); author.setPersistent(true); // Hide the name of this ID attribute. SingletonParameter hide = new SingletonParameter(this, "_hideName"); hide.setToken(BooleanToken.TRUE); hide.setVisibility(Settable.EXPERT); BoxedValuesIcon icon = new BoxedValuesIcon(this, "_icon"); icon.setPersistent(false); // No need to display any parameters when the "_showParameters" // preference asks for such display because presumably all the // parameters are reflected in the visual display already. Parameter hideAllParameters = new Parameter(this, "_hideAllParameters"); hideAllParameters.setVisibility(Settable.EXPERT); hideAllParameters.setExpression("true"); }
/** * Construct a Unit Solver Dialog. * * @param dialogTableau The DialogTableau. * @param owner The object that, per the user, appears to be generating the dialog. * @param target The object whose units are being solved. * @param configuration The configuration to use to open the help screen. */ public UnitSolverDialog( DialogTableau dialogTableau, Frame owner, Entity target, Configuration configuration) { super("Solve units for " + target.getName(), dialogTableau, owner, target, configuration); SelectionRenderer tempSelectionRenderer = null; _tableau = ((TableauFrame) owner).getTableau(); _model = (TypedCompositeActor) target; // ((TypedCompositeActor) (((PtolemyEffigy) (_tableau.getContainer())) // .getModel())); BasicGraphFrame parent = (BasicGraphFrame) (_tableau.getFrame()); JGraph jGraph = parent.getJGraph(); GraphPane graphPane = jGraph.getGraphPane(); _controller = graphPane.getGraphController(); _selectionModel = _controller.getSelectionModel(); Interactor interactor = _controller.getEdgeController(new Object()).getEdgeInteractor(); _graphModel = (AbstractBasicGraphModel) _controller.getGraphModel(); _selectionInteractor = (SelectionInteractor) interactor; _defaultSelectionRenderer = _selectionInteractor.getSelectionRenderer(); tempSelectionRenderer = new BasicSelectionRenderer(new BasicEdgeHighlighter()); if (_model == getTarget()) { _entities = _getSelectedNodes(); _relations = _getSelectedRelations(); if (_entities.isEmpty() && _relations.isEmpty()) { _entities = new Vector(_model.entityList(ComponentEntity.class)); _relations = new Vector(_model.relationList()); } } else { _entities = new Vector(); _entities.add(getTarget()); _relations = new Vector(); } _selectionModel.clearSelection(); _selectionInteractor.setSelectionRenderer(tempSelectionRenderer); _showComponents(); _selectionModel.addSelectionListener(this); JPanel fullSolverPanel = new JPanel(); fullSolverPanel.setLayout(new BoxLayout(fullSolverPanel, BoxLayout.Y_AXIS)); fullSolverPanel.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder("Full Solution"), BorderFactory.createEmptyBorder(5, 5, 5, 5))); _runFullSolverButton.addActionListener(this); fullSolverPanel.add(_runFullSolverButton); _fullSolutionResult.setOpaque(true); _fullSolutionResult.setBackground(Color.white); fullSolverPanel.add(_fullSolutionResult); JPanel componentsPanel = new JPanel(); componentsPanel.setLayout(new BoxLayout(componentsPanel, BoxLayout.Y_AXIS)); componentsPanel.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder("Components"), BorderFactory.createEmptyBorder(5, 5, 5, 5))); _setToSelectedButton.setEnabled(false); componentsPanel.add(_setToSelectedButton); _setToSelectedButton.addActionListener(this); componentsPanel.add(_showComponentsButton); _showComponentsButton.addActionListener(this); JPanel topPanel = new JPanel(); topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.X_AXIS)); topPanel.add(fullSolverPanel); topPanel.add(componentsPanel); JPanel minimalSpanPanel = new JPanel(new BorderLayout()); minimalSpanPanel.setBorder( BorderFactory.createCompoundBorder( BorderFactory.createTitledBorder("Minimal Spanning Solutions"), BorderFactory.createEmptyBorder(5, 5, 5, 5))); minimalSpanPanel.add(_runMinimalSpanSolverButton, BorderLayout.NORTH); _runMinimalSpanSolverButton.addActionListener(this); _solutionsListModel = new SolutionListModel(); _solutionsList = new JList(_solutionsListModel); _solutionsList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); _solutionsList.addListSelectionListener(this); JScrollPane scrollPane = new JScrollPane(_solutionsList); minimalSpanPanel.add(scrollPane, BorderLayout.CENTER); JPanel mainPane = new JPanel(); mainPane.setLayout(new BoxLayout(mainPane, BoxLayout.Y_AXIS)); mainPane.add(topPanel); mainPane.add(minimalSpanPanel); setContents(mainPane); }