Clean up structure a bit
(I'm doing this for a later commit I will push in this PR)
This commit is contained in:
parent
96f3e671b0
commit
8051e5c9c1
@ -60,7 +60,6 @@ import net.sf.openrocket.gui.dialogs.preferences.PreferencesDialog;
|
||||
import net.sf.openrocket.gui.figure3d.photo.PhotoFrame;
|
||||
import net.sf.openrocket.gui.help.tours.GuidedTourSelectionDialog;
|
||||
import net.sf.openrocket.gui.main.componenttree.ComponentTree;
|
||||
import net.sf.openrocket.gui.main.flightconfigpanel.FlightConfigurationPanel;
|
||||
import net.sf.openrocket.gui.scalefigure.RocketPanel;
|
||||
import net.sf.openrocket.gui.util.DummyFrameMenuOSX;
|
||||
import net.sf.openrocket.gui.util.FileHelper;
|
||||
@ -276,6 +275,7 @@ public class BasicFrame extends JFrame {
|
||||
* with the left component the design tree and the right component buttons
|
||||
* for adding components.
|
||||
*/
|
||||
// TODO LOW: Put this in a separate file...
|
||||
private JComponent designTab() {
|
||||
JSplitPane horizontal = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true);
|
||||
horizontal.setResizeWeight(0.5);
|
||||
|
@ -1,4 +1,4 @@
|
||||
package net.sf.openrocket.gui.main.flightconfigpanel;
|
||||
package net.sf.openrocket.gui.main;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
@ -20,7 +20,9 @@ import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.document.OpenRocketDocument;
|
||||
import net.sf.openrocket.document.Simulation;
|
||||
import net.sf.openrocket.gui.dialogs.flightconfiguration.RenameConfigDialog;
|
||||
import net.sf.openrocket.gui.main.BasicFrame;
|
||||
import net.sf.openrocket.gui.main.flightconfigpanel.MotorConfigurationPanel;
|
||||
import net.sf.openrocket.gui.main.flightconfigpanel.RecoveryConfigurationPanel;
|
||||
import net.sf.openrocket.gui.main.flightconfigpanel.SeparationConfigurationPanel;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfigurableComponent;
|
@ -1,334 +1,334 @@
|
||||
package net.sf.openrocket.gui.main.flightconfigpanel;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Font;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
|
||||
import net.sf.openrocket.util.ArrayList;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.formatting.RocketDescriptor;
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfigurableComponent;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.util.Pair;
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class FlightConfigurablePanel<T extends FlightConfigurableComponent> extends JPanel implements ComponentChangeListener {
|
||||
|
||||
protected static final Translator trans = Application.getTranslator();
|
||||
private static final Logger log = LoggerFactory.getLogger(FlightConfigurablePanel.class);
|
||||
protected RocketDescriptor descriptor = Application.getInjector().getInstance(RocketDescriptor.class);
|
||||
|
||||
protected final FlightConfigurationPanel flightConfigurationPanel;
|
||||
protected final Rocket rocket;
|
||||
protected final JTable table;
|
||||
|
||||
public FlightConfigurablePanel(final FlightConfigurationPanel flightConfigurationPanel, Rocket rocket) {
|
||||
super(new MigLayout("fill"));
|
||||
this.flightConfigurationPanel = flightConfigurationPanel;
|
||||
this.rocket = rocket;
|
||||
table = doTableInitialization();
|
||||
|
||||
installTableListener();
|
||||
synchronizeConfigurationSelection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the data in the table, with component change event type {cce}
|
||||
* @param cce index of the ComponentChangeEvent to use (e.g. ComponentChangeEvent.NONFUNCTIONAL_CHANGE)
|
||||
*/
|
||||
public void fireTableDataChanged(int cce) {
|
||||
int selectedRow = table.getSelectedRow();
|
||||
int selectedColumn = table.getSelectedColumn();
|
||||
this.rocket.fireComponentChangeEvent(cce);
|
||||
((AbstractTableModel)table.getModel()).fireTableDataChanged();
|
||||
restoreSelection(selectedRow,selectedColumn);
|
||||
updateButtonState();
|
||||
}
|
||||
|
||||
protected abstract void updateButtonState();
|
||||
|
||||
@Override
|
||||
public void componentChanged(ComponentChangeEvent e) {
|
||||
this.synchronizeConfigurationSelection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the table using the specific implementation's initializeTable
|
||||
* method and then select the row to match what the rocket's current selected
|
||||
* configuration is.
|
||||
*
|
||||
* @return the JTable created
|
||||
*/
|
||||
private final JTable doTableInitialization() {
|
||||
JTable table = this.initializeTable();
|
||||
FlightConfigurationId current = this.rocket.getSelectedConfiguration().getFlightConfigurationID();
|
||||
int col = (table.getColumnCount() > 1) ? table.getColumnCount() - 1 : 0;
|
||||
for (int row = 0; row < table.getRowCount(); row++) {
|
||||
FlightConfigurationId rowFCID = rocket.getId(row);
|
||||
if (rowFCID.equals(current)) {
|
||||
table.changeSelection(row, col, false, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
protected final void synchronizeConfigurationSelection() {
|
||||
FlightConfigurationId currentRocketFCID = rocket.getSelectedConfiguration().getFlightConfigurationID();
|
||||
FlightConfigurationId selectedFCID = getSelectedConfigurationId();
|
||||
|
||||
if ( currentRocketFCID == FlightConfigurationId.DEFAULT_VALUE_FCID ) {
|
||||
// need to unselect
|
||||
table.clearSelection();
|
||||
} else if ( !currentRocketFCID.equals(selectedFCID)){
|
||||
// Need to change selection
|
||||
// We'll select the correct row, in the currently selected column.
|
||||
int col = table.getSelectedColumn();
|
||||
if ( col < 0 ) {
|
||||
col = (table.getColumnCount() > 1) ? table.getColumnCount() - 1 : 0;
|
||||
}
|
||||
|
||||
for( int rowNum = 0; rowNum < table.getRowCount(); rowNum++ ) {
|
||||
FlightConfigurationId rowFCID = rocket.getId(rowNum );
|
||||
if ( rowFCID.equals(currentRocketFCID) ) {
|
||||
table.changeSelection(rowNum, col, false, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void restoreSelection( int row, int col ) {
|
||||
if ( row <= 0 || col <= 0 ) {
|
||||
synchronizeConfigurationSelection();
|
||||
return;
|
||||
}
|
||||
if ( row >= table.getRowCount() || col >= table.getColumnCount() ) {
|
||||
synchronizeConfigurationSelection();
|
||||
return;
|
||||
}
|
||||
table.changeSelection(row, col, true, false);
|
||||
table.requestFocusInWindow();
|
||||
}
|
||||
|
||||
protected void installTableListener() {
|
||||
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
if ( e.getValueIsAdjusting() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find the selected row and set it as the current selected configuration
|
||||
* for the rocket. This will propagate the event to ensure that other
|
||||
* pieces of the UI are updated and match the table selection.
|
||||
*/
|
||||
int firstrow = e.getFirstIndex();
|
||||
int lastrow = e.getLastIndex();
|
||||
ListSelectionModel model = (ListSelectionModel) e.getSource();
|
||||
for( int row = firstrow; row <= lastrow; row ++) {
|
||||
if ( model.isSelectedIndex(row) ) {
|
||||
FlightConfigurationId fcid = (FlightConfigurationId) table.getValueAt(row, table.convertColumnIndexToView(0));
|
||||
rocket.setSelectedConfiguration(fcid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to create the embedded JTable and it's backing Model.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected abstract JTable initializeTable();
|
||||
|
||||
protected T getSelectedComponent() {
|
||||
|
||||
int col = table.convertColumnIndexToModel(table.getSelectedColumn());
|
||||
int row = table.convertRowIndexToModel(table.getSelectedRow());
|
||||
if ( row < 0 || col < 0 ) {
|
||||
return null;
|
||||
}
|
||||
Object tableValue = table.getModel().getValueAt(row, col);
|
||||
if ( tableValue instanceof Pair ) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Pair<String,T> selectedComponent = (Pair<String,T>) tableValue;
|
||||
return selectedComponent.getV();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected List<T> getSelectedComponents() {
|
||||
int[] cols = Arrays.stream(table.getSelectedColumns()).map(table::convertRowIndexToModel).toArray();
|
||||
int[] rows = Arrays.stream(table.getSelectedRows()).map(table::convertRowIndexToModel).toArray();
|
||||
if (Arrays.stream(cols).min().isEmpty() || Arrays.stream(rows).min().isEmpty() ||
|
||||
Arrays.stream(cols).min().getAsInt() < 0 || Arrays.stream(rows).min().getAsInt() < 0) {
|
||||
return null;
|
||||
}
|
||||
List<T> components = new ArrayList<>();
|
||||
for (int row : rows) {
|
||||
for (int col : cols) {
|
||||
Object tableValue = table.getModel().getValueAt(row, col);
|
||||
if (tableValue instanceof Pair) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Pair<String, T> selectedComponent = (Pair<String, T>) tableValue;
|
||||
components.add(selectedComponent.getV());
|
||||
}
|
||||
}
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
protected FlightConfigurationId getSelectedConfigurationId() {
|
||||
int col = table.convertColumnIndexToModel(table.getSelectedColumn());
|
||||
int row = table.convertRowIndexToModel(table.getSelectedRow());
|
||||
if ( row < 0 || col < 0 || row >= table.getRowCount() || col >= table.getColumnCount() ) {
|
||||
return null;
|
||||
}
|
||||
Object tableValue = table.getModel().getValueAt(row, col);
|
||||
if ( tableValue instanceof Pair ) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Pair<FlightConfigurationId,T> selectedComponent = (Pair<FlightConfigurationId,T>) tableValue;
|
||||
FlightConfigurationId fcid = selectedComponent.getU();
|
||||
return fcid;
|
||||
} else if ( tableValue instanceof FlightConfigurationId ){
|
||||
return (FlightConfigurationId) tableValue;
|
||||
}
|
||||
return FlightConfigurationId.ERROR_FCID;
|
||||
}
|
||||
|
||||
protected List<FlightConfigurationId> getSelectedConfigurationIds() {
|
||||
int col = table.convertColumnIndexToModel(table.getSelectedColumn());
|
||||
int[] rows = Arrays.stream(table.getSelectedRows()).map(table::convertRowIndexToModel).toArray();
|
||||
if (Arrays.stream(rows).min().isEmpty() || Arrays.stream(rows).min().getAsInt() < 0 || col < 0 ||
|
||||
Arrays.stream(rows).max().getAsInt() >= table.getRowCount() || col >= table.getColumnCount() ) {
|
||||
return null;
|
||||
}
|
||||
Object[] tableValues = Arrays.stream(rows).mapToObj(c -> table.getModel().getValueAt(c, col)).toArray();
|
||||
List<FlightConfigurationId> Ids = new ArrayList<>();
|
||||
for (Object tableValue : tableValues) {
|
||||
if (tableValue instanceof Pair) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Pair<FlightConfigurationId, T> selectedComponent = (Pair<FlightConfigurationId, T>) tableValue;
|
||||
FlightConfigurationId fcid = selectedComponent.getU();
|
||||
Ids.add(fcid);
|
||||
} else if (tableValue instanceof FlightConfigurationId) {
|
||||
Ids.add((FlightConfigurationId) tableValue);
|
||||
} else {
|
||||
Ids.add(FlightConfigurationId.ERROR_FCID);
|
||||
}
|
||||
}
|
||||
|
||||
return Ids;
|
||||
}
|
||||
|
||||
protected abstract class FlightConfigurableCellRenderer extends DefaultTableCellRenderer {
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object newValue, boolean isSelected, boolean hasFocus, int row, int column) {
|
||||
JLabel label = (JLabel) super.getTableCellRendererComponent(table, newValue, isSelected, hasFocus, row, column);
|
||||
Object oldValue = table.getModel().getValueAt(row, column);
|
||||
|
||||
// this block is more for the benefit of the reader than the computer --
|
||||
// this assignment is technically redundant, but useful to point out that the new value here is often null,
|
||||
// while the old value seems to always be valid.
|
||||
if( null == newValue ){
|
||||
log.warn("Detected null newValue to render... (oldValue: "+oldValue+")");
|
||||
newValue = oldValue;
|
||||
}
|
||||
|
||||
column = table.convertColumnIndexToModel(column);
|
||||
switch (column) {
|
||||
case 0: {
|
||||
label.setText(descriptor.format(rocket, (FlightConfigurationId) oldValue));
|
||||
regular(label);
|
||||
setSelected(label, table, isSelected, hasFocus);
|
||||
return label;
|
||||
}
|
||||
default: {
|
||||
@SuppressWarnings("unchecked")
|
||||
Pair<FlightConfigurationId, T> v = (Pair<FlightConfigurationId, T>) oldValue;
|
||||
|
||||
if(v!=null){
|
||||
FlightConfigurationId fcid = v.getU();
|
||||
T component = v.getV();
|
||||
label = format(component, fcid, label );
|
||||
}
|
||||
for (Component c : label.getComponents()) {
|
||||
if (c instanceof JLabel) {
|
||||
setSelected((JLabel)c, table, isSelected, hasFocus);
|
||||
}
|
||||
}
|
||||
setSelected(label, table, isSelected, hasFocus);
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final void setSelected( JComponent c, JTable table, boolean isSelected, boolean hasFocus ) {
|
||||
c.setOpaque(true);
|
||||
if ( isSelected) {
|
||||
c.setBackground(table.getSelectionBackground());
|
||||
c.setForeground((Color)UIManager.get("Table.selectionForeground"));
|
||||
} else {
|
||||
c.setBackground(table.getBackground());
|
||||
c.setForeground(c.getForeground());
|
||||
}
|
||||
Border b = null;
|
||||
if ( hasFocus ) {
|
||||
if (isSelected) {
|
||||
b = UIManager.getBorder("Table.focusSelectedCellHighlightBorder");
|
||||
} else {
|
||||
b = UIManager.getBorder("Table.focusCellHighligtBorder");
|
||||
}
|
||||
} else {
|
||||
b = new EmptyBorder(1,1,1,1);
|
||||
}
|
||||
c.setBorder(b);
|
||||
}
|
||||
|
||||
protected final void shaded(JLabel label) {
|
||||
GUIUtil.changeFontStyle(label, Font.ITALIC);
|
||||
label.setForeground(Color.GRAY);
|
||||
}
|
||||
|
||||
protected final void regular(JLabel label) {
|
||||
GUIUtil.changeFontStyle(label, Font.PLAIN);
|
||||
label.setForeground(Color.BLACK);
|
||||
}
|
||||
|
||||
protected abstract JLabel format( T component, FlightConfigurationId configId, JLabel label );
|
||||
|
||||
}
|
||||
|
||||
package net.sf.openrocket.gui.main.flightconfigpanel;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Font;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.ListSelectionModel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import javax.swing.table.DefaultTableCellRenderer;
|
||||
|
||||
import net.sf.openrocket.gui.main.FlightConfigurationPanel;
|
||||
import net.sf.openrocket.util.ArrayList;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.formatting.RocketDescriptor;
|
||||
import net.sf.openrocket.gui.util.GUIUtil;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfigurableComponent;
|
||||
import net.sf.openrocket.rocketcomponent.FlightConfigurationId;
|
||||
import net.sf.openrocket.rocketcomponent.Rocket;
|
||||
import net.sf.openrocket.startup.Application;
|
||||
import net.sf.openrocket.util.Pair;
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public abstract class FlightConfigurablePanel<T extends FlightConfigurableComponent> extends JPanel implements ComponentChangeListener {
|
||||
|
||||
protected static final Translator trans = Application.getTranslator();
|
||||
private static final Logger log = LoggerFactory.getLogger(FlightConfigurablePanel.class);
|
||||
protected RocketDescriptor descriptor = Application.getInjector().getInstance(RocketDescriptor.class);
|
||||
|
||||
protected final FlightConfigurationPanel flightConfigurationPanel;
|
||||
protected final Rocket rocket;
|
||||
protected final JTable table;
|
||||
|
||||
public FlightConfigurablePanel(final FlightConfigurationPanel flightConfigurationPanel, Rocket rocket) {
|
||||
super(new MigLayout("fill"));
|
||||
this.flightConfigurationPanel = flightConfigurationPanel;
|
||||
this.rocket = rocket;
|
||||
table = doTableInitialization();
|
||||
|
||||
installTableListener();
|
||||
synchronizeConfigurationSelection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the data in the table, with component change event type {cce}
|
||||
* @param cce index of the ComponentChangeEvent to use (e.g. ComponentChangeEvent.NONFUNCTIONAL_CHANGE)
|
||||
*/
|
||||
public void fireTableDataChanged(int cce) {
|
||||
int selectedRow = table.getSelectedRow();
|
||||
int selectedColumn = table.getSelectedColumn();
|
||||
this.rocket.fireComponentChangeEvent(cce);
|
||||
((AbstractTableModel)table.getModel()).fireTableDataChanged();
|
||||
restoreSelection(selectedRow,selectedColumn);
|
||||
updateButtonState();
|
||||
}
|
||||
|
||||
public abstract void updateButtonState();
|
||||
|
||||
@Override
|
||||
public void componentChanged(ComponentChangeEvent e) {
|
||||
this.synchronizeConfigurationSelection();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the table using the specific implementation's initializeTable
|
||||
* method and then select the row to match what the rocket's current selected
|
||||
* configuration is.
|
||||
*
|
||||
* @return the JTable created
|
||||
*/
|
||||
private final JTable doTableInitialization() {
|
||||
JTable table = this.initializeTable();
|
||||
FlightConfigurationId current = this.rocket.getSelectedConfiguration().getFlightConfigurationID();
|
||||
int col = (table.getColumnCount() > 1) ? table.getColumnCount() - 1 : 0;
|
||||
for (int row = 0; row < table.getRowCount(); row++) {
|
||||
FlightConfigurationId rowFCID = rocket.getId(row);
|
||||
if (rowFCID.equals(current)) {
|
||||
table.changeSelection(row, col, false, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
public final void synchronizeConfigurationSelection() {
|
||||
FlightConfigurationId currentRocketFCID = rocket.getSelectedConfiguration().getFlightConfigurationID();
|
||||
FlightConfigurationId selectedFCID = getSelectedConfigurationId();
|
||||
|
||||
if ( currentRocketFCID == FlightConfigurationId.DEFAULT_VALUE_FCID ) {
|
||||
// need to unselect
|
||||
table.clearSelection();
|
||||
} else if ( !currentRocketFCID.equals(selectedFCID)){
|
||||
// Need to change selection
|
||||
// We'll select the correct row, in the currently selected column.
|
||||
int col = table.getSelectedColumn();
|
||||
if ( col < 0 ) {
|
||||
col = (table.getColumnCount() > 1) ? table.getColumnCount() - 1 : 0;
|
||||
}
|
||||
|
||||
for( int rowNum = 0; rowNum < table.getRowCount(); rowNum++ ) {
|
||||
FlightConfigurationId rowFCID = rocket.getId(rowNum );
|
||||
if ( rowFCID.equals(currentRocketFCID) ) {
|
||||
table.changeSelection(rowNum, col, false, false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void restoreSelection( int row, int col ) {
|
||||
if ( row <= 0 || col <= 0 ) {
|
||||
synchronizeConfigurationSelection();
|
||||
return;
|
||||
}
|
||||
if ( row >= table.getRowCount() || col >= table.getColumnCount() ) {
|
||||
synchronizeConfigurationSelection();
|
||||
return;
|
||||
}
|
||||
table.changeSelection(row, col, true, false);
|
||||
table.requestFocusInWindow();
|
||||
}
|
||||
|
||||
protected void installTableListener() {
|
||||
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
if ( e.getValueIsAdjusting() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find the selected row and set it as the current selected configuration
|
||||
* for the rocket. This will propagate the event to ensure that other
|
||||
* pieces of the UI are updated and match the table selection.
|
||||
*/
|
||||
int firstrow = e.getFirstIndex();
|
||||
int lastrow = e.getLastIndex();
|
||||
ListSelectionModel model = (ListSelectionModel) e.getSource();
|
||||
for( int row = firstrow; row <= lastrow; row ++) {
|
||||
if ( model.isSelectedIndex(row) ) {
|
||||
FlightConfigurationId fcid = (FlightConfigurationId) table.getValueAt(row, table.convertColumnIndexToView(0));
|
||||
rocket.setSelectedConfiguration(fcid);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to create the embedded JTable and it's backing Model.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
protected abstract JTable initializeTable();
|
||||
|
||||
protected T getSelectedComponent() {
|
||||
|
||||
int col = table.convertColumnIndexToModel(table.getSelectedColumn());
|
||||
int row = table.convertRowIndexToModel(table.getSelectedRow());
|
||||
if ( row < 0 || col < 0 ) {
|
||||
return null;
|
||||
}
|
||||
Object tableValue = table.getModel().getValueAt(row, col);
|
||||
if ( tableValue instanceof Pair ) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Pair<String,T> selectedComponent = (Pair<String,T>) tableValue;
|
||||
return selectedComponent.getV();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected List<T> getSelectedComponents() {
|
||||
int[] cols = Arrays.stream(table.getSelectedColumns()).map(table::convertRowIndexToModel).toArray();
|
||||
int[] rows = Arrays.stream(table.getSelectedRows()).map(table::convertRowIndexToModel).toArray();
|
||||
if (Arrays.stream(cols).min().isEmpty() || Arrays.stream(rows).min().isEmpty() ||
|
||||
Arrays.stream(cols).min().getAsInt() < 0 || Arrays.stream(rows).min().getAsInt() < 0) {
|
||||
return null;
|
||||
}
|
||||
List<T> components = new ArrayList<>();
|
||||
for (int row : rows) {
|
||||
for (int col : cols) {
|
||||
Object tableValue = table.getModel().getValueAt(row, col);
|
||||
if (tableValue instanceof Pair) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Pair<String, T> selectedComponent = (Pair<String, T>) tableValue;
|
||||
components.add(selectedComponent.getV());
|
||||
}
|
||||
}
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
protected FlightConfigurationId getSelectedConfigurationId() {
|
||||
int col = table.convertColumnIndexToModel(table.getSelectedColumn());
|
||||
int row = table.convertRowIndexToModel(table.getSelectedRow());
|
||||
if ( row < 0 || col < 0 || row >= table.getRowCount() || col >= table.getColumnCount() ) {
|
||||
return null;
|
||||
}
|
||||
Object tableValue = table.getModel().getValueAt(row, col);
|
||||
if ( tableValue instanceof Pair ) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Pair<FlightConfigurationId,T> selectedComponent = (Pair<FlightConfigurationId,T>) tableValue;
|
||||
FlightConfigurationId fcid = selectedComponent.getU();
|
||||
return fcid;
|
||||
} else if ( tableValue instanceof FlightConfigurationId ){
|
||||
return (FlightConfigurationId) tableValue;
|
||||
}
|
||||
return FlightConfigurationId.ERROR_FCID;
|
||||
}
|
||||
|
||||
public List<FlightConfigurationId> getSelectedConfigurationIds() {
|
||||
int col = table.convertColumnIndexToModel(table.getSelectedColumn());
|
||||
int[] rows = Arrays.stream(table.getSelectedRows()).map(table::convertRowIndexToModel).toArray();
|
||||
if (Arrays.stream(rows).min().isEmpty() || Arrays.stream(rows).min().getAsInt() < 0 || col < 0 ||
|
||||
Arrays.stream(rows).max().getAsInt() >= table.getRowCount() || col >= table.getColumnCount() ) {
|
||||
return null;
|
||||
}
|
||||
Object[] tableValues = Arrays.stream(rows).mapToObj(c -> table.getModel().getValueAt(c, col)).toArray();
|
||||
List<FlightConfigurationId> Ids = new ArrayList<>();
|
||||
for (Object tableValue : tableValues) {
|
||||
if (tableValue instanceof Pair) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Pair<FlightConfigurationId, T> selectedComponent = (Pair<FlightConfigurationId, T>) tableValue;
|
||||
FlightConfigurationId fcid = selectedComponent.getU();
|
||||
Ids.add(fcid);
|
||||
} else if (tableValue instanceof FlightConfigurationId) {
|
||||
Ids.add((FlightConfigurationId) tableValue);
|
||||
} else {
|
||||
Ids.add(FlightConfigurationId.ERROR_FCID);
|
||||
}
|
||||
}
|
||||
|
||||
return Ids;
|
||||
}
|
||||
|
||||
protected abstract class FlightConfigurableCellRenderer extends DefaultTableCellRenderer {
|
||||
|
||||
@Override
|
||||
public Component getTableCellRendererComponent(JTable table, Object newValue, boolean isSelected, boolean hasFocus, int row, int column) {
|
||||
JLabel label = (JLabel) super.getTableCellRendererComponent(table, newValue, isSelected, hasFocus, row, column);
|
||||
Object oldValue = table.getModel().getValueAt(row, column);
|
||||
|
||||
// this block is more for the benefit of the reader than the computer --
|
||||
// this assignment is technically redundant, but useful to point out that the new value here is often null,
|
||||
// while the old value seems to always be valid.
|
||||
if( null == newValue ){
|
||||
log.warn("Detected null newValue to render... (oldValue: "+oldValue+")");
|
||||
newValue = oldValue;
|
||||
}
|
||||
|
||||
column = table.convertColumnIndexToModel(column);
|
||||
switch (column) {
|
||||
case 0: {
|
||||
label.setText(descriptor.format(rocket, (FlightConfigurationId) oldValue));
|
||||
regular(label);
|
||||
setSelected(label, table, isSelected, hasFocus);
|
||||
return label;
|
||||
}
|
||||
default: {
|
||||
@SuppressWarnings("unchecked")
|
||||
Pair<FlightConfigurationId, T> v = (Pair<FlightConfigurationId, T>) oldValue;
|
||||
|
||||
if(v!=null){
|
||||
FlightConfigurationId fcid = v.getU();
|
||||
T component = v.getV();
|
||||
label = format(component, fcid, label );
|
||||
}
|
||||
for (Component c : label.getComponents()) {
|
||||
if (c instanceof JLabel) {
|
||||
setSelected((JLabel)c, table, isSelected, hasFocus);
|
||||
}
|
||||
}
|
||||
setSelected(label, table, isSelected, hasFocus);
|
||||
return label;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final void setSelected( JComponent c, JTable table, boolean isSelected, boolean hasFocus ) {
|
||||
c.setOpaque(true);
|
||||
if ( isSelected) {
|
||||
c.setBackground(table.getSelectionBackground());
|
||||
c.setForeground((Color)UIManager.get("Table.selectionForeground"));
|
||||
} else {
|
||||
c.setBackground(table.getBackground());
|
||||
c.setForeground(c.getForeground());
|
||||
}
|
||||
Border b = null;
|
||||
if ( hasFocus ) {
|
||||
if (isSelected) {
|
||||
b = UIManager.getBorder("Table.focusSelectedCellHighlightBorder");
|
||||
} else {
|
||||
b = UIManager.getBorder("Table.focusCellHighligtBorder");
|
||||
}
|
||||
} else {
|
||||
b = new EmptyBorder(1,1,1,1);
|
||||
}
|
||||
c.setBorder(b);
|
||||
}
|
||||
|
||||
protected final void shaded(JLabel label) {
|
||||
GUIUtil.changeFontStyle(label, Font.ITALIC);
|
||||
label.setForeground(Color.GRAY);
|
||||
}
|
||||
|
||||
protected final void regular(JLabel label) {
|
||||
GUIUtil.changeFontStyle(label, Font.PLAIN);
|
||||
label.setForeground(Color.BLACK);
|
||||
}
|
||||
|
||||
protected abstract JLabel format( T component, FlightConfigurationId configId, JLabel label );
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -33,6 +33,7 @@ import net.miginfocom.swing.MigLayout;
|
||||
import net.sf.openrocket.gui.dialogs.flightconfiguration.IgnitionSelectionDialog;
|
||||
import net.sf.openrocket.gui.dialogs.flightconfiguration.MotorMountConfigurationPanel;
|
||||
import net.sf.openrocket.gui.dialogs.motor.MotorChooserDialog;
|
||||
import net.sf.openrocket.gui.main.FlightConfigurationPanel;
|
||||
import net.sf.openrocket.gui.widgets.SelectColorButton;
|
||||
import net.sf.openrocket.motor.IgnitionEvent;
|
||||
import net.sf.openrocket.motor.Motor;
|
||||
@ -65,7 +66,7 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
|
||||
private final JPopupMenu popupMenuFull; // popup menu containing all the options
|
||||
|
||||
|
||||
MotorConfigurationPanel(final FlightConfigurationPanel flightConfigurationPanel, Rocket rocket) {
|
||||
public MotorConfigurationPanel(final FlightConfigurationPanel flightConfigurationPanel, Rocket rocket) {
|
||||
super(flightConfigurationPanel, rocket);
|
||||
|
||||
motorChooserDialog = new MotorChooserDialog(SwingUtilities.getWindowAncestor(flightConfigurationPanel));
|
||||
@ -294,7 +295,7 @@ public class MotorConfigurationPanel extends FlightConfigurablePanel<MotorMount>
|
||||
flightConfigurationPanel.setSelectedComponents(components);
|
||||
}
|
||||
|
||||
protected void updateButtonState() {
|
||||
public void updateButtonState() {
|
||||
if( configurationTableModel.getColumnCount() > 1 ) {
|
||||
showContent();
|
||||
|
||||
|
@ -25,6 +25,7 @@ import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import net.sf.openrocket.formatting.RocketDescriptor;
|
||||
import net.sf.openrocket.gui.dialogs.flightconfiguration.DeploymentSelectionDialog;
|
||||
import net.sf.openrocket.gui.main.FlightConfigurationPanel;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.*;
|
||||
import net.sf.openrocket.rocketcomponent.DeploymentConfiguration.DeployEvent;
|
||||
@ -43,7 +44,7 @@ public class RecoveryConfigurationPanel extends FlightConfigurablePanel<Recovery
|
||||
private final JPopupMenu popupMenuFull; // popup menu containing all the options
|
||||
|
||||
|
||||
RecoveryConfigurationPanel(FlightConfigurationPanel flightConfigurationPanel, Rocket rocket) {
|
||||
public RecoveryConfigurationPanel(FlightConfigurationPanel flightConfigurationPanel, Rocket rocket) {
|
||||
super(flightConfigurationPanel,rocket);
|
||||
|
||||
JScrollPane scroll = new JScrollPane(table);
|
||||
|
@ -25,6 +25,7 @@ import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import net.sf.openrocket.formatting.RocketDescriptor;
|
||||
import net.sf.openrocket.gui.dialogs.flightconfiguration.SeparationSelectionDialog;
|
||||
import net.sf.openrocket.gui.main.FlightConfigurationPanel;
|
||||
import net.sf.openrocket.l10n.Translator;
|
||||
import net.sf.openrocket.rocketcomponent.AxialStage;
|
||||
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
|
||||
@ -48,7 +49,7 @@ public class SeparationConfigurationPanel extends FlightConfigurablePanel<AxialS
|
||||
private final JPopupMenu popupMenuFull; // popup menu containing all the options
|
||||
|
||||
|
||||
SeparationConfigurationPanel(FlightConfigurationPanel flightConfigurationPanel, Rocket rocket) {
|
||||
public SeparationConfigurationPanel(FlightConfigurationPanel flightConfigurationPanel, Rocket rocket) {
|
||||
super(flightConfigurationPanel,rocket);
|
||||
|
||||
JScrollPane scroll = new JScrollPane(table);
|
||||
|
Loading…
x
Reference in New Issue
Block a user