package org.chesmapper.view.gui; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.HashMap; import javax.swing.ButtonGroup; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.chesmapper.view.cluster.ClusterController; import org.chesmapper.view.cluster.Clustering; import org.chesmapper.view.cluster.ClusteringImpl; import org.chesmapper.view.cluster.Compound; import org.chesmapper.view.cluster.JitteringProvider; import org.chesmapper.view.cluster.Clustering.SelectionListener; import org.chesmapper.view.gui.ViewControler.HighlightSorting; import org.chesmapper.view.gui.ViewControler.Style; import org.chesmapper.view.gui.swing.ComponentFactory; import org.chesmapper.view.gui.swing.TransparentViewPanel; import org.chesmapper.view.gui.swing.ComponentFactory.ClickableLabel; import org.chesmapper.view.gui.swing.ComponentFactory.StyleButton; import org.chesmapper.view.gui.util.CompoundPropertyHighlighter; import org.chesmapper.view.gui.util.Highlighter; import org.mg.javalib.gui.DescriptionListCellRenderer; import com.jgoodies.forms.builder.DefaultFormBuilder; import com.jgoodies.forms.layout.FormLayout; import com.jgoodies.forms.layout.Sizes; public class ControlPanel extends JPanel { boolean selfUpdate = false; StyleButton buttonWire; StyleButton buttonBalls; StyleButton buttonDots; JSlider sliderSize; ClickableLabel buttonPlusSize; ClickableLabel buttonMinusSize; JSlider sliderJitter; ClickableLabel buttonPlusJitter; ClickableLabel buttonMinusJitter; JComboBox<Highlighter> highlightCombobox; JComboBox<HighlightSorting> highlightMinMaxCombobox; ClickableLabel buttonClearFeature; ViewControler viewControler; Clustering clustering; GUIControler guiControler; ClusterController clusterControler; public ControlPanel(ViewControler viewControler, ClusterController clusterControler, Clustering clustering, GUIControler guiControler) { this.viewControler = viewControler; this.clusterControler = clusterControler; this.clustering = clustering; this.guiControler = guiControler; buildLayout(); addListeners(); } private void buildLayout() { buttonWire = new StyleButton("Wireframe", true, Style.wireframe); buttonBalls = new StyleButton("Balls & Sticks", false, Style.ballsAndSticks); buttonDots = new StyleButton("Dots", false, Style.dots); ButtonGroup g = new ButtonGroup(); for (StyleButton b : new StyleButton[] { buttonWire, buttonBalls, buttonDots }) { g.add(b); b.setOpaque(false); b.setFocusable(false); } updateSelectedStyle(); buttonPlusSize = ComponentFactory.createPlusViewButton(); buttonMinusSize = ComponentFactory.createMinusViewButton(); buttonPlusJitter = ComponentFactory.createPlusViewButton(); buttonMinusJitter = ComponentFactory.createMinusViewButton(); buttonMinusJitter.setEnabled(viewControler.getJitteringLevel() > 0); sliderSize = ComponentFactory.createViewSlider(0, viewControler.getCompoundSizeMax(), viewControler.getCompoundSize()); sliderSize.setPreferredSize(new Dimension(100, sliderSize.getPreferredSize().height)); sliderJitter = ComponentFactory.createViewSlider(0, JitteringProvider.STEPS, viewControler.getJitteringLevel()); sliderJitter.setPreferredSize(new Dimension(50, sliderJitter.getPreferredSize().height)); highlightCombobox = ComponentFactory.createViewComboBox(Highlighter.class); loadHighlighters(); highlightCombobox.setSelectedItem(viewControler.getHighlighter()); highlightMinMaxCombobox = ComponentFactory.createViewComboBox(HighlightSorting.values()); highlightMinMaxCombobox.setSelectedItem(viewControler.getHighlightSorting()); highlightMinMaxCombobox.setVisible(false); buttonClearFeature = ComponentFactory.createCrossViewButton(); JPanel p = new TransparentViewPanel(new FlowLayout(FlowLayout.CENTER, 0, 0)); p.add(ComponentFactory.createViewLabel("Size: ")); p.add(buttonMinusSize); p.add(sliderSize); p.add(buttonPlusSize); p.add(new JLabel(" ")); p.add(ComponentFactory.createViewLabel("Spread: ")); p.add(buttonMinusJitter); p.add(sliderJitter); p.add(buttonPlusJitter); p.setBorder(new EmptyBorder(5, 5, 2, 5)); JPanel p1 = new TransparentViewPanel(new FlowLayout(FlowLayout.CENTER, 0, 0)); // p1.add(ComponentFactory.createViewLabel("Style: ")); p1.add(buttonWire); p1.add(new JLabel("")); p1.add(buttonBalls); p1.add(new JLabel("")); p1.add(buttonDots); JPanel p2 = new TransparentViewPanel(); p2.add(ComponentFactory.createViewLabel("Feature:")); p2.add(highlightCombobox); p2.add(highlightMinMaxCombobox); JPanel clear = new JPanel(new BorderLayout()); clear.setOpaque(false); clear.add(buttonClearFeature); clear.setBorder(new EmptyBorder(0, 1, 0, 0)); p2.add(clear); DefaultFormBuilder b = new DefaultFormBuilder(new FormLayout("left:p")); b.setLineGapSize(Sizes.pixel(0)); b.append(p1); b.append(p); b.append(p2); b.getPanel().setOpaque(false); setLayout(new BorderLayout()); add(b.getPanel(), BorderLayout.WEST); setOpaque(false); } private void addListeners() { ActionListener l = new ActionListener() { public void actionPerformed(ActionEvent e) { if (selfUpdate) return; viewControler.setStyle(((StyleButton) e.getSource()).style); } }; for (StyleButton b : new StyleButton[] { buttonWire, buttonBalls, buttonDots }) b.addActionListener(l); ActionListener l2 = new ActionListener() { public void actionPerformed(ActionEvent e) { viewControler.changeCompoundSize(e.getSource() == buttonPlusSize); } }; buttonPlusSize.addActionListener(l2); buttonMinusSize.addActionListener(l2); ActionListener l3 = new ActionListener() { public void actionPerformed(ActionEvent e) { if (e.getSource() == buttonPlusJitter && viewControler.getJitteringLevel() < JitteringProvider.STEPS) viewControler.setJitteringLevel(viewControler.getJitteringLevel() + 1); else if (viewControler.getJitteringLevel() > 0) viewControler.setJitteringLevel(viewControler.getJitteringLevel() - 1); } }; buttonPlusJitter.addActionListener(l3); buttonMinusJitter.addActionListener(l3); sliderSize.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { if (selfUpdate) return; JSlider source = (JSlider) e.getSource(); if (!source.getValueIsAdjusting()) { viewControler.setCompoundSize((int) source.getValue()); } } }); sliderJitter.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { if (selfUpdate) return; JSlider source = (JSlider) e.getSource(); if (!source.getValueIsAdjusting()) { viewControler.setJitteringLevel((int) source.getValue()); } } }); highlightCombobox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (selfUpdate) return; SwingUtilities.invokeLater(new Runnable() { @Override public void run() { viewControler.setHighlighter((Highlighter) highlightCombobox.getSelectedItem()); } }); } }); highlightMinMaxCombobox.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (selfUpdate) return; SwingUtilities.invokeLater(new Runnable() { @Override public void run() { viewControler.setHighlightSorting((HighlightSorting) highlightMinMaxCombobox.getSelectedItem()); } }); } }); buttonClearFeature.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { viewControler.setHighlighter(Highlighter.DEFAULT_HIGHLIGHTER); } }); clustering.addSelectionListener(new SelectionListener() { @Override public void compoundActiveChanged(Compound[] c) { updateComboStuff(); updateJitteringButtons(); } }); clustering.addListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals(ClusteringImpl.CLUSTER_NEW)) updateSelectedStyle(); } }); viewControler.addViewListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { // Settings.LOGGER.println("fire updated " + // evt.getPropertyName()); if (evt.getPropertyName().equals(ViewControler.PROPERTY_HIGHLIGHT_CHANGED)) { updateComboStuff(); } else if (evt.getPropertyName().equals(ViewControler.PROPERTY_SUPERIMPOSE_CHANGED)) { updateComboStuff(); updateJitteringButtons(); } else if (evt.getPropertyName().equals(ViewControler.PROPERTY_NEW_HIGHLIGHTERS)) { loadHighlighters(); updateComboStuff(); } else if (evt.getPropertyName().equals(ViewControler.PROPERTY_DENSITY_CHANGED)) { selfUpdate = true; buttonPlusSize.setEnabled(viewControler.canChangeCompoundSize(true)); buttonMinusSize.setEnabled(viewControler.canChangeCompoundSize(false)); sliderSize.setEnabled(viewControler.canChangeCompoundSize(false) || viewControler.canChangeCompoundSize(true)); sliderSize.setValue(viewControler.getCompoundSize()); selfUpdate = false; } else if (evt.getPropertyName().equals(ViewControler.PROPERTY_FONT_SIZE_CHANGED)) updateComboSize(); else if (evt.getPropertyName().equals(ViewControler.PROPERTY_STYLE_CHANGED)) updateSelectedStyle(); else if (evt.getPropertyName().equals(ViewControler.PROPERTY_JITTERING_CHANGED)) updateJitteringButtons(); } }); guiControler.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals(GUIControler.PROPERTY_VIEWER_SIZE_CHANGED)) { updateComboSize(); } } }); } private void updateJitteringButtons() { selfUpdate = true; boolean enable = viewControler.canJitter(); buttonPlusJitter.setEnabled(enable && viewControler.getJitteringLevel() < JitteringProvider.STEPS); buttonMinusJitter.setEnabled(enable && viewControler.getJitteringLevel() > 0); sliderJitter.setEnabled(enable); sliderJitter.setValue(viewControler.getJitteringLevel()); selfUpdate = false; } private void updateSelectedStyle() { selfUpdate = true; for (StyleButton b : new StyleButton[] { buttonWire, buttonBalls, buttonDots }) { b.setSelected(viewControler.getStyle() == b.style); if (clustering.isBigDataMode()) b.setEnabled(b == buttonDots); else b.setEnabled(true); } selfUpdate = false; } private void updateComboStuff() { if (!SwingUtilities.isEventDispatchThread()) throw new IllegalStateException("GUI updates only in event dispatch thread plz"); selfUpdate = true; if (((DefaultComboBoxModel<Highlighter>) highlightCombobox.getModel()).getIndexOf(viewControler .getHighlighter()) == -1) new IllegalStateException("cannot find " + viewControler.getHighlighter() + " in highlighter combo box") .printStackTrace(); highlightCombobox.setSelectedItem(viewControler.getHighlighter()); highlightMinMaxCombobox.setSelectedItem(viewControler.getHighlightSorting()); boolean featHighSel = ((Highlighter) highlightCombobox.getSelectedItem()) instanceof CompoundPropertyHighlighter; highlightMinMaxCombobox.setVisible(featHighSel && viewControler.isSuperimpose() && !clustering.isClusterActive()); buttonClearFeature.setVisible(viewControler.getHighlighter() != Highlighter.DEFAULT_HIGHLIGHTER); selfUpdate = false; } private void loadHighlighters() { selfUpdate = true; ((DefaultComboBoxModel<Highlighter>) highlightCombobox.getModel()).removeAllElements(); (((DescriptionListCellRenderer) highlightCombobox.getRenderer())).clearDescriptions(); HashMap<String, Highlighter[]> h = viewControler.getHighlighters(); if (h != null) { int index = 0; for (String desc : h.keySet()) { if (desc != null && desc.length() > 0) (((DescriptionListCellRenderer) highlightCombobox.getRenderer())).addDescription(index, desc); index += h.get(desc).length; for (Highlighter hh : h.get(desc)) highlightCombobox.addItem(hh); } } updateComboSize(); selfUpdate = false; } private void updateComboSize() { highlightCombobox.setPreferredSize(null); Dimension dim = highlightCombobox.getPreferredSize(); int width = Math.min(dim.width, guiControler.getComponentMaxWidth(0.33)); // System.out.println(width); highlightCombobox.setPreferredSize(new Dimension(width, dim.height)); highlightCombobox.setMaximumRowCount(Math.min(highlightCombobox.getItemCount(), 15)); highlightCombobox.revalidate(); } }