1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
|
package tim.prune.function.distance;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;
import tim.prune.App;
import tim.prune.GenericFunction;
import tim.prune.I18nManager;
import tim.prune.data.DataPoint;
import tim.prune.data.TrackInfo;
/**
* Class to provide the distance measuring function between waypoints
*/
public class DistanceFunction extends GenericFunction
{
/** Dialog */
private JDialog _dialog = null;
/** Table for 'from' point selection */
private JTable _pointTable = null;
/** Model for 'from' table */
private FromTableModel _fromModel = null;
/** Table for showing distances, bearings */
private JTable _distancesTable = null;
/** Model for distance table */
private DistanceTableModel _distModel = null;
/**
* Constructor
* @param inApp App object
*/
public DistanceFunction(App inApp) {
super(inApp);
}
/** Get the name key */
public String getNameKey() {
return "function.distances";
}
/**
* Begin the function
*/
public void begin()
{
if (_dialog == null)
{
_dialog = new JDialog(_parentFrame, getName(), true);
_dialog.setLocationRelativeTo(_parentFrame);
_dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
_dialog.getContentPane().add(makeDialogComponents());
_dialog.pack();
}
ArrayList<DataPoint> pointList = getPointList(_app.getTrackInfo());
// Check if point list has size at least 2
if (pointList.size() < 2) {
_app.showErrorMessage(getNameKey(), "dialog.distances.toofewpoints");
return;
}
_fromModel.init(pointList);
_distModel.init(pointList);
final int pointIndex = getPointIndex(pointList, _app.getTrackInfo());
_pointTable.getSelectionModel().setSelectionInterval(pointIndex, pointIndex);
_distModel.recalculate(pointIndex, getConfig());
centerAlignBearingColumn();
_dialog.setVisible(true);
}
/**
* Create dialog components
* @return Panel containing all gui elements in dialog
*/
private Component makeDialogComponents()
{
JPanel dialogPanel = new JPanel();
dialogPanel.setLayout(new BorderLayout(5, 5));
// Label at top
JLabel topLabel = new JLabel(I18nManager.getText("dialog.distances.intro"));
topLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
dialogPanel.add(topLabel, BorderLayout.NORTH);
// First table for 'from point'
_fromModel = new FromTableModel();
_pointTable = new JTable(_fromModel);
_pointTable.getSelectionModel().addListSelectionListener(e -> {
if (!e.getValueIsAdjusting()) {
_distModel.recalculate(_pointTable.getSelectedRow(), getConfig());
}
});
JScrollPane fromScrollPane = new JScrollPane(_pointTable);
fromScrollPane.setPreferredSize(new Dimension(100, 250));
// second table for distances
_distModel = new DistanceTableModel();
_distancesTable = new JTable(_distModel);
_distancesTable.setAutoCreateRowSorter(true);
JScrollPane toScrollPane = new JScrollPane(_distancesTable);
toScrollPane.setPreferredSize(new Dimension(200, 250));
// Combine using a horizontal split pane
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, fromScrollPane, toScrollPane);
splitPane.setDividerLocation(0.3);
splitPane.setResizeWeight(0.4);
dialogPanel.add(splitPane, BorderLayout.CENTER);
// close window if escape pressed
KeyAdapter escListener = new KeyAdapter() {
public void keyReleased(KeyEvent inE) {
if (inE.getKeyCode() == KeyEvent.VK_ESCAPE) {
_dialog.dispose();
}
}
};
_pointTable.addKeyListener(escListener);
_distancesTable.addKeyListener(escListener);
// button panel at bottom
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
JButton closeButton = new JButton(I18nManager.getText("button.close"));
closeButton.addActionListener(e -> _dialog.dispose());
buttonPanel.add(closeButton);
dialogPanel.add(buttonPanel, BorderLayout.SOUTH);
return dialogPanel;
}
/**
* We want the right-hand column aligned centrally.
* For some reason we need to do this after every table update, as it gets forgotten after model.recalculate
*/
private void centerAlignBearingColumn()
{
// center the third column, so it's not so close to the second column
DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();
centerRenderer.setHorizontalAlignment(SwingConstants.CENTER);
_distancesTable.getColumnModel().getColumn(2).setCellRenderer(centerRenderer);
}
/**
* Get the point list for the tables
* @param inTrackInfo TrackInfo object
*/
private static ArrayList<DataPoint> getPointList(TrackInfo inTrackInfo)
{
// Get the list of waypoints (if any)
ArrayList<DataPoint> pointList = new ArrayList<>();
inTrackInfo.getTrack().getWaypoints(pointList);
// Get the current point (if any)
DataPoint currPoint = inTrackInfo.getCurrentPoint();
if (currPoint != null && !currPoint.isWaypoint()) {
// Add current point to start of list
pointList.add(0, currPoint);
}
return pointList;
}
/**
* Find the point to select from the given point list
* @param pointList list of points
* @param inTrackInfo current track info to get selected point (if any)
* @return index of point to be selected
*/
private static int getPointIndex(ArrayList<DataPoint> pointList, TrackInfo inTrackInfo)
{
DataPoint currPoint = inTrackInfo.getCurrentPoint();
if (currPoint != null && currPoint.isWaypoint())
{
// Currently selected point is a waypoint, so select this one for convenience
for (int i=0; i<pointList.size(); i++)
{
if (pointList.get(i) == currPoint) {
return i;
}
}
}
return 0;
}
}
|