/* 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. Copyright (C) 2008 Kevin Darty, Alain Denise and Yann Ponty. electronic mail : Yann.Ponty@lri.fr paper mail : LRI, bat 490 University Paris-Sud 91405 Orsay Cedex France This file is part of VARNA version 3.1. VARNA version 3.1 is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. VARNA version 3.1 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with VARNA version 3.1. If not, see http://www.gnu.org/licenses. */ package fr.orsay.lri.varna.views; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.GridLayout; import java.awt.geom.Point2D.Double; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JSlider; import javax.swing.JTextArea; import javax.swing.border.Border; import javax.swing.plaf.basic.BasicBorders; import fr.orsay.lri.varna.VARNAPanel; import fr.orsay.lri.varna.controlers.ControleurSliderLabel; import fr.orsay.lri.varna.controlers.ControleurVueAnnotation; import fr.orsay.lri.varna.models.annotations.TextAnnotation; /** * annoted text view for edition * * @author Darty@lri.fr * */ public class VueAnnotation { private VARNAPanel _vp; private JSlider ySlider, xSlider; private JButton colorButton; private JTextArea textArea; private JPanel panel; private TextAnnotation textAnnotation, textAnnotationSave; private VueFont vueFont; private ControleurVueAnnotation _controleurVueAnnotation; private boolean newAnnotation, limited; private Double position; private JSlider rotationSlider; /** * creates a view for a new annoted text * * @param vp * @param limited * if true, lets custom position and angle. */ public VueAnnotation(VARNAPanel vp, boolean limited) { this( vp, (int) (vp.getExtendedRNABBox().x + vp.getExtendedRNABBox().width / 2.0), (int) (vp.getExtendedRNABBox().y + vp.getExtendedRNABBox().height / 2.0), limited); } /** * creates a view for a new annoted text, without limited option * * @param vp */ public VueAnnotation(VARNAPanel vp) { this(vp, false); } /** * creates a view for a new annoted text at a given position, without * limited option * * @param vp */ public VueAnnotation(VARNAPanel vp, int x, int y) { this(vp, x, y, false); } /** * creates a view for a new annoted text at a given position, without * limited option * * @param vp */ public VueAnnotation(VARNAPanel vp, int x, int y, boolean limited) { this(vp, new TextAnnotation("", x, y), false, true); } /** * creates a view for an annoted text, without limited option * * @param vp * @param textAnnot */ public VueAnnotation(VARNAPanel vp, TextAnnotation textAnnot, boolean newAnnotation) { this(vp, textAnnot, (textAnnot.getType()!=TextAnnotation.POSITION), newAnnotation); } /** * creates a view for an annoted text * * * @param vp * @param textAnnot * @param reduite * if true, lets custom position and angle. * @param newAnnotation * if true, deleted if cancelled. */ public VueAnnotation(VARNAPanel vp, TextAnnotation textAnnot, boolean reduite, boolean newAnnotation) { this.limited = reduite; this.newAnnotation = newAnnotation; _vp = vp; textAnnotation = textAnnot; textAnnotationSave = textAnnotation.clone(); if (!_vp.getListeAnnotations().contains(textAnnot)) { _vp.addAnnotation(textAnnotation); } _controleurVueAnnotation = new ControleurVueAnnotation(this); position = textAnnotation.getCenterPosition(); /* * if (textAnnotation.getType() != TextAnnotation.POSITION) { position = * _vp.transformCoord(position); } */ JPanel py = new JPanel(); JPanel px = new JPanel(); panel = new JPanel(); panel.setLayout(new GridLayout(0, 1)); py.setLayout(new FlowLayout(FlowLayout.LEFT)); px.setLayout(new FlowLayout(FlowLayout.LEFT)); ySlider = new JSlider(JSlider.HORIZONTAL, 0, (int) (_vp .getExtendedRNABBox().height), Math.max(0, Math.min((int) (_vp .getExtendedRNABBox().height), (int) (position.y - _vp .getExtendedRNABBox().y)))); // Turn on labels at major tick marks. ySlider.setMajorTickSpacing(500); ySlider.setMinorTickSpacing(100); ySlider.setPaintTicks(true); ySlider.setPaintLabels(true); ySlider.setPreferredSize(new Dimension(400, ySlider.getPreferredSize().height)); JLabel yValueLabel = new JLabel(String.valueOf((int) position.y - _vp.getExtendedRNABBox().y)); yValueLabel.setPreferredSize(new Dimension(50, yValueLabel .getPreferredSize().height)); ySlider .addChangeListener(new ControleurSliderLabel(yValueLabel, false)); ySlider.addChangeListener(_controleurVueAnnotation); xSlider = new JSlider(JSlider.HORIZONTAL, 0, (int) (_vp .getExtendedRNABBox().width), Math.max(0, Math.min((int) _vp .getExtendedRNABBox().width, (int) (position.x - _vp .getExtendedRNABBox().x)))); // Turn on labels at major tick marks. xSlider.setMajorTickSpacing(500); xSlider.setMinorTickSpacing(100); xSlider.setPaintTicks(true); xSlider.setPaintLabels(true); xSlider.setPreferredSize(new Dimension(400, xSlider.getPreferredSize().height)); JLabel xValueLabel = new JLabel(String.valueOf((int) position.x - _vp.getExtendedRNABBox().x)); xValueLabel.setPreferredSize(new Dimension(50, xValueLabel .getPreferredSize().height)); xSlider .addChangeListener(new ControleurSliderLabel(xValueLabel, false)); xSlider.addChangeListener(_controleurVueAnnotation); JLabel labelY = new JLabel("Y:"); JLabel labelX = new JLabel("X:"); py.add(labelY); py.add(ySlider); py.add(yValueLabel); px.add(labelX); px.add(xSlider); px.add(xValueLabel); /*if (!limited) { panel.add(px); panel.add(py); }*/ JPanel panelTexte = new JPanel(); panelTexte.setLayout(new BorderLayout()); textArea = new JTextArea(textAnnotation.getTexte()); textArea.addCaretListener(_controleurVueAnnotation); textArea.setPreferredSize(panelTexte.getSize()); Border border = new BasicBorders.FieldBorder(Color.black, Color.black, Color.black, Color.black); textArea.setBorder(border); JLabel labelTexte = new JLabel("Text:"); panelTexte.add(textArea, BorderLayout.CENTER); panelTexte.add(labelTexte, BorderLayout.NORTH); panel.add(panelTexte); vueFont = new VueFont(textAnnot.getFont()); vueFont.getBoxPolice().addActionListener(_controleurVueAnnotation); vueFont.getSizeSlider().addChangeListener(_controleurVueAnnotation); vueFont.getStylesBox().addActionListener(_controleurVueAnnotation); colorButton = new JButton("Set color"); colorButton.setActionCommand("setcolor"); colorButton.setForeground(textAnnot.getColor()); colorButton.addActionListener(_controleurVueAnnotation); JPanel fontAndColor = new JPanel(); fontAndColor.add(vueFont.getPanel()); fontAndColor.add(colorButton); panel.add(fontAndColor); JPanel rotationPanel = new JPanel(); rotationSlider = new JSlider(JSlider.HORIZONTAL, -360, 360, (int) textAnnotation.getAngleInDegres()); rotationSlider.setMajorTickSpacing(60); rotationSlider.setPaintTicks(true); rotationSlider.setPaintLabels(true); rotationSlider.setPreferredSize(new Dimension(500, 50)); JLabel rotationLabel = new JLabel(String.valueOf(0)); rotationLabel.setPreferredSize(new Dimension(50, rotationLabel .getPreferredSize().height)); rotationSlider.addChangeListener(new ControleurSliderLabel( rotationLabel, false)); rotationSlider.addChangeListener(_controleurVueAnnotation); JLabel labelZ = new JLabel("Rotation (degrees):"); rotationPanel.add(labelZ); rotationPanel.add(rotationSlider); rotationPanel.add(rotationLabel); /* * if (!limited) { panel.add(rotationPanel); } */ if (limited) { ySlider.setEnabled(false); xSlider.setEnabled(false); rotationSlider.setEnabled(false); } textArea.requestFocusInWindow(); } private void applyFont() { textAnnotation.setFont(vueFont.getFont()); } /** * update the annoted text on the VARNAPanel */ public void update() { applyFont(); if (textAnnotation.getType() == TextAnnotation.POSITION) textAnnotation.setAncrage((double) xSlider.getValue() + _vp.getExtendedRNABBox().x, ySlider.getValue() + _vp.getExtendedRNABBox().y); textAnnotation.setTexte(textArea.getText()); textAnnotation.setAngleInDegres(rotationSlider.getValue()); _vp.clearSelection(); _vp.repaint(); } public JPanel getPanel() { return panel; } /** * * @return the annoted text */ public TextAnnotation getTextAnnotation() { return textAnnotation; } public VARNAPanel get_vp() { return _vp; } /** * shows the dialog which add it to the VARNAPanel for previsualization. * <p> * if validate, just update the annoted text * <p> * if cancelled : remove the annoted text if it was a new one, otherwise * cancel modifications * <p> * */ public void show() { _vp.set_selectedAnnotation(textAnnotation); _vp.highlightSelectedAnnotation(); if (JOptionPane.showConfirmDialog(_vp, getPanel(), "Add/edit annotation", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE) == JOptionPane.OK_OPTION) { update(); } else { if (newAnnotation) { _vp.set_selectedAnnotation(null); if (!_vp.removeAnnotation(textAnnotation)) _vp.errorDialog(new Exception("Impossible de supprimer")); } else { textAnnotation.copy(textAnnotationSave); } } _vp.resetAnnotationHighlight(); _vp.set_selectedAnnotation(null); _vp.repaint(); } public boolean isLimited() { return limited; } public void setLimited(boolean limited) { this.limited = limited; } public boolean isNewAnnotation() { return this.newAnnotation; } public void updateColor(Color c) { colorButton.setForeground(c); textAnnotation.setColor(c); } }