package org.das2.qds.filters; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; import java.util.logging.Level; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JCheckBox; import javax.swing.JFormattedTextField; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JSpinner; import javax.swing.SpinnerNumberModel; import org.das2.qds.QDataSet; import static org.das2.qds.filters.AbstractFilterEditorPanel.logger; /** * GUI for the slices operation. * @author jbf */ public class SlicesFilterEditorPanel extends AbstractFilterEditorPanel implements FilterEditorPanel { static final long t0= System.currentTimeMillis(); int[] qube= null; JSpinner[] spinners= new JSpinner[8]; JCheckBox[] checkboxs= new JCheckBox[8]; int rank= 8; public SlicesFilterEditorPanel() { setFilter("|slices(:)"); } @Override public String getFilter() { logger.fine( "getFilter" ); StringBuilder result= new StringBuilder("|slices("); for ( int i=0; i<rank; i++ ) { String sep= i==0 ? "" : ","; if ( checkboxs[i].isSelected() ) { result.append(sep).append(spinners[i].getValue()); } else { result.append(sep).append("':'"); } } result.append(")"); return result.toString(); } private JPanel getDimensionPanel( final int i, String s) throws NumberFormatException { JPanel p1= new JPanel( ); p1.setLayout( new BoxLayout( p1, BoxLayout.X_AXIS ) ); //p1.setBorder( new TitledBorder("One Panel")); final JCheckBox cb1= new JCheckBox("Index"+i+":"); cb1.setToolTipText("slice on this dimension"); p1.add( cb1 ); checkboxs[i]=cb1; cb1.addActionListener((ActionEvent e) -> { spinners[i].setEnabled( cb1.isSelected() ); }); p1.add( Box.createHorizontalStrut(14) ); JSpinner sp1= new JSpinner(); if ( sp1.getEditor() instanceof JFormattedTextField ) { ((JFormattedTextField)sp1.getEditor()).setColumns(10); } addMouseWheelListenerToSpinner( sp1 ); spinners[i]= sp1; if ( s.startsWith("'") && s.endsWith("'") ) s= s.substring(1,s.length()-1); if ( s.equals(":") ) { sp1.setEnabled(false); cb1.setSelected(false); } else { sp1.setValue(Integer.parseInt(s)); cb1.setSelected(true); } p1.add( sp1 ); p1.add( Box.createGlue() ); return p1; } private static void addMouseWheelListenerToSpinner( final JSpinner sliceIndexSpinner ) { sliceIndexSpinner.addMouseWheelListener( new MouseWheelListener() { @Override public void mouseWheelMoved(MouseWheelEvent evt) { SpinnerNumberModel snm= ((SpinnerNumberModel)sliceIndexSpinner.getModel()); int newIndex= snm.getNumber().intValue() - evt.getWheelRotation(); if ( newIndex<0 ) newIndex= 0; Number nmax= (Number)snm.getMaximum(); if ( nmax!=null ) { int maxIndex= nmax.intValue(); if ( newIndex>maxIndex ) newIndex= maxIndex; } snm.setValue( newIndex ); } } ); } @Override public final void setFilter(String filter) { logger.log(Level.FINE, "setFilter {0}", filter); Pattern p= Pattern.compile("\\|slices\\((.*)\\)"); Matcher m= p.matcher(filter); if ( m.matches() ) { String arg= m.group(1); String[] ss= arg.split(","); if ( ss.length==rank ) { for ( int i=0; i<rank; i++ ) { String s= ss[i]; JCheckBox cb1= checkboxs[i]; JSpinner sp1= spinners[i]; if ( s.startsWith("'") && s.endsWith("'") ) s= s.substring(1,s.length()-1); if ( s.equals(":") ) { sp1.setEnabled(false); cb1.setSelected(false); } else { sp1.setValue(Integer.parseInt(s)); cb1.setSelected(true); } } } else { rank= ss.length; this.removeAll(); this.setLayout( new BoxLayout( this, BoxLayout.Y_AXIS ) ); for ( int i=0; i<rank; i++ ) { add( getDimensionPanel(i, ss[i]) ); } } } } @Override public void setInput(QDataSet ds) { logger.log(Level.FINE, "setInput {0}", ds.toString() ); String[] depNames1= FilterEditorPanelUtil.getDimensionNames(ds); int rmCount= this.rank-ds.rank(); this.rank= ds.rank(); for ( int i=0; i<rank; i++ ) { QDataSet dep= (QDataSet) ds.property("DEPEND_"+i); if ( checkboxs[i]==null ) { add( getDimensionPanel( i,":") ); } checkboxs[i].setText(depNames1[i]); checkboxs[i].setToolTipText("slice on "+depNames1[i]); int max; if ( dep==null ) { max= Integer.MAX_VALUE; } else { if ( dep.rank()==1 ) { max= dep.length(); } else if ( dep.rank()==2 ) { max= dep.length(0); } else { max= Integer.MAX_VALUE; } } int val= ((Integer)spinners[i].getValue()); if ( val<0 ) val=0; if ( val>=max ) val= max; spinners[i].setModel( new SpinnerNumberModel( val, 0, max, 1 ) ); } for ( int i=ds.rank(); i<ds.rank()+rmCount; i++ ) { try { remove( i ); // DANGER: this assumes there are no other components preceding the guis. } catch ( ArrayIndexOutOfBoundsException ex ) { ex.printStackTrace(); } } for ( int i=0; i<rank-4; i++ ) { checkboxs[i].setEnabled(false); } } public static void main( String[] args ) { FilterEditorPanel filter= new SlicesFilterEditorPanel(); QDataSet ds= FiltersChainPanel.getExampleDataSet("qube"); filter.setFilter("|slices(0,:)"); filter.setInput(ds); JOptionPane.showMessageDialog( null, filter); System.err.println( filter.getFilter() ); } }