
org.nuiton.math.matrix.viewer.MatrixViewerPanel Maven / Gradle / Ivy
The newest version!
/*
* #%L
* Nuiton Matrix :: GUI
* %%
* Copyright (C) 2010 - 2012 Codelutin, Chatellier Eric
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
package org.nuiton.math.matrix.viewer;
import static org.nuiton.i18n.I18n.t;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSplitPane;
import javax.swing.JToggleButton;
import javax.swing.JToggleButton.ToggleButtonModel;
import org.nuiton.math.matrix.MatrixND;
import org.nuiton.util.Resource;
/**
* Panel that can display matrix list details (dimension) and rendering solutions.
*
* @author chatellier
* @version $Revision$
*
* Last update : $Date$
* By : $Author$
*/
public class MatrixViewerPanel extends JPanel {
/** serialVersionUID. */
private static final long serialVersionUID = -5447856858278176837L;
public static final String PROPERTY_MATRIX_RENDERER_SOLUTION = "matrixRendererSolution";
public static final String PROPERTY_MATRIX_RENDERERS = "matrixRenderers";
public static final String PROPERTY_MATRIX = "matrix";
/** Matrix renderer list solution. (default to {@link MatrixRendererSolution#RADIO_BUTTON} */
protected MatrixRendererSolution matrixRendererSolution = MatrixRendererSolution.RADIO_BUTTON;
/** Matrix renderer plugins. */
protected Map matrixRenderers;
/** La matrice courrement affichées. */
protected MatrixND matrix;
protected MatrixDimensionPanel dimensionPanel;
protected RadioButtonRenderingPanel radioPanel;
protected IconButtonRenderingPanel iconPanel;
protected JPanel renderingComponentContainer;
/**
* Map entre les renderers et les composants (valorisé par bouton de
* rendu) et utilisé par le choix du renderer.
*/
protected Map componentForRenderers;
public MatrixViewerPanel() {
// keep order
matrixRenderers = new LinkedHashMap<>();
componentForRenderers = new HashMap<>();
buildPanel();
}
public MatrixRendererSolution getMatrixRendererSolution() {
return matrixRendererSolution;
}
public void setMatrixRendererSolution(MatrixRendererSolution matrixRendererSolution) {
MatrixRendererSolution oldValue = this.matrixRendererSolution;
this.matrixRendererSolution = matrixRendererSolution;
firePropertyChange(PROPERTY_MATRIX_RENDERER_SOLUTION, oldValue, matrixRendererSolution);
}
public void addMatrixRenderer(MatrixRenderer matrixRenderer) {
addMatrixRenderer(matrixRenderer, false);
}
/**
* Add new matrix renderer.
*
* @param matrixRenderer matrix renderer
* @param defautRenderer renderer can be called with a null matrix to get default rendering
*/
public void addMatrixRenderer(MatrixRenderer matrixRenderer, boolean defautRenderer) {
matrixRenderers.put(matrixRenderer, defautRenderer);
firePropertyChange(PROPERTY_MATRIX_RENDERERS, null, matrixRenderers);
}
public void removeMatrixRenderer(Object matrixRenderer) {
matrixRenderers.remove(matrixRenderer);
firePropertyChange(PROPERTY_MATRIX_RENDERERS, null, matrixRenderers);
}
/**
* Set currently displayed matrix.
*
* @param matrix new matrix to display
*/
public void setMatrix(MatrixND matrix) {
MatrixND oldValue = this.matrix;
this.matrix = matrix;
firePropertyChange(PROPERTY_MATRIX, oldValue, matrix);
}
/**
* Get currently displayed matrix.
*
* @return current matrix
*/
public MatrixND getMatrix() {
return matrix;
}
/**
* Add new action.
*
* @param matrixDimentionAction new action
*/
public void addMatrixDimentionAction(MatrixDimensionAction matrixDimentionAction) {
dimensionPanel.addMatrixDimentionAction(matrixDimentionAction);
}
/** Matrix list combo renderer. */
protected static class MatrixComboRenderer extends DefaultListCellRenderer {
/** serialVersionUID. */
private static final long serialVersionUID = 6151127818315270895L;
@Override
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
String matrixName = null;
if (value != null) {
matrixName = t((String)value);
}
return super.getListCellRendererComponent(list, matrixName, index, isSelected, cellHasFocus);
}
}
/** Button model from button containing rendered instance. */
protected static class RendererButtonModel extends ToggleButtonModel {
/** serialVersionUID. */
private static final long serialVersionUID = -5737246124430280412L;
protected MatrixRenderer renderer;
public RendererButtonModel(MatrixRenderer renderer) {
this.renderer = renderer;
}
public MatrixRenderer getRenderer() {
return renderer;
}
}
/**
* Icon button rendering panel.
* Also contains main render action button (arrow).
*/
protected class IconButtonRenderingPanel extends JPanel implements PropertyChangeListener, ActionListener {
/** serialVersionUID. */
private static final long serialVersionUID = 2591696695747738619L;
protected ButtonGroup buttonGroup;
public IconButtonRenderingPanel() {
super(new GridBagLayout());
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
rebuildPanel();
validate();
repaint();
}
/**
* Rebuild radio button lists.
*/
protected void rebuildPanel() {
removeAll();
JButton renderButton = new JButton(Resource.getIcon("/icons/fatcow/report_go.png"));
renderButton.setActionCommand("render");
renderButton.addActionListener(this);
add(renderButton, new GridBagConstraints(0, 0, 1, 1, 1, 1,
GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
if (matrixRendererSolution == MatrixRendererSolution.ICON) {
int index = 1;
buttonGroup = new ButtonGroup();
for (MatrixRenderer renderer : matrixRenderers.keySet()) {
JToggleButton radioButton = new JToggleButton(renderer.getIcon());
radioButton.addActionListener(this);
radioButton.setModel(new RendererButtonModel(renderer));
// auto select first matrix renderer
if (index == 1) {
radioButton.setSelected(true);
}
buttonGroup.add(radioButton);
add(radioButton, new GridBagConstraints(0, index, 1, 1, 1, 0,
GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
index++;
}
}
}
public MatrixRenderer getSelectedRender() {
MatrixRenderer renderer = null;
RendererButtonModel model = (RendererButtonModel)buttonGroup.getSelection();
if (model != null) {
renderer = model.getRenderer();
}
return renderer;
}
@Override
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();
if ("render".equals(actionCommand)) {
performRendering();
} else {
// clic on render button
updateSelectedRenderingComponent();
}
}
protected void performRendering() {
// get matrix to display filtered
MatrixND matrix = dimensionPanel.getModifiedMatrix();
// matrice superieur a 2 dimensions non geree!!
if (matrix.getDimCount() > 2) {
JOptionPane.showMessageDialog(this, t("nuitonmatrix.viewer.matrix.more.2d"),
t("nuitonmatrix.error"), JOptionPane.ERROR_MESSAGE);
} else {
// get all display component for each renderer
componentForRenderers.clear();
for (MatrixRenderer matrixRenderer : matrixRenderers.keySet()) {
Component component = matrixRenderer.getComponent(matrix);
componentForRenderers.put(matrixRenderer, component);
}
// update UI with selected component
updateSelectedRenderingComponent();
// auto select the one with non default description (to see data matrix)
MatrixRenderer selectedRender = radioPanel.getSelectedRender();
if (matrixRenderers.get(selectedRender)) { // si c'est deja un composant non default, on le laisse
for (Map.Entry matrixRendererDefaults : matrixRenderers.entrySet()) {
if (!matrixRendererDefaults.getValue()) {
radioPanel.setSelectedRender(matrixRendererDefaults.getKey());
break;
}
}
}
}
}
}
/** Radio button rendering panel. */
protected class RadioButtonRenderingPanel extends JPanel implements PropertyChangeListener, ItemListener {
/** serialVersionUID. */
private static final long serialVersionUID = -6312518069621077533L;
protected ButtonGroup buttonGroup;
public RadioButtonRenderingPanel() {
super(new GridBagLayout());
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
rebuildPanel();
validate();
repaint();
}
/**
* Rebuild radio button lists.
*/
protected void rebuildPanel() {
removeAll();
if (matrixRendererSolution == MatrixRendererSolution.RADIO_BUTTON) {
int index = 0;
buttonGroup = new ButtonGroup();
for (MatrixRenderer renderer : matrixRenderers.keySet()) {
JRadioButton radioButton = new JRadioButton(renderer.getName());
radioButton.addItemListener(this);
radioButton.setModel(new RendererButtonModel(renderer));
buttonGroup.add(radioButton);
// auto select first matrix renderer
if (index == 0) {
radioButton.setSelected(true);
}
add(radioButton, new GridBagConstraints(index, 0, 1, 1, 1, 1,
GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
index++;
}
setVisible(true);
}
else {
setVisible(false);
}
}
public MatrixRenderer getSelectedRender() {
MatrixRenderer renderer = null;
RendererButtonModel model = (RendererButtonModel)buttonGroup.getSelection();
if (model != null) {
renderer = model.getRenderer();
}
return renderer;
}
/**
* Selectionne le radio button associé au renderer specifié.
*/
public void setSelectedRender(MatrixRenderer renderer) {
Enumeration elements = buttonGroup.getElements();
while (elements.hasMoreElements()) {
AbstractButton abstractButton = elements.nextElement();
RendererButtonModel buttonModel = (RendererButtonModel)abstractButton.getModel();
if (buttonModel.getRenderer().equals(renderer)) {
buttonGroup.setSelected(buttonModel, true);
}
}
}
@Override
public void itemStateChanged(ItemEvent itemEvent) {
if (itemEvent.getStateChange() == ItemEvent.SELECTED) {
updateSelectedRenderingComponent();
}
}
}
/**
* Build main panel.
*/
protected void buildPanel() {
setLayout(new BorderLayout());
// split main ui left/rigth
JPanel editionSidePanel = new JPanel(new BorderLayout());
JPanel renderSidePanel = new JPanel(new BorderLayout());
JSplitPane mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, editionSidePanel, renderSidePanel);
mainSplitPane.setDividerLocation(0.3);
add(mainSplitPane, BorderLayout.CENTER);
// panel d'affichage des dimensions
dimensionPanel = new MatrixDimensionPanel();
editionSidePanel.add(dimensionPanel, BorderLayout.CENTER);
addPropertyChangeListener(PROPERTY_MATRIX, dimensionPanel);
// fleche de d'action de rendu
// render type : icon
iconPanel = new IconButtonRenderingPanel();
editionSidePanel.add(iconPanel, BorderLayout.EAST);
addPropertyChangeListener(PROPERTY_MATRIX_RENDERER_SOLUTION, iconPanel);
addPropertyChangeListener(PROPERTY_MATRIX_RENDERERS, iconPanel);
// render type : combo box
// current rendering pane
renderingComponentContainer = new JPanel(new BorderLayout());
renderSidePanel.add(renderingComponentContainer, BorderLayout.CENTER);
// render type : radio button
radioPanel = new RadioButtonRenderingPanel();
renderSidePanel.add(radioPanel, BorderLayout.SOUTH);
addPropertyChangeListener(PROPERTY_MATRIX_RENDERER_SOLUTION, radioPanel);
addPropertyChangeListener(PROPERTY_MATRIX_RENDERERS, radioPanel);
}
/**
* Set rendering component in rendering container.
*/
public void updateSelectedRenderingComponent() {
renderingComponentContainer.removeAll();
MatrixRenderer matrixRenderer = null;
switch (matrixRendererSolution) {
case ICON:
matrixRenderer = iconPanel.getSelectedRender();
break;
case RADIO_BUTTON:
matrixRenderer = radioPanel.getSelectedRender();
break;
}
if (!componentForRenderers.isEmpty()) {
if (matrixRenderer != null) {
Component component = componentForRenderers.get(matrixRenderer);
if (component != null) {
renderingComponentContainer.add(component, BorderLayout.CENTER);
}
}
} else {
// if enables default rendering
if (matrixRenderers.get(matrixRenderer)) {
Component component = matrixRenderer.getComponent(null);
if (component != null) {
renderingComponentContainer.add(component, BorderLayout.CENTER);
}
}
}
renderingComponentContainer.validate();
renderingComponentContainer.repaint();
}
/**
* Init renderering by autoselecting some dimensions values and some dimensions
* action. And perform rendering.
*
* @param dimSelectedValues selected values in each dimensions
* @param selectedActions selected action in each dimensions
* @throws IllegalArgumentException if matrix has not been set
*/
public void initRenderering(List[] dimSelectedValues, int[] selectedActions) {
if (this.matrix == null) {
throw new IllegalArgumentException("Must set matrix first");
}
dimensionPanel.initRenderering(dimSelectedValues, selectedActions);
iconPanel.performRendering();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy