ProjectDefinitionDialog.java :  » IDE » Schmortopf » Schmortopf » Main » ProjectDefinition » Java Open Source

Java Open Source » IDE » Schmortopf 
Schmortopf » Schmortopf » Main » ProjectDefinition » ProjectDefinitionDialog.java
package Schmortopf.Main.ProjectDefinition;
  
                              
  /**                                                                            
   *    The dialog for editing the projectDefinition.
   */

                         
import java.awt.*;         
import java.awt.event.*;
import javax.swing.*;       
import javax.swing.event.*;
import javax.swing.border.*;
import javax.swing.filechooser.FileFilter;
import javax.swing.plaf.metal.*;
import java.util.*;
import java.io.*;

import Schmortopf.Main.ProjectDefinition.Panels.*;
import Schmortopf.Utility.*;
import Schmortopf.Utility.gui.*;
import Schmortopf.Main.*;
import Schmortopf.Utility.IniFile.IniFile;
import Language.Language;
import Shared.Logging.Log;


public class ProjectDefinitionDialog extends JDialog
{

  final ProjectDefinition projectDefinition;
  private boolean dialogWasCancelled = false;
  private JFrame parentFrame;
  private DataChangeListener dataChangeListener;

  private boolean doProcessTextUpdates = true;
  // a flag, so we can turn on or off updates.

  private boolean libraryContentHasChanged = false;
  // a flag, which is set, after the src file has been changed,
  // or if library files have been added or removed. The IDE
  // must reload the library tree, if this  is set after the
  // dialog has been closed. Use getLibraryContentHasChanged()
  // to ask this value.
                            
  private IDE_MainFrameProvider mainFrameProvider;
                                               
  private JTabbedPane tabPane;
  // the tab panels:
  private SourceFilesPanel sourceFilesPanel;
  private JDKSettingsPanel jdkSettingsPanel;
  private LaunchParametersPanel launchParametersPanel;
  
  private boolean allowChangeOfProjectDirectory;

  public ProjectDefinitionDialog( final ProjectDefinition _projectDefinition,
                                  final JFrame _parentFrame,
                                  final DataChangeListener _dataChangeListener,
                                  final IDE_MainFrameProvider _mainFrameProvider,
                                  boolean _allowChangeOfProjectDirectory )
  {
    super(_parentFrame);
    this.parentFrame = _parentFrame;
    this.dataChangeListener = _dataChangeListener;
    this.mainFrameProvider = _mainFrameProvider;
    this.allowChangeOfProjectDirectory = _allowChangeOfProjectDirectory;
    this.setModal( true );
    this.projectDefinition = _projectDefinition;
    this.getContentPane().setLayout( new BorderLayout() );

    this.setTitle(Language.Translate("Project Setting") +" "+ projectDefinition.getFilePathName() );

    this.tabPane = new JTabbedPane();
    this.getContentPane().add( this.tabPane, BorderLayout.CENTER );

    // Put all into a mainPanel with some border space :
    final JPanel mainPanel = new JPanel( new GridLayout(1,2,2,2) );
    int bsp = UIManager.getFont("TextField.font").getSize()/2;
    mainPanel.setBorder( BorderFactory.createEmptyBorder(bsp,bsp,bsp,bsp));

    this.sourceFilesPanel = new SourceFilesPanel( this,this.projectDefinition,this.mainFrameProvider,
                                                  this.allowChangeOfProjectDirectory );
    this.jdkSettingsPanel = new JDKSettingsPanel(this,this.projectDefinition,this.mainFrameProvider);
    this.launchParametersPanel = new LaunchParametersPanel(this,this.projectDefinition,this.mainFrameProvider);           

    this.tabPane.addTab("  " + Language.Translate("Source Files") + "  ", this.sourceFilesPanel);
    this.tabPane.addTab("  " + Language.Translate("JDK Settings") + "  ", this.jdkSettingsPanel );
    this.tabPane.addTab(" " + Language.Translate("Launch Parameters") + " ",this.launchParametersPanel );
    
    // Make a buttonpanel in the south with an OK and a cancel button,
    // which closes this dialog :
    final JPanel buttonPanel = new EFCNGradientPanel( new FlowLayout(),
                                                      EFCNGradientPanel.ApplyVerticalHighLight,
                                                      EFCNGradientPanel.StrongGradientStrength,
                                                      EFCNGradientPanel.ActiveTitleBackground );

    buttonPanel.setBorder( BorderFactory.createEtchedBorder() );
    this.getContentPane().add( buttonPanel, BorderLayout.SOUTH );

    final ImageIcon okIcon = mainFrameProvider.loadImageIcon("pics/menupics/ok.gif");
    JSenseButton okButton = new JSenseButton(" "+Language.Translate("Save and Close")+"  ",okIcon,true,mainFrameProvider);
    buttonPanel.add( okButton );
    okButton.addActionListener( new ActionListener()
     {
       public void actionPerformed( ActionEvent e )
       {      
         checkTerminateDialog();
       }
     });

    final ImageIcon cancelIcon = mainFrameProvider.loadImageIcon("pics/menupics/cancel.gif");
    JSenseButton cancelButton = new JSenseButton("   "+Language.Translate("Cancel")+"      ",cancelIcon,true,mainFrameProvider);
    buttonPanel.add( cancelButton );          
    cancelButton.addActionListener( new ActionListener()
     {
       public void actionPerformed( ActionEvent e )
       {
         dialogWasCancelled = true;
         setVisible(false);
       }
     });

    // Pack it. This is required to be delayed, cause some components
    //          initially will adapt their size (like JTextArea,
    //          which might process line breaks )
    this.pack(); // This IMMEDIATE one is required for positioning calcs.
    EventQueue.invokeLater( new Runnable()
     {
       public void run()
       {
         pack(); // This DELAYED one is required for updating.                  
       }
     });

    ActionListener escapeActionListener = new ActionListener()
    {
      public void actionPerformed(ActionEvent e)
      {
         dialogWasCancelled = true;
         setVisible(false);
      }
    };
    this.getRootPane().registerKeyboardAction( escapeActionListener,
                                               KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0, true),
                                               JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
  } // Constructor

  


