ModelMisalignmentsPanel.java
// @formatter:off
/*******************************************************************************
*
* This file is part of JMad.
*
* Copyright (c) 2008-2011, CERN. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************/
// @formatter:on
package cern.accsoft.steering.jmad.gui.panels;
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import cern.accsoft.steering.jmad.domain.machine.Range;
import cern.accsoft.steering.jmad.domain.machine.RangeListener;
import cern.accsoft.steering.jmad.domain.misalign.Misalignment;
import cern.accsoft.steering.jmad.domain.misalign.MisalignmentConfiguration;
import cern.accsoft.steering.jmad.gui.components.DoubleTableCellRenderer;
import cern.accsoft.steering.jmad.model.AbstractJMadModelListener;
import cern.accsoft.steering.jmad.model.JMadModel;
import cern.accsoft.steering.jmad.model.JMadModelListener;
import cern.accsoft.steering.jmad.model.manage.JMadModelManager;
import cern.accsoft.steering.jmad.model.manage.JMadModelManagerAdapter;
import cern.accsoft.steering.util.gui.CompUtils;
import cern.accsoft.steering.util.gui.panels.TableFilterPanel;
import cern.accsoft.steering.util.gui.table.BeanTableEditHandler;
import cern.accsoft.steering.util.gui.table.BeanTableModel;
import cern.accsoft.steering.util.gui.table.SelectionSetTableModel;
import cern.accsoft.steering.util.gui.table.TableModelSelectionAdapter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Kajetan Fuchsberger (kajetan.fuchsberger at cern.ch)
*/
public class ModelMisalignmentsPanel extends JPanel {
private static final long serialVersionUID = -2761017481167940042L;
/** the logger for the class */
private final static Logger logger = LoggerFactory.getLogger(ModelMisalignmentsPanel.class);
/**
* The initial location of the devider between elements-table and element-table.
*/
private final static int DIVIDER_LOCATION = 150;
/** the modelManager, which returns the active model */
private JMadModelManager modelManager;
/** the table model for all misalignment-configurations */
private MisalignmentsTableModel misalignmentsTableModel;
/** the tableModel for one misalignment */
private BeanTableModel misalignmentTableModel;
/** the text field which displays the name of the actual selected element. */
private JTextField txtElementName = null;
/** the listener, which shall be added to every model */
private JMadModelListener modelListener = new AbstractJMadModelListener() {
@Override
public void rangeChanged(Range newRange) {
newRange.addListener(new RangeListener() {
@Override
public void addedMisalignments(MisalignmentConfiguration misalignmentConfiguration) {
/* XXX never called */
misalignmentsTableModel.fireTableDataChanged();
validate();
}
@Override
public void addedMisalignments(List<MisalignmentConfiguration> arg0) {
misalignmentsTableModel.fireTableDataChanged();
validate();
}
});
misalignmentsTableModel.fireTableDataChanged();
validate();
}
@Override
public void becameDirty() {
/* for the moment do not update every time a single value changes. */
}
};
/**
* init-method
*/
public void init() {
initComponents();
}
/**
* create all containing Components
*/
private final void initComponents() {
setLayout(new BorderLayout());
JTable table;
/*
* the panel for the overall list
*/
JPanel listPanel = new JPanel(new GridBagLayout());
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 0;
constraints.gridy = 0;
constraints.weightx = 1;
constraints.weighty = 0;
constraints.fill = GridBagConstraints.BOTH;
misalignmentsTableModel = new MisalignmentsTableModel();
table = new JTable(misalignmentsTableModel);
table.setDefaultRenderer(Double.class, new DoubleTableCellRenderer());
table.setAutoCreateRowSorter(true);
table.getSelectionModel().addListSelectionListener(new MisalignmentsSelectionAdapter(table));
table.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
misalignmentsTableModel.setTableModelSelectionAdapter(new TableModelSelectionAdapter(table));
JScrollPane elementsScrollPane = CompUtils.createScrollPane(table);
/*
* the sorter for the elements-table
*/
listPanel.add(new TableFilterPanel(table), constraints);
constraints.weighty = 1;
constraints.gridx = 0;
constraints.gridy++;
constraints.gridwidth = 2;
listPanel.add(elementsScrollPane, constraints);
/*
* the panel for the details
*/
JPanel detailPanel = new JPanel(new GridBagLayout());
constraints.gridx = 0;
constraints.gridy = 0;
constraints.weightx = 1;
constraints.weighty = 0;
constraints.fill = GridBagConstraints.BOTH;
txtElementName = new JTextField();
txtElementName.setEditable(false);
detailPanel.add(txtElementName, constraints);
constraints.weighty = 1;
constraints.gridy++;
misalignmentTableModel = new BeanTableModel(Misalignment.class);
misalignmentTableModel.setEditable(true);
table = new JTable(misalignmentTableModel);
detailPanel.add(CompUtils.createScrollPane(table), constraints);
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
splitPane.setLeftComponent(listPanel);
// splitPane.setLeftComponent(elementsScrollPane);
splitPane.setRightComponent(detailPanel);
add(splitPane, BorderLayout.CENTER);
splitPane.setDividerLocation(DIVIDER_LOCATION);
}
/**
* the table model for the table of all misalignments
*
* @author Kajetan Fuchsberger (kajetan.fuchsberger at cern.ch)
*/
private class MisalignmentsTableModel extends SelectionSetTableModel {
private static final long serialVersionUID = -5686224769800416136L;
private final static int COL_COUNT = 1;
private final static int COL_INDEX_NAME = 0;
@Override
public int getColumnCount() {
return COL_COUNT;
}
@Override
public int getRowCount() {
return getMisalignmentConfigurations().size();
}
@Override
public Object getValueAt(int row, int col) {
if (COL_INDEX_NAME == col) {
return getMisalignmentConfigurations().get(row).getElementName();
}
return null;
}
@Override
public boolean isCellEditable(int row, int col) {
return false;
}
@Override
public Class<?> getColumnClass(int col) {
switch (col) {
case COL_INDEX_NAME:
return String.class;
default:
return null;
}
}
@Override
public String getColumnName(int col) {
switch (col) {
case COL_INDEX_NAME:
return "element name";
default:
return null;
}
}
}
/**
* This class is the implementation of a listener to change the misalignment
*
* @author Kajetan Fuchsberger (kajetan.fuchsberger at cern.ch)
*/
private class MisalignmentsSelectionAdapter implements ListSelectionListener {
private JTable table = null;
public MisalignmentsSelectionAdapter(JTable table) {
this.table = table;
}
@Override
public void valueChanged(ListSelectionEvent event) {
if (event.getSource() == table.getSelectionModel()) {
int index = table.getSelectedRow();
if (index >= 0) {
setCurrentMisalignment(table.convertRowIndexToModel(index));
}
}
}
}
/**
* sets the the element of the given index as the active one.
*
* @param index
*/
private void setCurrentMisalignment(int index) {
if ((index >= 0) && (modelManager != null)) {
if (index < getMisalignmentConfigurations().size()) {
MisalignmentConfiguration misalignmentConfiguration = getMisalignmentConfigurations().get(index);
txtElementName.setText(misalignmentConfiguration.getElementName());
misalignmentTableModel.setBean(misalignmentConfiguration.getMisalignment());
}
}
}
/**
* @return the active Misalignment-configurations to display
*/
private List<MisalignmentConfiguration> getMisalignmentConfigurations() {
if ((getModelManager() == null) || (getModelManager().getActiveModel() == null)
|| (getModelManager().getActiveModel().getActiveRange() == null)) {
return new ArrayList<MisalignmentConfiguration>();
}
return getModelManager().getActiveModel().getActiveRange().getMisalignmentConfigurations();
}
/**
* @return all mislignment-beans currently selected in the table
*/
private List<Misalignment> getSelectedMisalignments() {
List<Misalignment> misalignments = new ArrayList<Misalignment>();
List<MisalignmentConfiguration> configurations = getMisalignmentConfigurations();
List<Integer> indizes = misalignmentsTableModel.getTableModelSelectionAdapter().getSelectedRowIndizes();
for (Integer index : indizes) {
misalignments.add(configurations.get(index).getMisalignment());
}
return misalignments;
}
/**
* @param modelManager the modelManager to set
*/
public void setModelManager(JMadModelManager modelManager) {
this.modelManager = modelManager;
if (this.modelManager.getActiveModel() != null) {
this.modelManager.getActiveModel().addListener(modelListener);
}
modelManager.addListener(new JMadModelManagerAdapter() {
@Override
public void changedActiveModel(JMadModel newModel) {
if (newModel != null) {
newModel.addListener(modelListener);
}
misalignmentsTableModel.fireTableDataChanged();
}
});
}
/**
* @return the modelManager
*/
private JMadModelManager getModelManager() {
if (this.modelManager == null) {
logger.warn("model manager not set. Maybe config error.");
}
return modelManager;
}
/**
* set an edit-handler for the bean-properties of misalignments.
*
* @param editHandler the editHandler to set
*/
public void setEditHandler(BeanTableEditHandler editHandler) {
this.misalignmentTableModel.setEditHandler(new EditHandlerAdapter(editHandler));
}
/**
* this class adapts the general {@link ModelElementsPanelEditHandler} so, that we can cope with the
* multiple-selection in the misalignments-table.
*
* @author Kajetan Fuchsberger (kajetan.fuchsberger at cern.ch)
*/
private class EditHandlerAdapter implements BeanTableEditHandler {
/** the parent, which to delegate most things to */
private BeanTableEditHandler parent;
/**
* the constructor, which needs a parent to delegate most calls to.
*
* @param parent
*/
private EditHandlerAdapter(BeanTableEditHandler parent) {
this.parent = parent;
}
@Override
public Boolean getCheckValue(Object bean, String propertyName) {
return parent.getCheckValue(bean, propertyName);
}
@Override
public String getCheckableColumnHeader() {
return parent.getCheckableColumnHeader();
}
@Override
public void setCheckValue(Object bean, String propertyName, boolean value) {
/*
* this is the only special thing: we ignore the bean-paramater. Instead we apply to all actually selected
* beans.
*/
List<Misalignment> misalignments = getSelectedMisalignments();
for (Misalignment misalignment : misalignments) {
parent.setCheckValue(misalignment, propertyName, value);
}
}
@Override
public boolean isEditable() {
/*
* TODO: change to true, but how to handle for many models?
*/
return false;
}
}
}