package fr.unistra.pelican.gui;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.util.Random;
import javax.media.jai.*;
import javax.swing.*;
import javax.swing.event.*;
import fr.unistra.pelican.Image;
import fr.unistra.pelican.IntegerImage;
import fr.unistra.pelican.util.History;
/**
* The DrawVideo class allows the user to draw markers with a background image.
*/
public class DrawVideo extends JPanel
{
///////////////
// CONSTANTS //
///////////////
public static final boolean TRANSPARENCY_PRESENT_BY_DEFAULT = false;
public static final boolean ADD_LABELS_PRESENT_BY_DEFAULT = true;
////////////
// FIELDS //
////////////
// GUI fields
private JDialog frame;
/** Contains the labels list. */
private JComboBox labelsBox;
/** Allows to change the stroke size of the brush. */
private JSpinner brushSpinner;
/** Allows to change the transparency of the marker image. */
private JSlider transparencySlider;
/** Contains the slider to switch between frames */
private JScrollPane scroll;
/** Displays video's frames */
private CustomDisplayJAI display;
/** Slider that allows to switch between video's frames*/
private JSlider frameSld;
private JPanel colorPanel, npanel, spanel, bpanel;
private JLabel brushThicknessLabel, transparencyLabel, frameLbl;
private JButton addLabelsButton, renameButton, undoButton, redoButton, resetCurButton, resetAllButton, okButton;
// listeners
private aListener alistener;
private cListener clistener;
private kListener klistener;
private mListener mlistener;
// images
/** The "background" image that must be processed in this. */
public Image inputImage;
/** The user marked image. */
public IntegerImage output;
/** The background image converted in BufferedImage.
* Necessary for displaying the pic in the GUI.*/
private BufferedImage bimg;
/** The markers image.
* Always equal to the marker image that was passed in argument at creation.
* And : yes, that means "always equal to <tt>null</tt>" if nothing was passed.
*/
private IntegerImage markersImage = null;
// booleans
/** Whether or not {#transparencyLabel} and {#transparencySlider} will be added to this. */
private boolean transparencyEnabled;
/** Whether or not {#addLabelsButton} will be added to this. */
private boolean addLabelsEnabled;
/** true if resetting */
private boolean reset = false;
//time measurement
private long humanTime;
// arrays
/** Use to save the marker image after each drawing in case of an undo. */
private History<WritableRenderedImage>[] markersHistory;
/** Use to contain comboBox labels*/
public String[] tabLabels = new String[1]; // (eraser)
//////////////////
// CONSTRUCTORS //
//////////////////
/** Secondary constructor.
* @param inputImage An {@link fr.unistra.pelican.Image} to set as background.
*/
public DrawVideo( Image inputImage )
{
this( inputImage,null);
}
/** Secondary constructor.
* @param inputImage An {@link fr.unistra.pelican.Image} to set as background.
* @param title The frame's title.
*/
public DrawVideo( Image inputImage, String title)
{
this( inputImage,title, null);
}
/** Secondary constructor.
* @param inputImage An {@link fr.unistra.pelican.Image} to set as background.
* @param title The frame's title.
* @param markersImage
*/
public DrawVideo( Image inputImage, String title, IntegerImage markersImage )
{
this(inputImage,title, markersImage, TRANSPARENCY_PRESENT_BY_DEFAULT,ADD_LABELS_PRESENT_BY_DEFAULT);
}
/** Primary constructor.
* @param OrigVideo An {@link fr.unistra.pelican.Image} to set as background.
* @param title The frame's title.
* @param transparencyEnabled
* @param addLabelsEnabled
*/
public DrawVideo( Image _inputImage, String title, IntegerImage _markersImage, boolean transparencyEnabled, boolean addLabelsEnabled )
{
this.inputImage = _inputImage;
if ( this.inputImage.getBDim() != 3)
{
this.inputImage = fr.unistra.pelican.algorithms.conversion.GrayToRGB.exec(
fr.unistra.pelican.algorithms.conversion.AverageChannels.exec( this.inputImage ) );
}
this.markersImage = _markersImage;
this.transparencyEnabled = transparencyEnabled;
this.addLabelsEnabled = addLabelsEnabled;
this.bimg = fr.unistra.pelican.util.Tools.pelican2BufferedT( this.inputImage, 0);
this.output = new IntegerImage(inputImage.getXDim(),inputImage.getYDim(),1,inputImage.getTDim(),1);
this.output.fill(0);
this.frame = new JDialog();
if(title != null)
this.frame.setTitle( title );
this.frame.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
this.frame.setLocationRelativeTo(null);
this.frame.setModal(true);
System.out.println("GUI init...");
this.guiInitialization();
humanTime = System.currentTimeMillis();
this.frame.setVisible(true);
}
/////////////
// METHODS //
/////////////
/** Initialization of the Video2D GUI. */
private void guiInitialization()
{
this.setLayout( new BorderLayout() );
npanel = new JPanel(new GridBagLayout()); // the "north" panel
spanel = new JPanel(new BorderLayout()); // the "south" panel
bpanel = new JPanel(new GridBagLayout()); // the "button" panel into "south" panel
alistener = new aListener();
clistener = new cListener();
klistener = new kListener();
mlistener = new mListener();
// one: create the components which will be put on the "north" panel
if(markersImage != null)
{
this.output = this.markersImage;
this.tabLabels = new String[((String[])this.markersImage.getProperty("Labels")).length];
for(int i = 0; i< this.tabLabels.length; i++)
{
this.tabLabels = ((String[])markersImage.getProperty("Labels"));
}
}
else
{
this.tabLabels[0] = "Eraser";
}
this.labelsBox = new JComboBox(tabLabels);
this.labelsBox.setBackground(SystemColor.control);
this.labelsBox.setOpaque(false);
this.labelsBox.setSelectedIndex(0);
this.labelsBox.addActionListener( alistener );
int[][] colorMap = lutInitialization();
this.colorPanel = new JPanel();
this.colorPanel.setBorder( BorderFactory.createLineBorder( Color.black ) );
this.colorPanel.setMinimumSize( new Dimension( 20,20 ) );
this.colorPanel.setPreferredSize( new Dimension( 20,20 ) );
this.colorPanel.setBackground( new Color(
colorMap[ this.labelsBox.getSelectedIndex() ][0],
colorMap[ this.labelsBox.getSelectedIndex() ][1],
colorMap[ this.labelsBox.getSelectedIndex() ][2]));
this.addLabelsButton = new JButton( "+" );
this.addLabelsButton.addActionListener( alistener );
this.renameButton = new JButton("Rename label");
this.renameButton.addActionListener( alistener );
this.brushThicknessLabel = new JLabel( "Thickness: " );
this.brushThicknessLabel.setBackground( SystemColor.control );
this.brushSpinner = new JSpinner();
this.brushSpinner.setModel( new SpinnerNumberModel(
CustomDisplayJAI.DEFAULT_BRUSH_SIZE,
CustomDisplayJAI.MIN_BRUSH_SIZE,
CustomDisplayJAI.MAX_BRUSH_SIZE,
1) );
this.brushSpinner.setMaximumSize( new Dimension( 32767,32767 ) );
this.brushSpinner.setMinimumSize( new Dimension( 40,18 ) );
this.brushSpinner.setPreferredSize( new Dimension( 40,18 ) );
this.brushSpinner.addChangeListener( clistener );
// this will be a waste if this.transparencyEnabled = false
this.transparencyLabel = new JLabel( "Transparency:" );
this.transparencySlider = new JSlider();
this.transparencySlider.setExtent( 0 );
this.transparencySlider.setMaximum( 255 );
this.transparencySlider.setPaintLabels( false );
this.transparencySlider.setPaintTicks( false );
this.transparencySlider.setPaintTrack( true );
this.transparencySlider.setBackground(SystemColor.control);
this.transparencySlider.setMaximumSize( new Dimension( 32767,24 ) );
this.transparencySlider.setValue( 255 );
this.transparencySlider.addChangeListener( clistener );
// two: create the components which will be put on the "south" panel
this.undoButton = new JButton( "Undo" );
this.undoButton.addActionListener( alistener );
this.undoButton.setEnabled( false );
this.redoButton = new JButton( "Redo" );
this.redoButton.addActionListener( alistener );
this.redoButton.setEnabled( false );
this.resetCurButton = new JButton( "Reset current" );
this.resetCurButton.addActionListener( alistener );
this.resetCurButton.setEnabled( false );
//resetAllButton is always enabled
this.resetAllButton = new JButton ( "Reset all");
this.resetAllButton.addActionListener( alistener );
this.resetAllButton.setEnabled( true );
//okButton is always enabled
this.okButton = new JButton( "Done" );
this.okButton.addActionListener( alistener );
this.okButton.setEnabled( true );
// three: create the component which contains this.display
// and will be placed on the central panel
this.display = new CustomDisplayJAI();
this.display.colorMap = colorMap;
this.display.set( this.bimg,this.markersImage );
MouseListener[] ml = this.display.getMouseListeners();
this.display.removeMouseListener( ml[0] );
this.display.addMouseListener( mlistener );
markerHistoryInit();
// Component which contains the MarkerDisplayJAI instance (display)
this.scroll = new JScrollPane( this.display );
scroll.setViewportBorder( BorderFactory.createLineBorder( Color.black ) );
MouseWheelListener[] listeners = scroll.getMouseWheelListeners();
MouseWheelListener defaultMouseWheelListener = listeners[0];
scroll.removeMouseWheelListener( defaultMouseWheelListener );
this.display.defaultMouseWheelListener = defaultMouseWheelListener;
// four: put all that GUI stuff in the panels
GridBagConstraints nconstraints = new GridBagConstraints();
nconstraints.fill = GridBagConstraints.HORIZONTAL;
nconstraints.weightx = 1.0;
nconstraints.gridx = 0;
nconstraints.gridy = 0;
nconstraints.gridwidth = 1;
npanel.add( this.labelsBox, nconstraints );
nconstraints.weightx = .25;
nconstraints.gridx ++;
npanel.add( this.colorPanel, nconstraints );
if ( this.addLabelsEnabled )
{
nconstraints.gridx ++;
npanel.add( this.addLabelsButton, nconstraints );
}
nconstraints.weightx = 1.0;
nconstraints.gridx ++;
npanel.add( this.renameButton, nconstraints );
nconstraints.gridx ++;
npanel.add( Box.createRigidArea( new Dimension( 10,0 ) ) );
nconstraints.gridx ++;
npanel.add( brushThicknessLabel, nconstraints );
nconstraints.weightx = .25;
nconstraints.gridx ++;
npanel.add( this.brushSpinner, nconstraints );
nconstraints.weightx = 1.0;
nconstraints.gridx ++;
if ( this.transparencyEnabled )
{
npanel.add( Box.createRigidArea( new Dimension( 10,0 ) ) );
nconstraints.gridx++;
npanel.add( this.transparencyLabel, nconstraints );
nconstraints.weightx = 2.0;
nconstraints.gridx++;
npanel.add( this.transparencySlider, nconstraints );
}
GridBagConstraints sconstraints = new GridBagConstraints();
sconstraints.fill = GridBagConstraints.HORIZONTAL;
sconstraints.weightx = 1.0;
sconstraints.gridx = 0;
sconstraints.gridy = 0;
sconstraints.gridwidth = 1;
bpanel.add( this.undoButton, sconstraints );
sconstraints.gridx ++;
bpanel.add( this.redoButton, sconstraints );
sconstraints.gridx ++;
bpanel.add( this.resetCurButton, sconstraints );
sconstraints.gridx ++;
bpanel.add( this.resetAllButton, sconstraints );
sconstraints.gridx ++;
bpanel.add( Box.createRigidArea( new Dimension( 10,0 ) ) );
sconstraints.gridx ++;
bpanel.add( this.okButton, sconstraints );
sconstraints.gridx ++;
GridBagConstraints iconstraints = new GridBagConstraints();
iconstraints.fill = GridBagConstraints.BOTH;
iconstraints.gridx = 0;
iconstraints.gridy = 0;
iconstraints.gridwidth = 1;
iconstraints.gridheight = 1;
iconstraints.gridx ++;
//frames slider
JPanel frameBox = new JPanel();
frameBox.setLayout(new BoxLayout(frameBox, BoxLayout.X_AXIS));
frameLbl = new JLabel(" Frame : 1/" + inputImage.getTDim() + " ");
frameBox.add(frameLbl);
frameSld = new JSlider(SwingConstants.HORIZONTAL, 1, inputImage.getTDim(), 1);
frameSld.setSnapToTicks(true);
frameBox.add(frameSld);
frameSld.addChangeListener(new ChangeListener()
{
/**
* Listener qui change de frame selon le slider
**/
public void stateChanged(ChangeEvent e)
{
int t = frameSld.getValue() - 1;
frameLbl.setText(" Frame : " + Integer.toString(frameSld.getValue()) + "/" + inputImage.getTDim() + " ");
bimg = fr.unistra.pelican.util.Tools.pelican2BufferedT( inputImage, t );
int vValue = scroll.getVerticalScrollBar().getValue();
int hValue = scroll.getHorizontalScrollBar().getValue();
display.set(bimg, (IntegerImage)output.getImage4D(t, Image.T));
checkButtons();
scroll.getVerticalScrollBar().setValue(vValue);
scroll.getHorizontalScrollBar().setValue(hValue);
}
});
if (inputImage.getTDim() == 1)
{
frameLbl.setEnabled(false);
frameSld.setEnabled(false);
}
JPanel subPnl = new JPanel();
subPnl.setLayout( new BorderLayout() );
if (frameLbl.isEnabled())
{
subPnl.add(frameBox, BorderLayout.CENTER);
}
spanel.add(bpanel, BorderLayout.SOUTH);
spanel.add(subPnl, BorderLayout.NORTH);
this.add( npanel, BorderLayout.NORTH);
this.add( this.scroll, BorderLayout.CENTER );
this.add( spanel, BorderLayout.SOUTH);
// five : finalize. you know that.
this.display.getMouseListeners();
this.display.getMouseMotionListeners();
MouseWheelListener[] mwlis = this.display.getMouseWheelListeners();
this.display.removeMouseWheelListener( mwlis[0] );
Component[] allthegui = { this, frame, npanel, spanel, display, scroll,
undoButton, redoButton, resetCurButton, resetAllButton, okButton, labelsBox,
colorPanel, addLabelsButton, renameButton, brushThicknessLabel, brushSpinner,
transparencyLabel, transparencySlider };
KeyListener[] klis;
for ( int c = 0 ; c < allthegui.length ; c++ )
{
klis = allthegui[c].getKeyListeners();
System.out.println(klis.length+" "+allthegui[c].getClass().getName());
allthegui[c].addKeyListener( klistener );
allthegui[c].addMouseWheelListener( mwlis[0] );
}
//zoom +50%
for(int i =0; i< 6; i++)
{
display.zoom(true);
display.set( bimg, output);
}
this.setOpaque( true );
this.frame.setContentPane( this );
this.frame.pack();
}
/** Fill colorMap with 256 different colors. */
private int[][] lutInitialization()
{
int[][] colorMap = new int[257][4];
Random random = new Random();
byte[] color = new byte[3];
// Set the first table element to be transparent
colorMap[0][0] = 127;
colorMap[0][1] = 127;
colorMap[0][2] = 127;
colorMap[0][3] = 0;
int x = 1;
// Set all the other colors (opaque)
for ( int j = 0 ; j < 4; j++ )
{
for ( int k = 0 ; k < 4; k++ )
{
for ( int i = 0; i < 16; i++ )
{
random.setSeed(x * 131);
random.nextBytes(color);
colorMap[x][0] = color[0]+128;
colorMap[x][1] = color[1]+128;
colorMap[x][2] = color[2]+128;
colorMap[x][3] = 255;
x++;
}
}
}
return colorMap;
}
/** Get an estimation (upper bound) of the number of labels.
* @return The number of item currently in {@link #labelBox}.
*/
public int labels()
{
return labelsBox.getItemCount();
}
/** Initialise l'historique des marqueurs en sauvegardant
* la premiere image de toutes les frames de la videos. */
@SuppressWarnings("unchecked")
public void markerHistoryInit()
{
markersHistory = new History[inputImage.getTDim()];
for(int i = 0; i< inputImage.getTDim(); i++)
{
markersHistory[i] = new History<WritableRenderedImage>();
// save first image for undo
int widthTI = display.raster.getWidth();
int heightTI = display.raster.getHeight();
WritableRenderedImage copy = fr.unistra.pelican.util.Tools.createGrayImage( (IntegerImage)null, widthTI,heightTI );
copy.setData( display.raster.copyData() );
markersHistory[i].add(copy );
}
}
/** Enable/disable buttons. */
public void checkButtons()
{
int t = frameSld.getValue() - 1;
if ( markersHistory[t].canForward() )
{
redoButton.setEnabled( true );
}
else
{
redoButton.setEnabled( false );
}
if ( markersHistory[t].canRewind() )
{
undoButton.setEnabled( true );
resetCurButton.setEnabled( true );
}
else
{
resetCurButton.setEnabled( false );
undoButton.setEnabled( false );
}
}
/** Sauvegarde les marqueurs de la frame visionnée. */
public void saveMarker()
{
//redimensionner l'image avant la sauvegarde
BufferedImage bi = ((PlanarImage) display.raster).getAsBufferedImage();
Raster raster = bi.getData();
int type = bi.getType();
int height = raster.getHeight();
int width = raster.getWidth();
// Transfers each byte from raster to output
for ( int x = 0 ; x < width ; x++ )
{
for ( int y = 0 ; y < height ; y++ )
{
output.setPixelXYTBInt( x,y,frameSld.getValue()-1,0, (byte) raster.getSample( x,y,0 ) );
}
}
output.setColor( false );
output.setProperty("humanTime", humanTime);
output.type = type;
output.properties.put("Labels", tabLabels);
}
//////////////////////
// EVENT MANAGEMENT //
// INTERNAL CLASSES //
//////////////////////
private class aListener implements ActionListener
{
public void actionPerformed( ActionEvent e )
{
Object source = e.getSource();
if ( source == labelsBox )
{
if ( !reset )
{
//the +1 is a bug fixed but probably not really solve the bug just a temporary patch
display.color[0] = (float) ( (labelsBox.getSelectedIndex()) / 255f );
// set the current color to labelColor
Color color = new Color(
(int) display.colorMap[ labelsBox.getSelectedIndex() ][ 0 ],
(int) display.colorMap[ labelsBox.getSelectedIndex() ][ 1 ],
(int) display.colorMap[ labelsBox.getSelectedIndex() ][ 2 ] );
colorPanel.setBackground(color);
}
}
else if ( source == addLabelsButton )
{
display.color[0] = (float) ( labelsBox.getSelectedIndex() / 256f );
// set the current color to labelColor
Color color = new Color(
(int) display.colorMap[ labelsBox.getSelectedIndex() ][ 0 ],
(int) display.colorMap[ labelsBox.getSelectedIndex() ][ 1 ],
(int) display.colorMap[ labelsBox.getSelectedIndex() ][ 2 ] );
colorPanel.setBackground( color );
String newLabelName = JOptionPane.showInputDialog(null,
"What will be the name for this new label ?", "Add new label",
JOptionPane.QUESTION_MESSAGE);
if(newLabelName != null)
{
while(newLabelName.startsWith(" ") && newLabelName.length() > 1)
{
newLabelName = newLabelName.substring(1);
}
if(newLabelName.equals(" ") || newLabelName.length() <= 1 )
{
newLabelName = "Label " + tabLabels.length;
}
String[] temp = tabLabels;
tabLabels = new String[tabLabels.length + 1];
tabLabels[labelsBox.getItemCount()] = newLabelName;
for(int i =0; i< temp.length; i++)
{
tabLabels[i] = temp[i];
}
labelsBox.removeActionListener(alistener);
labelsBox.removeAllItems();
for(int i = 0; i< tabLabels.length; i++)
{
labelsBox.addItem(tabLabels[i]);
}
labelsBox.addActionListener( alistener );
labelsBox.setSelectedItem( newLabelName );
}
}
else if ( source == renameButton )
{
int saveItemIndex = labelsBox.getSelectedIndex();
String label = JOptionPane.showInputDialog(null,
"New label's name ? \n ", "Rename label",
JOptionPane.QUESTION_MESSAGE);
if(label != null)
{
while(label.startsWith(" ") && label.length() > 1)
{
label = label.substring(1);
}
if(label.length() > 1 )
{
tabLabels[labelsBox.getSelectedIndex()] = label;
labelsBox.removeActionListener(alistener);
labelsBox.removeAllItems();
for(int i = 0; i< tabLabels.length; i++)
{
labelsBox.addItem(tabLabels[i]);
}
labelsBox.addActionListener( alistener );
labelsBox.setSelectedIndex(saveItemIndex);
}
}
}
else if ( source == undoButton )
{
// re-display the last marker image saved in history
WritableRenderedImage copy = markersHistory[frameSld.getValue()-1].rewind();
display.raster.setData( copy.getData() );
display.createColorMarkerImage();
display.repaint();
saveMarker();
checkButtons();
}
else if ( source == redoButton )
{
WritableRenderedImage copy = markersHistory[frameSld.getValue()-1].forward();
display.raster.setData( copy.getData() );
if ( !markersHistory[frameSld.getValue()-1].canForward() ) redoButton.setEnabled( false );
display.createColorMarkerImage();
display.repaint();
saveMarker();
checkButtons();
}
else if ( source == resetCurButton )
{
reset = true;
WritableRenderedImage copy = markersHistory[frameSld.getValue()-1].genesis();
display.raster.setData( copy.getData() );
display.createColorMarkerImage();
display.repaint();
display.color[0] = (float) 1 / 256;
new Color(
(int) display.colorMap[ labelsBox.getSelectedIndex() ][ 0 ],
(int) display.colorMap[ labelsBox.getSelectedIndex() ][ 1 ],
(int) display.colorMap[ labelsBox.getSelectedIndex() ][ 2 ] );
reset = false;
saveMarker();
checkButtons();
}
else if ( source == resetAllButton )
{
int option = JOptionPane.showConfirmDialog(null,
"Are you sure you want to reset the entire video ?"
+"\nThis will clear all the markers you have drawn.",
"Reset every markers ?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if(option == JOptionPane.OK_OPTION)
{
bimg = fr.unistra.pelican.util.Tools.pelican2BufferedT( inputImage, 0);
frameSld.setValue(1);
display.set( bimg);
output = new IntegerImage(inputImage.getXDim(),inputImage.getYDim(),1,inputImage.getTDim(),1);
output.fill(0);
markerHistoryInit();
checkButtons();
}
}
else if ( source == okButton )
{
humanTime= System.currentTimeMillis()-humanTime;
saveMarker();
frame.dispose();
}
}
}
private class cListener implements ChangeListener
{
public void stateChanged( ChangeEvent e )
{
Object source = e.getSource();
if ( source == brushSpinner )
{
if ( brushSpinner.getValue() instanceof Number )
{
int brushSize = (Integer) brushSpinner.getValue();
display.stroke = new BasicStroke( brushSize );
}
}
else if ( source == transparencySlider )
{
display.rasterTransparency = transparencySlider.getValue();
// Set the colorMap transparency for all but the first element
for ( int i = 1 ; i < 256 ; i++ )
display.colorMap[i][3] = (byte) display.rasterTransparency;
// refresh
display.createColorMarkerImage();
repaint();
}
}
}
private class kListener extends KeyAdapter
{
public void keyPressed( KeyEvent e )
{
if ( e.getKeyCode() == KeyEvent.VK_SHIFT )
{
display.horizontalScrollEnabled = !display.horizontalScrollEnabled;
display.revalidate();
}
else if ( e.getKeyCode() == KeyEvent.VK_CONTROL )
{
display.setNavigateMode( CustomDisplayJAI.ZOOM_MODE );
}
else if ( e.getKeyCode() == KeyEvent.VK_ALT )
{
display.drawEnabled( CustomDisplayJAI.DRAW_OFF );
}
else if ( e.getKeyCode() == KeyEvent.VK_LEFT )
{
if(frameSld.getValue() > 1)
{
frameSld.setValue(frameSld.getValue()-1);
}
}
else if ( e.getKeyCode() == KeyEvent.VK_RIGHT )
{
if(frameSld.getValue() < inputImage.getTDim())
{
frameSld.setValue(frameSld.getValue()+1);
}
}
else if ( e.getKeyCode() == KeyEvent.VK_UP )
{
if(e.isAltDown())
{
if (labelsBox.getSelectedIndex() < (labelsBox.getItemCount()-1) )
{
labelsBox.setSelectedIndex(labelsBox.getSelectedIndex()+1);
}
}
}
else if ( e.getKeyCode() == KeyEvent.VK_DOWN )
{
if(e.isAltDown())
{
if (labelsBox.getSelectedIndex() > 0 )
{
labelsBox.setSelectedIndex(labelsBox.getSelectedIndex()-1);
}
}
}
else if( e.getKeyCode() == 107 ) // touche "+" du pavé numérique
{
addLabelsButton.doClick();
}
else System.out.println("glop ");
}
public void keyReleased( KeyEvent e )
{
if ( e.getKeyCode() == KeyEvent.VK_SHIFT )
{
display.horizontalScrollEnabled = !display.horizontalScrollEnabled;
display.revalidate();
}
else if ( e.getKeyCode() == KeyEvent.VK_CONTROL )
{
display.setNavigateMode( CustomDisplayJAI.DEFAULT_MODE );
}
else if ( e.getKeyCode() == KeyEvent.VK_ALT )
{
display.drawEnabled( CustomDisplayJAI.DRAW_ON );
}
}
}
private class mListener implements MouseListener
{
public void mouseClicked( MouseEvent e ) { display.mouseClicked(e); }
public void mouseEntered( MouseEvent e ) { display.mouseEntered(e); }
public void mouseExited( MouseEvent e ) { display.mouseExited(e); }
public void mousePressed( MouseEvent e ) { display.mousePressed(e); }
/** Invoked when the mouse button has been released on a component.
* @param e The event to process.
*/
public void mouseReleased( MouseEvent e )
{
// save current image for undo
int widthTI = display.raster.getWidth();
int heightTI = display.raster.getHeight();
WritableRenderedImage copy = fr.unistra.pelican.util.Tools.createGrayImage((IntegerImage) null, widthTI,heightTI );
copy.setData( display.raster.copyData() );
markersHistory[frameSld.getValue()-1].add( copy );
checkButtons();
saveMarker();
}
}
////////////////////
// ANNOYING STUFF //
////////////////////
public static final long serialVersionUID = 1L;
/* This gets rid of the annoying exception for not using native acceleration :
* "Could not find mediaLib accelerator wrapper classes. Continuing in pure Java mode."
*/ static { System.setProperty( "com.sun.media.jai.disableMediaLib", "true" ); }
}