 /**
  *  Overwritten: We must remove all view's :
  */
  public void setVisible( boolean state )
  {
    if( !state )
     {
       this.projectDefinition.removeAllEntryViews();
     }
    super.setVisible(state);
  }
          
          

  public DataChangeListener getDataChangeListener() {
    return this.dataChangeListener;
  }
          
          
          
  private void checkTerminateDialog()
  {
    // If the projectdefinition is not valid, we don't let the user proceed:
    if( projectDefinition.checkProjectDefinitionValues( this ) )
     {
       // Save the projectDefinition first :
       projectDefinition.saveToIniFile(parentFrame);
       // Then close it :
       setVisible(false);
       // inform the changeListener, cause data of the projectdefinition
       // could have been changed ... if there is one :
       if( dataChangeListener != null )
        {
          dataChangeListener.dataChanged();
        }
     } // if   
  } // checkTerminateDialog


  public void showCentered()
  {
     final Dimension size = this.getSize();
     final Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
     int xp = (screen.width-size.width)/2;
     int yp = (screen.height-size.height)/2;
     this.setLocation(xp,yp);
     this.setVisible(true);
  }









 /**
  *  Adds a view for a projectdefinitionentry.
  */
  public void addEditableEntryPanel(  final ProjectDefinitionEntry entry,
                                       final JPanel parentPanel,
                                       final boolean isEditable )
  {                                                                                          
    // theme flexible space value :
    int fs = UIManager.getFont("TextField.font").getSize()/6;

    JPanel entryPanel = new EFCNGradientPanel( new BorderLayout(),
                                               EFCNGradientPanel.ApplyVerticalHighLight,
                                               EFCNGradientPanel.StrongGradientStrength,
                                               EFCNGradientPanel.PanelBackground );
    entryPanel.setBorder( BorderFactory.createEmptyBorder(fs*2,fs*2,fs*2,fs*2));

    // put another panel around the entryPanel for making
    // some borderspace :
    JPanel borderPanel = new JPanel( new BorderLayout() );
    Border inb = BorderFactory.createEtchedBorder();
    Border outb = BorderFactory.createEmptyBorder(fs,fs,fs,fs);
    borderPanel.setBorder( BorderFactory.createCompoundBorder(outb,inb) );
    borderPanel.add( entryPanel, BorderLayout.CENTER );
    parentPanel.add( borderPanel );

    Object value = entry.getValue();
    // value is either a String or a String array or a Boolean :
    if( value instanceof String )
     {
      // key string :
      JContrastLabel keyLabel = new JContrastLabel( entry.getName() );
      entryPanel.add( keyLabel, BorderLayout.NORTH );
      // value string with a button for selecting it from
      // a filechooser dialog :
      final JPanel middleTextFieldPanel =
            createFileTextPanelWithChooserButton( entry,isEditable );
      entryPanel.add( middleTextFieldPanel, BorderLayout.CENTER );

      // Little explanation for the ProjectDirectory only :
      if( entry.getKey().equals( ProjectDefinition.ProjectDirectoryPath_Key ) )
       {
         JPanel expPanel = new JPanel( new BorderLayout(0,0) );
         expPanel.setBorder( BorderFactory.createEmptyBorder(fs*3,fs,fs*3,fs ) );
         expPanel.setOpaque(false);
         entryPanel.add( expPanel, BorderLayout.SOUTH );
     
         JTextArea textArea = new JTextArea( Language.Translate("Note: The project directory names must not be part of package names.") );
         textArea.setEditable(false);           
         textArea.setLineWrap(true);
         textArea.setWrapStyleWord(true);
         textArea.setBackground( UIManager.getColor("Panel.background") );
         textArea.setOpaque(false);
         expPanel.add(textArea, BorderLayout.SOUTH );
       }

     }
    else
    if( value instanceof String[] )
     {             
      // key string :
      JContrastLabel keyLabel = new JContrastLabel( entry.getName() );
      entryPanel.add( keyLabel, BorderLayout.NORTH );
      // value string with a button for selecting it from
      // a filechooser dialog :
      JPanel middleTextListPanel = null;
      if( entry.getDoShowAsRadioButtons() )
       {
         middleTextListPanel = createRadioButtonPanel( entry );
       }                                                    
      else
       {
         middleTextListPanel = createFileListPanelWithChooserButton( entry,isEditable );
       }  
      entryPanel.add( middleTextListPanel, BorderLayout.CENTER );
     }
    else
    if( value instanceof Boolean )
     {
      // key string :
      final JCheckBox checkBox = new JCheckBox( entry.getKey() );
      boolean checked = ((Boolean)value).booleanValue();
      // for this simple case, we just add the writeback functionality here :
      checkBox.addActionListener( new ActionListener()
       {
          public void actionPerformed(ActionEvent e)
          {
            final boolean state = checkBox.isSelected();
            entry.setValue( new Boolean(state) );
          }
       });
      checkBox.setSelected( checked );
      checkBox.setFocusPainted(false);
      checkBox.setOpaque(false);
      checkBox.setEnabled(isEditable);
      entryPanel.add( checkBox, BorderLayout.CENTER );
     }
  } // addEditableEntryPanel






       


  private JPanel createFileTextPanelWithChooserButton( final ProjectDefinitionEntry entry,
                                                       final boolean isEditablePanel )
  {                                                                                  
    JPanel panel = new JPanel( new BorderLayout() );
    panel.setOpaque(false);
    // textfield to the left (center so it fills the space):
    // calculate columns, so that JDialog doesnt exceed the screen :
    int maxColumns = Toolkit.getDefaultToolkit().getScreenSize().width / ( 3 * UIManager.getFont("TextField.font").getSize() / 2 );
    int columns = 42;
    if( columns > maxColumns ) columns = maxColumns;
    final JTextField textField = new JTextField( (String)entry.getValue(),columns );

    // add it as view for the lifetime of this dialog:
    entry.setEntryView(textField);

    textField.setEditable(isEditablePanel);
    panel.add(textField, BorderLayout.CENTER );
    entry.setEntryView(textField);
    this.updateTextFieldFileTextColor(entry,textField);
    textField.getDocument().addDocumentListener( new DocumentListener()
     {       
       public void insertUpdate(DocumentEvent e)
       {                     
         Log.Info("call processTextUpdate ");
         processTextUpdate( entry,textField );
         updateTextFieldFileTextColor(entry,textField);
       }
       public void removeUpdate(DocumentEvent e)
       {
         Log.Info("call processTextUpdate ");
         processTextUpdate( entry,textField );
         updateTextFieldFileTextColor(entry,textField);
       }
       public void changedUpdate(DocumentEvent e)
       {
         Log.Info("call processTextUpdate ");
         processTextUpdate( entry,textField );
         updateTextFieldFileTextColor(entry,textField);
       }
     });

    // button, which opens a filechooser for selection to the right :
    if( isEditablePanel )
     {
        JSenseButton chooserButton = new JSenseButton("...",this.mainFrameProvider.loadImageIcon("pics/editorpics/open.gif"),true,this.mainFrameProvider);
        chooserButton.setBorder( BorderFactory.createLoweredBevelBorder() );
        panel.add(chooserButton, BorderLayout.EAST );
        chooserButton.addActionListener( new ActionListener()
         {
           public void actionPerformed( ActionEvent e)
           {
             String[] allowedFileEndings;
             String osNameLowerCase = System.getProperty("os.name").toLowerCase();
             // see : http://www.tolstoy.com/samizdat/sysprops.html
             // All windows systems have either Windows or windows in it.
             boolean runsUnderWindows = ( osNameLowerCase.indexOf("windows") >= 0 ) ;
             if( runsUnderWindows )
              {
                if( entry.getContainsFileContents() )
                 {
                   allowedFileEndings = new String[]{"class","java","exe","jar","zip"};
                 } else
                 {
                   allowedFileEndings = new String[0]; // directories -> no files endings specified
                 }
              } else
              {
                allowedFileEndings = new String[0]; // all allowed
              }
             // Distinguish file and directory selection mode :
             String dialogTitle;
             int    dialogMode;
             if( entry.getContainsFileContents() )
              {
                dialogTitle = Language.Translate("Choose the file");
                dialogMode  = JFileChooser.FILES_ONLY;
              } else
              {
                dialogTitle = Language.Translate("Choose the directory");
                dialogMode  = JFileChooser.DIRECTORIES_ONLY;
              }
             String newPath = chooseFile( textField.getText(),
                                          allowedFileEndings,
                                          dialogTitle,
                                          entry.getOnlyAllowChoiceOfExistingFiles(),
                                          dialogMode );
             if( newPath.length() > 0 )
              {
                // Set it  : (this will force two updates in the document model -
                // First one removes all text, second one sets newPath text :
                textField.setText(newPath);
              }
           }
         });
     } // if isEditablePanel
    return panel;
  } // createFileTextPanelWithChooserButton






