Improved dialog for finding species codes

Now has a progress bar to block GUI while searching database.
This commit is contained in:
Douglas Gillespie 2024-01-22 18:04:57 +00:00
parent 7d30b303e7
commit 3d7224eb93
5 changed files with 97 additions and 14 deletions

View File

@ -15,7 +15,7 @@ public class ClickBlockSpeciesManager extends DataBlockSpeciesManager<ClickDetec
public ClickBlockSpeciesManager(ClickControl clickControl, ClickDataBlock clickDataBlock) { public ClickBlockSpeciesManager(ClickControl clickControl, ClickDataBlock clickDataBlock) {
super(clickDataBlock); super(clickDataBlock);
this.clickControl = clickControl; this.clickControl = clickControl;
setDefaultDefaultSpecies(new SpeciesMapItem(ITISTypes.UNKNOWN, "Unknown", "Unknown")); setDefaultDefaultSpecies(new SpeciesMapItem(ITISTypes.OTHER, "Unknown", "Unknown"));
setDefaultSpeciesCode("Unknown"); setDefaultSpeciesCode("Unknown");
} }

View File

@ -21,7 +21,7 @@ public class DataBlockSpeciesCodes {
/** /**
* Probably only to be used when there are no defined names, but helpful if it's set. * Probably only to be used when there are no defined names, but helpful if it's set.
*/ */
private int itisDefault = ITISTypes.UNKNOWN; private int itisDefault = ITISTypes.OTHER;
/** /**
* A default sound type, which can be used for all 'species', but can get * A default sound type, which can be used for all 'species', but can get

View File

@ -7,12 +7,12 @@ package tethys.species;
*/ */
public class ITISTypes { public class ITISTypes {
public static final int UNKNOWN = 0; public static final int OTHER = 0;
public static final int ANTHROPOGENIC = 1; public static final int ANTHROPOGENIC = 1;
public static final String getName(int code) { public static final String getName(int code) {
switch (code) { switch (code) {
case UNKNOWN: case OTHER:
return "Unknown"; return "Unknown";
case ANTHROPOGENIC: case ANTHROPOGENIC:
return "Anthropogenic"; return "Anthropogenic";

View File

@ -7,6 +7,7 @@ import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.border.TitledBorder; import javax.swing.border.TitledBorder;
@ -39,6 +40,8 @@ public class DataBlockSpeciesDialog extends PamDialog {
JPanel nPanel = new JPanel(new BorderLayout()); JPanel nPanel = new JPanel(new BorderLayout());
nPanel.setBorder(new TitledBorder("Code management")); nPanel.setBorder(new TitledBorder("Code management"));
nPanel.add(BorderLayout.EAST, itisButton); nPanel.add(BorderLayout.EAST, itisButton);
String otherMsg = "<html>Use a valid ITIS species code, Or for Noise Measurements <br>and \"Other Phenomena\" use code -10</html>";
nPanel.add(BorderLayout.CENTER, new JLabel(otherMsg , JLabel.LEFT));
// JPanel nwBit = new JPanel(new FlowLayout()); // JPanel nwBit = new JPanel(new FlowLayout());
// JButton exportButton = new JButton("Export"); // JButton exportButton = new JButton("Export");
// exportButton.addActionListener(SpeciesMapManager.getInstance().getExportAction(parentFrame)); // exportButton.addActionListener(SpeciesMapManager.getInstance().getExportAction(parentFrame));

View File

@ -9,6 +9,7 @@ import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JLabel; import javax.swing.JLabel;
@ -16,11 +17,16 @@ import javax.swing.JPanel;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import javax.swing.border.TitledBorder; import javax.swing.border.TitledBorder;
import javax.swing.table.AbstractTableModel; import javax.swing.table.AbstractTableModel;
import PamUtils.worker.PamWorkDialog;
import PamUtils.worker.PamWorkProgressMessage;
import PamView.dialog.PamDialog; import PamView.dialog.PamDialog;
import PamView.dialog.PamGridBagContraints; import PamView.dialog.PamGridBagContraints;
import PamView.dialog.warn.WarnOnce;
import PamView.tables.SwingTableColumnWidths; import PamView.tables.SwingTableColumnWidths;
import PamView.tables.TableColumnWidthData; import PamView.tables.TableColumnWidthData;
import tethys.TethysControl; import tethys.TethysControl;
@ -47,8 +53,10 @@ public class SpeciesSearchDialog extends PamDialog {
private DataModel tableModel; private DataModel tableModel;
private int selectedRow = -1; private volatile PamWorkDialog workDialog;
private Object synch = new Object();
private SpeciesSearchDialog(Window parentFrame, TethysControl tethysControl) { private SpeciesSearchDialog(Window parentFrame, TethysControl tethysControl) {
super(parentFrame, "Species search", false); super(parentFrame, "Species search", false);
@ -74,19 +82,26 @@ public class SpeciesSearchDialog extends PamDialog {
tableModel = new DataModel(); tableModel = new DataModel();
resultTable = new JTable(tableModel); resultTable = new JTable(tableModel);
JPanel centPanel = new JPanel(new BorderLayout()); JPanel centPanel = new JPanel(new BorderLayout());
centPanel.add(BorderLayout.NORTH, new JLabel("Possible matches", JLabel.LEFT)); centPanel.add(BorderLayout.NORTH, new JLabel("Possible matches (select one)", JLabel.LEFT));
JScrollPane scrollPane = new JScrollPane(resultTable); JScrollPane scrollPane = new JScrollPane(resultTable);
centPanel.add(BorderLayout.CENTER, scrollPane); centPanel.add(BorderLayout.CENTER, scrollPane);
mainPanel.add(BorderLayout.CENTER, centPanel); mainPanel.add(BorderLayout.CENTER, centPanel);
resultTable.addMouseListener(new TableMouse()); resultTable.addMouseListener(new TableMouse());
new SwingTableColumnWidths("Species Search Dialog Table", resultTable); SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new SwingTableColumnWidths("Species Search Dialog Table", resultTable);
}
});
setResizable(true); setResizable(true);
setDialogComponent(mainPanel); setDialogComponent(mainPanel);
} }
public static SpeciesMapItem showDialog(Window parentFrame, TethysControl tethysControl) { public static SpeciesMapItem showDialog(Window parentFrame, TethysControl tethysControl) {
singleInstance = new SpeciesSearchDialog(parentFrame, tethysControl); if (singleInstance == null) {
singleInstance = new SpeciesSearchDialog(parentFrame, tethysControl);
}
singleInstance.setParams(); singleInstance.setParams();
singleInstance.setVisible(true); singleInstance.setVisible(true);
return singleInstance.selectedItem; return singleInstance.selectedItem;
@ -99,10 +114,73 @@ public class SpeciesSearchDialog extends PamDialog {
if (str == null || str.length() == 0) { if (str == null || str.length() == 0) {
return; return;
} }
ITISFunctions itisFunctions = tethysControl.getItisFunctions(); SearchWorker searchWorker = new SearchWorker(str);
speciesMapItems = itisFunctions.searchSpecies(str); searchWorker.execute();
// then open the dialog to block this thread.
synchronized (synch) {
workDialog = new PamWorkDialog(getOwner(), 1, "Searching Tethys Database");
workDialog.setVisible(true);
}
}
public void setMapItems(ArrayList<SpeciesMapItem> newMapItems) {
this.speciesMapItems = newMapItems;
tableModel.fireTableDataChanged(); tableModel.fireTableDataChanged();
} }
private class SearchWorker extends SwingWorker<Integer, PamWorkProgressMessage> {
private String searchString;
private ArrayList<SpeciesMapItem> newMapItems;
public SearchWorker(String searchString) {
this.searchString = searchString;
}
@Override
protected Integer doInBackground() throws Exception {
String msg = String.format("Searching database for names containing \"%s\"", searchString);
PamWorkProgressMessage pm = new PamWorkProgressMessage(null, msg);
publish(pm);
try {
ITISFunctions itisFunctions = tethysControl.getItisFunctions();
this.newMapItems = itisFunctions.searchSpecies(searchString);
}
catch (Exception e) {
e.printStackTrace();
}
if (newMapItems == null) {
return 0;
}
if (workDialog != null) {
workDialog.setVisible(false);
workDialog.dispose();
}
return newMapItems.size();
}
@Override
protected void done() {
if (newMapItems == null || newMapItems.size() == 0) {
String msg = String.format("No matching ITIS types for search term %s", searchString);
WarnOnce.showNamedWarning("ITIS Lookup failure", getOwner(), "ITIS Code search", msg, WarnOnce.WARNING_MESSAGE);
}
setMapItems(newMapItems);
}
@Override
protected void process(List<PamWorkProgressMessage> chunks) {
for (PamWorkProgressMessage msg : chunks) {
synchronized (synch) {
if (workDialog != null) {
workDialog.update(msg);
}
}
}
}
}
private void setParams() { private void setParams() {
searchText.setText(null); searchText.setText(null);
@ -110,7 +188,6 @@ public class SpeciesSearchDialog extends PamDialog {
} }
private void clearResults() { private void clearResults() {
selectedRow = -1;
speciesMapItems = null; speciesMapItems = null;
selectedItem = null; selectedItem = null;
} }
@ -137,8 +214,11 @@ public class SpeciesSearchDialog extends PamDialog {
@Override @Override
public void mouseClicked(MouseEvent e) { public void mouseClicked(MouseEvent e) {
selectedRow = resultTable.getSelectedRow(); if (speciesMapItems == null) {
if (selectedRow >= 0) { return;
}
int selectedRow = resultTable.getSelectedRow();
if (selectedRow >= 0 && selectedRow < speciesMapItems.size()) {
selectedItem = speciesMapItems.get(selectedRow); selectedItem = speciesMapItems.get(selectedRow);
} }
tableModel.fireTableDataChanged(); tableModel.fireTableDataChanged();
@ -167,7 +247,7 @@ public class SpeciesSearchDialog extends PamDialog {
SpeciesMapItem mapItem = speciesMapItems.get(rowIndex); SpeciesMapItem mapItem = speciesMapItems.get(rowIndex);
switch (columnIndex) { switch (columnIndex) {
case 0: case 0:
return rowIndex == selectedRow; return mapItem == selectedItem;
case 1: case 1:
return mapItem.getItisCode(); return mapItem.getItisCode();
case 2: case 2: