2 VARNA is a tool for the automated drawing, visualization and annotation of the secondary structure of RNA, designed as a companion software for web servers and databases.
3 Copyright (C) 2008 Kevin Darty, Alain Denise and Yann Ponty.
4 electronic mail : Yann.Ponty@lri.fr
5 paper mail : LRI, bat 490 Université Paris-Sud 91405 Orsay Cedex France
7 This file is part of VARNA version 3.1.
8 VARNA version 3.1 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
11 VARNA version 3.1 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12 without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along with VARNA version 3.1.
16 If not, see http://www.gnu.org/licenses.
18 package fr.orsay.lri.varna.views;
20 import java.awt.BorderLayout;
21 import java.awt.Color;
22 import java.awt.Dimension;
23 import java.awt.FlowLayout;
24 import java.awt.GridLayout;
25 import java.awt.geom.Point2D.Double;
27 import javax.swing.JButton;
28 import javax.swing.JLabel;
29 import javax.swing.JPanel;
30 import javax.swing.JSlider;
31 import javax.swing.JTextArea;
32 import javax.swing.border.Border;
33 import javax.swing.plaf.basic.BasicBorders;
35 import fr.orsay.lri.varna.VARNAPanel;
36 import fr.orsay.lri.varna.controlers.ControleurSliderLabel;
37 import fr.orsay.lri.varna.controlers.ControleurVueAnnotation;
38 import fr.orsay.lri.varna.models.annotations.TextAnnotation;
42 * BH SwingJS using asynchronous JOptionPane.showConfirmDialog
44 * annoted text view for edition
46 * @author Darty@lri.fr
49 public class VueAnnotation {
51 protected VARNAPanel _vp;
52 private JSlider ySlider, xSlider;
53 private JButton colorButton;
54 private JTextArea textArea;
56 protected TextAnnotation textAnnotation, textAnnotationSave;
57 private VueFont vueFont;
58 private ControleurVueAnnotation _controleurVueAnnotation;
59 protected boolean newAnnotation, limited;
60 private Double position;
61 private JSlider rotationSlider;
64 * creates a view for a new annoted text
68 * if true, lets custom position and angle.
70 public VueAnnotation(VARNAPanel vp, boolean limited) {
73 (int) (vp.getExtendedRNABBox().x + vp.getExtendedRNABBox().width / 2.0),
74 (int) (vp.getExtendedRNABBox().y + vp.getExtendedRNABBox().height / 2.0),
79 * creates a view for a new annoted text, without limited option
83 public VueAnnotation(VARNAPanel vp) {
88 * creates a view for a new annoted text at a given position, without
93 public VueAnnotation(VARNAPanel vp, int x, int y) {
94 this(vp, x, y, false);
98 * creates a view for a new annoted text at a given position, without
103 public VueAnnotation(VARNAPanel vp, int x, int y, boolean limited) {
104 this(vp, new TextAnnotation("", x, y), false, true);
108 * creates a view for an annoted text, without limited option
113 public VueAnnotation(VARNAPanel vp, TextAnnotation textAnnot,
114 boolean newAnnotation) {
115 this(vp, textAnnot, (textAnnot.getType()!=TextAnnotation.AnchorType.POSITION), newAnnotation);
119 * creates a view for an annoted text
125 * if true, lets custom position and angle.
126 * @param newAnnotation
127 * if true, deleted if cancelled.
129 public VueAnnotation(VARNAPanel vp, TextAnnotation textAnnot,
130 boolean reduite, boolean newAnnotation) {
131 this.limited = reduite;
132 this.newAnnotation = newAnnotation;
134 textAnnotation = textAnnot;
135 textAnnotationSave = textAnnotation.clone();
137 if (!_vp.getListeAnnotations().contains(textAnnot)) {
138 _vp.addAnnotation(textAnnotation);
141 _controleurVueAnnotation = new ControleurVueAnnotation(this);
143 position = textAnnotation.getCenterPosition();
146 * if (textAnnotation.getType() != TextAnnotation.POSITION) { position =
147 * _vp.transformCoord(position); }
150 JPanel py = new JPanel();
151 JPanel px = new JPanel();
152 panel = new JPanel();
153 panel.setLayout(new GridLayout(0, 1));
154 py.setLayout(new FlowLayout(FlowLayout.LEFT));
155 px.setLayout(new FlowLayout(FlowLayout.LEFT));
157 ySlider = new JSlider(JSlider.HORIZONTAL, 0, (int) (_vp
158 .getExtendedRNABBox().height), Math.max(0, Math.min((int) (_vp
159 .getExtendedRNABBox().height), (int) (position.y - _vp
160 .getExtendedRNABBox().y))));
161 // Turn on labels at major tick marks.
162 ySlider.setMajorTickSpacing(500);
163 ySlider.setMinorTickSpacing(100);
164 ySlider.setPaintTicks(true);
165 ySlider.setPaintLabels(true);
166 ySlider.setPreferredSize(new Dimension(400,
167 ySlider.getPreferredSize().height));
169 JLabel yValueLabel = new JLabel(String.valueOf((int) position.y
170 - _vp.getExtendedRNABBox().y));
171 yValueLabel.setPreferredSize(new Dimension(50, yValueLabel
172 .getPreferredSize().height));
174 .addChangeListener(new ControleurSliderLabel(yValueLabel, false));
175 ySlider.addChangeListener(_controleurVueAnnotation);
177 xSlider = new JSlider(JSlider.HORIZONTAL, 0, (int) (_vp
178 .getExtendedRNABBox().width), Math.max(0, Math.min((int) _vp
179 .getExtendedRNABBox().width, (int) (position.x - _vp
180 .getExtendedRNABBox().x))));
181 // Turn on labels at major tick marks.
182 xSlider.setMajorTickSpacing(500);
183 xSlider.setMinorTickSpacing(100);
184 xSlider.setPaintTicks(true);
185 xSlider.setPaintLabels(true);
186 xSlider.setPreferredSize(new Dimension(400,
187 xSlider.getPreferredSize().height));
189 JLabel xValueLabel = new JLabel(String.valueOf((int) position.x
190 - _vp.getExtendedRNABBox().x));
191 xValueLabel.setPreferredSize(new Dimension(50, xValueLabel
192 .getPreferredSize().height));
194 .addChangeListener(new ControleurSliderLabel(xValueLabel, false));
195 xSlider.addChangeListener(_controleurVueAnnotation);
197 JLabel labelY = new JLabel("Y:");
198 JLabel labelX = new JLabel("X:");
212 JPanel panelTexte = new JPanel();
213 panelTexte.setLayout(new BorderLayout());
214 textArea = new JTextArea(textAnnotation.getTexte());
215 textArea.addCaretListener(_controleurVueAnnotation);
216 textArea.setPreferredSize(panelTexte.getSize());
217 Border border = new BasicBorders.FieldBorder(Color.black, Color.black,
218 Color.black, Color.black);
219 textArea.setBorder(border);
220 JLabel labelTexte = new JLabel("Text:");
221 panelTexte.add(textArea, BorderLayout.CENTER);
222 panelTexte.add(labelTexte, BorderLayout.NORTH);
223 panel.add(panelTexte);
225 vueFont = new VueFont(textAnnot.getFont());
226 vueFont.getBoxPolice().addActionListener(_controleurVueAnnotation);
227 vueFont.getSizeSlider().addChangeListener(_controleurVueAnnotation);
228 vueFont.getStylesBox().addActionListener(_controleurVueAnnotation);
230 colorButton = new JButton("Set color");
231 colorButton.setActionCommand("setcolor");
232 colorButton.setForeground(textAnnot.getColor());
233 colorButton.addActionListener(_controleurVueAnnotation);
235 JPanel fontAndColor = new JPanel();
236 fontAndColor.add(vueFont.getPanel());
237 fontAndColor.add(colorButton);
239 panel.add(fontAndColor);
241 JPanel rotationPanel = new JPanel();
243 rotationSlider = new JSlider(JSlider.HORIZONTAL, -360, 360,
244 (int) textAnnotation.getAngleInDegres());
245 rotationSlider.setMajorTickSpacing(60);
246 rotationSlider.setPaintTicks(true);
247 rotationSlider.setPaintLabels(true);
248 rotationSlider.setPreferredSize(new Dimension(500, 50));
250 JLabel rotationLabel = new JLabel(String.valueOf(0));
251 rotationLabel.setPreferredSize(new Dimension(50, rotationLabel
252 .getPreferredSize().height));
253 rotationSlider.addChangeListener(new ControleurSliderLabel(
254 rotationLabel, false));
255 rotationSlider.addChangeListener(_controleurVueAnnotation);
257 JLabel labelZ = new JLabel("Rotation (degrees):");
259 rotationPanel.add(labelZ);
260 rotationPanel.add(rotationSlider);
261 rotationPanel.add(rotationLabel);
264 * if (!limited) { panel.add(rotationPanel); }
268 ySlider.setEnabled(false);
269 xSlider.setEnabled(false);
270 rotationSlider.setEnabled(false);
272 textArea.requestFocusInWindow();
276 private void applyFont() {
277 textAnnotation.setFont(vueFont.getFont());
281 * update the annoted text on the VARNAPanel
283 public void update() {
285 if (textAnnotation.getType() == TextAnnotation.AnchorType.POSITION)
286 textAnnotation.setAncrage((double) xSlider.getValue()
287 + _vp.getExtendedRNABBox().x, ySlider.getValue()
288 + _vp.getExtendedRNABBox().y);
289 textAnnotation.setText(textArea.getText());
290 textAnnotation.setAngleInDegres(rotationSlider.getValue());
291 _vp.clearSelection();
295 public JPanel getPanel() {
301 * @return the annoted text
303 public TextAnnotation getTextAnnotation() {
304 return textAnnotation;
307 public VARNAPanel get_vp() {
312 * shows the dialog which add it to the VARNAPanel for previsualization.
314 * if validate, just update the annoted text
316 * if cancelled : remove the annoted text if it was a new one, otherwise
317 * cancel modifications
322 _vp.set_selectedAnnotation(textAnnotation);
323 _vp.highlightSelectedAnnotation();
325 // BH SwingjS using asynchronous dialog
326 Runnable ok = new Runnable() {
335 Runnable cancel = new Runnable() {
340 _vp.set_selectedAnnotation(null);
341 if (!_vp.removeAnnotation(textAnnotation))
342 _vp.errorDialog(new Exception("Impossible de supprimer"));
344 textAnnotation.copy(textAnnotationSave);
350 Runnable final_ = new Runnable() {
354 _vp.resetAnnotationHighlight();
355 _vp.set_selectedAnnotation(null);
361 _vp.getVARNAUI().showConfirmDialog(getPanel(), "Add/edit annotation", ok, cancel, cancel, final_);
364 public boolean isLimited() {
368 public void setLimited(boolean limited) {
369 this.limited = limited;
372 public boolean isNewAnnotation() {
373 return this.newAnnotation;
376 public void updateColor(Color c) {
377 colorButton.setForeground(c);
378 textAnnotation.setColor(c);