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
|