/******************************************************** * Copyright (C) 2008 Course Scheduler Team * * 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. * * 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, write to: * Free Software Foundation, Inc. * 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA ********************************************************/ /********************************************************* * Course Scheduler * File: MakeSchedule.java * * Contains class: * * MakeSchedule: * * Purpose: To display and edit course schedulers * * @author Mike Reinhold *********************************************************/ package Scheduler; /********************************************************* * The Following imports are necessary for this class *********************************************************/ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.LayoutManager; import java.awt.Point; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.Transferable; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.NoSuchElementException; import java.util.Scanner; import java.util.SortedMap; import java.util.TreeMap; import java.util.Vector; import javax.swing.BorderFactory; import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListModel; import javax.swing.DropMode; import javax.swing.GroupLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.JTabbedPane; import javax.swing.JTextField; import javax.swing.ListModel; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import javax.swing.SwingWorker; import javax.swing.TransferHandler; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.slf4j.ext.XLogger; import org.slf4j.ext.XLoggerFactory; /********************************************************* * class MakeSchedule * * @purpose to provide an interface for creating and viewing * schedules * * @see JPanel, Tab (custom) *********************************************************/ public class MakeSchedule extends JPanel implements Tab { /** * Static logger */ private static XLogger logger = XLoggerFactory.getXLogger(MakeSchedule.class); /********************************************************* * The following are static constants for versioning *********************************************************/ protected static final long versionID = 2013010900214L; //object version protected static final long serialVersionUID = 1L + Version.makeSchedule.id; //serial version /********************************************************* * The following are the data fields for the MakeSchedule object *********************************************************/ protected Database local; //local copy of the database protected JFrame owner; //owning frame of this panel protected ArrayList<String> primary; //list of primary courses protected int selectedSchedule; //item in the schedules list that is selected protected LinkedCourses dependancy; //the linked courses list for dependancies /********************************************************* * The following are the visual items for the course lists *********************************************************/ protected JLabel masterLabel; protected JLabel masterCounter; protected JPanel masterCounterPanel; protected TitleTipList masterClassList; //the master course list, with tool tips protected JScrollPane masterClassPane; //scroll bar for the master course list protected DefaultListModel masterClassModel; //list model for the schedule list protected JLabel scheduleCourseLabel; protected JLabel scheduleCourseCounter; protected JPanel scheduleCourseCounterPanel; protected TitleTipList scheduleClassList; //schedule course list, with tool tips protected DefaultListModel scheduleClassModel; //list model for the schedule list protected JScrollPane scheduleClassPane; //scroll pane for the schedule course list protected JPanel choosePanel; //panel for the schedule lists protected GroupLayout chooseLayout; //group layout for the lists protected keyListener keys; //keyboard adapter for registering keyboard events protected JCheckBox undergrad; //checkbox to enable filtering of undergrad courses protected JCheckBox gradCampus; //checkbox to enable filtering of on campus grad courses protected JCheckBox gradDist; //checkbox to enable filtering of off campus grad courses /********************************************************* * *********************************************************/ protected JPanel selectionPanel; protected GroupLayout selectionLayout; protected JButton addCourse; protected JButton removeCourse; protected buttonListener buttons; /********************************************************* * *********************************************************/ protected Dimension buttonDim; protected JCheckBox autoRefresh; protected JCheckBox useClosed; protected JCheckBox useAll; protected JCheckBox reportingEnabled; protected JTextField minUse; protected JLabel minUseLbl; protected checkListener checker; protected JButton refreshSchedules; protected mouseListener mouse; /********************************************************* * *********************************************************/ protected JTabbedPane view; protected Dimension large; protected Dimension small; protected JLabel downloaded; protected JPanel linksDisplay; protected JTabbedPane viewInternal; protected GroupLayout viewLayout; protected DepenTipList linksList; protected DefaultListModel linksModel; protected JScrollPane linksScroll; protected JLabel linked; protected JLabel primaryCourses; protected JList primaryList; protected JScrollPane primaryScroll; protected DefaultListModel primaryModel; protected JButton removeLink; protected JButton removePrimary; protected JMenuItem remLink; protected JMenuItem remPrimary; /********************************************************* * *********************************************************/ protected SectionTipList schedules; protected ListListener selected; protected DefaultListModel schedulesModel; protected JLabel scheduleLabel; protected JLabel scheduleCounter; protected JPanel scheduleCounterPanel; protected JLabel conflictLabel; protected JLabel conflictCounter; protected JPanel conflictCounterPanel; protected JScrollPane schedulesPane; protected GroupLayout schedulesLayout; protected JPanel schedulesPanel; protected JPanel displayPanel; protected JPanel displayWrapperPanel; protected JScrollPane displayPane; protected GridBagLayout displayLayout; protected JLabel closedCourse; protected JLabel openCourse; protected JPanel courseDescription; //protected JSlider zoomChooser; //protected JXTransformer scalePanel;//ZoomPanel scalePanel; /********************************************************* * *********************************************************/ protected JMenuItem addClass; protected JMenuItem showDetails; protected JMenuItem removeClass; protected DetachTabItem detach; protected JMenuItem closeThis; protected JMenuItem closeOthers; protected JMenuItem printDetails; protected JMenuItem printVisual; protected JMenuItem migrateTab; protected JMenuItem flagPrimary; protected JMenuItem selectSection; protected JMenuItem unflagPrimary; protected JPopupMenu contextMenu; protected JMenuItem linkCourses; protected JMenuItem addCoursesLinked; protected JMenuItem addCoursePrimary; /********************************************************* * *********************************************************/ protected JPanel sectionPanel; protected JScrollPane sectionPanelScroller; protected GroupLayout sectionLayout; protected TreeMap<String, JPanel> sectionSelectionPanels; protected TreeMap<String, boolean[]> sectionSelections; protected JPanel sectionPlaceHolder; protected TitleTipList sectionList; protected DefaultListModel sectionModel; protected JScrollPane sectionScroller; protected JPanel numberPanel; protected JScrollPane numberScroller; protected JPanel sectionWrapper; protected TreeMap<String, NumberComboBox> numberSelectionCombos; protected TreeMap<String, JPanel> numberSelectionPanels; protected TreeMap<String, Integer> numberSelections; /********************************************************* * *********************************************************/ protected JTabbedPane scheduleDisplay; protected JPanel infoPanel; protected JPanel infoWrapperPanel; protected JScrollPane infoPane; /********************************************************* * *********************************************************/ private final static int minGap = 10; private final static int listWidth = 100; private final static int sizeOffset = 440;//440 private final static int hourVal = 60; private final static double scaleColor = 1.2; private final static double noScale = 1.0; private final static int scale = 1; @SuppressWarnings("unused")private double zoomInit = 1.0;//.75; //for later once scaling events are fixed @SuppressWarnings("unused")private final static double zoomMin = .5; @SuppressWarnings("unused")private final static double zoomMax = 1.0; private final static int conflictZOrder = 0; @SuppressWarnings("unused")private final static int classZOrder = 1; @SuppressWarnings("unused")private final static int backgroundZOrder = 2; private boolean enabled = true; private SortedMap<Integer, Component> basicComp; private SortedMap<Integer, GridBagConstraints> basicCont; /********************************************************* * *********************************************************/ public MakeSchedule(){ super(new BorderLayout()); SwingWorker<Void, Void> help = new SwingWorker<Void,Void>(){ @Override public Void doInBackground(){ MakeSchedule.this.buildBasic(); return null; } @Override public void done(){ MakeSchedule.this.setBasic(); } }; Main.threadExec.execute(help); dependancy = new LinkedCourses(); primary = new ArrayList<String>(); mouse = new mouseListener(); selected = new ListListener(); keys = new keyListener(); checker = new checkListener(); masterClassModel = new DefaultListModel(); masterClassList = new TitleTipList(masterClassModel); masterClassList.setSelectionMode( ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); masterClassList.setDragEnabled(true); masterClassList.setTransferHandler(new ListTransferHandler()); masterClassList.addMouseListener(mouse); masterClassList.addListSelectionListener(selected); masterClassList.addKeyListener(keys); masterClassPane = new JScrollPane(masterClassList); masterLabel = new JLabel("Master: "); masterCounter = new JLabel("0"); masterCounterPanel = new JPanel(); masterCounterPanel.add(masterLabel); masterCounterPanel.add(masterCounter); scheduleClassModel = new DefaultListModel(); scheduleClassList = new TitleTipList(scheduleClassModel); scheduleClassList.setSelectionMode( ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); scheduleClassList.setDropMode(DropMode.ON_OR_INSERT); scheduleClassList.setTransferHandler(new ListTransferHandler()); scheduleClassList.addMouseListener(mouse); scheduleClassList.addKeyListener(keys); scheduleClassList.addListSelectionListener(selected); scheduleClassModel = new DefaultListModel(); scheduleClassPane = new JScrollPane(scheduleClassList); scheduleClassList.setCellRenderer(new FlaggedCellRenderer()); scheduleCourseLabel = new JLabel("Schedule: "); scheduleCourseCounter = new JLabel("0"); scheduleCourseCounterPanel = new JPanel(); scheduleCourseCounterPanel.add(scheduleCourseLabel); scheduleCourseCounterPanel.add(scheduleCourseCounter); undergrad = new JCheckBox("Undergrad"); undergrad.setToolTipText("Show undergraduate courses in the master course list"); undergrad.setSelected(Main.prefs.isDownloadUGrad()); undergrad.setEnabled(Main.prefs.isDownloadUGrad()); undergrad.addActionListener(checker); gradCampus = new JCheckBox("On Campus"); gradCampus.setToolTipText("Show on-campus graduate courses in the master course list"); gradCampus.setSelected(Main.prefs.isDownloadGrad()); gradCampus.setEnabled(Main.prefs.isDownloadGrad()); gradCampus.addActionListener(checker); gradDist = new JCheckBox("Off Campus"); gradDist.setToolTipText("Show distance learning graduate courses in the master course list"); gradDist.setSelected(Main.prefs.isDownloadGradDist()); gradDist.setEnabled(Main.prefs.isDownloadGradDist()); gradDist.addActionListener(checker); buttons = new buttonListener(); addCourse = new JButton("Add Course >>"); addCourse.addActionListener(buttons); removeCourse = new JButton("<< Remove Course"); removeCourse.addActionListener(buttons); refreshSchedules = new JButton("Refresh Schedules"); refreshSchedules.addActionListener(buttons); autoRefresh = new JCheckBox("Auto-refresh Schedules"); autoRefresh.setSelected(true); useClosed = new JCheckBox("Allow Closed Courses"); useClosed.addActionListener(checker); useAll = new JCheckBox("Use all specified courses"); useAll.addActionListener(checker); minUse = new JTextField(); minUseLbl = new JLabel("Minimum number of courses: "); useAll.setSelected(true); minUse.setEnabled(false); minUse.setText("4"); minUse.setHorizontalAlignment(JTextField.CENTER); minUse.addKeyListener(keys); minUseLbl.setEnabled(false); minUseLbl.setLabelFor(minUse); reportingEnabled = new JCheckBox("Report Conflicts"); reportingEnabled.setSelected(false); reportingEnabled.addActionListener(checker); buttonDim = new Dimension(143, 30); addCourse.setMinimumSize(buttonDim); removeCourse.setMinimumSize(buttonDim); downloaded = new JLabel(); selectionPanel = new JPanel(); selectionLayout = new GroupLayout(selectionPanel); selectionPanel.setLayout(selectionLayout); selectionLayout.setHorizontalGroup(selectionLayout.createParallelGroup(GroupLayout.Alignment.CENTER) .addComponent(downloaded) .addGroup(selectionLayout.createSequentialGroup() .addGap(minGap) .addGroup(selectionLayout.createParallelGroup(GroupLayout.Alignment.CENTER) .addComponent(addCourse) .addComponent(removeCourse) ) .addGap(minGap) ) ); selectionLayout.setVerticalGroup(selectionLayout.createSequentialGroup() .addComponent(addCourse) .addGap(minGap) .addComponent(removeCourse) .addGap(minGap) .addComponent(downloaded) ); choosePanel = new JPanel(); chooseLayout = new GroupLayout(choosePanel); choosePanel.setLayout(chooseLayout); chooseLayout.setHorizontalGroup(chooseLayout.createSequentialGroup() .addGap(minGap) .addGroup(chooseLayout.createParallelGroup(GroupLayout.Alignment.CENTER) .addGroup(chooseLayout.createSequentialGroup() .addGroup(chooseLayout.createParallelGroup(GroupLayout.Alignment.LEADING) .addComponent(masterCounterPanel, listWidth, listWidth, listWidth) .addComponent(masterClassPane, listWidth, listWidth, listWidth) ) .addGap(minGap) .addGroup(chooseLayout.createParallelGroup() .addComponent(scheduleCourseCounterPanel, listWidth, listWidth, listWidth) .addComponent(scheduleClassPane, listWidth, listWidth, listWidth) .addComponent(undergrad, listWidth, listWidth, listWidth) .addComponent(gradCampus, listWidth, listWidth, listWidth) .addComponent(gradDist, listWidth, listWidth, listWidth) ) ) .addComponent(selectionPanel) ) .addGap(minGap) ); chooseLayout.setVerticalGroup(chooseLayout.createSequentialGroup() .addGroup(chooseLayout.createParallelGroup() .addGroup(chooseLayout.createSequentialGroup() .addComponent(masterCounterPanel, 3 * minGap, 3 * minGap, 3 * minGap) .addComponent(masterClassPane) ) .addGroup(chooseLayout.createSequentialGroup() .addComponent(scheduleCourseCounterPanel, 3 * minGap, 3 * minGap, 3 * minGap) .addComponent(scheduleClassPane) .addGap(minGap) .addComponent(undergrad) .addComponent(gradCampus) .addComponent(gradDist) ) ) .addGap(minGap) .addComponent(selectionPanel) .addGap(minGap) ); linksDisplay = new JPanel(); linked = new JLabel("Linked Courses:"); primaryCourses = new JLabel("Primary Courses:"); linked.setEnabled(false); primaryCourses.setEnabled(false); primaryList = new TitleTipList(new DefaultListModel()); primaryList.setCellRenderer(new CenteredCellRenderer()); primaryList.addKeyListener(keys); primaryList.addMouseListener(mouse); primaryList.addListSelectionListener(selected); primaryScroll = new JScrollPane(primaryList); primaryModel = new DefaultListModel(); linksList = new DepenTipList(dependancy.toArray()); linksList.setCellRenderer(new CenteredCellRenderer()); linksList.addKeyListener(keys); linksList.addMouseListener(mouse); linksList.addListSelectionListener(selected); linksModel = new DefaultListModel(); linksScroll = new JScrollPane(linksList); removeLink = new JButton("Remove Course Link"); removePrimary = new JButton("Remove Primary Course"); removeLink.addActionListener(buttons); removePrimary.addActionListener(buttons); viewLayout = new GroupLayout(linksDisplay); linksDisplay.setLayout(viewLayout); viewLayout.setHorizontalGroup(viewLayout.createSequentialGroup() .addGap(2 * minGap) .addGroup(viewLayout.createParallelGroup() .addComponent(linked) .addGroup(viewLayout.createSequentialGroup() .addGap(minGap) .addGroup(viewLayout.createParallelGroup(GroupLayout.Alignment.CENTER) .addComponent(linksScroll, 2 * listWidth + minGap, 2 * listWidth + minGap, 2 * listWidth + minGap) .addComponent(primaryScroll, 2 * listWidth + minGap, 2 * listWidth + minGap, 2 * listWidth + minGap) .addComponent(removeLink) .addComponent(removePrimary) ) ) .addComponent(primaryCourses) ) .addGap(3 * minGap) ); viewLayout.setVerticalGroup(viewLayout.createSequentialGroup() .addGap(minGap) .addComponent(linked) .addComponent(linksScroll) .addGap(minGap) .addComponent(removeLink) .addGap(2 * minGap) .addComponent(primaryCourses) .addComponent(primaryScroll) .addGap(minGap) .addComponent(removePrimary) .addGap(minGap) ); sectionPanel = new JPanel(); sectionLayout = new GroupLayout(sectionPanel); sectionPanel.setLayout(sectionLayout); sectionSelectionPanels = new TreeMap<String, JPanel>(); sectionSelections = new TreeMap<String, boolean[]>(); sectionPlaceHolder = new JPanel(); sectionPanelScroller = new JScrollPane(sectionPlaceHolder); sectionModel = new DefaultListModel(); sectionList = new TitleTipList(sectionModel); sectionScroller = new JScrollPane(sectionList); numberSelectionCombos = new TreeMap<String, NumberComboBox>(); numberSelectionPanels = new TreeMap<String, JPanel>(); numberSelections = new TreeMap<String, Integer>(); numberPanel = new JPanel(new GridLayout(0,2)); numberScroller = new JScrollPane(numberPanel); sectionWrapper = new JPanel(new GridLayout(2,1)); sectionList.addListSelectionListener(new ListSelectionListener(){ public void valueChanged(ListSelectionEvent event){ showSelectedSection(); } }); sectionLayout.setHorizontalGroup(sectionLayout.createParallelGroup() .addGroup(sectionLayout.createSequentialGroup() .addGap(1 * minGap) .addComponent(sectionScroller, listWidth, listWidth, listWidth) .addGap(minGap) .addComponent(sectionPanelScroller) .addGap(minGap) ) ); sectionLayout.setVerticalGroup(sectionLayout.createSequentialGroup() .addGap(minGap) .addGroup(sectionLayout.createParallelGroup() .addComponent(sectionScroller) .addComponent(sectionPanelScroller) ) .addGap(minGap) ); sectionWrapper.add(sectionPanel);//, BorderLayout.CENTER); sectionWrapper.add(numberScroller);//, BorderLayout.SOUTH); viewInternal = new TippedTabbedPane(); viewInternal.addTab("Choose Courses", choosePanel); viewInternal.addTab("Dependancies", linksDisplay); viewInternal.addTab("Set Sections", sectionWrapper); view = new JTabbedPane(JTabbedPane.RIGHT); view.addTab("<<", viewInternal); view.addMouseListener(mouse); view.setToolTipText("Click to minimize the choose courses pane."); large = view.getSize(); small = new Dimension(50,large.height); schedules = new SectionTipList(new DefaultListModel()); schedules.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); schedules.addListSelectionListener(selected); schedules.setCellRenderer(new ClosedCellRenderer()); schedules.addMouseListener(mouse); schedulesModel = new DefaultListModel(); schedulesPane = new JScrollPane(schedules); scheduleCounter = new JLabel("0"); scheduleLabel = new JLabel("Schedules: "); scheduleCounterPanel = new JPanel(); scheduleCounterPanel.add(scheduleLabel); scheduleCounterPanel.add(scheduleCounter); conflictCounter = new JLabel("0"); conflictLabel = new JLabel("Conflicts: "); conflictCounterPanel = new JPanel(); conflictCounterPanel.add(conflictLabel); conflictCounterPanel.add(conflictCounter); schedulesPanel = new JPanel(); schedulesLayout = new GroupLayout(schedulesPanel); schedulesPanel.setLayout(schedulesLayout); displayLayout = new GridBagLayout(); displayLayout.rowHeights = new int[(20*hourVal - sizeOffset)]; Arrays.fill(displayLayout.rowHeights, 1); displayPanel = new JPanel(displayLayout); displayPanel.setBorder(BorderFactory.createLineBorder(Color.black)); closedCourse = new JLabel("Closed Course"); closedCourse.setForeground(Color.RED.darker()); openCourse = new JLabel("Open Course"); courseDescription = new JPanel(); courseDescription.add(closedCourse); courseDescription.add(openCourse); //scalePanel = new ZoomPanel(zoomInit, displayPanel); //scalePanel = new JXTransformer(displayPanel); //scalePanel.add(displayPanel); displayWrapperPanel = new JPanel(); //displayWrapperPanel.add(scalePanel); displayWrapperPanel.add(displayPanel); //displayWrapperPanel.setBorder(BorderFactory.createLineBorder(Color.black)); displayPane = new JScrollPane(displayWrapperPanel); displayPane.getVerticalScrollBar().setUnitIncrement( displayPane.getVerticalScrollBar().getUnitIncrement() * 64); //zoomChooser = new JSlider(JSlider.HORIZONTAL, (int)(zoomMin * 100), (int)(zoomMax * 100), (int)(zoomInit * 100)); //zoomChooser.setVisible(false); /*zoomChooser.addChangeListener(new ChangeListener(){ @Override public void stateChanged(ChangeEvent event) { JSlider source = (JSlider)event.getSource(); double scale = (double)(source.getValue())/100; if(!source.getValueIsAdjusting()){ //try { //scalePanel.setZoom(scale); scalePanel.setTransform(getTransform(scale)); //} catch (PropertyVetoException e){ // e.printStackTrace(); //} scalePanel.invalidate(); scalePanel.repaint(); JScrollBar temp = displayPane.getHorizontalScrollBar(); temp.setValue((temp.getMaximum() + temp.getMinimum())/2); } } });*/ infoPanel = new JPanel(); infoPanel.setBorder(BorderFactory.createLineBorder(Color.black)); infoPanel.setLayout(new GridLayout(0, 3)); setInfo((Schedule)null); infoWrapperPanel = new JPanel(new GridLayout(0,1)); infoWrapperPanel.add(infoPanel); infoWrapperPanel.setBackground(Color.white); infoWrapperPanel.setBorder(BorderFactory.createLineBorder(Color.black)); infoPane = new JScrollPane(infoWrapperPanel); infoPane.getVerticalScrollBar().setUnitIncrement( infoPane.getVerticalScrollBar().getUnitIncrement() * 64); scheduleDisplay = new JTabbedPane(); scheduleDisplay.addTab("View Schedule", displayPane); scheduleDisplay.addTab("View Details", infoPane); scheduleDisplay.addMouseListener(mouse); schedulesLayout.setHorizontalGroup(schedulesLayout.createSequentialGroup() .addGap(minGap) .addGroup(schedulesLayout.createParallelGroup() .addGroup(schedulesLayout.createSequentialGroup() .addGap(minGap) .addComponent(scheduleCounterPanel, (int)(1.42 * listWidth), (int)(1.42 * listWidth), (int)(1.42 * listWidth)) ) .addGroup(schedulesLayout.createSequentialGroup() .addGap(minGap) .addComponent(conflictCounterPanel, (int)(1.42 * listWidth), (int)(1.42 * listWidth), (int)(1.42 * listWidth)) ) .addGroup(schedulesLayout.createSequentialGroup() .addGap(minGap) .addComponent(schedulesPane, (int)(1.42 * listWidth), (int)(1.42 * listWidth), (int)(1.42 * listWidth)) ) .addGroup(schedulesLayout.createSequentialGroup() .addGap(minGap) .addComponent(refreshSchedules, (int)(1.42 * listWidth), (int)(1.42 * listWidth), (int)(1.42 * listWidth)) ) .addComponent(autoRefresh) .addComponent(useClosed) .addComponent(reportingEnabled) .addComponent(useAll) .addComponent(minUseLbl) .addGroup(schedulesLayout.createSequentialGroup() .addGap(3 * minGap) .addComponent(minUse, 3 * minGap, 3 * minGap, 3 * minGap) ) ) .addGap(minGap) .addGroup(schedulesLayout.createParallelGroup(GroupLayout.Alignment.CENTER) .addComponent(scheduleDisplay) //.addComponent(zoomChooser, 100, 100, 100) .addComponent(courseDescription) ) .addGap(minGap) ); schedulesLayout.setVerticalGroup(schedulesLayout.createSequentialGroup() .addGroup(schedulesLayout.createParallelGroup() .addGroup(schedulesLayout.createSequentialGroup() .addComponent(scheduleCounterPanel, 2 * minGap, 2 * minGap, 2 * minGap) .addComponent(conflictCounterPanel, 2 * minGap, 2 * minGap, 2 * minGap) .addComponent(schedulesPane) .addGap(minGap) .addComponent(refreshSchedules) .addGap(minGap) .addComponent(autoRefresh) .addGap(minGap) .addComponent(useClosed) .addGap(minGap) .addComponent(reportingEnabled) .addGap(minGap) .addComponent(useAll) .addGap(minGap) .addComponent(minUseLbl) .addGap(minGap) .addComponent(minUse, 3 * minGap, 3 * minGap, 3 * minGap) ) .addGroup(schedulesLayout.createSequentialGroup() .addComponent(scheduleDisplay) //.addComponent(zoomChooser) .addComponent(courseDescription) ) ) .addGap(minGap) ); schedulesPanel.setBorder(BorderFactory.createTitledBorder("Schedules Display")); addClass = new JMenuItem("Add course to schedule"); addClass.addActionListener(buttons); removeClass = new JMenuItem("Remove course from schedule"); removeClass.addActionListener(buttons); showDetails = new JMenuItem("Show course details"); showDetails.addActionListener(buttons); detach = new DetachTabItem(this); detach.addActionListener(buttons); closeThis = new JMenuItem("Close This Tab"); closeThis.addActionListener(buttons); closeOthers = new JMenuItem("Close Other Tabs"); closeOthers.addActionListener(buttons); printDetails = new JMenuItem("Print Details"); printDetails.addActionListener(buttons); printVisual = new JMenuItem("Print Schedule"); printVisual.addActionListener(buttons); migrateTab = new JMenuItem("Migrate Tab"); migrateTab.addActionListener(buttons); flagPrimary = new JMenuItem("Flag course as primary"); flagPrimary.addActionListener(buttons); selectSection = new JMenuItem("Select allowed sections"); selectSection.addActionListener(buttons); unflagPrimary = new JMenuItem("Remove primary flag"); unflagPrimary.addActionListener(buttons); linkCourses = new JMenuItem("Link courses together"); linkCourses.addActionListener(buttons); addCoursesLinked = new JMenuItem("Add courses as linked"); addCoursesLinked.addActionListener(buttons); addCoursePrimary = new JMenuItem("Add course as primary"); addCoursePrimary.addActionListener(buttons); remLink = new JMenuItem("Remove course link"); remLink.addActionListener(buttons); remPrimary = new JMenuItem("Remove primary course"); remPrimary.addActionListener(buttons); contextMenu = new JPopupMenu(); contextMenu.add(printVisual); contextMenu.add(printDetails); contextMenu.add(new JSeparator()); //contextMenu.add(migrateTab); //contextMenu.add(detach); contextMenu.add(new JSeparator()); contextMenu.add(closeThis); contextMenu.add(closeOthers); while(!help.isDone()){} setDatabase(Main.terms.get(Main.prefs.getCurrentTerm()), true, true); owner = Main.master; addCourse.setEnabled(false); removeCourse.setEnabled(false); add(view, BorderLayout.WEST); add(schedulesPanel, BorderLayout.CENTER); } /********************************************************* * *********************************************************/ public void fixScheduleTypes(){ Vector<Object> temp = new Vector<Object>(); TreeMap<String, Integer> back = numberSelections; for(Object course: scheduleClassModel.toArray()){ if(masterClassModel.contains(course)){ temp.add(course); } } numberSelections = new TreeMap<String, Integer>(); numberPanel.removeAll(); scheduleClassModel.removeAllElements(); sectionModel.removeAllElements(); for(Object course: temp){ scheduleClassModel.addElement(course); sectionModel.addElement(course); numberSelections.put((String)course, back.get(course)); numberPanel.add(numberSelectionPanels.get(course)); } scheduleClassList.setModel(scheduleClassModel); sectionList.setModel(sectionModel); showSelectedSection(); } /********************************************************* * *********************************************************/ public void fixMasterTypes(CourseType toShow, Database items){ for(String course: items.getCourseList(toShow)){ masterClassModel.addElement(course); } masterClassList.setModel(masterClassModel); updateMasterCount(); } /********************************************************* * *********************************************************/ public void setDatabase(Database items, boolean ignorePopups, boolean allowBuild){ local = items; if(local != null){ undergrad.setEnabled(local.isUndergrad()); gradCampus.setEnabled(local.isGradCampus()); gradDist.setEnabled(local.isGradDist()); undergrad.setSelected(local.isUndergrad()); gradCampus.setSelected(local.isGradCampus()); gradDist.setSelected(local.isGradDist()); fillCourses(local); setDate(); if(allowBuild){ updateSchedules(ignorePopups); } } } /********************************************************* * *********************************************************/ public void setDate(){ try{ downloaded.setText("Downloaded: " + local.getCreation().getTime().toString()); } catch(NullPointerException ex){ downloaded.setText("Not Yet Downloaded"); } } /********************************************************* * *********************************************************/ public void fillCourses(Database items){ if (items != null){ masterClassModel.clear(); CourseType toShow = CourseType.getCourseType(undergrad.isSelected(), gradCampus.isSelected(), gradDist.isSelected()); fixMasterTypes(toShow, items); fixScheduleTypes(); fixPrimaryTypes(); fixDependancyTypes(); } } /********************************************************* * *********************************************************/ @Override public void setEnabled(boolean enable){ super.setEnabled(enable); this.enabled = enable; masterClassList.setEnabled(enable); masterClassPane.setEnabled(enable); scheduleClassList.setEnabled(enable); scheduleClassPane.setEnabled(enable); selectionPanel.setEnabled(enable); addCourse.setEnabled(enable); removeCourse.setEnabled(enable); choosePanel.setEnabled(enable); linksDisplay.setEnabled(enable); linksScroll.setEnabled(enable); linksList.setEnabled(enable); viewInternal.setEnabled(enable); useClosed.setEnabled(enable); useAll.setEnabled(enable); reportingEnabled.setEnabled(enable); if(enable){ view.addMouseListener(mouse); } else{ view.removeMouseListener(mouse); } view.setEnabled(enable); if(useAll.isSelected()){ minUse.setEnabled(false); } else{ minUse.setEnabled(enable); } for(String item: sectionSelectionPanels.keySet()){ JPanel panel = sectionSelectionPanels.get(item); for(Component temp: panel.getComponents()){ temp.setEnabled(enable); } } sectionList.setEnabled(enable); linked.setEnabled(enable); primaryCourses.setEnabled(enable); primaryList.setEnabled(enable); primaryScroll.setEnabled(enable); removeLink.setEnabled(enable); removePrimary.setEnabled(enable); undergrad.setEnabled(enable); gradCampus.setEnabled(enable); gradDist.setEnabled(enable); refreshSchedules.setEnabled(enable); autoRefresh.setEnabled(enable); schedules.setEnabled(enable); schedulesPane.setEnabled(enable); schedulesPanel.setEnabled(enable); displayPanel.setEnabled(enable); displayPane.setEnabled(enable); flagPrimary.setEnabled(enable); unflagPrimary.setEnabled(enable); selectSection.setEnabled(enable); addClass.setEnabled(enable); showDetails.setEnabled(enable); removeClass.setEnabled(enable); detach.setEnabled(enable); closeThis.setEnabled(enable); closeOthers.setEnabled(enable); printDetails.setEnabled(enable); printVisual.setEnabled(enable); scheduleDisplay.setEnabled(enable); infoPanel.setEnabled(enable); infoPane.setEnabled(enable); int pos = Main.master.tabControl.indexOfComponent(this); try{ Main.master.tabControl.getTabComponentAt(pos).setEnabled(enable); } catch(Exception ex){} } /********************************************************* * *********************************************************/ public void updateSchedules(boolean ignorePopups){ Main.master.setModified(MakeSchedule.this, true); local = Main.terms.get(local.getTerm()); Object[] items = scheduleClassModel.toArray(); String[] courses = new String[items.length]; Object[] temp; try { int sectionsRequested = 0; for(String key: numberSelections.keySet()){ sectionsRequested += numberSelections.get(key).intValue(); } int use = useAll.isSelected() ? sectionsRequested : Integer.parseInt(minUse.getText()); int max = items.length; if(!useAll.isSelected()){ if(max < use){ minUse.setText(Integer.toString(max)); use = max; } } else{ minUse.setText(Integer.toString(max)); use = max; } if(items.length != 0){ for(int index = 0; index < items.length; index++){ courses[index] = (String)(items[index]); } setEnabled(false); buildSchedules(courses, primary, useClosed.isSelected(), use, this, !ignorePopups, CourseType.getCourseType(undergrad.isSelected(), gradCampus.isSelected(), gradDist.isSelected()), sectionSelections, numberSelections, reportingEnabled.isSelected()); } else{ schedulesModel = new DefaultListModel(); temp = new Object[1]; schedules.setListData(temp); updateScheduleCount(); conditionalDisable(); showSchedule((Schedule)null); } refreshSchedules.setForeground(null); } catch (NumberFormatException e) { JOptionPane.showMessageDialog(Main.master, "Invalid entry for minimum number of courses.", "Invalid Number", JOptionPane.ERROR_MESSAGE); } } public void updateScheduleCount(){ int sched = 0, conf = 0; for(Object item: schedulesModel.toArray()){ if(item instanceof Schedule) sched++; else if(item instanceof Conflict) conf++; } scheduleCounter.setText(Integer.toString(sched)); conflictCounter.setText(Integer.toString(conf)); } public void updateMasterCount(){ masterCounter.setText(Integer.toString(masterClassModel.getSize())); } public void updateScheduleCourseCount(){ scheduleCourseCounter.setText(Integer.toString(scheduleClassModel.getSize())); } /******************************************************** * @purpose Update the schedules display *********************************************************/ public void buildSchedules(String[] classes, ArrayList<String> primary, boolean allowClosed, int useMin, MakeSchedule owner, boolean allowPopup, CourseType type, TreeMap<String, boolean[]> allowedSections, TreeMap<String, Integer> numberSelections, boolean reportingEnabled){ BuildScheduleThread worker = new BuildScheduleThread(); worker.setAllowClosed(allowClosed); worker.setClasses(classes); worker.setPrimary(primary); worker.setUseMin(useMin); worker.setOwner(owner); worker.setType(type); worker.setAllowPopup(allowPopup); worker.setAllowedSections(allowedSections); worker.setNumberSelections(numberSelections); worker.setReportingEnabled(reportingEnabled); Main.threadExec.execute(worker); } /********************************************************* * *********************************************************/ public void conditionalDisable(){ if(masterClassList.getSelectedIndices().length == 0){ addCourse.setEnabled(false); } if(scheduleClassList.getSelectedIndices().length == 0){ removeCourse.setEnabled(false); } if(linksList.getSelectedIndices().length == 0){ removeLink.setEnabled(false); } if(primaryList.getSelectedIndices().length == 0){ removePrimary.setEnabled(false); } } /********************************************************* * *********************************************************/ public void maybeUpdateSchedules(){ if(autoRefresh.isSelected()){ updateSchedules(false); } else{ refreshSchedules.setForeground(Color.RED); } } @SuppressWarnings("boxing") public void setBasic(){ for(int item: basicComp.keySet()){ displayPanel.add(basicComp.get(item), basicCont.get(item)); } } /********************************************************* * *********************************************************/ @SuppressWarnings("boxing") public void buildBasic(){ basicComp = Collections.synchronizedSortedMap(new TreeMap<Integer, Component>()); basicCont = Collections.synchronizedSortedMap(new TreeMap<Integer, GridBagConstraints>()); int scaledHour = hourVal * scale; int scaledDay = 1 * scale; int zeroScale = 0 * scale; int halfHourScale = (hourVal/2) * scale; int count = 0; final String emptyString = "<html><pre> <br><br><br> </pre></html>"; for(Day item: Day.values()){ for (int hour = 8; hour < 20; hour++) { JLabel empty = new JLabel(); empty.setText(emptyString); if(hour % 2 == 0){ empty.setBackground(Color.white); empty.setOpaque(true); } empty.setForeground(empty.getBackground()); empty.setHorizontalAlignment(SwingConstants.CENTER); empty.setVerticalAlignment(SwingConstants.CENTER); empty.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1)); GridBagConstraints daily = new GridBagConstraints(); daily.gridy = (hour * hourVal - sizeOffset) * scale; daily.gridx = (item.value() + 1) * scale; daily.gridwidth = scaledDay; daily.gridheight = scaledHour; daily.fill = GridBagConstraints.BOTH; try{ basicComp.put(count, empty); basicCont.put(count++, daily); } catch(ClassCastException ex){ logger.error("Unable to build display constraints", ex); } } JLabel empty = new JLabel(); empty.setText(item.toString()); empty.setOpaque(false); empty.setHorizontalAlignment(SwingConstants.CENTER); empty.setVerticalAlignment(SwingConstants.BOTTOM); GridBagConstraints daily = new GridBagConstraints(); daily.gridy = zeroScale; daily.gridx = (item.value() + 1) * scale; daily.gridwidth = scaledDay; daily.gridheight = halfHourScale; daily.fill = GridBagConstraints.BOTH; basicComp.put(count, empty); basicCont.put(count++, daily); } for(int hour = 8; hour < 20; hour++){ JLabel empty = new JLabel(); String text; if (hour == 12){ text = new String(hour + " pm"); } else if(hour < 12){ text = new String(hour + "am"); } else { text = new String(hour-12 + "pm"); } empty.setText(text); empty.setOpaque(false); empty.setHorizontalAlignment(SwingConstants.CENTER); empty.setVerticalAlignment(SwingConstants.NORTH); GridBagConstraints daily = new GridBagConstraints(); daily.gridy = (hour * hourVal - sizeOffset) * scale; daily.gridx = zeroScale; daily.gridwidth = scaledDay; daily.gridheight = scaledHour; daily.fill = GridBagConstraints.BOTH; basicComp.put(count, empty); basicCont.put(count++, daily); } } /********************************************************* * *********************************************************/ public Color getColor(String course, String section){ String ident; Scanner parse = new Scanner(course); ident = parse.next(); Color temp = CourseColor.getColor(ident); if(section.length() != 2){ float[] comps = temp.getColorComponents(null); comps[0] *= (comps[0] == noScale) ? noScale : scaleColor; comps[1] *= (comps[1] == noScale) ? noScale : scaleColor; comps[2] *= (comps[2] == noScale) ? noScale : scaleColor; temp = new Color(comps[0], comps[1], comps[2]); } return temp; } public void setInfo(Object schedule){ if(schedule == null || schedule instanceof Schedule){ setInfo((Schedule)schedule, true); } else if(schedule instanceof Conflict){ setInfo((Conflict)schedule); } } private void setInfo(Conflict schedule){ setInfo(schedule.item, false); TreeMap<Section,ClassPanel> errs = new TreeMap<Section,ClassPanel>(); for(Section one: schedule.conflicted.keySet()){ ClassPanel panel; if(errs.keySet().contains(one)){ panel = errs.get(one); } else{ panel = getInfoPanel(one); } JPanel inner = (JPanel)panel.getComponent(0); JLabel conf = new JLabel(); switch(schedule.conflictedTypes.get(one)){ case minUse:{ String sec = one.getDescription(); conf = new JLabel(schedule.minUse.get(sec) + " [" + Conflict.ConflictType.minUse.toString() + "]"); break; } case link:{ String err[] = schedule.getLinkError(one); String links[] = err[0].split(":"); for(int pos = 2; pos < links.length; pos++){ links[1] += ", " + links[pos]; } err[1] = "Conflicts" + err[1].split(" conflicts")[1] + " [" + Conflict.ConflictType.link.toString() + ": " + links[1] + "]"; conf = new JLabel(err[1]); break; } case number:{ String[] err = schedule.getNumberError(one); err[0] = err[0].split(" times")[0]; err[0] = err[0].substring(err[0].length()-2); conf = new JLabel(err[1] + " [" + Conflict.ConflictType.number + err[0] + "]"); break; } case primary:{ String err = schedule.getPrimaryError(one); err = "C" + err.split(" it c")[1] + " [" + Conflict.ConflictType.primary + "]"; conf = new JLabel(err); break; } } Font temp = conf.getFont(); conf.setFont(temp.deriveFont(Font.BOLD, temp.getSize()-2)); conf.setForeground(Color.red.darker()); conf.setHorizontalAlignment(SwingConstants.CENTER); inner.add(conf); errs.put(one, panel); } for(Section key: errs.keySet()){ infoPanel.add(errs.get(key)); } int count = infoPanel.getComponentCount(); for(; count % 3 != 0; count++){ ClassPanel panel = getInfoPanel(null); infoPanel.add(panel); } } /********************************************************* * *********************************************************/ private void setInfo(Schedule schedule, boolean pad){ infoPanel.removeAll(); int count = 0; if (schedule != null){ for(Section item: schedule.getClassesObj()){ ClassPanel panel = getInfoPanel(item); panel.addMouseListener(mouse); infoPanel.add(panel); count++; } if(pad){ for(; count % 3 != 0; count++){ ClassPanel panel = getInfoPanel(null); infoPanel.add(panel); } } } else{ for(count = 0; count < 6; count++){ ClassPanel panel = getInfoPanel(null); infoPanel.add(panel); } } } /********************************************************* * *********************************************************/ public ClassPanel getInfoPanel(Section section){ ClassPanel outer = new ClassPanel(new BorderLayout()); JPanel inner = new JPanel(new GridLayout(14,1)); inner.setOpaque(true); inner.setBackground(Color.white); if (section != null){ inner.add(new JLabel(Integer.toString(section.getCRN()), JLabel.CENTER)); inner.add(new JLabel("<html><strong>" + section.getCourseID() + " " + section.getSection() + "</strong></html>", JLabel.CENTER)); inner.add(new JLabel("<html><strong>" + section.getTitle() + "</strong></html>", JLabel.CENTER)); if (section.getNotes().length() != 0){ inner.add(new JLabel("<html><font color=\"red\">" + section.getNotes(), JLabel.CENTER)); } inner.add(new JLabel("Course Rating: " + Double.toString(Math.round(section.getRating() * 10)/10.0), JLabel.CENTER)); inner.add(new JLabel(section.getInstructor().getName(), JLabel.CENTER)); if (!section.getInstructor().getName().equals("STAFF") && section.getInstructor().getRating() != 0.0){ inner.add(new JLabel("Professor Rating: " + Double.toString(Math.round(section.getInstructor().getRating() * 10)/10.0), JLabel.CENTER)); } inner.add(new JLabel(section.getCredit() + " Credits", JLabel.CENTER)); inner.add(new JLabel(section.getDaysStr() + " " + section.getPeriodStr(), JLabel.CENTER)); inner.add(new JLabel(section.getLocation(), JLabel.CENTER)); JLabel seats = new JLabel(section.isClosed() ? "Course Closed" : "Open Seats: " + section.getSeats(), JLabel.CENTER); seats.setForeground(section.isClosed() ? Color.RED : seats.getForeground()); inner.add(seats); if(section.hasSecondary()){ inner.add(new JLabel(section.getSecDaysStr() + " " + section.getSecPeriodStr(), JLabel.CENTER)); inner.add(new JLabel(section.getSecLocation(), JLabel.CENTER)); } } else { for(int count = 0; count < 12; count++){ inner.add(new JLabel(" ")); } } outer.add(inner); return outer; } /********************************************************* * *********************************************************/ private void showSchedule(Schedule sched){ displayPanel.removeAll(); if (sched != null){ Section[] sections = sched.getClassesObj().toArray(new Section[0]); for (Section section: sections){ int[] define = new int[2]; GridBagConstraints[] places = getConstraints(section, define); int current = 0; for(GridBagConstraints item: places){ boolean secondary = (current >= define[0]); ClassPanel holder = new ClassPanel(section, secondary); if(section.hasValidTime(secondary)){ displayPanel.add(holder, item); } current++; } } } selectedSchedule = schedules.getSelectedIndex(); setBasic(); scheduleDisplay.validate(); scheduleDisplay.repaint(); Main.master.validate(); } private void showSchedule(Conflict conf){ showSchedule(conf.item); for(Section miss: conf.conflicted.keySet()){ Section in = conf.conflicted.get(miss); Section conflict = Section.getConflictAsSection(miss, in); int[] define = new int[2]; GridBagConstraints[] places = getConstraints(conflict, define); int current = 0; for(GridBagConstraints item: places){ boolean secondary = (current >= define[0]); ConflictPanel holder = new ConflictPanel(conflict, miss, in); if(miss.hasValidTime(secondary)){ displayPanel.add(holder, item); } current++; } } setZOrders(); } public void setZOrders(){ for(Component one: displayPanel.getComponents()){ if(one instanceof ConflictPanel){ displayPanel.setComponentZOrder(one, conflictZOrder); } } } public void showSchedule(Object item){ if(item == null || item instanceof Schedule){ showSchedule((Schedule)item);//display schedule } else if(item instanceof Conflict){ showSchedule((Conflict)item); } setInfo(item); } /********************************************************* * *********************************************************/ public void addLinkedCourses(String[] courses){ dependancy.addLinkedCourses(courses); linksModel = new DefaultListModel(); for(CourseList item: dependancy){ linksModel.addElement(item); } linksList.setModel(linksModel); maybeUpdateSchedules(); } /********************************************************* * *********************************************************/ public void displayLinkedCourses(){ linksModel.removeAllElements(); for(CourseList item: dependancy){ linksModel.addElement(item); } linksList.setModel(linksModel); } /********************************************************* * *********************************************************/ public void displayPrimaryCourses(boolean emptyFirst){ if(emptyFirst){ primaryModel.removeAllElements(); } for(String item: primary){ if(!primaryModel.contains(item)){ primaryModel.addElement(item); } } primaryList.setModel(primaryModel); } /********************************************************* * *********************************************************/ public void fixPrimaryTypes(){ Vector<Object> temp = new Vector<Object>(); for(Object item: primary){ if(masterClassModel.contains(item)){ temp.add(item); } } primary.clear(); for(Object item: temp){ primary.add((String)item); } displayPrimaryCourses(true); } /********************************************************* * *********************************************************/ public void fixDependancyTypes(){ Vector<String> toRemove = new Vector<String>(); for(CourseList item: dependancy.links){ for(String temp: item){ if(!scheduleClassModel.contains(temp)){ toRemove.add(temp); } } } for(String item: toRemove){ for(CourseList found: dependancy.getLinks(item)){ dependancy.remove(item, found); } } displayLinkedCourses(); } /********************************************************* * *********************************************************/ public GridBagConstraints[] getConstraints(Section item, int[] define){ int numDays = 0; int regDays = 0; boolean[] days = item.getDaysBool(); boolean[] secDays = item.getSecDaysBool(); for(boolean day: days){ if (day){ numDays++; } } regDays = numDays; if(item.hasSecondary()){ for(boolean day: secDays){ if (day){ numDays++; } } } define[0] = regDays; define[1] = numDays; GridBagConstraints[] results = new GridBagConstraints[numDays]; int start = item.getPeriodPer().getStartTime().getHour(); boolean am = item.getPeriodPer().getStartTime().getAm(); start = (!am) ? (start == 12) ? start : start + 12 : start; start *= hourVal; start += item.getPeriodPer().getStartTime().getMinute(); int duration = (int)item.getPeriodPer().getDurationMin(); int secStart = item.getSecPeriodPer().getStartTime().getHour(); boolean secAm = item.getSecPeriodPer().getStartTime().getAm(); secStart = (!secAm) ? (secStart == 12) ? secStart : secStart + 12 : secStart; secStart *= hourVal; secStart += item.getSecPeriodPer().getStartTime().getMinute(); int secDuration = (int)item.getSecPeriodPer().getDurationMin(); int current = 0; int secCurrent = regDays; for(Day curr: Day.values()){ boolean day = days[curr.value()]; if (day){ results[current] = new GridBagConstraints(); results[current].gridx = (curr.value() + 1) * scale; results[current].gridy = (start - sizeOffset) * scale; results[current].gridwidth = 1 * scale; results[current].gridheight = duration * scale; results[current].fill = GridBagConstraints.BOTH; current++; } if(item.hasSecondary()){ boolean secDay = secDays[curr.value()]; if (secDay){ results[secCurrent] = new GridBagConstraints(); results[secCurrent].gridx = (curr.value() + 1) * scale; results[secCurrent].gridy = (secStart - sizeOffset) * scale; results[secCurrent].gridwidth = 1 * scale; results[secCurrent].gridheight = secDuration * scale; results[secCurrent].fill = GridBagConstraints.BOTH; secCurrent++; } } } return results; } /********************************************************* * *********************************************************/ public void toggleViewSize(){ if (view.getTitleAt(0).compareTo("<<") != Compare.equal.value()){ choosePanel.setMinimumSize(null); choosePanel.setMaximumSize(null); choosePanel.setPreferredSize(null); linksDisplay.setMinimumSize(null); linksDisplay.setMaximumSize(null); linksDisplay.setPreferredSize(null); viewInternal.setMinimumSize(null); viewInternal.setMaximumSize(null); viewInternal.setPreferredSize(null); view.setTitleAt(0, "<<"); view.setToolTipText("Click to minimize the choose courses pane."); } else{ Dimension size = new Dimension(0,30); choosePanel.setMinimumSize(size); choosePanel.setMaximumSize(size); choosePanel.setPreferredSize(size); linksDisplay.setMinimumSize(size); linksDisplay.setMaximumSize(size); linksDisplay.setPreferredSize(size); viewInternal.setMinimumSize(size); viewInternal.setMaximumSize(size); viewInternal.setPreferredSize(size); view.setTitleAt(0, ">>"); view.setToolTipText("Click to maximize the choose courses pane."); } } /********************************************************* * *********************************************************/ public boolean atLeastOneSelected(){ return undergrad.isSelected() || gradCampus.isSelected() || gradDist.isSelected(); } /********************************************************* * *********************************************************/ public void showContextMenu(Component item, int x, int y){ if(item.equals(masterClassList)){ JPopupMenu show = new JPopupMenu(); int index = masterClassList.locationToIndex(new Point(x,y)); show.add(addClass); show.add(addCoursePrimary); show.add(addCoursesLinked); //show.add(showDetails); addClass.setEnabled(this.enabled); addCoursePrimary.setEnabled(this.enabled); addCoursesLinked.setEnabled(this.enabled); showDetails.setEnabled(this.enabled); if (!masterClassList.isSelectedIndex(index)){ masterClassList.setSelectedIndex(index); } if (masterClassList.getSelectedIndices().length != 1){ showDetails.setEnabled(false); addClass.setText("Add courses to schedule"); addCoursePrimary.setText("Add courses as primary"); } else{ addClass.setText("Add course to schedule"); addCoursePrimary.setText("Add course as primary"); addCoursesLinked.setEnabled(false); } if (masterClassList.getSelectedIndices().length < 1){ addClass.setEnabled(false); addCoursePrimary.setEnabled(false); addCoursesLinked.setEnabled(false); } show.show(item, x, y); } else if(item.equals(scheduleClassList)){ JPopupMenu show = new JPopupMenu(); int index = scheduleClassList.locationToIndex(new Point(x,y)); show.add(removeClass); //show.add(showDetails); show.add(selectSection); show.add(flagPrimary); show.add(unflagPrimary); show.add(linkCourses); removeClass.setEnabled(this.enabled); showDetails.setEnabled(this.enabled); flagPrimary.setEnabled(this.enabled); selectSection.setEnabled(this.enabled); unflagPrimary.setEnabled(this.enabled); linkCourses.setEnabled(this.enabled); if (!scheduleClassList.isSelectedIndex(index)){ scheduleClassList.setSelectedIndex(index); } if (scheduleClassList.getSelectedIndices().length != 1){ showDetails.setEnabled(false); removeClass.setText("Remove courses from schedule"); flagPrimary.setText("Flag courses as primary"); unflagPrimary.setText("Remove primary flags from courses"); selectSection.setEnabled(false); } else{ removeClass.setText("Remove course from schedule"); flagPrimary.setText("Flag course as primary"); unflagPrimary.setText("Remove primary flag from course"); } if (scheduleClassList.getSelectedIndices().length < 1){ removeClass.setEnabled(false); flagPrimary.setEnabled(false); unflagPrimary.setEnabled(false); selectSection.setEnabled(false); } else if(scheduleClassList.getSelectedIndices().length < 2){ linkCourses.setEnabled(false); } Object[] values = scheduleClassList.getSelectedValues(); if(primary.containsAll(Arrays.asList(values))){ flagPrimary.setEnabled(false); } boolean shouldEnable = false; for(Object one: values){ shouldEnable |= primary.contains(one); } unflagPrimary.setEnabled(unflagPrimary.isEnabled() && shouldEnable); show.show(item, x, y); } else if(item.equals(scheduleDisplay)){ JPopupMenu show = new JPopupMenu(); try{ if(scheduleDisplay.getComponentAt(scheduleDisplay.indexAtLocation(x, y)) .equals(scheduleDisplay.getComponentAt(0))){ show.add(printVisual); if(schedulesModel.size() != 0){ show.show(item, x, y); } } if(scheduleDisplay.getComponentAt(scheduleDisplay.indexAtLocation(x, y)) .equals(scheduleDisplay.getComponentAt(1))){ show.add(printDetails); if(schedulesModel.size() != 0){ show.show(item, x, y); } } } catch(IndexOutOfBoundsException ex){/*do nothing if bad index*/} } else if(item.equals(schedules)){ JPopupMenu show = new JPopupMenu(); show.add(printVisual); show.add(printDetails); schedules.setSelectedIndex(schedules.locationToIndex(new Point(x, y))); if(schedulesModel.size() != 0){ show.show(item, x, y); } } else if(item.equals(linksList)){ JPopupMenu show = new JPopupMenu(); show.add(remLink); int index = linksList.locationToIndex(new Point(x,y)); if (!linksList.isSelectedIndex(index)){ linksList.setSelectedIndex(index); } remLink.setEnabled(linksList.getSelectedIndices().length > 0); show.show(item, x, y); } else if(item.equals(primaryList)){ JPopupMenu show = new JPopupMenu(); show.add(remPrimary); int index = primaryList.locationToIndex(new Point(x,y)); if (!primaryList.isSelectedIndex(index)){ primaryList.setSelectedIndex(index); } remPrimary.setEnabled(primaryList.getSelectedIndices().length > 0); show.show(item, x, y); } else if(item instanceof ClassPanel){ ((ClassPanel)item).showContextMenu(x, y); } } /********************************************************* * *********************************************************/ private class buttonListener implements ActionListener{ public void actionPerformed(ActionEvent event){ Object source = event.getSource(); if(source.equals(addCourse) || source.equals(addClass)){ addCourseAction(event); } else if(source.equals(addCoursesLinked)){ addCoursesLinked(event); } else if(source.equals(addCoursePrimary)){ addCoursesPrimary(event); } else if(source.equals(removeCourse) || source.equals(removeClass)){ removeCourseAction(event); } else if(source.equals(refreshSchedules)){ updateSchedules(false); } else if(source.equals(closeThis)){ Main.master.tabControl.remove(view.getParent()); } else if(source.equals(closeOthers)){ for(Component comp: Main.master.tabControl.getComponents()){ Tab item; try{ item = (Tab)comp; if(view.getParent() != item){ Main.master.tabControl.remove(comp); } } catch(ClassCastException ex){} } } else if(source.equals(detach)){ Component comp = detach.getOwner(); MakeSchedule mkSched = (MakeSchedule)comp; Popup item = new Popup(mkSched, Main.master.tabControl.getTitleAt(Main.master.tabControl.indexOfComponent(comp))); owner = item; Main.master.tabControl.remove(mkSched); Main.master.detached.add(item); item.setVisible(true); } else if(source.equals(printDetails)){ PrintUtilities.printComponent(infoPanel, Main.master.tabControl.getTitleAt(Main.master.tabControl.indexOfComponent(MakeSchedule.this)) + " - Details"); } else if(source.equals(printVisual)){ PrintUtilities.printComponent(displayPanel, Main.master.tabControl.getTitleAt(Main.master.tabControl.indexOfComponent(MakeSchedule.this)) + " - Display"); } else if(source.equals(flagPrimary)){ for(Object item: scheduleClassList.getSelectedValues()){ if(!primary.contains(item)){ primary.add((String)item); } } scheduleClassList.repaint(); displayPrimaryCourses(false); maybeUpdateSchedules(); } else if(source.equals(unflagPrimary)){ for(Object item: scheduleClassList.getSelectedValues()){ primary.remove(item); } scheduleClassList.repaint(); displayPrimaryCourses(false); maybeUpdateSchedules(); } else if(source.equals(linkCourses)){ String [] link = new String[scheduleClassList.getSelectedIndices().length]; int pos = 0; for(Object item: scheduleClassList.getSelectedValues()){ link[pos++] = (String)item; } addLinkedCourses(link); } else if(source.equals(removeLink) || source.equals(remLink)){ for(Object item: linksList.getSelectedValues()){ dependancy.remove((CourseList)item); } displayLinkedCourses(); maybeUpdateSchedules(); } else if(source.equals(removePrimary) || source.equals(remPrimary)){ for(Object item: primaryList.getSelectedValues()){ primary.remove(item); } displayPrimaryCourses(true); maybeUpdateSchedules(); } else if(source.equals(migrateTab)){ } else if(source.equals(selectSection)){ String item = (String)scheduleClassList.getSelectedValue(); viewInternal.setSelectedIndex(viewInternal.indexOfComponent(sectionPanelScroller)); sectionList.setSelectedValue(item, true); } } public void addCoursesLinked(ActionEvent event){ boolean back = autoRefresh.isSelected(); autoRefresh.setSelected(false); Object[] selected = masterClassList.getSelectedValues(); addCourse.doClick(); int[] indices = new int[selected.length]; for(int pos = 0; pos < selected.length; pos++){ indices[pos] = scheduleClassModel.indexOf(selected[pos]); } scheduleClassList.setSelectedIndices(indices); autoRefresh.setSelected(back); linkCourses.doClick(); } public void addCoursesPrimary(ActionEvent event){ boolean back = autoRefresh.isSelected(); autoRefresh.setSelected(false); Object[] items = masterClassList.getSelectedValues(); addCourse.doClick(); int[] select = new int[items.length]; for(int pos = 0; pos < items.length; pos++){ select[pos] = scheduleClassModel.indexOf(items[pos]); } scheduleClassList.setSelectedIndices(select); autoRefresh.setSelected(back); flagPrimary.doClick(); } public void addCourseAction(ActionEvent event){ for(Object item: masterClassList.getSelectedValues()){ if(!scheduleClassModel.contains(item)){ scheduleClassModel.addElement(item); addSectionPanel((String)item); addNumberPanel((String)item); } else{ JOptionPane.showMessageDialog(Main.master, "The course \"" + item + "\" has already been added" + " to this schedule.", "Course Not Added", JOptionPane.INFORMATION_MESSAGE); } } Object[] temp = scheduleClassModel.toArray(); Arrays.sort(temp); scheduleClassModel.clear(); for(Object item: temp){ scheduleClassModel.addElement(item); } scheduleClassList.setModel(scheduleClassModel); maybeUpdateSchedules(); int[] clear = new int[]{masterClassList.getModel().getSize() + 1}; masterClassList.setSelectedIndices(clear); sectionList.setModel(sectionModel); sectionList.setSelectedIndex(0); updateScheduleCourseCount(); showSelectedSection(); } public void removeCourseAction(ActionEvent event){ for(Object item: scheduleClassList.getSelectedValues()){ scheduleClassModel.removeElement(item); primary.remove(item); removeSectionPanel((String)item); removeNumberPanel((String)item); } Object[] temp = scheduleClassModel.toArray(); Arrays.sort(temp); scheduleClassModel.clear(); for(Object item: temp){ scheduleClassModel.addElement(item); } scheduleClassList.setModel(scheduleClassModel); fixPrimaryTypes(); fixDependancyTypes(); if(autoRefresh.isSelected()){ updateSchedules(false); } else{ refreshSchedules.setForeground(Color.RED); } sectionList.setModel(sectionModel); sectionList.setSelectedIndex(0); updateScheduleCourseCount(); showSelectedSection(); } } public void addNumberPanel(String course){ Course item = local.getCourse(course); JPanel pane = new JPanel(); JLabel tempLabel = new JLabel(item.getPerceivedCourse()); String[] values = new String[item.getNumOfSections()]; for(int pos = 1; pos <= item.getNumOfSections(); pos++){ values[pos-1] = Integer.toString(pos); } NumberComboBox tempCombo = new NumberComboBox(course, values); tempCombo.setToolTipText("Choose the number of sections of " + item.getPerceivedCourse() + " required"); tempLabel.setToolTipText(item.getTitle()); pane.add(tempLabel); pane.add(tempCombo); numberSelectionCombos.put(course, tempCombo); numberSelectionPanels.put(course, pane); numberPanel.add(pane); numberPanel.invalidate(); } public void addSectionPanel(String course){ Course item = local.getCourse(course); JPanel pane = new JPanel(new GridLayout(0,1)); Section[] sections = item.getSectionsSObj(); boolean[] flags = new boolean[sections.length]; sectionSelections.put(course, flags); for(int pos = 0; pos < sections.length; pos++){ Section one = sections[pos]; SectionBox toAllow = new SectionBox(one.getCourseID() + " " + one.getSection(), course); toAllow.setToolTipText("<html><p>" + one.getDaysStr() + "<br>" + one.getPeriodStr() + "<br>" + one.getLocation() + "<br>" + one.getInstructor().toString() + (one.hasSecondary() ? "<br>" + one.getSecDaysStr() + "<br>" + one.getSecPeriodStr() + "<br>" + one.getSecLocation() : "")); toAllow.setSelected(true); flags[pos] = true; toAllow.setPos(pos); pane.add(toAllow); } sectionSelectionPanels.put(course, pane); sectionModel.addElement(course); sectionPlaceHolder.add(pane); } public void removeNumberPanel(String course){ JPanel removed = numberSelectionPanels.get(course); numberSelectionPanels.remove(course); numberPanel.remove(removed); } public void removeSectionPanel(String course){ sectionModel.removeElement(course); sectionSelectionPanels.remove(course); sectionSelections.remove(course); } public void setSectionSelections(TreeMap<String, boolean[]> newSelections){ sectionSelections = newSelections; for(String key: sectionSelectionPanels.keySet()){ JPanel panel = sectionSelectionPanels.get(key); for(Component one: panel.getComponents()){ ((SectionBox)one).resetValues(); } } } public void setNumberSelections(TreeMap<String, Integer> newSelections){ numberSelections.putAll(newSelections); for(String key: numberSelectionCombos.keySet()){ numberSelectionCombos.get(key).resetValues(); } } public void showSelectedSection(){ try{ sectionPlaceHolder.removeAll(); Object value = sectionList.getSelectedValue(); if(value == null){ value = sectionModel.firstElement(); } JPanel panel = sectionSelectionPanels.get(value); boolean[] vals = sectionSelections.get(value); for(Component item: panel.getComponents()){ SectionBox temp = (SectionBox)item; temp.setSelected(vals[temp.getPos()]); } sectionPlaceHolder.add(panel); } catch(NoSuchElementException ex){ } finally{ sectionPanelScroller.validate(); sectionPlaceHolder.validate(); sectionPlaceHolder.repaint(); } } /********************************************************* * *********************************************************/ private class checkListener implements ActionListener{ /********************************************************* * *********************************************************/ public void actionPerformed(ActionEvent event){ Object source = event.getSource(); if (source.equals(useClosed)){ maybeUpdateSchedules(); } else if(source.equals(useAll)){ minUse.setEnabled(!useAll.isSelected()); minUseLbl.setEnabled(!useAll.isSelected()); maybeUpdateSchedules(); } else if(source.equals(reportingEnabled)){ maybeUpdateSchedules(); } else if(source.equals(undergrad)){ if(!atLeastOneSelected()){ undergrad.setSelected(true); } fillCourses(local); maybeUpdateSchedules(); } else if(source.equals(gradCampus)){ if(!atLeastOneSelected()){ gradCampus.setSelected(true); } fillCourses(local); maybeUpdateSchedules(); } else if(source.equals(gradDist)){ if(!atLeastOneSelected()){ gradDist.setSelected(true); } fillCourses(local); maybeUpdateSchedules(); } } } /********************************************************* * *********************************************************/ private class mouseListener implements MouseListener{ private MouseEvent last; /********************************************************* * *********************************************************/ public void mouseClicked(MouseEvent event){ Object source = event.getSource(); if (event.getButton() == MouseEvent.BUTTON1){ if(event.getClickCount() == 2){ if (source.equals(masterClassList)){ addCourse.doClick(); } else if(source.equals(scheduleClassList)){ removeCourse.doClick(); } else if(source.equals(view)){ if(event != last){ toggleViewSize(); } } } else if(event.getClickCount() == 1){ if(source.equals(view)){ if (view.indexAtLocation(event.getPoint().x, event.getPoint().y) != -1){ if(event != last){ toggleViewSize(); } } } } } last = event; } /********************************************************* * *********************************************************/ public void mouseEntered(MouseEvent event){} /********************************************************* * *********************************************************/ public void mouseReleased(MouseEvent e) { maybeShowPopup(e); } /********************************************************* * *********************************************************/ public void mouseExited(MouseEvent event){} /********************************************************* * *********************************************************/ public void mousePressed(MouseEvent e) { maybeShowPopup(e); } /********************************************************* * *********************************************************/ private void maybeShowPopup(MouseEvent e) { if (e.isPopupTrigger()) { showContextMenu(e.getComponent(), e.getX(), e.getY()); } } } /********************************************************* * *********************************************************/ private class keyListener extends KeyAdapter{ /********************************************************* * *********************************************************/ @Override public void keyPressed(KeyEvent event){ if(event.getSource().equals(scheduleClassList)){ if(event.getKeyCode() == KeyEvent.VK_DELETE){ removeCourse.doClick(); } } else if(event.getSource().equals(linksList)){ if(event.getKeyCode() == KeyEvent.VK_DELETE){ removeLink.doClick(); } } else if(event.getSource().equals(primaryList)){ if(event.getKeyCode() == KeyEvent.VK_DELETE){ removePrimary.doClick(); } } else if(event.getSource().equals(minUse)){ if(event.getKeyCode() == KeyEvent.VK_ENTER){ maybeUpdateSchedules(); } } else if(event.getSource().equals(masterClassList)){ if(event.getKeyCode() == KeyEvent.VK_ENTER){ addCourse.doClick(); } } } } /********************************************************* * *********************************************************/ private class DetachTabItem extends JMenuItem{ /********************************************************* * *********************************************************/ private MakeSchedule itemOwner; static final long serialVersionUID = 267000000; /********************************************************* * *********************************************************/ public DetachTabItem(MakeSchedule owner){ super("Detach Item"); this.itemOwner = owner; } /********************************************************* * *********************************************************/ public MakeSchedule getOwner(){ return itemOwner; } } /********************************************************* * *********************************************************/ public class TitleTipList extends JList{ static final long serialVersionUID = 265000000; public TitleTipList(ListModel model){ super(model); } /********************************************************* * *********************************************************/ @Override public String getToolTipText(MouseEvent event) { Point p = event.getPoint(); int location = locationToIndex(p); ListModel model = getModel(); try{ String item = ((String)model.getElementAt(location)); if (!(item.compareTo("No Data Model") == Compare.equal.value())){ try{ return local.getCourse(item).getTitle(); } catch (NullPointerException ex){} } } catch(ArrayIndexOutOfBoundsException ex){} return null; } } /********************************************************* * *********************************************************/ private class ListListener implements ListSelectionListener{ /********************************************************* * *********************************************************/ public void valueChanged(ListSelectionEvent event){ if(event.getSource().equals(schedules)){ showSchedule(schedules.getSelectedValue()); } else if(event.getSource().equals(masterClassList)){ addCourse.setEnabled(masterClassList.getSelectedIndices().length > 0); } else if(event.getSource().equals(scheduleClassList)){ removeCourse.setEnabled(scheduleClassList.getSelectedIndices().length > 0); } else if(event.getSource().equals(linksList)){ removeLink.setEnabled(linksList.getSelectedIndices().length > 0); } else if(event.getSource().equals(primaryList)){ removePrimary.setEnabled(primaryList.getSelectedIndices().length > 0); } } } /********************************************************* * *********************************************************/ public class ClassPanel extends JPanel{ /********************************************************* * *********************************************************/ static final long serialVersionUID = 266000000; public ClassPanel(Section item, boolean secondary){ super(new BorderLayout()); addMouseListener(mouse); JPanel inner = new JPanel(new GridLayout(6,1)); Color back = getColor(item.getCourseID(), item.getSection()); for(int pos = 0; pos <=5; pos++){ String text = new String(); switch(pos){ case 0:{ text = Integer.toString(item.getCRN()); break; } case 1:{ text = item.getCourseID() + " " + item.getSection(); break; } case 2:{ text = item.getTitle(); break; } case 3:{ text = item.getInstructor().toString(); break; } case 4:{ text = (!secondary) ? item.getLocation() : item.getSecLocation(); break; } case 5:{ text = (!secondary) ? item.getPeriodStr() : item.getSecPeriodStr(); break; } } JLabel row = new JLabel(text); row.setVerticalAlignment(SwingConstants.CENTER); row.setHorizontalAlignment(SwingConstants.CENTER); row.setForeground(item.isClosed() ? Color.red.darker() : Color.black); //row.setMaximumSize(new Dimension(100,100)); inner.add(row); inner.setBackground(back); } add(inner, BorderLayout.CENTER); setBorder(BorderFactory.createLineBorder( item.isClosed() ? Color.red.darker() : Color.black)); setToolTipText("<html>" + item.getTitle() + "<BR>" + "<font color=\"red\">" + item.getNotes() + "</font>" + (item.getNotes() == null || item.getNotes().compareTo("") == Compare.equal.value() ? "" : "<BR>") + item.getCredit() + " Credit Hours<BR>" + (item.getRating() == 0.0 ? "" : "Course Rating: " + Math.round(item.getRating() * 10)/10.0 + "<BR>") + (item.getInstructor().getRating() == 0.0 ? "" : "Professor Rating: " + Math.round(item.getInstructor().getRating() * 10)/10.0)); } /********************************************************* * *********************************************************/ public ClassPanel(LayoutManager layout){ super(layout); addMouseListener(mouse); /*addMouseListener(new MouseListener(){ @Override public void mouseClicked(MouseEvent arg0) { scalePanel.getZoomListen().mouseClicked(arg0); } @Override public void mouseEntered(MouseEvent arg0) { scalePanel.getZoomListen().mouseEntered(arg0); } @Override public void mouseExited(MouseEvent arg0) { scalePanel.getZoomListen().mouseExited(arg0); } @Override public void mousePressed(MouseEvent arg0) { scalePanel.getZoomListen().mousePressed(arg0); } @Override public void mouseReleased(MouseEvent arg0) { scalePanel.getZoomListen().mouseReleased(arg0); } });*/ } /********************************************************* * *********************************************************/ public void selectCourse(){ Component first = this.getComponent(0); JPanel holder = (JPanel) first; Component second = holder.getComponent(1); JLabel label = (JLabel)second; String detail = label.getText(); Scanner parse = new Scanner(detail); String course = parse.next() + " " + parse.next(); Section temp = new Section(); temp.setCourseID(course); temp.setSection(detail); String perceivedCourse = temp.getPerceivedCourse(); scheduleClassList.setSelectedValue(perceivedCourse, true); } public void showContextMenu(int x, int y){ JPopupMenu show = new JPopupMenu(); show.add(removeClass); removeClass.setEnabled(MakeSchedule.this.enabled); ClassPanel.this.selectCourse(); show.show(ClassPanel.this, x, y); } } public class ConflictPanel extends JPanel{ private static final long serialVersionUID = 1L; public ConflictPanel(Section conf, Section miss, Section in){ super(new GridLayout(6,1)); setOpaque(true); setBackground(Color.red.darker()); setBorder(BorderFactory.createLineBorder(Color.black)); JLabel first = new JLabel("Conflict between: "); JLabel second = new JLabel(in.getCourseID() + " " + in.getSection()); JLabel third = new JLabel(in.getTitle()); JLabel fourth = new JLabel(miss.getCourseID() + " " + miss.getSection()); JLabel fifth = new JLabel(miss.getTitle()); JLabel sixth = new JLabel(conf.getPeriodStr()); first.setHorizontalAlignment(JLabel.CENTER); second.setHorizontalAlignment(JLabel.CENTER); third.setHorizontalAlignment(JLabel.CENTER); fourth.setHorizontalAlignment(JLabel.CENTER); fifth.setHorizontalAlignment(JLabel.CENTER); sixth.setHorizontalAlignment(JLabel.CENTER); add(first); add(second); add(third); add(fourth); add(fifth); add(sixth); setToolTipText("<html>" + in.getTitle() + "<BR>" + "<font color=\"red\">" + in.getNotes() + "</font>" + (in.getNotes() == null || in.getNotes().compareTo("") == Compare.equal.value() ? "" : "<BR>") + in.getCredit() + " Credit Hours<BR>" + (in.getRating() == 0.0 ? "" : "Course Rating: " + Math.round(in.getRating() * 10)/10.0 + "<BR>") + (in.getInstructor().getRating() == 0.0 ? "" : "Professor Rating: " + Math.round(in.getInstructor().getRating() * 10)/10.0) + "<br><br>Conflicts with<br><br>" + miss.getTitle() + "<BR>" + "<font color=\"red\">" + miss.getNotes() + "</font>" + (miss.getNotes() == null || miss.getNotes().compareTo("") == Compare.equal.value() ? "" : "<BR>") + miss.getCredit() + " Credit Hours<BR>" + (miss.getRating() == 0.0 ? "" : "Course Rating: " + Math.round(miss.getRating() * 10)/10.0 + "<BR>") + (miss.getInstructor().getRating() == 0.0 ? "" : "Professor Rating: " + Math.round(miss.getInstructor().getRating() * 10)/10.0)); } } /********************************************************* * *********************************************************/ public JMenuItem getDetach() { return detach; } /********************************************************* * *********************************************************/ public void setDetach(DetachTabItem detach) { this.detach = detach; } /********************************************************* * *********************************************************/ public JMenuItem getCloseThis() { return closeThis; } /********************************************************* * *********************************************************/ public void setCloseThis(JMenuItem closeThis) { this.closeThis = closeThis; } /********************************************************* * *********************************************************/ public JMenuItem getCloseOthers() { return closeOthers; } /********************************************************* * *********************************************************/ public void setCloseOthers(JMenuItem closeOthers) { this.closeOthers = closeOthers; } /********************************************************* * *********************************************************/ public JFrame getOwner() { return owner; } /********************************************************* * *********************************************************/ public void setOwner(JFrame owner) { this.owner = owner; } /********************************************************* * *********************************************************/ public Database getDatabase(){ return this.local; } /********************************************************* * *********************************************************/ public JMenuItem getMigrateTab() { return migrateTab; } /********************************************************* * *********************************************************/ public void setMigrateTab(JMenuItem migrateTab) { this.migrateTab = migrateTab; } /********************************************************* * *********************************************************/ public JPopupMenu getContextMenu() { return contextMenu; } /********************************************************* * *********************************************************/ public void setContextMenu(JPopupMenu contextMenu) { this.contextMenu = contextMenu; } /********************************************************* * *********************************************************/ private class FlaggedCellRenderer extends DefaultListCellRenderer{ public static final long serialVersionUID = 267000000; /********************************************************* * *********************************************************/ public FlaggedCellRenderer(){ setOpaque(true); } /********************************************************* * *********************************************************/ @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { Component sup = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if(primary.contains(value)){ setForeground(Color.BLUE); } return sup; } } /********************************************************* * *********************************************************/ private class ClosedCellRenderer extends DefaultListCellRenderer{ public static final long serialVersionUID = 1L; /********************************************************* * *********************************************************/ public ClosedCellRenderer(){ setOpaque(true); } /********************************************************* * *********************************************************/ @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { Component sup = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); if(value != null){ if(value instanceof Schedule){ if(((Schedule)value).hasClosedCourse()){ setForeground(Color.RED.darker()); } } else if(value instanceof Conflict){ if(((Conflict)value).hasClosedCourse()){ setForeground(Color.RED.darker()); } } } return sup; } } /********************************************************* * *********************************************************/ private class CenteredCellRenderer extends DefaultListCellRenderer{ public static final long serialVersionUID = 268000000; /********************************************************* * *********************************************************/ public CenteredCellRenderer(){ setOpaque(true); } /********************************************************* * *********************************************************/ @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { JLabel sup = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); sup.setHorizontalAlignment(JLabel.CENTER); if(list.equals(primaryList)){ try{ Course found = local.getCourse((String)value); sup.setText(sup.getText() + " - " + found.getTitle()); } catch(NullPointerException ex){ } } return sup; } } /********************************************************* * *********************************************************/ public class DepenTipList extends JList{ static final long serialVersionUID = 265000000; /********************************************************* * *********************************************************/ DepenTipList(Object[] array){ super(array); } /********************************************************* * *********************************************************/ @Override public String getToolTipText(MouseEvent event) { Point p = event.getPoint(); int location = locationToIndex(p); ListModel model = getModel(); String item = model.getElementAt(location).toString(); if (!(item.compareTo("No Data Model") == Compare.equal.value())){ Scanner parse = new Scanner(item); parse.useDelimiter(" :: "); try{ String text = local.getCourse(parse.next()).getTitle(); while(parse.hasNext()){ Course found = local.getCourse(parse.next()); text += " :: " + found.getTitle(); } return text; } catch (NullPointerException ex){} } return null; } } /********************************************************* * *********************************************************/ public ArrayList<String> getPrimary() { return primary; } /********************************************************* * *********************************************************/ public void setPrimary(ArrayList<String> primary) { this.primary = primary; displayPrimaryCourses(true); } /********************************************************* * *********************************************************/ public void setDependancy(LinkedCourses dependancy){ this.dependancy = dependancy; try{ displayLinkedCourses(); } catch(Exception ex){ this.dependancy = new LinkedCourses(); } } public class ListTransferHandler extends TransferHandler{ private static final long serialVersionUID = 269000000L; private int[] indices = null; @SuppressWarnings("unused") private int addIndex = -1; //Location where items were added @SuppressWarnings("unused") private int addCount = 0; //Number of items added. /** * We only support importing strings. */ @Override public boolean canImport(TransferHandler.TransferSupport info) { // Check for String flavor if (!info.isDataFlavorSupported(DataFlavor.stringFlavor)) { return false; } return true; } /** * Bundle up the selected items in a single list for export. * Each line is separated by a newline. */ @Override protected Transferable createTransferable(JComponent c) { JList list = (JList)c; indices = list.getSelectedIndices(); Object[] values = list.getSelectedValues(); StringBuffer buff = new StringBuffer(); for (int i = 0; i < values.length; i++) { Object val = values[i]; buff.append(val == null ? "" : val.toString()); if (i != values.length - 1) { buff.append("\n"); } } return new StringSelection(buff.toString()); } /** * We support both copy and move actions. */ @Override public int getSourceActions(JComponent c) { return TransferHandler.COPY; } /** * Perform the actual import. This demo only supports drag and drop. */ @Override public boolean importData(TransferHandler.TransferSupport info) { if (!info.isDrop()) { return false; } JList list = (JList)info.getComponent(); if(list.equals(scheduleClassList)){ DefaultListModel listModel = (DefaultListModel)list.getModel(); JList.DropLocation dl = (JList.DropLocation)info.getDropLocation(); int index = dl.getIndex(); boolean insert = dl.isInsert(); // Get the string that is being dropped. Transferable t = info.getTransferable(); String data; try { data = (String)t.getTransferData(DataFlavor.stringFlavor); } catch (Exception e) { return false; } // Wherever there is a newline in the incoming data, // break it into a separate item in the list. String[] values = data.split("\n"); addIndex = index; addCount = values.length; boolean anyUpdated = false; if(!insert){ String tmp = (String)listModel.get(index); removeNumberPanel(tmp); removeSectionPanel(tmp); } // Perform the actual import. for (int i = 0; i < values.length; i++) { if (insert) { //addCourse.doClick(); //anyUpdated = true; if(!listModel.contains(values[i])){ listModel.add(index++, values[i]); addNumberPanel(values[i]); addSectionPanel(values[i]); anyUpdated = true; } } else { // If the items go beyond the end of the current // list, add them in. if(!listModel.contains(values[i])){ //addCourse.doClick(); if (index < listModel.getSize()) { listModel.set(index++, values[i]); addNumberPanel(values[i]); addSectionPanel(values[i]); } else { listModel.add(index++, values[i]); addNumberPanel(values[i]); addSectionPanel(values[i]); } anyUpdated = true; } } } if(anyUpdated){ scheduleClassModel = sortList(listModel); scheduleClassList.setModel(scheduleClassModel); sectionModel = sortList(sectionModel); sectionList.setModel(sectionModel); MakeSchedule.this.showSelectedSection(); MakeSchedule.this.updateScheduleCourseCount(); maybeUpdateSchedules(); } return true; } return false; } /** * Remove the items moved from the list. */ @Override protected void exportDone(JComponent c, Transferable data, int action) { JList source = (JList)c; DefaultListModel listModel = (DefaultListModel)source.getModel(); if (action == TransferHandler.MOVE) { for (int i = indices.length - 1; i >= 0; i--) { listModel.remove(indices[i]); } } indices = null; addCount = 0; addIndex = -1; } } public class SectionBox extends JCheckBox{ static final long serialVersionUID = 1L; private int pos; private String course; public SectionBox(String value, String course){ super(value); this.course = course; this.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent event){ sectionSelections.get(SectionBox.this.course)[pos] = SectionBox.this.isSelected(); if(!SectionBox.this.validValues()){ SectionBox.this.setSelected(true); } sectionSelections.get(SectionBox.this.course)[pos] = SectionBox.this.isSelected(); numberSelectionCombos.get(SectionBox.this.getCourse()).validateValues(); maybeUpdateSchedules(); }}); } public boolean validValues(){ boolean atLeastOne = false; for(boolean item: sectionSelections.get(SectionBox.this.course)){ atLeastOne |= item; } return atLeastOne; } public void resetValues(){ setSelected(sectionSelections.get(course)[pos]); } public int getPos() { return pos; } public void setPos(int pos) { this.pos = pos; } public String getCourse() { return course; } public void setCourse(String course) { this.course = course; } } public class NumberComboBox extends JComboBox{ private static final long serialVersionUID = 1L; private String course; @SuppressWarnings("boxing") public NumberComboBox(String course, String[] values){ super(values); this.course = course; setEditable(false); addActionListener( new ActionListener(){ @Override public void actionPerformed(ActionEvent arg0) { NumberComboBox.this.validateValues(); maybeUpdateSchedules(); } }); numberSelections.put(course, 1); } @SuppressWarnings("boxing") public void validateValues(){ int selected = new Scanner((String)this.getSelectedItem()).nextInt(); String course = getCourse(); boolean[] enabled = sectionSelections.get(course); int allowed = 0; for(boolean once: enabled){ if(once) allowed++; } if(selected > allowed){ this.setSelectedIndex(allowed-1); } selected = new Scanner((String)this.getSelectedItem()).nextInt(); numberSelections.remove(course); numberSelections.put(course, selected); } @SuppressWarnings("boxing") public void resetValues(){ setSelectedIndex(numberSelections.get(course) - 1); } public String getCourse() { return course; } public void setCourse(String course) { this.course = course; } } public DefaultListModel sortList(DefaultListModel toSort){ Object[] temp = toSort.toArray(); Arrays.sort(temp); DefaultListModel toReturn = new DefaultListModel(); for(Object item: temp){ toReturn.addElement(item); } return toReturn; } static final String depenString = new String("View or remove variable building dependancies"); static final String sectionString = new String("Specify or exclude sections or specify number of sections per course"); static final String courseString = new String("Add or remove courses and create dependancies"); static final String emptyString = new String(""); protected class TippedTabbedPane extends JTabbedPane{ private static final long serialVersionUID = 1L; public TippedTabbedPane(){ setToolTipText(emptyString); } @Override public String getToolTipText(MouseEvent e){ int index = this.indexAtLocation(e.getX(), e.getY()); if(index == this.indexOfTab("Dependancies")){ return depenString; } else if(index == this.indexOfTab("Set Sections")){ return sectionString; } else if(index == this.indexOfTab("Choose Courses")){ return courseString; } return null; } } protected class SectionTipList extends JList{ static final long serialVersionUID = 265000000; public SectionTipList(ListModel model){ super(model); } /********************************************************* * *********************************************************/ @Override public String getToolTipText(MouseEvent event) { Point p = event.getPoint(); int location = locationToIndex(p); ListModel model = getModel(); try { Object value = model.getElementAt(location); if (value instanceof Schedule) { Schedule item = (Schedule) value; String toReturn = new String("<html>"); for (Section one : item.getClassesObj()) { boolean closed = one.isClosed(); if (closed) { toReturn += "<font color=\"maroon\">"; } toReturn += one.getCourseID() + " " + one.getSection() + " " + one.getTitle() + " [" + one.getInstructor() + "] (" + one.getPeriodStr() + ")<br>"; if (closed) { toReturn += "</font>"; } } toReturn += "</html>"; return toReturn; } else if (value instanceof Conflict) { Conflict item = (Conflict) value; String toReturn = item.toTipString(); return toReturn; } } catch (ArrayIndexOutOfBoundsException e) { //do nothing } return null; } } }