View Javadoc
1   // ******************************************************************************
2   //
3   // Title:       Force Field X.
4   // Description: Force Field X - Software for Molecular Biophysics.
5   // Copyright:   Copyright (c) Michael J. Schnieders 2001-2024.
6   //
7   // This file is part of Force Field X.
8   //
9   // Force Field X is free software; you can redistribute it and/or modify it
10  // under the terms of the GNU General Public License version 3 as published by
11  // the Free Software Foundation.
12  //
13  // Force Field X is distributed in the hope that it will be useful, but WITHOUT
14  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  // FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
16  // details.
17  //
18  // You should have received a copy of the GNU General Public License along with
19  // Force Field X; if not, write to the Free Software Foundation, Inc., 59 Temple
20  // Place, Suite 330, Boston, MA 02111-1307 USA
21  //
22  // Linking this library statically or dynamically with other modules is making a
23  // combined work based on this library. Thus, the terms and conditions of the
24  // GNU General Public License cover the whole combination.
25  //
26  // As a special exception, the copyright holders of this library give you
27  // permission to link this library with independent modules to produce an
28  // executable, regardless of the license terms of these independent modules, and
29  // to copy and distribute the resulting executable under terms of your choice,
30  // provided that you also meet, for each linked independent module, the terms
31  // and conditions of the license of that module. An independent module is a
32  // module which is not derived from or based on this library. If you modify this
33  // library, you may extend this exception to your version of the library, but
34  // you are not obligated to do so. If you do not wish to do so, delete this
35  // exception statement from your version.
36  //
37  // ******************************************************************************
38  package ffx.ui;
39  
40  import ffx.potential.bonded.MSRoot;
41  import ffx.potential.bonded.RendererCache;
42  import java.awt.Dimension;
43  import java.awt.Frame;
44  import java.awt.GridBagConstraints;
45  import java.awt.GridBagLayout;
46  import java.awt.Insets;
47  import java.awt.event.ActionEvent;
48  import java.awt.event.ActionListener;
49  import java.io.Serial;
50  import java.util.Hashtable;
51  import java.util.logging.Logger;
52  import javax.swing.BorderFactory;
53  import javax.swing.JButton;
54  import javax.swing.JDialog;
55  import javax.swing.JLabel;
56  import javax.swing.JSlider;
57  import javax.swing.border.Border;
58  import javax.swing.border.EtchedBorder;
59  import javax.swing.border.TitledBorder;
60  
61  /**
62   * The GraphicsPrefs class allows users to select graphics preferences.
63   *
64   * @author Michael J. Schnieders
65   */
66  public class GraphicsPrefs extends JDialog implements ActionListener {
67  
68    @Serial
69    private static final long serialVersionUID = 1L;
70  
71    private static final Logger logger = Logger.getLogger(GraphicsPrefs.class.getName());
72    private final MSRoot root;
73    private final GridBagConstraints constraints;
74    private boolean change = false;
75  
76    /**
77     * Contructor
78     *
79     * @param frame Parent frame
80     * @param r Data structure root
81     */
82    GraphicsPrefs(Frame frame, MSRoot r) {
83      super(frame, "", true);
84      root = r;
85      setTitle("Graphics Preferences");
86      setSize(400, 200);
87      setResizable(false);
88      getContentPane().setLayout(new GridBagLayout());
89      constraints = new GridBagConstraints();
90      constraints.weighty = 100;
91      constraints.gridheight = 1;
92      constraints.gridwidth = 2;
93      constraints.ipadx = 5;
94      constraints.ipady = 5;
95      constraints.gridx = 0;
96      constraints.gridy = 0;
97      constraints.insets = new Insets(5, 5, 5, 5);
98      // Slider for radius
99      JSlider radius = new JSlider(0, 200, 1);
100     radius.setMajorTickSpacing(50);
101     radius.setMinorTickSpacing(10);
102     radius.setPaintLabels(true);
103     radius.setPaintTicks(true);
104     radius.setValue((int) (RendererCache.radius * 100));
105     Hashtable<Integer, JLabel> labelTable = new Hashtable<>();
106     labelTable.put(1, new JLabel("0%"));
107     labelTable.put(50, new JLabel("50%"));
108     labelTable.put(100, new JLabel("100%"));
109     labelTable.put(150, new JLabel("150%"));
110     labelTable.put(200, new JLabel("200%"));
111     radius.setLabelTable(labelTable);
112     addSlider(radius, " Radius", 1);
113     // Slider for bondwidth
114     JSlider bondwidth = new JSlider(1, 5, 5);
115     bondwidth.setMajorTickSpacing(1);
116     bondwidth.setMinorTickSpacing(1);
117     bondwidth.setPaintLabels(true);
118     bondwidth.setPaintTicks(true);
119     labelTable = new Hashtable<>();
120     labelTable.put(1, new JLabel("1"));
121     labelTable.put(3, new JLabel("3"));
122     labelTable.put(5, new JLabel("5"));
123     bondwidth.setLabelTable(labelTable);
124     bondwidth.setValue(RendererCache.bondwidth);
125     addSlider(bondwidth, " Wireframe Thickness", 3);
126     // Slider for detail
127     JSlider detail = new JSlider(0, 10, 3);
128     detail.setMajorTickSpacing(1);
129     detail.setMinorTickSpacing(1);
130     detail.setPaintLabels(true);
131     detail.setPaintTicks(true);
132     detail.setValue(RendererCache.detail);
133     labelTable = new Hashtable<>();
134     labelTable.put(0, new JLabel("Performance"));
135     labelTable.put(10, new JLabel("Quality"));
136     detail.setLabelTable(labelTable);
137     addSlider(detail, " Detail", 2);
138     constraints.gridwidth = 1;
139     JButton jb = new JButton("Apply");
140     jb.addActionListener(this);
141     getContentPane().add(jb, constraints);
142     JButton jbclose = new JButton("Close");
143     jbclose.addActionListener(this);
144     constraints.gridx++;
145     getContentPane().add(jbclose, constraints);
146     pack();
147     Dimension dim = getToolkit().getScreenSize();
148     Dimension ddim = getSize();
149     setLocation((dim.width - ddim.width) / 2, (dim.height - ddim.height) / 2);
150   }
151 
152   /** {@inheritDoc} */
153   public void actionPerformed(ActionEvent e) {
154     if (e.getActionCommand().equalsIgnoreCase("Apply")) {
155       if (change) {
156         root.setView(RendererCache.ViewModel.DETAIL, null);
157       }
158       change = false;
159     } else if (e.getActionCommand().equalsIgnoreCase("Close")) {
160       if (change) {
161         root.setView(RendererCache.ViewModel.DETAIL, null);
162       }
163       change = false;
164       dispose();
165     }
166   }
167 
168   /**
169    * addSlider
170    *
171    * @param s a {@link javax.swing.JSlider} object.
172    * @param description a {@link java.lang.String} object.
173    * @param sliderID a int.
174    */
175   private void addSlider(JSlider s, String description, final int sliderID) {
176     Border eb = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
177     s.setSnapToTicks(true);
178     s.setBorder(new TitledBorder(eb, description));
179     s.addChangeListener(
180         e -> {
181           JSlider source = (JSlider) e.getSource();
182           if (source.getValueIsAdjusting()) {
183             return;
184           }
185           int value = source.getValue();
186           switch (sliderID) {
187             case 1 -> {
188               if (value < 1) {
189                 return;
190               }
191               double temp = value / 100.0d;
192               if (temp != RendererCache.radius) {
193                 change = true;
194                 RendererCache.radius = temp;
195               }
196             }
197             case 2 -> {
198               if (RendererCache.detail != value) {
199                 change = true;
200                 RendererCache.detail = value;
201               }
202             }
203             case 3 -> {
204               if (RendererCache.bondwidth != value) {
205                 change = true;
206                 RendererCache.bondwidth = value;
207               }
208             }
209             default -> logger.info("Unknown Slider");
210           }
211         });
212     // add three components into the next row
213     constraints.gridx = 0;
214     constraints.anchor = GridBagConstraints.WEST;
215     constraints.fill = GridBagConstraints.NONE;
216     getContentPane().add(s, constraints);
217     constraints.gridy++;
218   }
219 }