/* CropDBCropInfo.java - created: March 15, 2007
* Copyright (C) 2007, 2008 Clayton Carter
*
* This file is part of the project "Crop Planning Software". For more
* information:
* website: https://github.com/claytonrcarter/cropplanning
* email: cropplanning@gmail.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package CPS.Core.CropPlans;
import CPS.Data.CPSCrop;
import CPS.Data.CPSDateValidator;
import CPS.Data.CPSRecord;
import CPS.UI.Modules.CPSDetailView;
import CPS.Data.CPSPlanting;
import CPS.Module.CPSGlobalSettings;
import CPS.UI.Modules.CPSMasterDetailModule;
import CPS.UI.Swing.*;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import javax.swing.*;
import net.miginfocom.swing.MigLayout;
public class CropPlanInfo extends CPSDetailView implements ActionListener, ItemListener {
private CPSTextField tfldCropName, tfldVarName, tfldMatDays, tfldLocation;
private JComboBox cmbDates;
private CPSTextField tfldDatePlant, tfldDateTP, tfldDateHarvest;
private CPSCheckBox chkDonePlant, chkDoneTP, chkDoneHarvest, chkIgnore, chkFrostHardy;
private CPSRadioButton rdoDS, rdoTP;
private JLabel lblDateTP, lblTimeToTP, lblFlatSize, lblFlatsNeeded, lblPlantsToStart,
lblInRowSpace, lblPlantsNeeded, lblBedsToPlant, lblRowFtToPlant;
private CPSTextField tfldMatAdjust, tfldTimeToTP, tfldRowsPerBed, tfldInRowSpace, tfldBetRowSpace,
tfldFlatSize;
private CPSTextField tfldBedsToPlant, tfldRowFtToPlant, tfldPlantsNeeded,
tfldPlantsToStart, tfldFlatsNeeded;
private CPSTextField tfldYieldPerFt, tfldTotalYield, tfldYieldNumWeeks, tfldYieldPerWeek,
tfldCropYieldUnit, tfldCropYieldUnitValue;
private CPSTextArea tareGroups, tareKeywords, tareOtherReq;
// private CPSTextArea tareNotes;
private CPSTextArea tarePlantingNotesCrop, tarePlantingNotes;
private CPSTextField tfldCustom1, tfldCustom2, tfldCustom3, tfldCustom4, tfldCustom5;
private CPSTextField tfldSeedsPerUnit, tfldSeedsPer, tfldSeedNeeded;
private CPSComboBox cmbSeedUnit;
private JLabel lblSeedsPer;
private CPSButtonGroup /* bgDates, */ bgSeedMethod;
private ArrayList<JLabel> anonLabels;
private CPSCardPanel columnFour;
private Date lastDatePlant, lastDateTP, lastDateHarvest;
private final String DATE_EFFECTIVE = "Effective Dates";
private final String DATE_ACTUAL = "Actual Dates";
private final String DATE_PLANNED = "Planned Dates";
private CPSPlanting displayedPlanting;
CropPlanInfo( CPSMasterDetailModule mdm ) {
super( mdm, "Planting Info" );
lastDatePlant = null;
lastDateTP = null;
lastDateHarvest = null;
}
/** this constructor does nothing and is meant for testing purposes only */
private CropPlanInfo() {}
public CPSRecord getDisplayedRecord() {
// TODO we should do some double checking in case the displayed info has changed but
// has not been saved
if ( displayedPlanting == null )
return new CPSPlanting();
else
return displayedPlanting;
}
public void displayRecord( CPSRecord r ) { displayRecord( (CPSPlanting) r ); }
public void displayRecord( CPSPlanting p ) {
if ( ! isMainPanelBuilt() ) {
setMainPanelBuilt();
rebuildMainPanel();
updateAutocompletionComponents();
}
if ( p == null ) {
displayedPlanting = new CPSPlanting();
setRecordDisplayed( false );
}
else {
displayedPlanting = p;
setRecordDisplayed( true );
}
CropPlans.debug( "CropPlanInfo", "Displaying planting:\n" + displayedPlanting );
tfldCropName.setInitialText( displayedPlanting.getCropName() );
tfldVarName.setInitialText( displayedPlanting.getVarietyName(),
displayedPlanting.getVarietyNameState() );
tfldMatDays.setInitialText( displayedPlanting.getMaturityDaysString(),
displayedPlanting.getMaturityDaysState() );
tfldLocation.setInitialText( displayedPlanting.getLocation(),
displayedPlanting.getLocationState() );
chkDonePlant.setInitialState( displayedPlanting.getDonePlanting(),
displayedPlanting.getDonePlantingState() );
chkDoneTP.setInitialState( displayedPlanting.getDoneTP(),
displayedPlanting.getDoneTPState() );
chkDoneHarvest.setInitialState( displayedPlanting.getDoneHarvest(),
displayedPlanting.getDoneHarvestState() );
chkFrostHardy.setInitialState( displayedPlanting.isFrostHardy(),
displayedPlanting.getFrostHardyState() );
tfldInRowSpace.setInitialText( displayedPlanting.getInRowSpacingString(),
displayedPlanting.getInRowSpacingState() );
tfldFlatSize.setInitialText( displayedPlanting.getFlatSize(),
displayedPlanting.getFlatSizeState() );
tfldTimeToTP.setInitialText( displayedPlanting.getTimeToTPString(),
displayedPlanting.getTimeToTPState() );
tarePlantingNotes.setInitialText( displayedPlanting.getPlantingNotes(),
displayedPlanting.getPlantingNotesState() );
tfldBedsToPlant.setInitialText( displayedPlanting.getBedsToPlantString(),
displayedPlanting.getBedsToPlantState() );
tfldRowFtToPlant.setInitialText( displayedPlanting.getRowFtToPlantString(),
displayedPlanting.getRowFtToPlantState() );
tfldPlantsNeeded.setInitialText( displayedPlanting.getPlantsNeededString(),
displayedPlanting.getPlantsNeededState() );
tfldPlantsToStart.setInitialText( displayedPlanting.getPlantsToStartString(),
displayedPlanting.getPlantsToStartState() );
tfldFlatsNeeded.setInitialText( displayedPlanting.getFlatsNeededString(),
displayedPlanting.getFlatsNeededState() );
tfldTotalYield.setInitialText( displayedPlanting.getTotalYieldString(),
displayedPlanting.getTotalYieldState() );
tfldYieldPerFt.setInitialText( displayedPlanting.getYieldPerFootString(),
displayedPlanting.getYieldPerFootState() );
tfldYieldNumWeeks.setInitialText( displayedPlanting.getYieldNumWeeksString(),
displayedPlanting.getYieldNumWeeksState() );
tfldYieldPerWeek.setInitialText( displayedPlanting.getYieldPerWeekString(),
displayedPlanting.getYieldPerWeekState() );
tfldCropYieldUnit.setInitialText( displayedPlanting.getCropYieldUnit(),
displayedPlanting.getCropYieldUnitState() );
tfldCropYieldUnitValue.setInitialText( displayedPlanting.getCropYieldUnitValueString(),
displayedPlanting.getCropYieldUnitValueState() );
tfldSeedsPerUnit.setInitialText( displayedPlanting.getSeedsPerUnitString(),
displayedPlanting.getSeedsPerUnitState() );
cmbSeedUnit.setInitialSelection( displayedPlanting.getSeedUnit(),
displayedPlanting.getSeedUnitState() );
tfldSeedNeeded.setInitialText( displayedPlanting.getSeedNeededString(),
displayedPlanting.getSeedNeededState() );
tareGroups.setInitialText( displayedPlanting.getGroups(),
displayedPlanting.getGroupsState() );
tareOtherReq.setInitialText( displayedPlanting.getOtherRequirements(),
displayedPlanting.getOtherRequirementsState() );
tareKeywords.setInitialText( displayedPlanting.getKeywords(),
displayedPlanting.getKeywordsState());
// tareNotes.setInitialText( displayedPlanting.getNotes(),
// displayedPlanting.getNotesState());
tfldCustom1.setInitialText( displayedPlanting.getCustomField1(), displayedPlanting.getCustomField1State() );
tfldCustom2.setInitialText( displayedPlanting.getCustomField2(), displayedPlanting.getCustomField2State() );
tfldCustom3.setInitialText( displayedPlanting.getCustomField3(), displayedPlanting.getCustomField3State() );
tfldCustom4.setInitialText( displayedPlanting.getCustomField4(), displayedPlanting.getCustomField4State() );
tfldCustom5.setInitialText( displayedPlanting.getCustomField5(), displayedPlanting.getCustomField5State() );
/*
* These all affect how other things are displayed so we should do them last.
*/
chkIgnore.setInitialState( displayedPlanting.getIgnore(),
displayedPlanting.getIgnoreState() );
if ( displayedPlanting.isDirectSeeded() ) {
boolean d = rdoDS.isEnabled();
rdoDS.setEnabled( true );
bgSeedMethod.setInitialSelection( rdoDS, true, displayedPlanting.getDirectSeededState() );
rdoDS.setEnabled( d );
}
else {
boolean t = rdoTP.isEnabled();
rdoTP.setEnabled( true );
bgSeedMethod.setInitialSelection( rdoTP, true, displayedPlanting.getDirectSeededState() );
rdoTP.setEnabled( t );
}
setAllComponentsEnabled( isRecordDisplayed() && ! displayedPlanting.getIgnore() );
displayDates();
displayDSTPProperties();
if ( isRecordDisplayed() )
setTPComponentsEnabled( displayedPlanting.isTransplanted() );
if ( chkIgnore.isSelected() )
setStatus( CPSMasterDetailModule.STATUS_IGNORED );
else
setStatus( CPSMasterDetailModule.STATUS_BLANK );
if ( ! displayedPlanting.isSingleRecord() ) {
setStatus( "showing identical fields for selected rows" );
}
}
@Override
public void setForEditting() {
tfldCropName.requestFocus();
}
protected void saveChangesToRecord() {
String selectedPlan = getDisplayedTableName();
CPSPlanting currentlyDisplayed = this.asPlanting();
if ( currentlyDisplayed == null ) {
// currently the only reason asPlanting returns null is for a
// NumberFormatException
new CPSNumberFormatErrorDialog( this.getMainPanel() ).setVisible( true );
return;
}
CPSPlanting diff = (CPSPlanting) displayedPlanting.diff( currentlyDisplayed );
if ( diff.getID() == -1 ) {
// TODO this would be great to optimize as follows, though it isn't a priority:
// if there were no changes, then just return; if there the user changed
// values which the software isn't taking as changes (blank value, spaces, etc)
// then redisplay the displayed planting
debug( "No differences found, not saving." );
// for now, just reset the display w/ the current planting
displayRecord( displayedPlanting );
return;
}
// update items in db
if ( ! displayedPlanting.isSingleRecord() ) {
// multiple selection
List<Integer> ids = displayedPlanting.getCommonIDs();
// this triggers an update of all of the lists
getDataSource().updatePlantings( selectedPlan, diff, ids );
selectRecordsInMasterView(ids);
}
else {
// single selection
getDataSource().updatePlanting( selectedPlan, currentlyDisplayed );
CPSPlanting p; // = currentlyDisplayed;
// do we need to get updated planting info to
// make sure we have the best inheritance data
//if ( tfldCropName.hasChanged() || tfldVarName.hasChanged() )
p = getDataSource().getPlanting( selectedPlan, diff.getID() );
updateRecordInMasterView(p);
selectRecordsInMasterView( Arrays.asList( p.getID() ) );
}
}
/** asPlanting - create a planting data struct to represent this detail view
*
* @return a CPSPlanting object populated to represent the planting which is
* currently displayed
*/
private CPSPlanting asPlanting() {
// make a copy of the displayed planting
CPSPlanting changes = new CPSPlanting();
changes.merge( displayedPlanting );
debug("Original (prechanges) : " + changes.toString());
changes.setID( displayedPlanting.getID() );
if ( tfldCropName.hasChanged() ) changes.setCropName( tfldCropName.getText() );
if ( tfldVarName.hasChanged() ) changes.setVarietyName( tfldVarName.getText() );
if ( tfldMatDays.hasChanged() ) changes.setMaturityDays( tfldMatDays.getText() );
if ( tfldLocation.hasChanged() ) changes.setLocation( tfldLocation.getText() );
/* We do not need to store the value of the "date radio buttons"
* group because that button group only acts to control which dates
* are displayed. We *do* have to check those radiobuttons to
* determine how to store any values that the user has changed.
*/
String s = (String) cmbDates.getSelectedItem();
if ( tfldDatePlant.hasChanged() )
if ( s.equalsIgnoreCase( DATE_ACTUAL )) {
changes.setDateToPlantActual( tfldDatePlant.getText() );
lastDatePlant = changes.getDateToPlantActual();
}
else if ( s.equalsIgnoreCase( DATE_PLANNED ))
changes.setDateToPlantPlanned( tfldDatePlant.getText() );
// else do nothing for "effective" dates
if ( tfldDateTP.hasChanged() )
if ( s.equalsIgnoreCase( DATE_ACTUAL )) {
changes.setDateToTPActual( tfldDateTP.getText() );
lastDateTP = changes.getDateToTPActual();
}
else if ( s.equalsIgnoreCase( DATE_PLANNED ))
changes.setDateToTPPlanned( tfldDateTP.getText() );
// else do nothing for "effective" dates
if ( tfldDateHarvest.hasChanged() )
if ( s.equalsIgnoreCase( DATE_ACTUAL )) {
changes.setDateToHarvestActual( tfldDateHarvest.getText() );
lastDateHarvest = changes.getDateToHarvestActual();
}
else if ( s.equalsIgnoreCase( DATE_PLANNED ))
changes.setDateToHarvestPlanned( tfldDateHarvest.getText() );
// else do nothing for "effective" dates
if ( chkDonePlant.hasChanged() ) changes.setDonePlanting( chkDonePlant.isSelected() );
if ( chkDoneTP.hasChanged() ) changes.setDoneTP( chkDoneTP.isSelected() );
if ( chkDoneHarvest.hasChanged() ) changes.setDoneHarvest( chkDoneHarvest.isSelected() );
if ( chkIgnore.hasChanged() ) changes.setIgnore( chkIgnore.isSelected() );
if ( rdoDS.hasChanged() || rdoTP.hasChanged() ) changes.setDirectSeeded( rdoDS.isSelected() );
// changes.setDirectSeeded( rdoDS.isSelected() );
try {
if ( tfldMatAdjust.hasChanged() ) changes.setMatAdjust( tfldMatAdjust.getText() );
if ( tfldTimeToTP.hasChanged() ) changes.setTimeToTP( tfldTimeToTP.getText() );
if ( tfldRowsPerBed.hasChanged() ) changes.setRowsPerBed( tfldRowsPerBed.getText() );
if ( tfldInRowSpace.hasChanged() ) changes.setInRowSpacing( tfldInRowSpace.getText() );
if ( tfldBetRowSpace.hasChanged() ) changes.setRowSpacing( tfldBetRowSpace.getText() );
if ( tfldFlatSize.hasChanged() ) changes.setFlatSize( tfldFlatSize.getText() );
if ( tarePlantingNotesCrop.hasChanged() ) changes.setPlantingNotesInherited( tarePlantingNotesCrop.getText() );
if ( tarePlantingNotes.hasChanged() ) changes.setPlantingNotes( tarePlantingNotes.getText() );
if ( tfldBedsToPlant.hasChanged() ) changes.setBedsToPlant( tfldBedsToPlant.getText() );
if ( tfldRowFtToPlant.hasChanged() ) changes.setRowFtToPlant( tfldRowFtToPlant.getText() );
if ( tfldPlantsNeeded.hasChanged() ) changes.setPlantsNeeded( tfldPlantsNeeded.getText() );
if ( tfldPlantsToStart.hasChanged() ) changes.setPlantsToStart( tfldPlantsToStart.getText() );
if ( tfldFlatsNeeded.hasChanged() ) changes.setFlatsNeeded( tfldFlatsNeeded.getText() );
if ( tfldYieldPerFt.hasChanged() ) changes.setYieldPerFoot( tfldYieldPerFt.getText() );
if ( tfldTotalYield.hasChanged() ) changes.setTotalYield( tfldTotalYield.getText() );
if ( tfldYieldNumWeeks.hasChanged() ) changes.setYieldNumWeeks( tfldYieldNumWeeks.getText() );
if ( tfldYieldPerWeek.hasChanged() ) changes.setYieldPerWeek( tfldYieldPerWeek.getText() );
if ( tfldCropYieldUnit.hasChanged() ) changes.setCropYieldUnit( tfldCropYieldUnit.getText() );
if ( tfldCropYieldUnitValue.hasChanged() ) changes.setCropYieldUnitValue( tfldCropYieldUnitValue.getText() );
if ( tfldSeedsPerUnit.hasChanged() ) changes.setSeedsPerUnit( tfldSeedsPerUnit.getText() );
if ( cmbSeedUnit.hasChanged() ) changes.setSeedUnit( cmbSeedUnit.getSelectedItem() );
if ( tfldSeedsPer.hasChanged() ) changes.setSeedsPer( tfldSeedsPer.getText() );
if ( tfldSeedNeeded.hasChanged() ) changes.setSeedNeeded( tfldSeedNeeded.getText() );
} catch ( NumberFormatException e ) {
return null;
}
if ( tareGroups.hasChanged() ) changes.setGroups( tareGroups.getText() );
if ( tareOtherReq.hasChanged() ) changes.setOtherRequirements( tareOtherReq.getText() );
if ( tareKeywords.hasChanged() ) changes.setKeywords( tareKeywords.getText() );
// if ( tareNotes.hasChanged() ) changes.setNotes( tareNotes.getText( ) );
if ( tfldCustom1.hasChanged() ) changes.setCustomField1( tfldCustom1.getText() );
if ( tfldCustom2.hasChanged() ) changes.setCustomField2( tfldCustom2.getText() );
if ( tfldCustom3.hasChanged() ) changes.setCustomField3( tfldCustom3.getText() );
if ( tfldCustom4.hasChanged() ) changes.setCustomField4( tfldCustom4.getText() );
if ( tfldCustom5.hasChanged() ) changes.setCustomField5( tfldCustom5.getText() );
CropPlans.debug( "CPInfo", "panel display represents: " + changes.toString() );
return changes;
}
protected void buildDetailsPanel() {
String migPanelDefaults = "gapy 0px!, insets 2px";
List<String> names = new ArrayList<String>();
if ( isDataAvailable() )
names = getDataSource().getCropNameList();
tfldCropName = new CPSTextField( FIELD_LEN_WAY_LONG, names, CPSTextField.MATCH_STRICT );
tfldVarName = new CPSTextField( FIELD_LEN_WAY_LONG );
tfldMatDays = new CPSTextField( FIELD_LEN_SHORT );
tfldLocation = new CPSTextField( FIELD_LEN_WAY_LONG );
cmbDates = new JComboBox( new String[] { DATE_EFFECTIVE, DATE_ACTUAL, DATE_PLANNED } );
cmbDates.addActionListener( this );
tfldDatePlant = new CPSTextField( FIELD_LEN_LONG );
tfldDateTP = new CPSTextField( FIELD_LEN_LONG );
tfldDateHarvest = new CPSTextField( FIELD_LEN_LONG );
chkDonePlant = new CPSCheckBox( "", false );
chkDonePlant.setToolTipText( "Check if planted" );
chkDonePlant.addItemListener( this );
chkDoneTP = new CPSCheckBox( "", false );
chkDoneTP.setToolTipText( "Check if transplanted (if applicable)" );
chkDoneTP.addItemListener( this );
chkDoneHarvest = new CPSCheckBox( "", false );
chkDoneHarvest.setToolTipText( "Check if harvested" );
chkDoneHarvest.addItemListener( this );
chkIgnore = new CPSCheckBox( "Ignore this planting?", false );
chkIgnore.setToolTipText( "Ignore or skip this planting. Hides it from view without deleting it." );
chkIgnore.addItemListener( this );
chkFrostHardy = new CPSCheckBox( "Frost hardy?", false );
rdoDS = new CPSRadioButton( "DS", false );
rdoTP = new CPSRadioButton( "TP", false );
rdoDS.addItemListener( this );
rdoTP.addItemListener( this );
bgSeedMethod = new CPSButtonGroup( new AbstractButton[] { rdoDS, rdoTP } );
bgSeedMethod.setSelectionModel( CPSButtonGroup.SELECT_ONLY_ONE );
tfldMatAdjust = new CPSTextField( FIELD_LEN_SHORT );
tfldRowsPerBed = new CPSTextField( FIELD_LEN_SHORT );
tfldInRowSpace = new CPSTextField( FIELD_LEN_SHORT );
tfldBetRowSpace = new CPSTextField( FIELD_LEN_SHORT );
tfldTimeToTP = new CPSTextField( FIELD_LEN_SHORT );
tfldFlatSize = new CPSTextField( FIELD_LEN_MED );
tfldBedsToPlant = new CPSTextField( FIELD_LEN_SHORT );
tfldRowFtToPlant = new CPSTextField( FIELD_LEN_MED );
tfldPlantsNeeded = new CPSTextField( FIELD_LEN_MED );
tfldPlantsToStart = new CPSTextField( FIELD_LEN_MED );
tfldFlatsNeeded = new CPSTextField( FIELD_LEN_SHORT );
tfldTotalYield = new CPSTextField( FIELD_LEN_MED );
tfldYieldPerFt = new CPSTextField( FIELD_LEN_SHORT );
tfldYieldNumWeeks = new CPSTextField( FIELD_LEN_SHORT );
tfldYieldPerWeek = new CPSTextField( FIELD_LEN_SHORT );
tfldCropYieldUnit = new CPSTextField( FIELD_LEN_MED );
tfldCropYieldUnitValue = new CPSTextField( FIELD_LEN_SHORT );
tfldSeedsPerUnit = new CPSTextField( FIELD_LEN_MED );
cmbSeedUnit = new CPSComboBox( CPSCrop.SEED_UNIT_STRINGS );
tfldSeedsPer = new CPSTextField( FIELD_LEN_MED );
tfldSeedNeeded = new CPSTextField( FIELD_LEN_MED );
tareGroups = new CPSTextArea( 4, FIELD_LEN_WAY_LONG );
tareKeywords = new CPSTextArea( 4, FIELD_LEN_WAY_LONG );
tareOtherReq = new CPSTextArea( 4, FIELD_LEN_WAY_LONG );
tarePlantingNotesCrop = new CPSTextArea( 14, 22 );
tarePlantingNotes = new CPSTextArea( 12, 22 );
Font f = tarePlantingNotesCrop.getFont();
f = new Font( f.getFamily(), f.getStyle(), f.getSize()-2 );
tarePlantingNotes.setFont(f);
tarePlantingNotesCrop.setFont(f);
tfldCustom1 = new CPSTextField( FIELD_LEN_LONG );
tfldCustom2 = new CPSTextField( FIELD_LEN_LONG );
tfldCustom3 = new CPSTextField( FIELD_LEN_LONG );
tfldCustom4 = new CPSTextField( FIELD_LEN_LONG );
tfldCustom5 = new CPSTextField( FIELD_LEN_LONG );
JPanel columnOne = new JPanel( new MigLayout( migPanelDefaults ));
JPanel columnTwo = new JPanel( new MigLayout( migPanelDefaults ));
JPanel columnThree = new JPanel( new MigLayout( migPanelDefaults ));
JLabel tempLabel;
/* ***********************************/
/* COLUMN ONE */
/* ***********************************/
JPanel jplName = new JPanel( new MigLayout( migPanelDefaults ));
if ( anonLabels == null )
anonLabels = new ArrayList<JLabel>();
tempLabel = new JLabel( "Crop Name:" );
jplName.add( tempLabel, "align right" );
jplName.add( tfldCropName, "wrap" );
anonLabels.add( tempLabel );
tempLabel = new JLabel( "Variety:" );
jplName.add( tempLabel, "align right" );
jplName.add( tfldVarName, "wrap" );
anonLabels.add( tempLabel );
tempLabel = new JLabel( "Maturity Days:" );
jplName.add( tempLabel, "align right" );
jplName.add( tfldMatDays, "wrap" );
anonLabels.add( tempLabel );
tempLabel = new JLabel( "Location" );
jplName.add( tempLabel, "align right" );
jplName.add( tfldLocation, "wrap" );
anonLabels.add( tempLabel );
JPanel jplDates = new JPanel( new MigLayout( migPanelDefaults ));
jplDates.setBorder( BorderFactory.createTitledBorder( "Dates & Completed" ) );
tempLabel = new JLabel( "Show" );
tempLabel.setToolTipText( "Select which dates to display" );
jplDates.add( tempLabel, "align right" );
jplDates.add( cmbDates, "span 2, wrap" );
anonLabels.add( tempLabel );
tempLabel = new JLabel( "Planting" );
jplDates.add( tempLabel, "align right" );
jplDates.add( tfldDatePlant );
jplDates.add( chkDonePlant, "wrap" );
anonLabels.add( tempLabel );
lblDateTP = new JLabel( "Transplant" );
// lblDateTP.setToolTipText( "Transplanting" );
jplDates.add( lblDateTP, "align right" );
jplDates.add( tfldDateTP );
jplDates.add( chkDoneTP, "wrap" );
anonLabels.add( lblDateTP );
tempLabel = new JLabel( "Harvest" );
jplDates.add( tempLabel, "align right" );
jplDates.add( tfldDateHarvest );
jplDates.add( chkDoneHarvest, "wrap" );
anonLabels.add( tempLabel );
jplDates.add( chkIgnore, "align center, span 3" );
columnOne.add( jplName, "wrap" );
columnOne.add( jplDates, "wrap" );
/* ***********************************/
/* COLUMN TWO
/* ***********************************/
JPanel jplPlanting = new JPanel( new MigLayout( migPanelDefaults ));
jplPlanting.setBorder( BorderFactory.createTitledBorder( "Planting Info" ) );
jplPlanting.add( rdoDS, "align center, span 2, split 2" );
jplPlanting.add( rdoTP, "wrap" );
tempLabel = new JLabel( "Mat. adj" );
tempLabel.setToolTipText( "Adjust maturity by so many days" );
jplPlanting.add( tempLabel, "align right" );
jplPlanting.add( tfldMatAdjust, "wrap" );
anonLabels.add( tempLabel );
tempLabel = new JLabel( "Rows/Bed" );
jplPlanting.add( tempLabel, "align right" );
jplPlanting.add( tfldRowsPerBed, "wrap" );
anonLabels.add( tempLabel );
tempLabel = new JLabel( "Row Spacing" );
jplPlanting.add( tempLabel, "align right" );
jplPlanting.add( tfldBetRowSpace, "wrap" );
anonLabels.add( tempLabel );
lblInRowSpace = new JLabel( "Plant Spacing" );
lblInRowSpace.setToolTipText("Spacing between plants within the row (in or cm)");
jplPlanting.add( lblInRowSpace, "align right" );
jplPlanting.add( tfldInRowSpace, "wrap" );
anonLabels.add( lblInRowSpace );
jplPlanting.add( new JSeparator(), "growx, span 2, wrap" );
lblFlatSize = new JLabel( "Flat Size" );
jplPlanting.add( lblFlatSize, "align right" );
jplPlanting.add( tfldFlatSize, "wrap" );
anonLabels.add( lblFlatSize );
lblTimeToTP = new JLabel( "Weeks to TP" );
jplPlanting.add( lblTimeToTP, "align right" );
jplPlanting.add( tfldTimeToTP, "wrap" );
anonLabels.add( lblTimeToTP );
columnTwo.add( jplPlanting );
/* *************************************/
/* COLUMN THREE
/* *************************************/
JPanel jplAmount = new JPanel( new MigLayout( migPanelDefaults ));
jplAmount.setBorder( BorderFactory.createTitledBorder( "How Much" ) );
lblBedsToPlant = new JLabel( "Beds to Plant" );
lblBedsToPlant.setDisplayedMnemonic( 'b' );
lblBedsToPlant.setLabelFor( tfldBedsToPlant );
jplAmount.add( lblBedsToPlant, "align right" );
jplAmount.add( tfldBedsToPlant, "wrap" );
anonLabels.add( lblBedsToPlant );
if ( CPSGlobalSettings.useMetric() )
lblRowFtToPlant = new JLabel( "Row Meters to Plant" );
else
lblRowFtToPlant = new JLabel( "Row Ft to Plant" );
lblRowFtToPlant.setDisplayedMnemonic( 'r' );
lblRowFtToPlant.setLabelFor( tfldRowFtToPlant );
jplAmount.add( lblRowFtToPlant, "align right" );
jplAmount.add( tfldRowFtToPlant, "wrap" );
anonLabels.add( lblRowFtToPlant );
lblPlantsNeeded = new JLabel( "Plants Needed" );
lblPlantsNeeded.setDisplayedMnemonic( 'p' );
lblPlantsNeeded.setLabelFor( tfldPlantsNeeded );
jplAmount.add( lblPlantsNeeded, "align right" );
jplAmount.add( tfldPlantsNeeded, "wrap" );
anonLabels.add( lblPlantsNeeded );
lblPlantsToStart = new JLabel( "Plants to Start" );
lblPlantsToStart.setToolTipText("Plants needed plus fudge factor");
lblPlantsToStart.setDisplayedMnemonic( 's' );
lblPlantsToStart.setDisplayedMnemonicIndex( 10 );
lblPlantsToStart.setLabelFor( tfldPlantsToStart );
jplAmount.add( lblPlantsToStart, "align right" );
jplAmount.add( tfldPlantsToStart, "wrap" );
anonLabels.add( lblPlantsToStart );
lblFlatsNeeded = new JLabel( "Flats to Start" );
lblFlatsNeeded.setDisplayedMnemonic( 'f' );
lblFlatsNeeded.setLabelFor( tfldFlatsNeeded );
jplAmount.add( lblFlatsNeeded, "align right" );
jplAmount.add( tfldFlatsNeeded, "wrap" );
anonLabels.add( lblFlatsNeeded );
columnThree.add( jplAmount, "wrap" );
/* *************************************/
/* COLUMN FOUR
/* *************************************/
JPanel jplSeeds = new JPanel( new MigLayout( migPanelDefaults ));
tempLabel = new JLabel( "Units" );
tempLabel.setToolTipText("Usually this would be from the catalog. i.e. Do they sell by the oz or the gram or by count?");
jplSeeds.add( tempLabel, "align right" );
jplSeeds.add( cmbSeedUnit, "wrap" );
anonLabels.add( tempLabel );
tempLabel = new JLabel( "Seeds/Unit" );
tempLabel.setToolTipText("Seeds/Oz or Seeds/g, for example");
jplSeeds.add( tempLabel, "align right" );
jplSeeds.add( tfldSeedsPerUnit, "wrap" );
anonLabels.add( tempLabel );
if ( CPSGlobalSettings.useMetric() )
lblSeedsPer = new JLabel( "Seeds/Meter or Plant" );
else
lblSeedsPer = new JLabel( "Seeds/Ft or Plant" );
jplSeeds.add( lblSeedsPer, "align right" );
jplSeeds.add( tfldSeedsPer, "wrap" );
anonLabels.add( tempLabel );
tempLabel = new JLabel( "Units Needed" );
jplSeeds.add( tempLabel, "align right" );
jplSeeds.add( tfldSeedNeeded, "wrap" );
anonLabels.add( tempLabel );
/* *************************************/
/* *************************************/
JPanel jplMisc = new JPanel( new MigLayout( migPanelDefaults ));
tempLabel = new JLabel( "<html><body style='text-align:right'>Belongs to <br>Groups:" );
tempLabel.setToolTipText( "Groups to which this planting belongs" );
jplMisc.add( tempLabel, "align right top" );
jplMisc.add( new JScrollPane( tareGroups ), "wrap" );
anonLabels.add( tempLabel );
tempLabel = new JLabel( "<html><body style='text-align:right'>Other <br>Requirements:" );
tempLabel.setToolTipText( "Other requirements for this planting" );
jplMisc.add( tempLabel, "align right top" );
jplMisc.add( new JScrollPane( tareOtherReq ), "wrap" );
anonLabels.add( tempLabel );
tempLabel = new JLabel( "Keywords:" );
jplMisc.add( tempLabel, "align right top" );
jplMisc.add( new JScrollPane( tareKeywords ), "wrap" );
anonLabels.add( tempLabel );
/* *************************************/
/* *************************************/
JPanel jplYield = new JPanel( new MigLayout( migPanelDefaults ));
tempLabel = new JLabel( "Total Yield" );
jplYield.add( tempLabel, "align right" );
jplYield.add( tfldTotalYield, "wrap" );
anonLabels.add( tempLabel );
/* unit, per foot, weeks, per week, value */
tempLabel = new JLabel( "Yield Units" );
jplYield.add( tempLabel, "align right" );
jplYield.add( tfldCropYieldUnit, "wrap" );
anonLabels.add( tempLabel );
if ( CPSGlobalSettings.useMetric() )
tempLabel = new JLabel( "Total Yield/Meter" );
else
tempLabel = new JLabel( "Total Yield/Ft" );
jplYield.add( tempLabel, "align right" );
jplYield.add( tfldYieldPerFt, "wrap" );
anonLabels.add( tempLabel );
tempLabel = new JLabel( "Value/Unit" );
jplYield.add( tempLabel, "align right" );
jplYield.add( tfldCropYieldUnitValue, "wrap" );
anonLabels.add( tempLabel );
tempLabel = new JLabel( "Yields for (wks)" );
tempLabel.setToolTipText( "Approx. how many weeks do you expect to " +
"harvest a planting of this?" );
jplYield.add( tempLabel, "align right" );
jplYield.add( tfldYieldNumWeeks, "wrap" );
anonLabels.add( tempLabel );
JPanel jplNotesCrop = new JPanel( new MigLayout( migPanelDefaults ));
tempLabel = new JLabel( "<html><font size=\"-2\">" +
"displayed on the planting list printout"+
"</font></html>" );
jplNotesCrop.add( tempLabel, "align center, wrap" );
jplNotesCrop.add( new JScrollPane( tarePlantingNotesCrop ), "wrap" );
anonLabels.add( tempLabel );
JPanel jplNotes = new JPanel( new MigLayout( migPanelDefaults ));
tempLabel = new JLabel( "<html><font size=\"-2\">" +
"about this specifc planting"+
"</font></html>" );
jplNotes.add( tempLabel, "align center, wrap" );
jplNotes.add( new JScrollPane( tarePlantingNotes ), "wrap" );
JButton btn = new JButton("Add Date");
btn.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
int p = tarePlantingNotes.getCaretPosition();
String s = ( p == 0 ? "" : "\n" ) +
"=== " +
CPSDateValidator.format( new Date(),
CPSDateValidator.DATE_FORMAT_MON_DAY_YEAR ) +
" ===\n";
tarePlantingNotes.insert( s, p );
tarePlantingNotes.setCaretPosition( p + s.length() );
tarePlantingNotes.requestFocusInWindow();
}
});
jplNotes.add( btn, "span 2, align right" );
anonLabels.add( tempLabel );
columnFour =
new CPSCardPanel( new String[] {
"Notes",
"Planter Notes",
"Yield Info",
"Seed Info",
"Keywords etc" },
new JPanel[] {
jplNotes,
jplNotesCrop,
jplYield,
jplSeeds,
jplMisc } );
/* *************************************/
/* BOTTOW ROW */
/* *************************************/
jplDetails = new JPanel( new MigLayout( migPanelDefaults ) );
jplDetails.add( columnOne, "aligny top" );
jplDetails.add( columnTwo, "aligny top" );
jplDetails.add( columnThree, "aligny top" );
jplDetails.add( columnFour, "aligny top, wrap" );
if ( uiManager != null )
uiManager.signalUIChanged();
}
@Override
protected void buildBelowDetailsPanel() {
super.buildBelowDetailsPanel();
btnSaveChanges.setText( "Save & Recalculate" );
}
protected void updateAutocompletionComponents() {
if ( ! isDataAvailable() )
return;
tfldCropName.updateAutocompletionList( getDataSource().getCropNameList(),
CPSTextField.MATCH_PERMISSIVE );
if ( displayedPlanting != null )
tfldVarName.updateAutocompletionList( getDataSource().getVarietyNameList( displayedPlanting.getCropName(), getDisplayedTableName() ),
CPSTextField.MATCH_PERMISSIVE );
tfldLocation.updateAutocompletionList( getDataSource().getFieldNameList( this.getDisplayedTableName() ),
CPSTextField.MATCH_PERMISSIVE );
tfldFlatSize.updateAutocompletionList( getDataSource().getFlatSizeList( this.getDisplayedTableName() ),
CPSTextField.MATCH_PERMISSIVE );
}
@Override
public void dataUpdated() {
updateAutocompletionComponents();
}
@Override
protected int saveState() {
throw new UnsupportedOperationException( "Not supported yet." );
}
// Implemented as per ItemListener
public void itemStateChanged ( ItemEvent arg0 ) {
Object source = arg0.getItemSelectable();
if ( source == rdoDS ) {
if ( ! chkIgnore.isSelected() )
setTPComponentsEnabled( ! rdoDS.isSelected() );
// redisplay the DS/TP values
displayDSTPProperties();
}
else if ( source == rdoTP ) {
if ( ! chkIgnore.isSelected() )
setTPComponentsEnabled( rdoTP.isSelected() );
// redisplay the DS/TP values
displayDSTPProperties();
}
else if ( source == chkIgnore ) {
setAllComponentsEnabled( ! chkIgnore.isSelected() );
setStatus( CPSMasterDetailModule.STATUS_IGNORED );
}
else if ( source == chkDonePlant ) {
// IF the actual dates are displayed
// AND the textbox is blank OR the textbox is calculated
if ( ((String) cmbDates.getSelectedItem()).equalsIgnoreCase( DATE_ACTUAL ) &&
( tfldDatePlant.getText().equalsIgnoreCase( "" ) ||
! displayedPlanting.getDateToPlantState().isCalculated() )) {
Date d = lastDatePlant;
if ( d == null )
d = new Date();
tfldDatePlant.setText( CPSDateValidator.format( d ));
}
}
else if ( source == chkDoneTP ) {
// IF the actual dates are displayed
// AND the textbox is blank OR the textbox is calculated
if ( ((String) cmbDates.getSelectedItem()).equalsIgnoreCase( DATE_ACTUAL ) &&
( tfldDateTP.getText().equalsIgnoreCase( "" ) ||
! displayedPlanting.getDateToTPState().isCalculated() )) {
Date d = lastDateTP;
if ( d == null )
d = new Date();
tfldDateTP.setText( CPSDateValidator.format( d ));
}
}
else if ( source == chkDoneHarvest ) {
// IF the actual dates are displayed
// AND the textbox is blank OR the textbox is calculated
if ( ((String) cmbDates.getSelectedItem()).equalsIgnoreCase( DATE_ACTUAL ) &&
( tfldDateHarvest.getText().equalsIgnoreCase( "" ) ||
! displayedPlanting.getDateToHarvestState().isCalculated() )) {
Date d = lastDateHarvest;
if ( d == null )
d = new Date();
tfldDateHarvest.setText( CPSDateValidator.format( d ));
}
}
}
private void setTPComponentsEnabled( boolean b ) {
lblDateTP.setEnabled( b );
lblInRowSpace.setEnabled(b);
lblTimeToTP.setEnabled( b );
lblFlatSize.setEnabled( b );
lblFlatsNeeded.setEnabled( b );
lblPlantsNeeded.setEnabled(b);
lblPlantsToStart.setEnabled( b );
tfldDateTP.setEnabled( b );
if ( ( (String) cmbDates.getSelectedItem() )
.equalsIgnoreCase( DATE_ACTUAL ) ||
( ! ( isRecordDisplayed() && b )))
chkDoneTP.setEnabled( b );
tfldInRowSpace.setEnabled(b);
tfldTimeToTP.setEnabled( b );
tfldFlatSize.setEnabled( b );
tfldFlatsNeeded.setEnabled( b );
tfldPlantsNeeded.setEnabled(b);
tfldPlantsToStart.setEnabled( b );
if ( b ) {
lblSeedsPer.setText("Seeds/Cell");
lblSeedsPer.setToolTipText("How many seeds get sown in each cell or plug?");
}
else {
if ( CPSGlobalSettings.useMetric() )
lblSeedsPer.setText("Seeds/RowMeter");
else
lblSeedsPer.setText("Seeds/RowFt");
lblSeedsPer.setToolTipText("Appox. how many seeds are sown per row-foot?");
}
}
protected void setAllComponentsEnabled( boolean b ) {
tfldCropName.setEnabled( b );
tfldVarName.setEnabled( b );
tfldMatDays.setEnabled( b );
tfldLocation.setEnabled( b );
cmbDates.setEnabled( b );
tfldDatePlant.setEnabled( b );
tfldDateHarvest.setEnabled( b );
chkDonePlant.setEnabled( b );
chkDoneHarvest.setEnabled( b );
chkFrostHardy.setEnabled( b );
rdoDS.setEnabled( b );
rdoTP.setEnabled( b );
tfldMatAdjust.setEnabled( b );
tfldRowsPerBed.setEnabled( b );
tfldInRowSpace.setEnabled( b );
tfldBetRowSpace.setEnabled( b );
tarePlantingNotesCrop.setEnabled( b );
tarePlantingNotes.setEnabled( b );
tfldBedsToPlant.setEnabled( b );
tfldRowFtToPlant.setEnabled( b );
tfldPlantsNeeded.setEnabled( b );
tfldYieldPerFt.setEnabled( b );
tfldTotalYield.setEnabled( b );
tfldYieldNumWeeks.setEnabled( b );
tfldYieldPerWeek.setEnabled( b );
tfldCropYieldUnit.setEnabled( b );
tfldCropYieldUnitValue.setEnabled( b );
tfldSeedsPerUnit.setEnabled( b );
cmbSeedUnit.setEnabled( b );
tfldSeedsPer.setEnabled( b );
tfldSeedNeeded.setEnabled( b );
tareGroups.setEnabled( b );
tareKeywords.setEnabled( b );
tareOtherReq.setEnabled( b );
// tareNotes.setEnabled( b );
tfldCustom1.setEnabled( b );
tfldCustom2.setEnabled( b );
tfldCustom3.setEnabled( b );
tfldCustom4.setEnabled( b );
tfldCustom5.setEnabled( b );
columnFour.setEnabled(b);
if ( ! isRecordDisplayed() ) {
chkIgnore.setEnabled( false );
btnSaveChanges.setEnabled( false );
btnDiscardChanges.setEnabled( false );
} else if ( isRecordDisplayed() ) {
chkIgnore.setEnabled( true );
btnSaveChanges.setEnabled( true );
btnDiscardChanges.setEnabled( true );
}
setTPComponentsEnabled( b );
for ( JLabel jl : anonLabels ) {
jl.setEnabled( b );
}
}
@Override
public void actionPerformed ( ActionEvent actionEvent ) {
if ( actionEvent.getSource() != cmbDates )
super.actionPerformed( actionEvent );
else {
displayDates();
}
}
private void displayDates() {
if ( ! isDataAvailable() )
return;
String s = (String) cmbDates.getSelectedItem();
boolean editTBox, enableCBox;
if ( s.equalsIgnoreCase( DATE_EFFECTIVE ) ) {
editTBox = false;
enableCBox = false;
tfldDatePlant.setInitialText( displayedPlanting.getDateToPlantString(),
displayedPlanting.getDateToPlantState() );
if ( displayedPlanting.isTransplanted() )
tfldDateTP.setInitialText( displayedPlanting.getDateToTPString(),
displayedPlanting.getDateToTPState() );
else
tfldDateTP.setInitialText( "" );
tfldDateHarvest.setInitialText( displayedPlanting.getDateToHarvestString(),
displayedPlanting.getDateToHarvestState());
} else if ( s.equalsIgnoreCase( DATE_ACTUAL ) ) {
editTBox = enableCBox = true;
enableCBox = true;
tfldDatePlant.setInitialText( displayedPlanting.getDateToPlantActualString(),
displayedPlanting.getDateToPlantActualState() );
if ( displayedPlanting.isTransplanted() )
tfldDateTP.setInitialText( displayedPlanting.getDateToTPActualString(),
displayedPlanting.getDateToTPActualState() );
else
tfldDateTP.setInitialText( "" );
tfldDateHarvest.setInitialText( displayedPlanting.getDateToHarvestActualString(),
displayedPlanting.getDateToHarvestActualState());
} else {
editTBox = true;
enableCBox = false;
tfldDatePlant.setInitialText( displayedPlanting.getDateToPlantPlannedString(),
displayedPlanting.getDateToPlantPlannedState() );
if ( displayedPlanting.isTransplanted() )
tfldDateTP.setInitialText( displayedPlanting.getDateToTPPlannedString(),
displayedPlanting.getDateToTPPlannedState() );
else
tfldDateTP.setInitialText( "" );
tfldDateHarvest.setInitialText( displayedPlanting.getDateToHarvestPlannedString(),
displayedPlanting.getDateToHarvestPlannedState() );
}
tfldDatePlant.setEditable( editTBox );
tfldDateTP.setEditable( editTBox );
tfldDateHarvest.setEditable( editTBox );
chkDonePlant.setEnabled( enableCBox );
if ( rdoTP.isSelected() )
chkDoneTP.setEnabled( enableCBox );
chkDoneHarvest.setEnabled( enableCBox );
}
private void displayDSTPProperties() {
if ( ! isDataAvailable() ) {
CropPlans.debug( "CPInfo", "data unavailable, not displaying DS/TP values" );
return;
}
// save our current or saved state
boolean initState = displayedPlanting.isDirectSeeded();
displayedPlanting.setDirectSeeded( rdoDS.isSelected() );
// set the displayed planting to act like what's been selected
// and update the display
displayedPlanting.setDirectSeeded( rdoDS.isSelected() );
tfldMatAdjust.setInitialText( displayedPlanting.getMatAdjustString(),
displayedPlanting.getMatAdjustState() );
tfldRowsPerBed.setInitialText( displayedPlanting.getRowsPerBedString(),
displayedPlanting.getRowsPerBedState() );
tfldBetRowSpace.setInitialText( displayedPlanting.getRowSpacingString(),
displayedPlanting.getRowSpacingState() );
tarePlantingNotesCrop.setInitialText( displayedPlanting.getPlantingNotesInherited(),
displayedPlanting.getPlantingNotesInheritedState() );
tfldSeedsPer.setInitialText( displayedPlanting.getSeedsPerString(),
displayedPlanting.getSeedsPerState() );
// then reset the "saved" planting
displayedPlanting.setDirectSeeded( initState );
}
/* for testing only */
public static void main( String[] args ) {
// "test" construtor
CropPlanInfo ci = new CropPlanInfo();
ci.buildDetailsPanel();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setContentPane( ci.getDetailsPanel() );
frame.setTitle( "CropPlan Info Layout" );
frame.pack();
frame.setVisible(true);
}
}