001/* 002 * Copyright 2010-2015 Institut Pasteur. 003 * 004 * This file is part of Icy. 005 * 006 * Icy is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * Icy is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with Icy. If not, see <http://www.gnu.org/licenses/>. 018 */ 019package icy.gui.sequence.tools; 020 021import icy.gui.component.sequence.SequencePreviewPanel; 022import icy.image.IcyBufferedImage; 023import icy.sequence.AbstractSequenceModel; 024import icy.sequence.Sequence; 025import icy.sequence.SequenceUtil; 026 027import java.awt.GridBagConstraints; 028import java.awt.GridBagLayout; 029import java.awt.Insets; 030import java.awt.event.ActionEvent; 031import java.awt.event.ActionListener; 032import java.awt.image.BufferedImage; 033 034import javax.swing.ButtonGroup; 035import javax.swing.DefaultBoundedRangeModel; 036import javax.swing.JLabel; 037import javax.swing.JPanel; 038import javax.swing.JRadioButton; 039import javax.swing.JSlider; 040import javax.swing.JSpinner; 041import javax.swing.SpinnerNumberModel; 042import javax.swing.SwingConstants; 043import javax.swing.border.TitledBorder; 044import javax.swing.event.ChangeEvent; 045import javax.swing.event.ChangeListener; 046 047/** 048 * @author Stephane 049 */ 050public class SequenceDimensionConvertPanel extends JPanel 051{ 052 private class SequenceDimensionConvertPanelModel extends AbstractSequenceModel 053 { 054 public SequenceDimensionConvertPanelModel() 055 { 056 super(); 057 } 058 059 @Override 060 public BufferedImage getImage(int t, int z) 061 { 062 return SequenceUtil.AdjustZTHelper 063 .getImage(sequence, t, z, getNewSizeZ(), getNewSizeT(), isOrderReversed()); 064 } 065 066 @Override 067 public int getSizeX() 068 { 069 return sequence.getSizeX(); 070 } 071 072 @Override 073 public int getSizeY() 074 { 075 return sequence.getSizeY(); 076 } 077 078 @Override 079 public int getSizeZ() 080 { 081 return getNewSizeZ(); 082 } 083 084 @Override 085 public int getSizeT() 086 { 087 return getNewSizeT(); 088 } 089 090 @Override 091 public int getSizeC() 092 { 093 return sequence.getSizeC(); 094 } 095 096 @Override 097 public BufferedImage getImage(int t, int z, int c) 098 { 099 return ((IcyBufferedImage) getImage(t, z)).getImage(c); 100 } 101 } 102 103 /** 104 * 105 */ 106 private static final long serialVersionUID = -6906749224563258829L; 107 108 // GUI 109 private JRadioButton ztRadioButton; 110 private JRadioButton tzRadioButton; 111 JSlider sizeZSlider; 112 JSlider sizeTSlider; 113 JSpinner sizeZSpinner; 114 JSpinner sizeTSpinner; 115 SequencePreviewPanel previewPane; 116 private ButtonGroup dimensionGroup; 117 118 // internals 119 final Sequence sequence; 120 boolean changingZ; 121 boolean changingT; 122 123 public SequenceDimensionConvertPanel(Sequence sequence) 124 { 125 super(); 126 127 this.sequence = sequence; 128 changingZ = false; 129 changingT = false; 130 131 initialize(); 132 133 dimensionGroup = new ButtonGroup(); 134 dimensionGroup.add(tzRadioButton); 135 dimensionGroup.add(ztRadioButton); 136 dimensionGroup.setSelected(ztRadioButton.getModel(), true); 137 138 final int sizeZ = sequence.getSizeZ(); 139 final int sizeT = sequence.getSizeT(); 140 final int sizeZT = sizeZ * sizeT; 141 142 sizeZSlider.setModel(new DefaultBoundedRangeModel(sizeZ, 0, 1, sizeZT)); 143 sizeZSpinner.setModel(new SpinnerNumberModel(sizeZ, 1, sizeZT, 1)); 144 sizeTSlider.setModel(new DefaultBoundedRangeModel(sizeT, 0, 1, sizeZT)); 145 sizeTSpinner.setModel(new SpinnerNumberModel(sizeT, 1, sizeZT, 1)); 146 147 tzRadioButton.addActionListener(new ActionListener() 148 { 149 @Override 150 public void actionPerformed(ActionEvent e) 151 { 152 previewPane.imageChanged(); 153 } 154 }); 155 156 ztRadioButton.addActionListener(new ActionListener() 157 { 158 @Override 159 public void actionPerformed(ActionEvent e) 160 { 161 previewPane.imageChanged(); 162 } 163 }); 164 165 sizeZSlider.addChangeListener(new ChangeListener() 166 { 167 @Override 168 public void stateChanged(ChangeEvent e) 169 { 170 if (changingT) 171 return; 172 173 final int newSize = sizeZSlider.getValue(); 174 175 sizeZSpinner.setValue(Integer.valueOf(newSize)); 176 177 sizeZChanged(); 178 } 179 }); 180 sizeZSpinner.addChangeListener(new ChangeListener() 181 { 182 @Override 183 public void stateChanged(ChangeEvent e) 184 { 185 if (changingT) 186 return; 187 188 final int newSize = ((Integer) sizeZSpinner.getValue()).intValue(); 189 190 sizeZSlider.setValue(newSize); 191 192 sizeZChanged(); 193 } 194 }); 195 196 sizeTSlider.addChangeListener(new ChangeListener() 197 { 198 @Override 199 public void stateChanged(ChangeEvent e) 200 { 201 if (changingZ) 202 return; 203 204 final int newSize = sizeTSlider.getValue(); 205 206 sizeTSpinner.setValue(Integer.valueOf(newSize)); 207 208 sizeTChanged(); 209 } 210 }); 211 sizeTSpinner.addChangeListener(new ChangeListener() 212 { 213 @Override 214 public void stateChanged(ChangeEvent e) 215 { 216 if (changingZ) 217 return; 218 219 final int newSize = ((Integer) sizeTSpinner.getValue()).intValue(); 220 221 sizeTSlider.setValue(newSize); 222 223 sizeTChanged(); 224 } 225 }); 226 227 previewPane.setModel(new SequenceDimensionConvertPanelModel()); 228 } 229 230 private void initialize() 231 { 232 GridBagLayout gridBagLayout = new GridBagLayout(); 233 gridBagLayout.columnWidths = new int[] {20, 0, 20, 0, 0, 0, 80, 20, 0}; 234 gridBagLayout.rowHeights = new int[] {0, 0, 0, 0, 0}; 235 gridBagLayout.columnWeights = new double[] {1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE}; 236 gridBagLayout.rowWeights = new double[] {0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE}; 237 setLayout(gridBagLayout); 238 239 final JLabel lblNewLabel = new JLabel("Dimension order"); 240 lblNewLabel.setHorizontalAlignment(SwingConstants.TRAILING); 241 GridBagConstraints gbc_lblNewLabel = new GridBagConstraints(); 242 gbc_lblNewLabel.fill = GridBagConstraints.BOTH; 243 gbc_lblNewLabel.insets = new Insets(0, 0, 5, 5); 244 gbc_lblNewLabel.gridx = 1; 245 gbc_lblNewLabel.gridy = 0; 246 add(lblNewLabel, gbc_lblNewLabel); 247 248 ztRadioButton = new JRadioButton("Z - T"); 249 GridBagConstraints gbc_ztRadioButton = new GridBagConstraints(); 250 gbc_ztRadioButton.fill = GridBagConstraints.BOTH; 251 gbc_ztRadioButton.insets = new Insets(0, 0, 5, 5); 252 gbc_ztRadioButton.gridx = 3; 253 gbc_ztRadioButton.gridy = 0; 254 add(ztRadioButton, gbc_ztRadioButton); 255 256 tzRadioButton = new JRadioButton("T - Z"); 257 GridBagConstraints gbc_tzRadioButton = new GridBagConstraints(); 258 gbc_tzRadioButton.gridwidth = 2; 259 gbc_tzRadioButton.fill = GridBagConstraints.BOTH; 260 gbc_tzRadioButton.insets = new Insets(0, 0, 5, 5); 261 gbc_tzRadioButton.gridx = 4; 262 gbc_tzRadioButton.gridy = 0; 263 add(tzRadioButton, gbc_tzRadioButton); 264 265 final JLabel lblNewLabel_1 = new JLabel("Size Z"); 266 lblNewLabel_1.setHorizontalAlignment(SwingConstants.TRAILING); 267 lblNewLabel_1.setToolTipText("Size of Z dimension"); 268 GridBagConstraints gbc_lblNewLabel_1 = new GridBagConstraints(); 269 gbc_lblNewLabel_1.fill = GridBagConstraints.BOTH; 270 gbc_lblNewLabel_1.insets = new Insets(0, 0, 5, 5); 271 gbc_lblNewLabel_1.gridx = 1; 272 gbc_lblNewLabel_1.gridy = 1; 273 add(lblNewLabel_1, gbc_lblNewLabel_1); 274 275 sizeZSpinner = new JSpinner(); 276 sizeZSpinner.setToolTipText("Size of Z dimension"); 277 GridBagConstraints gbc_zSpinner = new GridBagConstraints(); 278 gbc_zSpinner.gridwidth = 2; 279 gbc_zSpinner.fill = GridBagConstraints.BOTH; 280 gbc_zSpinner.insets = new Insets(0, 0, 5, 5); 281 gbc_zSpinner.gridx = 3; 282 gbc_zSpinner.gridy = 1; 283 add(sizeZSpinner, gbc_zSpinner); 284 285 sizeZSlider = new JSlider(); 286 GridBagConstraints gbc_zSlider = new GridBagConstraints(); 287 gbc_zSlider.gridwidth = 2; 288 gbc_zSlider.fill = GridBagConstraints.BOTH; 289 gbc_zSlider.insets = new Insets(0, 0, 5, 5); 290 gbc_zSlider.gridx = 5; 291 gbc_zSlider.gridy = 1; 292 add(sizeZSlider, gbc_zSlider); 293 294 final JLabel lblNewLabel_2 = new JLabel("Size T"); 295 lblNewLabel_2.setHorizontalAlignment(SwingConstants.TRAILING); 296 lblNewLabel_2.setToolTipText("Size of T dimension"); 297 GridBagConstraints gbc_lblNewLabel_2 = new GridBagConstraints(); 298 gbc_lblNewLabel_2.fill = GridBagConstraints.BOTH; 299 gbc_lblNewLabel_2.insets = new Insets(0, 0, 5, 5); 300 gbc_lblNewLabel_2.gridx = 1; 301 gbc_lblNewLabel_2.gridy = 2; 302 add(lblNewLabel_2, gbc_lblNewLabel_2); 303 304 sizeTSpinner = new JSpinner(); 305 sizeTSpinner.setToolTipText("Size of T dimension"); 306 GridBagConstraints gbc_tSpinner = new GridBagConstraints(); 307 gbc_tSpinner.gridwidth = 2; 308 gbc_tSpinner.fill = GridBagConstraints.BOTH; 309 gbc_tSpinner.insets = new Insets(0, 0, 5, 5); 310 gbc_tSpinner.gridx = 3; 311 gbc_tSpinner.gridy = 2; 312 add(sizeTSpinner, gbc_tSpinner); 313 314 sizeTSlider = new JSlider(); 315 GridBagConstraints gbc_tSlider = new GridBagConstraints(); 316 gbc_tSlider.gridwidth = 2; 317 gbc_tSlider.insets = new Insets(0, 0, 5, 5); 318 gbc_tSlider.fill = GridBagConstraints.BOTH; 319 gbc_tSlider.gridx = 5; 320 gbc_tSlider.gridy = 2; 321 add(sizeTSlider, gbc_tSlider); 322 323 previewPane = new SequencePreviewPanel(true); 324 previewPane.setBorder(new TitledBorder(null, "Preview", TitledBorder.LEADING, TitledBorder.TOP, null, null)); 325 GridBagConstraints gbc_previewPane = new GridBagConstraints(); 326 gbc_previewPane.gridwidth = 8; 327 gbc_previewPane.insets = new Insets(0, 0, 0, 5); 328 gbc_previewPane.fill = GridBagConstraints.BOTH; 329 gbc_previewPane.gridx = 0; 330 gbc_previewPane.gridy = 3; 331 add(previewPane, gbc_previewPane); 332 } 333 334 void sizeZChanged() 335 { 336 final int sizeZT = sequence.getSizeZ() * sequence.getSizeT(); 337 final int newSizeZ = getNewSizeZ(); 338 int newSizeT = sizeZT / newSizeZ; 339 340 if ((sizeZT % newSizeZ) != 0) 341 newSizeT++; 342 343 changingZ = true; 344 try 345 { 346 sizeTSpinner.setValue(Integer.valueOf(newSizeT)); 347 sizeTSlider.setValue(newSizeT); 348 previewPane.dimensionChanged(); 349 } 350 finally 351 { 352 changingZ = false; 353 } 354 } 355 356 void sizeTChanged() 357 { 358 final int sizeZT = sequence.getSizeZ() * sequence.getSizeT(); 359 final int newSizeT = getNewSizeT(); 360 int newSizeZ = sizeZT / newSizeT; 361 362 if ((sizeZT % newSizeT) != 0) 363 newSizeZ++; 364 365 changingT = true; 366 try 367 { 368 sizeZSpinner.setValue(Integer.valueOf(newSizeZ)); 369 sizeZSlider.setValue(newSizeZ); 370 previewPane.dimensionChanged(); 371 } 372 finally 373 { 374 changingT = false; 375 } 376 } 377 378 public Sequence getSequence() 379 { 380 return sequence; 381 } 382 383 public boolean isOrderReversed() 384 { 385 return dimensionGroup.getSelection() == tzRadioButton.getModel(); 386 } 387 388 public int getNewSizeZ() 389 { 390 return ((Integer) sizeZSpinner.getValue()).intValue(); 391 } 392 393 public int getNewSizeT() 394 { 395 return ((Integer) sizeTSpinner.getValue()).intValue(); 396 } 397 398}