X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=forester%2Fjava%2Fsrc%2Forg%2Fforester%2Farchaeopteryx%2FMainFrameApplication.java;h=9a9c233399f312a7468539fec1e71fe71dd58d29;hb=02afcdbc87b196aa929bcffabf83e409fd807077;hp=9488a1c9a188327ed4ab8687b9eaa819f0606c17;hpb=bfc94c88eba9f1f317b44c1316d625697cc441a6;p=jalview.git diff --git a/forester/java/src/org/forester/archaeopteryx/MainFrameApplication.java b/forester/java/src/org/forester/archaeopteryx/MainFrameApplication.java index 9488a1c..9a9c233 100644 --- a/forester/java/src/org/forester/archaeopteryx/MainFrameApplication.java +++ b/forester/java/src/org/forester/archaeopteryx/MainFrameApplication.java @@ -57,6 +57,8 @@ import javax.swing.UnsupportedLookAndFeelException; import javax.swing.WindowConstants; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import javax.swing.event.InternalFrameAdapter; +import javax.swing.event.InternalFrameEvent; import org.forester.analysis.TaxonomyDataManager; import org.forester.archaeopteryx.Options.CLADOGRAM_TYPE; @@ -161,10 +163,11 @@ public final class MainFrameApplication extends MainFrame { setSize( MainFrameApplication.FRAME_X_SIZE, MainFrameApplication.FRAME_Y_SIZE ); // The window listener setDefaultCloseOperation( WindowConstants.DO_NOTHING_ON_CLOSE ); - addWindowListener( new WindowAdapter() { + addFrameListener( new FrameAdapter() { @Override - public void windowClosing( final WindowEvent e ) { + public void FrameClosing () { + exit(); } } ); @@ -180,15 +183,18 @@ public final class MainFrameApplication extends MainFrame { _contentpane.repaint(); } + + private MainFrameApplication( final Phylogeny[] phys, final Configuration config, final String title ) { this( phys, config, title, null ); } - - private MainFrameApplication( final Phylogeny[] phys, + + private MainFrameApplication(final Phylogeny[] phys, final Configuration config, final String title, - final File current_dir ) { - super(); + final File current_dir, + final boolean isEmbedded) { + super(isEmbedded); _configuration = config; if ( _configuration == null ) { throw new IllegalArgumentException( "configuration is null" ); @@ -302,14 +308,16 @@ public final class MainFrameApplication extends MainFrame { // } ); // The window listener setDefaultCloseOperation( WindowConstants.DO_NOTHING_ON_CLOSE ); - addWindowListener( new WindowAdapter() { + + addFrameListener( new FrameAdapter() { @Override - public void windowClosing( final WindowEvent e ) { + public void FrameClosing( ) { + if (MainFrameApplication.this.getParent() == null) { if ( isUnsavedDataPresent() ) { - final int r = JOptionPane.showConfirmDialog( null, - "Exit despite potentially unsaved changes?", - "Exit?", + final int r = JOptionPane.showConfirmDialog( _mainpanel, + "Close Archaeopteryx despite potentially unsaved changes?", + "Close viewer?", JOptionPane.YES_NO_OPTION ); if ( r != JOptionPane.YES_OPTION ) { return; @@ -321,10 +329,10 @@ public final class MainFrameApplication extends MainFrame { if ( r != JOptionPane.YES_OPTION ) { return; } - } + }} exit(); - } - } ); + + } }); // The component listener addComponentListener( new ComponentAdapter() { @@ -350,6 +358,14 @@ public final class MainFrameApplication extends MainFrame { // ...and its children _contentpane.repaint(); System.gc(); + + } + + private MainFrameApplication( final Phylogeny[] phys, + final Configuration config, + final String title, + final File current_dir ) { + this(phys,config,title,current_dir,false); } private MainFrameApplication( final Phylogeny[] phys, final String config_file, final String title ) { @@ -515,12 +531,12 @@ public final class MainFrameApplication extends MainFrame { msa = FastaParser.parseMsa( is ); } else { - msa = GeneralMsaParser.parse( is ); + msa = GeneralMsaParser.parseMsa( is ); } } catch ( final MsaFormatException e ) { setArrowCursor(); - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), e.getLocalizedMessage(), "Multiple sequence alignment format error", JOptionPane.ERROR_MESSAGE ); @@ -528,7 +544,7 @@ public final class MainFrameApplication extends MainFrame { } catch ( final IOException e ) { setArrowCursor(); - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), e.getLocalizedMessage(), "Failed to read multiple sequence alignment", JOptionPane.ERROR_MESSAGE ); @@ -536,7 +552,7 @@ public final class MainFrameApplication extends MainFrame { } catch ( final IllegalArgumentException e ) { setArrowCursor(); - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), e.getLocalizedMessage(), "Unexpected error during reading of multiple sequence alignment", JOptionPane.ERROR_MESSAGE ); @@ -545,28 +561,28 @@ public final class MainFrameApplication extends MainFrame { catch ( final Exception e ) { setArrowCursor(); e.printStackTrace(); - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), e.getLocalizedMessage(), "Unexpected error during reading of multiple sequence alignment", JOptionPane.ERROR_MESSAGE ); return; } if ( ( msa == null ) || ( msa.getNumberOfSequences() < 1 ) ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Multiple sequence alignment is empty", "Illegal Multiple Sequence Alignment", JOptionPane.ERROR_MESSAGE ); return; } if ( msa.getNumberOfSequences() < 4 ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Multiple sequence alignment needs to contain at least 3 sequences", "Illegal multiple sequence alignment", JOptionPane.ERROR_MESSAGE ); return; } if ( msa.getLength() < 2 ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Multiple sequence alignment needs to contain at least 2 residues", "Illegal multiple sequence alignment", JOptionPane.ERROR_MESSAGE ); @@ -607,7 +623,7 @@ public final class MainFrameApplication extends MainFrame { } catch ( final MsaFormatException e ) { setArrowCursor(); - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), e.getLocalizedMessage(), "Multiple sequence file format error", JOptionPane.ERROR_MESSAGE ); @@ -615,7 +631,7 @@ public final class MainFrameApplication extends MainFrame { } catch ( final IOException e ) { setArrowCursor(); - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), e.getLocalizedMessage(), "Failed to read multiple sequence file", JOptionPane.ERROR_MESSAGE ); @@ -623,7 +639,7 @@ public final class MainFrameApplication extends MainFrame { } catch ( final IllegalArgumentException e ) { setArrowCursor(); - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), e.getLocalizedMessage(), "Unexpected error during reading of multiple sequence file", JOptionPane.ERROR_MESSAGE ); @@ -632,21 +648,21 @@ public final class MainFrameApplication extends MainFrame { catch ( final Exception e ) { setArrowCursor(); e.printStackTrace(); - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), e.getLocalizedMessage(), "Unexpected error during reading of multiple sequence file", JOptionPane.ERROR_MESSAGE ); return; } if ( ( seqs == null ) || ( seqs.size() < 1 ) ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Multiple sequence file is empty", "Illegal multiple sequence file", JOptionPane.ERROR_MESSAGE ); return; } if ( seqs.size() < 4 ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Multiple sequence file needs to contain at least 3 sequences", "Illegal multiple sequence file", JOptionPane.ERROR_MESSAGE ); @@ -667,7 +683,7 @@ public final class MainFrameApplication extends MainFrame { private void addExpressionValuesFromFile() { if ( ( getCurrentTreePanel() == null ) || ( getCurrentTreePanel().getPhylogeny() == null ) ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Need to load evolutionary tree first", "Can Not Read Expression Values", JOptionPane.WARNING_MESSAGE ); @@ -691,21 +707,21 @@ public final class MainFrameApplication extends MainFrame { } } catch ( final IOException e ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), e.getMessage(), "Could Not Read Expression Value Table", JOptionPane.ERROR_MESSAGE ); return; } if ( t.getNumberOfColumns() < 2 ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Table contains " + t.getNumberOfColumns() + " column(s)", "Problem with Expression Value Table", JOptionPane.ERROR_MESSAGE ); return; } if ( t.getNumberOfRows() < 1 ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Table contains zero rows", "Problem with Expression Value Table", JOptionPane.ERROR_MESSAGE ); @@ -713,7 +729,7 @@ public final class MainFrameApplication extends MainFrame { } final Phylogeny phy = getCurrentTreePanel().getPhylogeny(); if ( t.getNumberOfRows() != phy.getNumberOfExternalNodes() ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Table contains " + t.getNumberOfRows() + " rows, but tree contains " + phy.getNumberOfExternalNodes() + " external nodes", "Warning", @@ -730,7 +746,7 @@ public final class MainFrameApplication extends MainFrame { row = t.findRow( node_name ); } catch ( final IllegalArgumentException e ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), e.getMessage(), "Error Mapping Node Identifiers to Expression Value Identifiers", JOptionPane.ERROR_MESSAGE ); @@ -749,7 +765,7 @@ public final class MainFrameApplication extends MainFrame { d = Double.parseDouble( t.getValueAsString( col, row ) ); } catch ( final NumberFormatException e ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Could not parse \"" + t.getValueAsString( col, row ) + "\" into a decimal value", "Issue with Expression Value Table", @@ -767,7 +783,7 @@ public final class MainFrameApplication extends MainFrame { } if ( not_found > 0 ) { JOptionPane - .showMessageDialog( this, + .showMessageDialog( getThisFrame(), "Could not fine expression values for " + not_found + " external node(s)", "Warning", JOptionPane.WARNING_MESSAGE ); @@ -778,7 +794,7 @@ public final class MainFrameApplication extends MainFrame { private void addSequencesFromFile() { if ( ( getCurrentTreePanel() == null ) || ( getCurrentTreePanel().getPhylogeny() == null ) ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Need to load evolutionary tree first", "Can Not Read Sequences", JOptionPane.WARNING_MESSAGE ); @@ -805,7 +821,7 @@ public final class MainFrameApplication extends MainFrame { } } else { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Format does not appear to be Fasta", "Multiple sequence file format error", JOptionPane.ERROR_MESSAGE ); @@ -820,7 +836,7 @@ public final class MainFrameApplication extends MainFrame { } catch ( final MsaFormatException e ) { setArrowCursor(); - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), e.getLocalizedMessage(), "Multiple sequence file format error", JOptionPane.ERROR_MESSAGE ); @@ -828,7 +844,7 @@ public final class MainFrameApplication extends MainFrame { } catch ( final IOException e ) { setArrowCursor(); - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), e.getLocalizedMessage(), "Failed to read multiple sequence file", JOptionPane.ERROR_MESSAGE ); @@ -837,14 +853,14 @@ public final class MainFrameApplication extends MainFrame { catch ( final Exception e ) { setArrowCursor(); e.printStackTrace(); - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), e.getLocalizedMessage(), "Unexpected error during reading of multiple sequence file", JOptionPane.ERROR_MESSAGE ); return; } if ( ( seqs == null ) || ( seqs.size() < 1 ) ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Multiple sequence file is empty", "Empty multiple sequence file", JOptionPane.ERROR_MESSAGE ); @@ -874,7 +890,7 @@ public final class MainFrameApplication extends MainFrame { nodes = phy.getNodes( seq_name ); } if ( nodes.size() > 1 ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Sequence name \"" + seq_name + "\" is not unique", "Sequence name not unique", JOptionPane.ERROR_MESSAGE ); @@ -892,7 +908,7 @@ public final class MainFrameApplication extends MainFrame { nodes = phy.getNodes( seq_name_split ); } if ( nodes.size() > 1 ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Split sequence name \"" + seq_name_split + "\" is not unique", "Sequence name not unique", @@ -934,13 +950,13 @@ public final class MainFrameApplication extends MainFrame { + " external nodes now have a molecular sequence attached to them."; } if ( ( attached_counter == total_counter ) && ( ext_nodes == ext_nodes_with_seq ) ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Attached all " + total_counter + " sequences to tree nodes.\n" + s, "All sequences attached", JOptionPane.INFORMATION_MESSAGE ); } else { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Attached " + attached_counter + " sequences out of a total of " + total_counter + " sequences.\n" + s, attached_counter + " sequences attached", @@ -948,7 +964,7 @@ public final class MainFrameApplication extends MainFrame { } } else { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "No maching tree node for any of the " + total_counter + " sequences", "Could not attach any sequences", JOptionPane.ERROR_MESSAGE ); @@ -959,7 +975,7 @@ public final class MainFrameApplication extends MainFrame { private void closeCurrentPane() { if ( getMainPanel().getCurrentTreePanel() != null ) { if ( getMainPanel().getCurrentTreePanel().isEdited() ) { - final int r = JOptionPane.showConfirmDialog( this, + final int r = JOptionPane.showConfirmDialog( getThisFrame(), "Close tab despite potentially unsaved changes?", "Close Tab?", JOptionPane.YES_NO_OPTION ); @@ -1017,7 +1033,7 @@ public final class MainFrameApplication extends MainFrame { repaint(); } if ( to_be_removed.size() > 0 ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Collapsed " + to_be_removed.size() + " branches with\nconfidence values below " + getMinNotCollapseConfidenceValue(), @@ -1025,7 +1041,7 @@ public final class MainFrameApplication extends MainFrame { JOptionPane.INFORMATION_MESSAGE ); } else { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "No branch collapsed,\nminimum confidence value per branch is " + min_support, "No branch collapsed", @@ -1033,7 +1049,7 @@ public final class MainFrameApplication extends MainFrame { } } else { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "No branch collapsed because no confidence values present", "No confidence values present", JOptionPane.INFORMATION_MESSAGE ); @@ -1044,7 +1060,7 @@ public final class MainFrameApplication extends MainFrame { if ( getCurrentTreePanel() != null ) { final Phylogeny phy = getCurrentTreePanel().getPhylogeny(); if ( ( phy != null ) && !phy.isEmpty() ) { - final String s = ( String ) JOptionPane.showInputDialog( this, + final String s = ( String ) JOptionPane.showInputDialog( getThisFrame(), "Please enter the minimum branch length value\n", "Minimal Branch Length Value", JOptionPane.QUESTION_MESSAGE, @@ -1079,7 +1095,7 @@ public final class MainFrameApplication extends MainFrame { if ( getCurrentTreePanel() != null ) { final Phylogeny phy = getCurrentTreePanel().getPhylogeny(); if ( ( phy != null ) && !phy.isEmpty() ) { - final String s = ( String ) JOptionPane.showInputDialog( this, + final String s = ( String ) JOptionPane.showInputDialog( getThisFrame(), "Please enter the minimum confidence value\n", "Minimal Confidence Value", JOptionPane.QUESTION_MESSAGE, @@ -1149,7 +1165,7 @@ public final class MainFrameApplication extends MainFrame { repaint(); } if ( to_be_removed.size() > 0 ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Collapsed " + to_be_removed.size() + " branches with\nbranch length values below " + getMinNotCollapseBlValue(), @@ -1157,14 +1173,14 @@ public final class MainFrameApplication extends MainFrame { JOptionPane.INFORMATION_MESSAGE ); } else { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "No branch collapsed,\nminimum branch length is " + min_bl, "No branch collapsed", JOptionPane.INFORMATION_MESSAGE ); } } else { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "No branch collapsed because no branch length values present", "No branch length values present", JOptionPane.INFORMATION_MESSAGE ); @@ -1178,7 +1194,7 @@ public final class MainFrameApplication extends MainFrame { xml_parser = PhyloXmlParser.createPhyloXmlParserXsdValidating(); } catch ( final Exception e ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), e.getLocalizedMessage(), "failed to create validating XML parser", JOptionPane.WARNING_MESSAGE ); @@ -1205,7 +1221,7 @@ public final class MainFrameApplication extends MainFrame { new Thread( inferrer ).start(); } else { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "No multiple sequence alignment selected", "Phylogenetic Inference Not Launched", JOptionPane.WARNING_MESSAGE ); @@ -1220,7 +1236,7 @@ public final class MainFrameApplication extends MainFrame { new Thread( inferrer ).start(); } else { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "No input sequences selected", "Phylogenetic Inference Not Launched", JOptionPane.WARNING_MESSAGE ); @@ -1272,7 +1288,7 @@ public final class MainFrameApplication extends MainFrame { failed = "\nCould not extract taxonomic data for " + counter_failed + " named external nodes:\n" + sb_failed; } - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Extracted taxonomic data from " + all + counter + " named external nodes:\n" + sb.toString() + failed, "Taxonomic Data Extraction Completed", @@ -1280,7 +1296,7 @@ public final class MainFrameApplication extends MainFrame { : JOptionPane.INFORMATION_MESSAGE ); } else { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Could not extract any taxonomic data.\nMaybe node names are empty\n" + "or not in the forms \"XYZ_CAEEL\", \"XYZ_6239\", or \"XYZ_Caenorhabditis_elegans\"\n" + "or nodes already have taxonomic data?\n", @@ -1544,7 +1560,7 @@ public final class MainFrameApplication extends MainFrame { getMainPanel() ); _mainpanel.getControlPanel().showWhole(); if ( nhx_or_nexus && one_desc ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "One or more trees contain (a) node(s) with one descendant, " + ForesterUtil.LINE_SEPARATOR + "possibly indicating illegal parentheses within node names.", @@ -1606,7 +1622,7 @@ public final class MainFrameApplication extends MainFrame { if ( !exception && ( t != null ) && !t.isRooted() ) { exception = true; t = null; - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Species tree is not rooted", "Species tree not loaded", JOptionPane.ERROR_MESSAGE ); @@ -1618,7 +1634,7 @@ public final class MainFrameApplication extends MainFrame { if ( !node.getNodeData().isHasTaxonomy() ) { exception = true; t = null; - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Species tree contains external node(s) without taxonomy information", "Species tree not loaded", JOptionPane.ERROR_MESSAGE ); @@ -1629,7 +1645,7 @@ public final class MainFrameApplication extends MainFrame { exception = true; t = null; JOptionPane - .showMessageDialog( this, + .showMessageDialog( getThisFrame(), "Taxonomy [" + node.getNodeData().getTaxonomy().asSimpleText() + "] is not unique in species tree", "Species tree not loaded", @@ -1644,7 +1660,7 @@ public final class MainFrameApplication extends MainFrame { } if ( !exception && ( t != null ) ) { setSpeciesTree( t ); - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Species tree successfully loaded", "Species tree loaded", JOptionPane.INFORMATION_MESSAGE ); @@ -2090,7 +2106,7 @@ public final class MainFrameApplication extends MainFrame { @Override void close() { if ( isUnsavedDataPresent() ) { - final int r = JOptionPane.showConfirmDialog( this, + final int r = JOptionPane.showConfirmDialog( getThisFrame(), "Exit despite potentially unsaved changes?", "Exit?", JOptionPane.YES_NO_OPTION ); @@ -2115,7 +2131,7 @@ public final class MainFrameApplication extends MainFrame { Phylogeny[] phys = null; final String message = "Please enter a complete URL, for example \"http://purl.org/phylo/treebase/phylows/study/TB2:S15480?format=nexus\""; final String url_string = JOptionPane - .showInputDialog( this, + .showInputDialog( getThisFrame(), message, "Use URL/webservice to obtain a phylogeny", JOptionPane.QUESTION_MESSAGE ); @@ -2148,20 +2164,20 @@ public final class MainFrameApplication extends MainFrame { phys = factory.create( url.openStream(), parser ); } catch ( final MalformedURLException e ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Malformed URL: " + url + "\n" + e.getLocalizedMessage(), "Malformed URL", JOptionPane.ERROR_MESSAGE ); } catch ( final IOException e ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), "Could not read from " + url + "\n" + ForesterUtil.wordWrap( e.getLocalizedMessage(), 80 ), "Failed to read URL", JOptionPane.ERROR_MESSAGE ); } catch ( final Exception e ) { - JOptionPane.showMessageDialog( this, + JOptionPane.showMessageDialog( getThisFrame(), ForesterUtil.wordWrap( e.getLocalizedMessage(), 80 ), "Unexpected Exception", JOptionPane.ERROR_MESSAGE );