2 * Sonitus - PipelinePanel.java - Copyright © 2013 David Roden
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 package net.pterodactylus.sonitus.gui;
20 import static javax.swing.BorderFactory.createEtchedBorder;
22 import java.awt.GridBagConstraints;
23 import java.awt.GridBagLayout;
24 import java.awt.Insets;
25 import java.util.Collection;
26 import java.util.List;
27 import javax.swing.JLabel;
28 import javax.swing.JPanel;
30 import net.pterodactylus.sonitus.data.Controlled;
31 import net.pterodactylus.sonitus.data.Filter;
32 import net.pterodactylus.sonitus.data.Pipeline;
33 import net.pterodactylus.sonitus.data.Sink;
34 import net.pterodactylus.sonitus.data.Source;
36 import com.google.common.collect.Lists;
39 * {@link JPanel} that displays all components of a {@link Pipeline}.
41 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
43 public class PipelinePanel extends JPanel {
45 /** The pipeline being displayed. */
46 private final Pipeline pipeline;
49 * Creates a new pipeline panel displaying the given pipeline.
52 * The pipeline to display
54 public PipelinePanel(Pipeline pipeline) {
55 super(new GridBagLayout());
56 this.pipeline = pipeline;
64 /** Update the panel. Needs to be called when the pipeline is changed. */
65 private void updatePanel() {
66 /* clear everything. */
69 /* count all sinks. */
71 List<Source> sources = Lists.newArrayList(pipeline.source());
72 while (!sources.isEmpty()) {
73 Collection<Sink> sinks = pipeline.sinks(sources.remove(0));
74 for (Sink sink : sinks) {
75 /* only count real sinks, everything else is filter. */
76 if (sink instanceof Filter) {
77 sources.add((Filter) sink);
84 /* get number of maximum horizontal grid cells. */
85 int gridCellCount = 1;
86 for (int n = 2; n <= sinkCount; ++n) {
90 /* paint all components recursively. */
91 addControlled(pipeline.source(), 0, 0, gridCellCount);
95 * Displays the given component.
98 * The component to add this panel.
100 * The level at which to show the component (the source is level {@code 0})
102 * The position at which to display the component
104 * The width of the component in grid cells
106 private void addControlled(Controlled controlled, int level, int position, int width) {
107 /* create a GUI component that displays the component. */
108 JLabel sourceLabel = new JLabel(controlled.name());
109 sourceLabel.setBorder(createEtchedBorder());
111 /* show component. */
112 add(sourceLabel, new GridBagConstraints(position, level, width, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
114 /* if the component does not have connected sinks, exit here. */
115 if (!(controlled instanceof Source)) {
119 /* iterate over the component’s sinks. */
120 Collection<Sink> sinks = pipeline.sinks((Source) controlled);
121 int sinkWidth = width / sinks.size();
123 for (Sink connectedSink : sinks) {
124 /* distribute all sinks evenly below this source. */
125 addControlled(connectedSink, level + 1, position + sinkIndex * sinkWidth, sinkWidth);