 /**
  *  Called for textfields, which are associated with a file on disk.
  *  The method paints the text red, if the file doesnt exist, and
  *  blue, if it does exist. Colors are chosen so that contrasts still are ok.
  */
  private void updateTextFieldFileTextColor( final ProjectDefinitionEntry entry,
                                             final JTextField textField )
  {
    // Skip directories, which we create automatically, if they don't exist :
    if( !entry.getKey().equals( ProjectDefinition.ProjectMainFileName_Key ) &&
        !entry.getKey().equals( ProjectDefinition.ClassFilesOutputPath_Key )   )
     {
       File testFileObject = new File( textField.getText() ); // getText = absolute filepath
       int grayScaleValue = ColorUtilities.GetGrayScaleValueFor( UIManager.getColor("TextField.foreground") );
       // Give some space for coloring :
       if( grayScaleValue < 100 ) grayScaleValue = 100; // Asymmetry: We need more room here
       if( grayScaleValue > 200 ) grayScaleValue = 200; // Contrast easier here
       if( testFileObject.exists() )
        {
          // Give it a blue touch, keep contrast :
          Color newForeGround = ColorUtilities.CreateColorFromFractions(0.7,0.7,1.6,grayScaleValue);
          textField.setForeground( newForeGround );
        }
       else
        {
          // Give it a red touch, keep contrast :
          Color newForeGround = ColorUtilities.CreateColorFromFractions(1.6,0.7,0.7,grayScaleValue);
          textField.setForeground( newForeGround );
        }
     }
  } // updateTextFieldFileTextColor

     
     



 /**
  *  Called by createFileTextPanelWithChooserButton.
  *  Updates the ProjectDefinitionEntry and if the entry
  *  is the jdk basisdirectory entry, some other entries are
  *  updated too.
  */
  private void processTextUpdate( final ProjectDefinitionEntry entry,
                                  final JTextField textField )
  {              
    // Scan for library content update and set the flag if required :
    if( entry.getKey().equals( ProjectDefinition.SourceJarFilePath_Key ) )
     {
       this.libraryContentHasChanged = true;
     }

    // Only update if the doProcessTextUpdates flag is set :
    if( this.doProcessTextUpdates )
     {
      // If the projectdefinition path is changed, set the path
      // of the project main file to this path too :
      if( entry.getKey().equals(ProjectDefinition.ProjectDirectoryPath_Key) )
       {
         final String oldValue = (String)entry.getValue();
         final String newValue = textField.getText();

         ProjectDefinitionEntry mainfileEntry = this.projectDefinition.getProjectDefinitionEntry(ProjectDefinition.ProjectMainFileName_Key);
         String oldMainFileValue = (String)mainfileEntry.getValue();
         // Keep the last token, which is the name of the mainfile :
         String[] tokens = StringUtilities.SplitString(oldMainFileValue,SchmortopfConstants.OSDelimiter);
         String fileName = "";
         if( tokens.length > 0 ) fileName = tokens[ tokens.length-1 ];
         // See that the format is ok :
         if( fileName.length() < 6 ) fileName = ProjectDefinition.DefaultProjectFileName;
         if( !fileName.endsWith(".java") ) fileName += ".java";
         mainfileEntry.setValue( newValue + SchmortopfConstants.OSDelimiter + fileName );
         // We have changed the model, so give the view a call :
         if( mainfileEntry.getEntryView() != null )
          {
            if( mainfileEntry.getEntryView() instanceof JTextField )
             {
               JTextField v = (JTextField)mainfileEntry.getEntryView();
               v.setText( (String)mainfileEntry.getValue() );
             }
          }
       }
      // If the JDK basis directory has been changed update all dependent entries too :
      if( entry.getKey().equals( ProjectDefinition.JDKBasisDirectory_Key) )
       {
         final String oldBasisDirectoryPath = (String)entry.getValue();
         final String newBasisDirectoryPath = textField.getText();
         
         Log.Info("called for " + ProjectDefinition.JDKBasisDirectory_Key );
         Log.Info("oldBasisDirectoryPath= " + oldBasisDirectoryPath);
         Log.Info("newBasisDirectoryPath= " + newBasisDirectoryPath);

         // update some other entries and textfields, which start with oldtext :
         // We must decouple, cause its called while updating the origin textfield :
         EventQueue.invokeLater( new Runnable()
          {
            public void run()
            {
              // 1) Update some main definitions and all specific main definitions:
              Vector entryUpdateVector = new Vector();
              entryUpdateVector.addElement( projectDefinition.getProjectDefinitionEntry(ProjectDefinition.SourceJarFilePath_Key) );
              ProjectDefinitionEntry[] detailedJDKEntries = projectDefinition.getDetailedJDKDefinitions();
              for( int i=0; i < detailedJDKEntries.length; i++ )
               {
                 entryUpdateVector.addElement( detailedJDKEntries[i] );
               }
              for( int i=0; i < entryUpdateVector.size(); i++ )
               {
                 ProjectDefinitionEntry thisEntry = (ProjectDefinitionEntry)entryUpdateVector.elementAt(i);
                 if( thisEntry.getValue() instanceof String )
                  {
                    String thisEntryText = (String)thisEntry.getValue();
                    
                    Log.Info("oldjdk: " + oldBasisDirectoryPath + "  this: " + thisEntryText );
                    
                    if( thisEntryText.startsWith( oldBasisDirectoryPath ) )
                     {
                       String newText = newBasisDirectoryPath +
                                        thisEntryText.substring( oldBasisDirectoryPath.length() );
                       thisEntry.setValue(newText);
                       // Update the view too, if it's present (will optionally update other entries]:
                       Object thisEntryView = thisEntry.getEntryView();
                       if( thisEntryView != null )
                        {
                          if( thisEntryView instanceof JTextField )
                           {
                             // Sync the textfield associated with thisEntry :
                             JTextField thisEntryTextField = (JTextField)thisEntryView;
                             // Turn off the update flag (otherwise it would go wildly recursive)
                             doProcessTextUpdates = false;
                             thisEntryTextField.setText(newText);
                             // reset the flag :
                             doProcessTextUpdates = true;
                           }
                        }
                     }
                  }
               }

              Log.Info("check src file ending:");
              // Finally adapt the src file ending, if required:
              ProjectDefinitionEntry thisEntry = 
                  projectDefinition.getProjectDefinitionEntry(ProjectDefinition.SourceJarFilePath_Key);
              String old_srcFilePathText = (String)thisEntry.getValue();
              String srcFilePathText = old_srcFilePathText;
              // Addition for the src jar file : If the jdk version is 1.4+, this
              // file isn't called src.jar, but src.zip, so if the current path
              // ends with src.jar, updare this one :
              final ProjectDefinitionEntry javaExePathEntry = projectDefinition.getProjectDefinitionEntry(ProjectDefinition.Java_EXEpath_Key);
              final String javaExePath = (String)javaExePathEntry.getValue();
              String compilerVersion = projectDefinition.getCompilerVersion(javaExePath);

              Log.Info("javaExePath= " + javaExePath );        
              Log.Info("compilerVersion= " + compilerVersion );

              if( compilerVersion.compareTo("1.4") >= 0 ) {
                if( srcFilePathText.endsWith("src.jar") ) {
                    srcFilePathText = srcFilePathText.substring(0,srcFilePathText.length()-7) + "src.zip";
                }
              }
              else // other direction:
              if( compilerVersion.compareTo("1.4") < 0 ) {
                if( srcFilePathText.endsWith("src.zip") ) {
                    srcFilePathText = srcFilePathText.substring(0,srcFilePathText.length()-7) + "src.jar";
                }
              }
              // adjust if required:                    
              if( !srcFilePathText.equals( old_srcFilePathText ) ) {
                thisEntry.setValue(srcFilePathText);
                // Update the view too, if it's present (will optionally update other entries]:
                Object thisEntryView = thisEntry.getEntryView();
                if( thisEntryView != null ) {
                  if( thisEntryView instanceof JTextField ) {
                     // Sync the textfield associated with thisEntry :
                     JTextField thisEntryTextField = (JTextField)thisEntryView;
                     // Turn off the update flag (otherwise it would go wildly recursive)
                     doProcessTextUpdates = false;
                     thisEntryTextField.setText(srcFilePathText);
                     // reset the flag :
                     doProcessTextUpdates = true;
                  }
                }
              }
            }
          });
       }
      // Update this entry finally :
      entry.setValue( textField.getText() );
     } // if doProcessTextUpdates

  } // processTextUpdate




    

 /**
  *  Used for entries with String arrays where the only task is that
  *  one of them can be selected.    
  */
  private JPanel createRadioButtonPanel( final ProjectDefinitionEntry entry )
  {                                                               
    int textSize = UIManager.getFont("Label.font").getSize();
    final JPanel panel = new JPanel( new FlowLayout(FlowLayout.LEFT,textSize,0) );
    panel.setBackground( UIManager.getColor("TextField.background") );                 
    String[] buttonNames = (String[])entry.getValue();  
    ButtonGroup buttonGroup = new ButtonGroup();
    final JRadioButton[] buttons = new JRadioButton[ buttonNames.length ];                                                    
    
    
    Log.Info("buttons.length= " + buttons.length );
    for( int i=0; i < buttons.length; i++ )
     {
       buttons[i] = new JRadioButton( buttonNames[i] );
       buttons[i].setOpaque(false);
       buttons[i].setFocusPainted(false);
       buttons[i].setBorder( BorderFactory.createEmptyBorder(0,0,0,0) );                                      
       buttonGroup.add( buttons[i] );
       panel.add( buttons[i] );                                                              
       // Autoselect the selected index :  
       if( entry.getSelectedIndex() == i )
        {
          buttons[i].setSelected(true);
          entry.setSelectedIndex(i);
        }          
       final int iFinal = i; 
       buttons[iFinal].addActionListener( new ActionListener()
        {
          public void actionPerformed( ActionEvent e)
          {
            entry.setSelectedIndex(iFinal);
          }
        });
     }      
    JPanel wrapPanel = new JPanel( new BorderLayout(0,0) );
    wrapPanel.setBorder( BorderFactory.createEtchedBorder() );
    wrapPanel.add( panel, BorderLayout.CENTER );
    return wrapPanel;
  } // createRadioButtonPanel
                     
                     
                     




  private JPanel createFileListPanelWithChooserButton( final ProjectDefinitionEntry entry,
                                                       final boolean isEditablePanel )
  {
    final JPanel panel = new JPanel( new BorderLayout() );
    panel.setOpaque(false);
    // textfield to the left (center so it fills the space):
    // calculate columns, so that JDialog doesnt exceed the screen :
    int columns = 46;
    int maxColumns = Toolkit.getDefaultToolkit().getScreenSize().width / ( 3 * UIManager.getFont("TextField.font").getSize() / 2 );
    if( columns > maxColumns ) columns = maxColumns;
    final JList stringList = new JList( (String[])entry.getValue() );
    stringList.setFixedCellWidth(columns);
    stringList.setEnabled(isEditablePanel);
    if( ( entry.getSelectedIndex() >= 0 ) &&
        ( entry.getSelectedIndex() < stringList.getComponentCount() ) )
     {
       stringList.setSelectedIndex( entry.getSelectedIndex() );
     }
    JScrollPane scrollPane = new JScrollPane( stringList );
    // Ttrack changes of the selected index:
    stringList.addListSelectionListener( new ListSelectionListener()
     {
       public void valueChanged( ListSelectionEvent e )
       {
         entry.setSelectedIndex( stringList.getSelectedIndex() );
       }
     });
    Dimension prefDim = new Dimension( (columns * 4 * UIManager.getFont("TextField.font").getSize()/8),
                                       5 * UIManager.getFont("TextField.font").getSize() );
    scrollPane.setPreferredSize(prefDim);

    panel.add( scrollPane, BorderLayout.CENTER );
    // button, which opens a filechooser for selection to the right :
    if( isEditablePanel )
     {
      JSenseButton addButton = new JSenseButton(
          Language.Translate("add"),
          this.mainFrameProvider.loadImageIcon("pics/plusicon.gif"),
          true,
          this.mainFrameProvider );
      addButton.setBorder( BorderFactory.createLoweredBevelBorder() );
      addButton.setHorizontalTextPosition(SwingConstants.RIGHT);
      addButton.setHorizontalAlignment(SwingConstants.LEFT);
      addButton.addActionListener( new ActionListener()
       {
         public void actionPerformed( ActionEvent e)
         {
           if( entry.getUseFileDialog() ) // The String is the result of a filechooser action :
            {
               String[] allowedFileEndings;
               String osNameLowerCase = System.getProperty("os.name").toLowerCase();
               // All windows systems have either Windows or windows in it.
               boolean runsUnderWindows = ( osNameLowerCase.indexOf("windows") >= 0 ) ;
               if( runsUnderWindows )
                {
                  if( entry.getContainsFileContents() )
                   {
                     allowedFileEndings = new String[]{"jar"};
                   } else
                   {
                     allowedFileEndings = new String[0]; // directories -> no files endings specified
                   }
                } else
                {
                  allowedFileEndings = new String[0]; // all allowed
                }
               IniFile iniFile = IDE_MainFrame.MainFrame.getGlobalIniFile();
               String initialPath = iniFile.getStringValue("ProjectDefinitionDialog.createFileListPanelWithChooserButton: " + entry.getKey(), "." );
               final String dialogTitle = Language.Translate("Choose the Jar file");
               final int dialogMode  = JFileChooser.FILES_ONLY;
               // Multiple choice dialog:
               String[] newRawPathes = chooseMultipleFiles( initialPath,
                                                            allowedFileEndings,
                                                            dialogTitle,
                                                            entry.getOnlyAllowChoiceOfExistingFiles(),
                                                            dialogMode );
               if( newRawPathes != null )
                {
                  for( int i=0; i < newRawPathes.length; i++ )
                   {
                     String newPath = newRawPathes[i].trim();
                     if( newPath.length() > 0 )
                      {
                        iniFile.setStringValue( "ProjectDefinitionDialog.createFileListPanelWithChooserButton: " + entry.getKey(),
                                                newPath );

                        // Scan for library content update and set the flag if required :
                        if( entry.getKey().equals( ProjectDefinition.AdditionalJarLibrariesPaths_Key ) )
                         {
                           libraryContentHasChanged = true;
                         }

                        // Set it in the entry object (which still is hold by
                        // the projectDefinition too )
                        String[] oldEntryValue = (String[])entry.getValue();
                        String[] newEntryValue = new String[oldEntryValue.length+1];
                        for( int k=0; k < oldEntryValue.length; k++ )
                         {
                           newEntryValue[k] = oldEntryValue[k];
                         }
                        newEntryValue[ newEntryValue.length-1 ] = newPath;
                        entry.setValue(newEntryValue); // Automatically marks it changed, so
                                                       // it will be saved to filesystem when needed
                        // and update the model of the gui JList too :
                        stringList.setListData(newEntryValue);
                      }
                   } // for
                } // if
            }
           else // The String just can be typed in, we use a dialog for that :
            {
               InputStringDialog dia = new InputStringDialog( Language.Translate( "InputDialog" ),
                                                              Language.Translate("Parameter:")+" ",
                                                              entry.getPredefinedChoices(),
                                                              entry.getPredefinedChoicesExplanations(),
                                                              parentFrame,
                                                              mainFrameProvider,
                                                              IDE_MainFrame.MainFrame.getGlobalIniFile() );
               dia.setVisible( true );
               if( !dia.getDialogWasCancelled() )
                {
                  String inputString = dia.getInputString().trim();
                  if( inputString.length() > 0 )
                   {
                     // Set it in the entry object (which still is hold by
                     // the projectDefinition too )
                     String[] oldEntryValue = (String[])entry.getValue();
                     String[] newEntryValue = new String[oldEntryValue.length+1];
                     for( int i=0; i < oldEntryValue.length; i++ )
                      {
                        newEntryValue[i] = oldEntryValue[i];
                      }
                     newEntryValue[ newEntryValue.length-1 ] = inputString;
                     entry.setValue(newEntryValue); // Automatically marks it changed, so
                                                    // it will be saved to filesystem when needed
                     // and update the model of the gui JList too :
                     stringList.setListData(newEntryValue);
                   }
                }
            }
         }
       });
      JSenseButton removeButton = new JSenseButton(Language.Translate("remove"),mainFrameProvider.loadImageIcon("pics/minusicon.gif"),true,mainFrameProvider);
      removeButton.setBorder( BorderFactory.createLoweredBevelBorder() );
      removeButton.setHorizontalTextPosition(SwingConstants.RIGHT);
      removeButton.setHorizontalAlignment(SwingConstants.LEFT);
      final ProjectDefinitionDialog thisDialog = this;
      removeButton.addActionListener( new ActionListener()
       {
         public void actionPerformed( ActionEvent e)
         {
           final String[] oldEntryValue = (String[])entry.getValue();
           int remIndex = stringList.getSelectedIndex();
           //ystem.out.println("remIndex = " + remIndex);
           if( ( remIndex >= 0 ) && ( remIndex < oldEntryValue.length ) )
            {
              // Update the entry object (which still is hold by
              // the projectDefinition too )
              String[] newEntryValue = new String[oldEntryValue.length-1];
              int loopIndex = 0;
              for( int i=0; i < oldEntryValue.length; i++ )
               {
                 if( i != remIndex )
                  {
                    newEntryValue[loopIndex++] = oldEntryValue[i];
                  }
               }
              entry.setValue(newEntryValue); // Automatically marks it changed, so
                                             // it will be saved to filesystem when needed
              // and update the model of the gui JList too :
              stringList.setListData(newEntryValue);

              // Scan for library content update and set the flag if required :
              if( entry.getKey().equals( ProjectDefinition.AdditionalJarLibrariesPaths_Key ) )
               {
                 libraryContentHasChanged = true;
               }

            }
           else
            {
              JOptionPane.showMessageDialog(
                thisDialog,
                Language.Translate("Please select the entry you want to remove."));
            }
         }
       });
      JPanel buttonPanel = new JPanel( new BorderLayout(0,0) );
      buttonPanel.add( addButton, BorderLayout.NORTH );
      buttonPanel.add( removeButton, BorderLayout.SOUTH );
      panel.add(buttonPanel, BorderLayout.EAST );
     }
    return panel;
  } // createFileListPanelWithChooserButton







