📄 main.java
字号:
handleCalendarFilterSelection (); } public void itemUnselected ( int ind ) { dataRepository.getCalendars ().elementAt ( ind ) .setSelected ( true ); handleCalendarFilterSelection (); } public Vector<ListItemMenuItem> getMenuChoicesForIndex ( int ind ) { Vector<ListItemMenuItem> ret = new Vector<ListItemMenuItem> (); Calendar c = dataRepository.getCalendars ().elementAt ( ind ); ret.addElement ( new ListItemMenuItem ( MENU_CALENDAR_EDIT ) ); ret.addElement ( new ListItemMenuItem ( MENU_CALENDAR_REFRESH, c .getType () != Calendar.LOCAL_CALENDAR ) ); ret.addElement ( new ListItemMenuItem ( MENU_CALENDAR_DELETE ) ); ret.addElement ( new ListItemMenuItem ( MENU_CALENDAR_ADD_EVENT, c .getType () == Calendar.LOCAL_CALENDAR ) ); if ( c.getType () == Calendar.REMOTE_ICAL_CALENDAR ) { // Does this calendar have errors? // TODO: implement error viewer... // Vector<ParseError> errors = // dataRepository.getErrorsAt ( ind ); // if ( errors != null && errors.size () > 0 ) // ret.addElement ( MENU_CALENDAR_VIEW_ERRORS + " " // + "(" // + errors.size () + ")" ); } return ret; } public void menuChoice ( int ind, String actionCommand ) { Calendar c = dataRepository.getCalendars ().elementAt ( ind ); if ( MENU_CALENDAR_EDIT.equals ( actionCommand ) ) { editCalendar ( c ); } else if ( MENU_CALENDAR_REFRESH.equals ( actionCommand ) ) { if ( c.getType () == Calendar.LOCAL_CALENDAR ) { showError ( "You can only refresh\nremote/subscribed calendars." ); } else { refreshCalendar ( c ); } } else if ( MENU_CALENDAR_DELETE.equals ( actionCommand ) ) { if ( JOptionPane.showConfirmDialog ( parent, "Are you sure you want to\nDelete the following calendar?" + "\n\n" + c.toString (), "Confirm Delete", JOptionPane.YES_NO_OPTION ) == 0 ) { deleteCalendar ( c ); } } else if ( MENU_CALENDAR_ADD_EVENT.equals ( actionCommand ) ) { Date now = Date.getCurrentDateTime ( "DTSTART" ); now.setMinute ( 0 ); new EditEventWindow ( parent, dataRepository, now, c ); } else { System.err.println ( "Unknown menu command: " + actionCommand ); } } } ); for ( int i = 0; i < dataRepository.getCalendars ().size (); i++ ) { Calendar c = dataRepository.getCalendars ().elementAt ( i ); ListItem item = this.calendarJList.getListItemAt ( i ); item .setState ( c.isSelected () ? ListItem.STATE_YES : ListItem.STATE_OFF ); } topPanel .add ( new MyScrollPane ( this.calendarJList ), BorderLayout.CENTER ); return topPanel; } // Handle user selecting a calendar checkbox to display/hide a calendar void handleCalendarFilterSelection () { // Repaint the calendar view, which will reload the data for ( int i = 0; i < dataRepository.getCalendars ().size (); i++ ) { dataRepository .getCalendars () .elementAt ( i ) .setSelected ( this.calendarJList.getListItemAt ( i ).getState () == ListItem.STATE_YES ); } this.calendarPanel.clearSelection (); this.dataRepository.rebuild (); this.calendarPanel.repaint (); } public void editCalendar ( Calendar c ) { if ( c.getType () == Calendar.LOCAL_CALENDAR ) { editLocalCalendar ( c ); } else { new EditRemoteCalendarWindow ( parent, dataRepository, c, getDataDirectory () ); } } /** * Refresh the specified calendar by reloading it from its URL. Because this * is likely to take a second or more in ideal circumstances (and much longer * in many cases), we will use the SwingWorker class to execute this in a * separate thread so we don't lock up the UI. * * @param cal * The Calendar to refresh */ public void refreshCalendar ( final Calendar cal ) { // Before we get started, update the status bar to indicate we are // loading // the calendar. showStatusMessage ( "Refreshing calendar" + ": " + cal.getName () ); SwingWorker refreshWorker = new SwingWorker () { private String error = null; private String statusMsg = null; private File outputFile = null; public Object construct () { // Execute time-consuming task... // For now, we only support HTTP/HTTPS since 99.99% of all users // will // use it // instead of something like FTP. outputFile = new File ( dataDir, cal.getFilename () + ".new" ); String username = null, password = null; if ( cal.getAuthType () == Calendar.AUTH_BASIC ) { username = cal.getAuthUsername (); password = cal.getAuthPassword (); } HttpClientStatus result = HttpClient.getRemoteCalendar ( cal.getUrl (), username, password, outputFile ); // We're not supposed to make UI calls from this thread. So, // when // we get an error, save it in the error variable for use in the // finished method. // TODO: implement a way to show these errors to the user. switch ( result.getStatus () ) { case HttpClientStatus.HTTP_STATUS_SUCCESS: statusMsg = "Calendar successfully refreshed" + ": " + cal.getName (); break; case HttpClientStatus.HTTP_STATUS_AUTH_REQUIRED: error = "Authorization required.\nPlease provide a username\n" + "and password." + "\n\n" + "Calendar" + ": " + cal.getName () + "\n" + "URL" + ": " + cal.getUrl (); return null; case HttpClientStatus.HTTP_STATUS_NOT_FOUND: error = "Invalid calendar URL (not found).\n\nServer response" + ": " + result.getMessage (); return null; default: case HttpClientStatus.HTTP_STATUS_OTHER_ERROR: error = "Error downloading calendar.\n\nServer response: " + result.getMessage () + "\n\n" + "Calendar" + ": " + cal.getName () + "\n" + "URL" + ": " + cal.getUrl (); return null; } return null; } public void finished () { // Update UI if ( error != null ) showError ( error ); if ( this.statusMsg != null ) showStatusMessage ( statusMsg ); if ( error == null ) { // TODO: validate what we downloaded was ICS data rather // than an HTML // page // Rename file from ".ics.new" to ".ics" File file = new File ( dataDir, cal.getFilename () ); // Delete old file first since renameTo may file if file // already // exists file.delete (); // Now rename if ( !outputFile.renameTo ( file ) ) { // Error renaming showError ( "Error renaming file" ); } else { // System.out.println ( "Renamed " + outputFile + " to " // + file ); // If no error, then save calendar update cal.setLastUpdatedAsNow (); saveCalendars ( dataDir ); dataRepository.updateCalendar ( getDataDirectory (), cal ); } } } }; refreshWorker.start (); } public void deleteCalendar ( Calendar c ) { boolean found = false; for ( int i = 0; i < dataRepository.getCalendars ().size () && !found; i++ ) { Calendar c1 = (Calendar) dataRepository.getCalendars ().elementAt ( i ); if ( c1.equals ( c ) ) { dataRepository.removeCalendar ( getDataDirectory (), c ); found = true; } } if ( found ) { updateCalendarJList (); updateCategoryJList (); this.dataRepository.rebuild (); this.calendarPanel.repaint (); saveCalendars ( getDataDirectory () ); } else { System.err.println ( "deleteCalendar: could not find calendar!" ); } } /** * Update the list of Calendars shown to the user */ public void updateCalendarJList () { this.calendarJList.setChoices ( dataRepository.getCalendars () ); for ( int i = 0; i < dataRepository.getCalendars ().size (); i++ ) { Calendar cal = (Calendar) dataRepository.getCalendars ().elementAt ( i ); ListItem item = this.calendarJList.getListItemAt ( i ); item.setBackground ( cal.getBackgroundColor () ); item.setForeground ( cal.getForegroundColor () ); item.setState ( cal.isSelected () ? ListItem.STATE_YES : ListItem.STATE_OFF ); } this.calendarJList.validate (); } protected JPanel createCategorySelectionPanel ( Vector categories ) { JPanel panel = new JPanel (); panel.setLayout ( new BorderLayout () ); this.categoryJList = new JList ( categories ); final JList list = this.categoryJList; updateCategoryJList (); JPanel buttonPanel = new JPanel (); buttonPanel.setLayout ( new FlowLayout () ); JButton allButton = new JButton ( "Select All" ); allButton.addActionListener ( new ActionListener () { public void actionPerformed ( ActionEvent e ) { int len = list.getModel ().getSize (); if ( len > 0 ) list.getSelectionModel ().setSelectionInterval ( 0, len - 1 ); } } ); buttonPanel.add ( allButton ); JButton noneButton = new JButton ( "Clear" ); noneButton.addActionListener ( new ActionListener () { public void actionPerformed ( ActionEvent e ) { list.clearSelection (); } } ); buttonPanel.add ( noneButton ); panel.add ( buttonPanel, BorderLayout.SOUTH ); // Add handler for when user changes category selectios list.addListSelectionListener ( new ListSelectionListener () { public void valueChanged ( ListSelectionEvent e ) { handleCategoryFilterSelection (); } } ); JScrollPane sp = new MyScrollPane ( this.categoryJList ); panel.add ( sp, BorderLayout.CENTER ); return panel; } // Handle user selecting a category to filter by void handleCategoryFilterSelection () { boolean uncategorized = this.categoryJList.getSelectionModel () .isSelectedIndex ( 0 ); int[] selected = this.categoryJList.getSelectedIndices (); Vector selectedCats = new Vector<String> (); for ( int i = 0; i < selected.length; i++ ) { if ( selected[i] > 0 ) { String cat = (String) this.categoryJList.getModel ().getElementAt ( selected[i] ); selectedCats.addElement ( cat ); } } if ( selected == null || selected.length == 0 ) { ap.setTitleAt ( 1, "Categories" ); this.dataRepository.clearCategoryFilter (); } else { ap.setTitleAt ( 1, "Categories" + " [" + selected.length + "]" ); this.dataRepository.setCategoryFilter ( uncategorized, selectedCats ); } this.calendarPanel.clearSelection (); this.dataRepository.rebuild (); this.calendarPanel.repaint (); } /** * Update the list of Calendars shown to the user */ public void updateCategoryJList () { // Get current selections so we can preserve Object[] oldSelections = this.categoryJList.getSelectedValues (); HashMap<String, String> old = new HashMap<String, String> (); for ( int i = 0; i < oldSelections.length; i++ ) { old.put ( oldSelections[i].toString (), oldSelections[i].toString () ); } Vector cats = dataRepository.getCategories (); // Sort categories alphabetically Collections.sort ( cats ); cats.insertElementAt ( "Uncategorized", 0 ); this.categoryJList.setListData ( cats ); int[] newSelections = new int[oldSelections.length]; int j = 0; for ( int i = 0; i < dataRepository.getCategories ().size (); i++ ) { String cat = (String) dataRepository.getCategories ().elementAt ( i ); if ( old.containsKey ( cat ) ) newSelections[j++] = i + 1; // skip over "uncategorized" } int[] indices = new int[j]; for ( int i = 0; i < j; i++ ) { indices[i] = newSelections[i]; } this.categoryJList.setSelectedIndices ( indices ); this.categoryJList.validate (); } /** * Get the data directory that data files for this application will be stored * in. * * @return */ // TODO: allow user preferences to override this setting File getDataDirectory () { if ( dataDir != null ) return dataDir; String s = (String) System.getProperty ( "user.home" ); if ( s == null ) { System.err .println ( "Could not find user.home setting. Using current directory instead." ); s = "."; } File f = new File ( s ); if ( f == null ) fatalError ( "Invalid user.home value" + ": " + s ); if ( !f.exists () ) fatalError ( "Home directory does not exist" + ": " + f ); if ( !f.isDirectory () ) fatalError ( "Home directory is not a directory: " + f ); // Use the home directory as the base. Data files will // be stored in a subdirectory. File dir = new File ( f, DEFAULT_DIR_NAME ); if ( !dir.exists () ) { if ( !dir.mkdirs () ) fatalError ( "Unable to create data directory" + ": " + dir ); showMessage ( "The following directory was created\nto store data files" + ":\n\n" + dir ); } if ( !dir.isDirectory () ) fatalError ( "Not a directory: " + dir ); dataDir = dir; return dir; } void showStatusMessage ( String string ) { this.messageArea.setText ( string ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -