jalview.release=releases/Release_2_11_2_Branch
-jalview.version=2.11.2.3
+jalview.version=2.11.2.4
whatsnewHtml = whatsnewTemplateFile.text.replaceAll("__WHATS_NEW__", whatsnewHtml)
whatsnewHtmlFile.text = hugoTemplateSubstitutions(whatsnewHtml,
[
+ VERSION: JALVIEW_VERSION,
DISPLAY_DATE: wnDisplayDate
]
)
# download
git clone http://source.jalview.org/git/jalview.git
# compile
-cd jalview
+cd ./jalview
gradle shadowJar
# run
java -jar build/libs/jalview-all-*-j11.jar
# and/or create launcher
gradle getdown
# use launcher
-cd getdown/files
+cd ./build/getdown/files/11
java -jar getdown-launcher.jar . jalview
```
---
version: 2.11.2.3
-date: 2022-06-09
+date: 2022-07-06
channel: "release"
---
- <!-- JAL-3989 --> Release process generates Hugo friendly JSON metadata to use when publishing releases on www.jalview.org
- <!-- JAL-3553 --> New gradle tasks for publishing to the Jalview version archive
- <!-- JAL-4023 --> Tree branch labels shown using Scientific notation for very small or large lengths
-- <!-- JAL-4036 --> Uniprot Free Text Search redirected to legacy.uniprot.org
+- <!-- JAL-4036 --> Uniprot Free Text Search now uses legacy.uniprot.org rather than main Uniprot query service
## Issues Resolved
--- /dev/null
+---
+version: 2.11.2.4
+date: 2022-08-04
+channel: "release"
+---
+
+## New Features
+
+- <!-- JAL-4036 --> Migrated Uniprot Free Text Search to latest Uniprot search API
+- <!-- JAL-4034 --> Improved Structure Chooser's 3D-Beacons search button design and visual delay indicators
+- <!-- JAL-4034 --> 3D beacons Fetch Uniprot References confirmation dialog is only shown when number of sequences exceeds a threshold
+- <!-- -->
+
+
+
+
+## Issues Resolved
+
+- <!-- JAL-4045 --> buggy PCA plot axes rendering can make them appear to be non-orthogonal
-Jalview 2.11.2.3 is the third patch release in the 2.11.2 series. It addresses a critical bugs affecting Uniprot free text search, users working with very wide alignments and those needing to use alternate JABAWS servers, support for display of very small and large tree lengths with scientific notation, and essential improvements to the build and release notes documentation system.
+Jalview 2.11.2.3 is the third patch release in the 2.11.2 series. It addresses a critical bugs affecting Uniprot free text search, users working with very wide alignments and those needing to use alternate JABAWS servers. The tree-viewer now utilises scientific notation for display of very small and large tree lengths, and improvements to the documentation system allow a more streamlined authoring process for release notes.
--- /dev/null
+Jalview 2.11.2.4 is the fourth patch release in the 2.11.2 series. It includes a new client for the latest Uniprot Search API (released June 2022), updated build documentation and improved user experience when discovering models and experimental structures from 3D-Beacons.
+
</head>
<body>
<p>
- <strong>Welcome to Jalview Version $$Version-Rel$$ !!</strong><br/>
+ <strong>Welcome to Jalview Version __VERSION__ (released __DISPLAY_DATE__)!!</strong><br/>
</p>
- <p><em>__DISPLAY_DATE__</em></p>
__WHATS_NEW__
<p>
- This release series provides support for two popular 3D
+ The 2.11.2 release series provides support for two popular 3D
structure visualisation tools, new features for discovery of 3D
structures, improved platform integration and a new command line
tool allowing Jalview to be more easily called from scripts.</p>
<p>
For the full details, see <a
- href="releases.html#Jalview.2.11.2.1">the Jalview 2.11.2.1
+ href="releases.html#Jalview.2.11.2">the Jalview 2.11.2 series
release notes</a>.
</p>
<p>
label.standard_databases = Standard Databases
label.fetch_embl_uniprot = Fetch from EMBL/EMBLCDS or Uniprot/PDB and any selected DAS sources
label.fetch_uniprot_references = Fetch Uniprot references
-label.search_3dbeacons = 3D-Beacons Search
+label.search_3dbeacons = Search 3D-Beacons
label.find_models_from_3dbeacons = Search 3D-Beacons for 3D structures and models
label.3dbeacons = 3D-Beacons
label.fetch_references_for = Fetch database references for {0} sequences ?
-label.fetch_references_for_3dbeacons = 3D Beacons needs Uniprot References. Fetch database references for {0} sequences ?
+label.fetch_references_for_3dbeacons = 3D Beacons needs to fetch Uniprot References for {0} sequences. Do you want to continue ?
label.reset_min_max_colours_to_defaults = Reset min and max colours to defaults from user preferences.
label.align_structures_using_linked_alignment_views = Superpose structures using {0} selected alignment view(s)
label.threshold_feature_display_by_score = Threshold the feature display by score.
package jalview.gui;
import java.awt.Component;
+import java.awt.Dialog.ModalityType;
import java.awt.HeadlessException;
+import java.awt.Window;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.Executors;
import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JInternalFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
+import javax.swing.UIManager;
import jalview.util.Platform;
import jalview.util.dialogrunner.DialogRunnerI;
public void showDialog(String message, String title, int optionType,
int messageType, Icon icon, Object[] options, Object initialValue)
{
+ showDialog(message, title, optionType, messageType, icon, options,
+ initialValue, true);
+ }
+ public void showDialog(String message, String title, int optionType,
+ int messageType, Icon icon, Object[] options, Object initialValue,
+ boolean modal)
+ {
if (!isInteractiveMode())
{
handleResponse(getMockResponse());
ourOptions = Arrays.asList(options);
- int response = JOptionPane.showOptionDialog(parentComponent, message,
- title, optionType, messageType, icon, options, initialValue);
-
- /*
- * In Java, the response is returned to this thread and handled here;
- * (for Javascript, see propertyChange)
- */
- if (!Platform.isJS())
- /**
- * Java only
- *
- * @j2sIgnore
- */
+ if (modal)
{
- handleResponse(response);
+ // use a JOptionPane as usual
+ int response = JOptionPane.showOptionDialog(parentComponent, message,
+ title, optionType, messageType, icon, options, initialValue);
+
+ /*
+ * In Java, the response is returned to this thread and handled here;
+ * (for Javascript, see propertyChange)
+ */
+ if (!Platform.isJS())
+ /**
+ * Java only
+ *
+ * @j2sIgnore
+ */
+ {
+ handleResponse(response);
+ }
+ }
+ else
+ {
+ /*
+ * This is java similar to the swingjs handling, with the callbacks
+ * attached to the button press of the dialog. This means we can use
+ * a non-modal JDialog for the confirmation without blocking the GUI.
+ */
+ JOptionPane joptionpane = new JOptionPane();
+ // Make button options
+ int[] buttonActions = { JvOptionPane.YES_OPTION,
+ JvOptionPane.NO_OPTION, JvOptionPane.CANCEL_OPTION };
+
+ // we need the strings to make the buttons with actionEventListener
+ if (options == null)
+ {
+ ArrayList<String> options_default = new ArrayList<>();
+ options_default
+ .add(UIManager.getString("OptionPane.yesButtonText"));
+ if (optionType == JvOptionPane.YES_NO_OPTION
+ || optionType == JvOptionPane.YES_NO_CANCEL_OPTION)
+ {
+ options_default
+ .add(UIManager.getString("OptionPane.noButtonText"));
+ }
+ if (optionType == JvOptionPane.YES_NO_CANCEL_OPTION)
+ {
+ options_default
+ .add(UIManager.getString("OptionPane.cancelButtonText"));
+ }
+ options = options_default.toArray();
+ }
+
+ ArrayList<JButton> options_btns = new ArrayList<>();
+ Object initialValue_btn = null;
+ if (!Platform.isJS()) // JalviewJS already uses callback, don't need to add them here
+ {
+ for (int i = 0; i < options.length && i < 3; i++)
+ {
+ Object o = options[i];
+ int buttonAction = buttonActions[i];
+ Runnable action = callbacks.get(buttonAction);
+ JButton jb = new JButton();
+ jb.setText((String) o);
+ jb.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ joptionpane.setValue(buttonAction);
+ if (action != null)
+ Executors.defaultThreadFactory().newThread(action).start();
+ // joptionpane.transferFocusBackward();
+ joptionpane.transferFocusBackward();
+ joptionpane.setVisible(false);
+ // put focus and raise parent window if possible, unless cancel
+ // button pressed
+ boolean raiseParent = (parentComponent != null);
+ if (buttonAction == JvOptionPane.CANCEL_OPTION)
+ raiseParent = false;
+ if (optionType == JvOptionPane.YES_NO_OPTION
+ && buttonAction == JvOptionPane.NO_OPTION)
+ raiseParent = false;
+ if (raiseParent)
+ {
+ parentComponent.requestFocus();
+ if (parentComponent instanceof JInternalFrame)
+ {
+ JInternalFrame jif = (JInternalFrame) parentComponent;
+ jif.show();
+ jif.moveToFront();
+ jif.grabFocus();
+ }
+ else if (parentComponent instanceof Window)
+ {
+ Window w = (Window) parentComponent;
+ w.toFront();
+ w.requestFocus();
+ }
+ }
+ joptionpane.setVisible(false);
+ }
+ });
+ options_btns.add(jb);
+ if (o.equals(initialValue))
+ initialValue_btn = jb;
+ }
+ }
+ joptionpane.setMessage(message);
+ joptionpane.setMessageType(messageType);
+ joptionpane.setOptionType(optionType);
+ joptionpane.setIcon(icon);
+ joptionpane.setOptions(
+ Platform.isJS() ? options : options_btns.toArray());
+ joptionpane.setInitialValue(
+ Platform.isJS() ? initialValue : initialValue_btn);
+
+ JDialog dialog = joptionpane.createDialog(parentComponent, title);
+ dialog.setModalityType(modal ? ModalityType.APPLICATION_MODAL
+ : ModalityType.MODELESS);
+ dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+ dialog.setVisible(true);
}
}
*/
package jalview.gui;
-import jalview.api.RotatableCanvasI;
-import jalview.datamodel.Point;
-import jalview.datamodel.SequenceGroup;
-import jalview.datamodel.SequenceI;
-import jalview.datamodel.SequencePoint;
-import jalview.math.RotatableMatrix;
-import jalview.math.RotatableMatrix.Axis;
-import jalview.util.ColorUtils;
-import jalview.util.MessageManager;
-import jalview.viewmodel.AlignmentViewport;
-
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import javax.swing.JPanel;
import javax.swing.ToolTipManager;
+import jalview.api.RotatableCanvasI;
+import jalview.datamodel.Point;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.SequencePoint;
+import jalview.math.RotatableMatrix;
+import jalview.math.RotatableMatrix.Axis;
+import jalview.util.ColorUtils;
+import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
+
/**
* Models a Panel on which a set of points, and optionally x/y/z axes, can be
* drawn, and rotated or zoomed with the mouse
int midX = getWidth() / 2;
int midY = getHeight() / 2;
- float maxWidth = Math.max(Math.abs(seqMax[0] - seqMin[0]),
- Math.abs(seqMax[1] - seqMin[1]));
+ // float maxWidth = Math.max(Math.abs(seqMax[0] - seqMin[0]),
+ // Math.abs(seqMax[1] - seqMin[1]));
int pix = Math.min(getWidth(), getHeight());
- float scaleBy = pix * getScaleFactor() / (2f * maxWidth);
+ float scaleBy = pix * getScaleFactor() / (2f);
for (int i = 0; i < DIMS; i++)
{
g.drawLine(midX, midY,
- midX + (int) (getAxisEndPoints()[i].x * scaleBy * seqMax[0]),
- midY + (int) (getAxisEndPoints()[i].y * scaleBy * seqMax[1]));
+ midX + (int) (getAxisEndPoints()[i].x * scaleBy * 0.25),
+ midY + (int) (getAxisEndPoints()[i].y * scaleBy * 0.25));
}
}
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
-import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import jalview.api.structures.JalviewStructureDisplayI;
import jalview.bin.Cache;
+import jalview.bin.Console;
import jalview.bin.Jalview;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
{
private static final String AUTOSUPERIMPOSE = "AUTOSUPERIMPOSE";
+ /**
+ * warn user if need to fetch more than this many uniprot records at once
+ */
+ private static final int THRESHOLD_WARN_UNIPROT_FETCH_NEEDED = 20;
+
private SequenceI selectedSequence;
private SequenceI[] selectedSequences;
Executors.defaultThreadFactory().newThread(new Runnable()
{
+ @Override
public void run()
{
populateSeqsWithoutSourceDBRef();
progressBar.setProgressBar(
MessageManager.getString("status.searching_3d_beacons"),
progressId);
+ btn_queryTDB.setEnabled(false);
// TODO: warn if no accessions discovered
populateSeqsWithoutSourceDBRef();
// redo initial discovery - this time with 3d beacons
btn_queryTDB.setToolTipText(MessageManager.getString(
"status.no_structures_discovered_from_3d_beacons"));
btn_queryTDB.setEnabled(false);
+ pnl_queryTDB.setVisible(false);
}
else
{
cmb_filterOption.setSelectedIndex(0); // select 'best'
btn_queryTDB.setVisible(false);
+ pnl_queryTDB.setVisible(false);
progressBar.setProgressBar(null, progressId);
}
mainFrame.setEnabled(true);
@Override
public void run()
{
+ btn_queryTDB.setEnabled(false);
populateSeqsWithoutSourceDBRef();
final int y = seqsWithoutSourceDBRef.size();
{ new jalview.ws.dbsources.Uniprot() }, null, false);
dbRefFetcher.addListener(afterDbRefFetch);
// ideally this would also gracefully run with callbacks
+
dbRefFetcher.fetchDBRefs(true);
}
else
};
final Runnable revertview = new Runnable()
{
+ @Override
public void run()
{
if (lastSelected != null)
}
};
};
- if (ignoreGui)
+ int threshold = Cache.getDefault("UNIPROT_AUTOFETCH_THRESHOLD",
+ THRESHOLD_WARN_UNIPROT_FETCH_NEEDED);
+ Console.debug("Using Uniprot fetch threshold of " + threshold);
+ if (ignoreGui || seqsWithoutSourceDBRef.size() < threshold)
{
Executors.defaultThreadFactory().newThread(discoverCanonicalDBrefs)
.start();
}
// need cancel and no to result in the discoverPDB action - mocked is
// 'cancel' TODO: mock should be OK
- JvOptionPane.newOptionDialog(this)
+
+ StructureChooser thisSC = this;
+ JvOptionPane.newOptionDialog(thisSC.getFrame())
.setResponseHandler(JvOptionPane.OK_OPTION,
discoverCanonicalDBrefs)
.setResponseHandler(JvOptionPane.CANCEL_OPTION, revertview)
null, new Object[]
{ MessageManager.getString("action.ok"),
MessageManager.getString("action.cancel") },
- MessageManager.getString("action.ok"));
+ MessageManager.getString("action.ok"), false);
}
/**
if (canQueryTDB && notQueriedTDBYet)
{
btn_queryTDB.setVisible(true);
+ pnl_queryTDB.setVisible(true);
}
if (cachedPDBExist)
popup.add(viewUrl);
SwingUtilities.invokeLater(new Runnable()
{
+ @Override
public void run()
{
popup.show(getResultTable(), x, y);
{
if (selectedSequences != null)
{
+ lbl_loading.setVisible(true);
Thread refreshThread = new Thread(new Runnable()
{
@Override
filterResultSet(
((FilterOption) cmb_filterOption.getSelectedItem())
.getValue());
+ lbl_loading.setVisible(false);
}
});
refreshThread.start();
package jalview.jbgui;
-import jalview.datamodel.SequenceI;
-import jalview.fts.api.FTSDataColumnI;
-import jalview.fts.core.FTSDataColumnPreferences;
-import jalview.fts.core.FTSDataColumnPreferences.PreferenceSource;
-import jalview.fts.service.pdb.PDBFTSRestClient;
-import jalview.gui.AlignmentPanel;
-import jalview.gui.Desktop;
-import jalview.gui.JvSwingUtils;
-import jalview.gui.StructureViewer;
-import jalview.util.MessageManager;
-
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.GridLayout;
+import java.awt.Insets;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;
+import javax.swing.SwingConstants;
import javax.swing.Timer;
-import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.InternalFrameEvent;
import javax.swing.table.TableColumn;
+import jalview.datamodel.SequenceI;
+import jalview.fts.api.FTSDataColumnI;
+import jalview.fts.core.FTSDataColumnPreferences;
+import jalview.gui.AlignmentPanel;
+import jalview.gui.Desktop;
+import jalview.gui.JvSwingUtils;
+import jalview.gui.StructureViewer;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
import net.miginfocom.swing.MigLayout;
@SuppressWarnings("serial")
protected JButton btn_pdbFromFile = new JButton();
+ // holder for icon and button
+ protected JPanel pnl_queryTDB;
+
protected JButton btn_queryTDB = new JButton();
protected JCheckBox chk_superpose = new JCheckBox(
});
chk_invertFilter.addItemListener(this);
- btn_queryTDB.setFont(VERDANA_12);
- // btn_queryTDB.setPreferredSize(new Dimension(200,22));
+ btn_queryTDB = new JButton();
+ if (Platform.isMac())
+ {
+ // needed to make icon button have round corners in vaqua
+ btn_queryTDB.putClientProperty("JButton.buttonType", "bevel");
+ }
+ btn_queryTDB.setMargin(new Insets(0, 16, 0, 20));
btn_queryTDB
.setText(MessageManager.getString("label.search_3dbeacons"));
+ btn_queryTDB.setIconTextGap(12);
+ btn_queryTDB.setIcon(tdbImage);
+ btn_queryTDB.setVerticalTextPosition(SwingConstants.CENTER);
+ btn_queryTDB.setHorizontalTextPosition(SwingConstants.TRAILING);
+ btn_queryTDB.setFont(VERDANA_12);
btn_queryTDB.setToolTipText(
MessageManager.getString("label.find_models_from_3dbeacons"));
- btn_queryTDB.setIcon(tdbImage);
+ // btn_queryTDB.setPreferredSize(new Dimension(200, 32));
btn_queryTDB.setVisible(false);
targetView.setVisible(false);
JPanel pnl_main = new JPanel(new BorderLayout());
JPanel pnl_controls = new JPanel();
- pnl_main.add(btn_queryTDB, BorderLayout.NORTH);
+ pnl_queryTDB = new JPanel();
+ pnl_queryTDB.setLayout(new FlowLayout(FlowLayout.CENTER, 4, 4));
+ pnl_queryTDB.setBackground(getBackground());
+ pnl_queryTDB.add(btn_queryTDB);
+
+ pnl_queryTDB.setVisible(false);
+ pnl_main.add(pnl_queryTDB, BorderLayout.NORTH);
pnl_controls.add(cmb_filterOption);
pnl_controls.add(lbl_loading);
pnl_controls.add(chk_invertFilter);
protected abstract void tabRefresh();
protected abstract void validateSelections();
-}
\ No newline at end of file
+
+ public JInternalFrame getFrame()
+ {
+ return mainFrame;
+ }
+}