 /**
  *  Shows a filechooser save dialog.
  *  Pass an empty stringarray for allowedFileEndings, if any file ending
  *  is allowed.
  *
  *  dialogMode can be :
  *  JFileChooser.FILES_ONLY
  *  JFileChooser.FILES_AND_DIRECTORIES
  *  JFileChooser.DIRECTORIES_ONLY
  */
  public String chooseFile( final String initialAbsoluteFilePathName,
                            final String[] allowedFileEndings,
                            final String title,
                            final boolean mustBeExisting,
                            final int dialogMode )
  {
    FileChooser fileChooser = new FileChooser(this.parentFrame);                         
    return fileChooser.chooseFile( initialAbsoluteFilePathName,
                                   allowedFileEndings,
                                   title,
                                   mustBeExisting,
                                   false,
                                   dialogMode,
                                   null /* no accessory component */ );
  } // chooseFile


                  
                  

 /**
  *  Like chooseFile(), but allows multiple selection.
  */
  public String[] chooseMultipleFiles( final String initialAbsoluteFilePathName,
                                       final String[] allowedFileEndings,
                                       final String title,
                                       final boolean mustBeExisting,
                                       final int dialogMode )
  {                        
    FileChooser fileChooser = new FileChooser(this.parentFrame);
    return fileChooser.chooseMultipleFiles( initialAbsoluteFilePathName,
                                            allowedFileEndings,
                                            title,
                                            mustBeExisting,
                                            false,
                                            dialogMode );
  } // chooseMultipleFiles




  public boolean getDialogWasCanceled()
  {
    return this.dialogWasCancelled;
  }


  
  public boolean getLibraryContentHasChanged()
  {
    return this.libraryContentHasChanged;
  }



 /**
  *  Allows the caller to check, if the project has changed,
  *  in a way so one has to force the compiler to
  *  recompile all files on the next request.
  */
  public boolean getDoChangesNeedRecompilation()
  {
    return this.projectDefinition.getDoChangesNeedRecompilation();
  } // getDoChangesNeedRecompilation



                         
} // ProjectDefinitionDialog




























java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.