from json.decoder import WHITESPACE from javax.swing import JTable, JScrollPane, JFrame, JPanel, JComboBox, BorderFactory, DefaultCellEditor, JLabel, UIManager, SwingConstants, JFileChooser from javax.swing.table import TableCellRenderer, DefaultTableCellRenderer from java.awt.event import MouseAdapter,MouseEvent, WindowListener, WindowEvent from java.awt import GridLayout, Dimension, BorderLayout, Color from javax.swing.table import AbstractTableModel, DefaultTableModel from java.lang.Object import getClass import jarray from javax.swing.event import TableModelListener, TableModelEvent from javax.swing.filechooser import FileNameExtensionFilter from org.apache.commons.io import FilenameUtils from java.io import File import jmri class CreateAndShowGUI4(TableModelListener): def __init__(self, class_ResetButtonMaster): global CreateAndShowGUI4_frame self.logLevel = 0 self.class_ResetButtonMaster = class_ResetButtonMaster #Create and set up the window. self.initialise_model(class_ResetButtonMaster) CreateAndShowGUI4_frame = JFrame("Scheduled Trains") self.frame = CreateAndShowGUI4_frame self.frame.setSize(600, 600); self.completeTablePanel1() # print "about to populate" self.populate_action(None) self.cancel = False def completeTablePanel1(self): self.topPanel= JPanel(); self.topPanel.setLayout(BoxLayout(self.topPanel, BoxLayout.X_AXIS)) self.self_table() self.scrollPane = JScrollPane(self.table); self.scrollPane.setPreferredSize(Dimension(600,600)) self.topPanel.add(self.scrollPane); self.buttonPane = JPanel(); self.buttonPane.setLayout(BoxLayout(self.buttonPane, BoxLayout.LINE_AXIS)) self.buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)) button_add = JButton("Add", actionPerformed = self.add_row_action) self.buttonPane.add(button_add); self.buttonPane.add(Box.createRigidArea(Dimension(10, 0))) # button_populate = JButton("Populate", actionPerformed = self.populate_action) # self.buttonPane.add(button_populate); # self.buttonPane.add(Box.createRigidArea(Dimension(10, 0))) # button_tidy = JButton("Tidy", actionPerformed = self.tidy_action) # self.buttonPane.add(button_tidy); # self.buttonPane.add(Box.createRigidArea(Dimension(10, 0))) # # button_apply = JButton("Save", actionPerformed = self.save_action) # self.buttonPane.add(button_apply) # self.buttonPane.add(Box.createHorizontalGlue()); button_close = JButton("Save & Close", actionPerformed = self.close_action) self.buttonPane.add(button_close) self.buttonPane.add(Box.createHorizontalGlue()); button_task = JButton("Repeat", actionPerformed = self.task_action) self.buttonPane.add(button_task) self.buttonPane.add(Box.createHorizontalGlue()); # button_task = JButton("Delay", actionPerformed = self.delay_action) # self.buttonPane.add(button_task) # self.buttonPane.add(Box.createHorizontalGlue()); button_delete = JButton("Delete All Rows", actionPerformed = self.delete_all_action) self.buttonPane.add(button_delete) self.buttonPane.add(Box.createHorizontalGlue()); button_savetofile = JButton("Save To File", actionPerformed = self.savetofile_action) self.buttonPane.add(button_savetofile) self.buttonPane.add(Box.createRigidArea(Dimension(10, 0))) button_loadfromfile = JButton("Load From File", actionPerformed = self.loadfromfile_action) self.buttonPane.add(button_loadfromfile) self.buttonPane.add(Box.createRigidArea(Dimension(10, 0))) button_deletesavedfile = JButton("Delete Saved Files", actionPerformed = self.deletesavedfile_action) self.buttonPane.add(button_deletesavedfile) self.buttonPane.add(Box.createHorizontalGlue()) contentPane = self.frame.getContentPane() contentPane.removeAll() contentPane.add(self.topPanel, BorderLayout.CENTER) contentPane.add(self.buttonPane, BorderLayout.PAGE_END) self.frame.pack(); self.frame.setVisible(True) return def completeTablePanel(self): # self.self_table() contentPane = self.frame.getContentPane() contentPane.removeAll() contentPane.add(self.topPanel, BorderLayout.CENTER) contentPane.add(self.buttonPane, BorderLayout.PAGE_END) size_of_one_row = 30 height = 50 for row in reversed(range(len(self.model.data))): height += size_of_one_row height = min(height, 800) self.scrollPane.setPreferredSize(Dimension(1000,height)) self.frame.pack(); self.frame.setVisible(True) return def buttonPanel(self): row1_1_button = JButton("Add Row", actionPerformed = self.add_row_action) # row1_2_button = JButton("Save", actionPerformed = self.save_action) row1 = JPanel() row1.setLayout(BoxLayout(row1, BoxLayout.X_AXIS)) row1.add(Box.createVerticalGlue()) row1.add(Box.createRigidArea(Dimension(20, 0))) row1.add(row1_1_button) row1.add(Box.createRigidArea(Dimension(20, 0))) row1.add(row1_2_button) layout = BorderLayout() # layout.setHgap(10); # layout.setVgap(10); jPanel = JPanel() jPanel.setLayout(layout); jPanel.add(self.table,BorderLayout.NORTH) jPanel.add(row1,BorderLayout.SOUTH) #return jPanel return topPanel def initialise_model(self, class_ResetButtonMaster): self.model = None self.model = MyTableModel4() self.table = JTable(self.model) self.model.addTableModelListener(MyModelListener4(self, class_ResetButtonMaster)); self.class_ResetButtonMaster = class_ResetButtonMaster pass def self_table(self): self.table.setPreferredScrollableViewportSize(Dimension(1000, 300)); #table.setFillsViewportHeight(True) #self.table.getModel().addtableModelListener(self) self.table.setFillsViewportHeight(True); self.table.setRowHeight(30); #table.setAutoResizeMode( JTable.AUTO_RESIZE_OFF ); # self.resizeColumnWidth(table) columnModel = self.table.getColumnModel(); [time_col, route_col, repeat_col, dont_schedule_col, train_name_col, train_description_col, edit_col, delete_col] = [0, 1, 2, 3, 4, 5, 6, 7] columnModel.getColumn(route_col).setPreferredWidth(300); columnModel.getColumn(repeat_col).setPreferredWidth(210); columnModel.getColumn(dont_schedule_col).setPreferredWidth(150); columnModel.getColumn(train_name_col).setMinWidth(0); # train_name is unique identifier which can be hidden from user columnModel.getColumn(train_name_col).setMaxWidth(0); # train_name is unique identifier which can be hidden from user columnModel.getColumn(train_description_col).setPreferredWidth(300); columnModel.getColumn(edit_col).setPreferredWidth(100); columnModel.getColumn(delete_col).setPreferredWidth(100); # routes column self.routesColumn = self.table.getColumnModel().getColumn(route_col); self.combobox1 = JComboBox() RouteManager=jmri.InstanceManager.getDefault(jmri.jmrit.operations.routes.RouteManager) routes = RouteManager.getRoutesByNameList() for route in routes: self.combobox1.addItem(route) self.routesColumn.setCellEditor(DefaultCellEditor(self.combobox1)) renderer1 = ComboBoxCellRenderer4() self.routesColumn.setCellRenderer(renderer1) # repeat column self.taskColumn = self.table.getColumnModel().getColumn(repeat_col) self.combobox3 = JComboBox() tasks = ["Once", "Repeat every 20 mins", "Repeat every 30 mins", "Repeat every Hour", "Repeat every 2 Hours"] for task in tasks: self.combobox3.addItem(task) self.taskColumn.setCellEditor(DefaultCellEditor(self.combobox3)) renderer3 = ComboBoxCellRenderer4() self.taskColumn.setCellRenderer(renderer3) # train column self.trainColumn = self.table.getColumnModel().getColumn(train_description_col) self.combobox4 = JComboBox() all_trains = self.get_all_roster_entries_with_speed_profile() for train in all_trains: self.combobox4.addItem(train) self.trainColumn.setCellEditor(DefaultCellEditor(self.combobox4)) renderer4 = ComboBoxCellRenderer4() self.trainColumn.setCellRenderer(renderer4) jpane = JScrollPane(self.table) panel = JPanel() panel.add(jpane) result = JScrollPane(panel) return self.table def get_all_roster_entries_with_speed_profile(self): roster_entries_with_speed_profile = [] r = jmri.jmrit.roster.Roster.getDefault() for roster_entry in jmri.jmrit.roster.Roster.getAllEntries(r): if self.logLevel > 0: print "roster_entry.getSpeedProfile()",roster_entry,roster_entry.getSpeedProfile() if roster_entry.getSpeedProfile() != None: roster_entries_with_speed_profile.append(roster_entry.getId()) if self.logLevel > 0: print "roster_entry.getId()",roster_entry.getId() return roster_entries_with_speed_profile def add_row_action(self, e): model = e.getSource() # data = self.model.getValueAt(0, 0) count = self.model.getRowCount() colcount = self.model.getColumnCount() self.model.add_row() # self.save() self.completeTablePanel() def get_route_list(self): TrainManager=jmri.InstanceManager.getDefault(jmri.jmrit.operations.trains.TrainManager) train_list = TrainManager.getTrainsByTimeList() my_list = [[train.getName(), train.getDescription(), train.getDepartureTime().partition(":")[2], train.getComment(), train.getRoute()] for train in train_list] # print "my_list", my_list return my_list def populate_action(self, event): # print "populating" items_to_put_in_dropdown = self.get_route_list() # print "items_to_put_in_dropdown", items_to_put_in_dropdown self.model.populate(items_to_put_in_dropdown) # print "populated" self.completeTablePanel() def tidy_action(self,e): self.model.remove_not_set_row() self.completeTablePanel() def savetofile_action(self, event): #Tidy self.model.remove_not_set_row() self.completeTablePanel() if self.model.getRowCount() == 0: msg = "There are no valid rows" result = OptionDialog().displayMessage(msg) return msg = "Saving Valid rows" result = OptionDialog().displayMessage(msg) dir = self.directory() j = JFileChooser(dir); j.setAcceptAllFileFilterUsed(False) filter = FileNameExtensionFilter("text files txt", ["txt"]) j.addChoosableFileFilter(filter); j.setDialogTitle("Select a .txt file"); # Automatically select the first file in the directory files = j.getCurrentDirectory().listFiles() j.setSelectedFile(files[0]) ret = j.showSaveDialog(None) if (ret == JFileChooser.APPROVE_OPTION) : file = j.getSelectedFile() if file == "" or file == None: msg = "No file selected" result = OptionDialog().displayMessage(msg) return if FilenameUtils.getExtension(file.getName()).lower() == "txt" : #filename is OK as-is pass else: #file = File(file.toString() + ".txt"); # append .txt if "foo.jpg.txt" is OK file = File(file.getParentFile(), FilenameUtils.getBaseName(file.getName())+".txt") # ALTERNATIVELY: remove the extension (if any) and replace it with ".xml" else: return if self.logLevel > 0: print "savetofile action", file my_list = [] [time_col, route_col, repeat_col, dont_schedule_col, train_name_col, train_description_col, edit_col, delete_col] = [0, 1, 2, 3, 4, 5, 6, 7] for row in range(len(self.model.data)): time_name = str(self.model.data[row][time_col]) route_name = str(self.model.data[row][route_col]) task_name = str(self.model.data[row][repeat_col]) dont_schedule_name = str(self.model.data[row][dont_schedule_col]) train_name = str(self.model.data[row][train_name_col]) train_description = str(self.model.data[row][train_description_col]) edit_name = str(self.model.data[row][edit_col]) delete_name = str(self.model.data[row][delete_col]) row_list = [time_name, route_name, task_name, dont_schedule_name, train_name, train_description, edit_name, delete_name] my_list.append(row_list) self.write_list(my_list,file) def loadfromfile_action(self, event): # load the file dir = self.directory() j = JFileChooser(dir); j.setAcceptAllFileFilterUsed(False) filter = FileNameExtensionFilter("text files txt", ["txt"]) j.setDialogTitle("Select a .txt file") j.addChoosableFileFilter(filter) # Automatically select the first file in the directory files = j.getCurrentDirectory().listFiles() j.setSelectedFile(files[0]) ret = j.showOpenDialog(None) if (ret == JFileChooser.APPROVE_OPTION) : file = j.getSelectedFile() if self.logLevel > 0: print "about to read list", file my_list = self.read_list(file) if self.logLevel > 0: print "my_list", my_list for row in reversed(range(len(self.model.data))): self.model.data.pop(row) i = 0 [time_col, route_col, repeat_col, dont_schedule_col, train_name_col, train_description_col, edit_col, delete_col] = [0, 1, 2, 3, 4, 5, 6, 7] for row in my_list: [time_val, route_val, repeat_val, dont_schedule_val, train_name_val, train_description_val, edit_val, delete_val] = row # print "reading row", row self.model.add_row() self.model.data[i][time_col] = time_val.replace('"','') self.model.data[i][route_col] = route_val.replace('"','') self.model.data[i][repeat_col] = repeat_val.replace('"','') # print "dont_schedule_val", dont_schedule_val, "(dont_schedule_val == 'True'') ", (dont_schedule_val == "True") self.model.data[i][dont_schedule_col] = (dont_schedule_val.replace('"','') == "True") #convert string to boolean self.model.data[i][train_name_col] = train_name_val.replace('"','') self.model.data[i][train_description_col] = train_description_val.replace('"','') # self.model.data[i][edit_col] = edit_val.replace('"','') # self.model.data[i][delete_col] = bool(delete_val.replace('"','')) i += 1 # print "read row", row self.save() self.completeTablePanel() msg = "Deleting invalid rows" result = OptionDialog().displayMessage(msg) if result == JOptionPane.NO_OPTION: return self.completeTablePanel() self.save() def deletesavedfile_action(self, event): while(True): self.model.remove_not_set_row() self.completeTablePanel() if self.model.getRowCount() == 0: return self.model.remove_not_set_row() self.completeTablePanel() if self.model.getRowCount() == 0: return dir = self.directory() j = JFileChooser(dir); j.setAcceptAllFileFilterUsed(False) filter = FileNameExtensionFilter("text files txt", ["txt"]) j.addChoosableFileFilter(filter); j.setDialogTitle("Delete not wanted files"); ret = j.showDialog(None, "Delete"); if ret == JFileChooser.APPROVE_OPTION: file = j.getSelectedFile() if file == "" or file == None: return if file.exists(): os.remove(file.getAbsolutePath()) # print("File " + file.getName() + " has been deleted successfully.") else: print("The selected file does not exist.") else: print("File selection cancelled.") return def close_action(self, event): self.completeTablePanel() self.save() # Open and close the Operations Panel to force save of any extra trains if self.find_frame_by_title("Trains") is None: # print "did not find frame Trains so creating it" a = jmri.jmrit.operations.trains.gui.TrainsTableAction() a.actionPerformed(None) # now close f = self.find_frame_by_title("Trains") if f is not None: # print f f.dispose() # f = None # print "should be closed" self.frame.dispatchEvent(WindowEvent(self.frame, WindowEvent.WINDOW_CLOSING)); # Function to find a frame by name def find_frame_by_name(self, name): frames = JFrame.getFrames() for f in frames: # print f.getName() if f.getName() == name: return f return None # Function to find a frame by title def find_frame_by_title(self, title): frames = JFrame.getFrames() for f in frames: if f.getTitle() == title: return f return None def delay_action(self, event): [time_col, route_col, repeat_col, dont_schedule_col, train_name_col, train_description_col, edit_col, delete_col] = [0, 1, 2, 3, 4, 5, 6, 7] for row in reversed(range(len(self.model.data))): old_delay = int(self.model.data[0][train_name_col]) if old_delay == None: old_delay = 0 new_delay = self.new_delay(old_delay) self.model.data[row][train_name_col] = new_delay self.completeTablePanel() def new_delay(self, old_val): if old_val < 3: new_val = 3 elif old_val < 5: new_val = 5 elif old_val < 10: new_val = 10 elif old_val < 15: new_val = 15 else: new_val = 0 return new_val def delete_all_action(self, event): [time_col, route_col, repeat_col, dont_schedule_col, train_name_col, train_description_col, edit_col, delete_col] = [0, 1, 2, 3, 4, 5, 6, 7] # self.model.getDataVector().removeAllElements(); for row in reversed(range(len(self.model.data))): self.model.data.pop(row) # return # # for rowToRemove in reversed(range(len(self.model.data))): # for rowToRemove in range(len(self.model.data)): # rowtoremove = self.table. # self.model.removeRow(rowToRemove); # if(table.getSelectedRow() != -1) { # // remove selected row from the model # model.removeRow(table.getSelectedRow()); # JOptionPane.showMessageDialog(null, "Selected row deleted successfully"); # } # # break self.save() self.completeTablePanel() def new_val(self, old_val): if old_val < 3: new_val = 3 elif old_val < 10: new_val = 10 elif old_val < 30: new_val = 30 elif old_val < 100: new_val = 100 else: new_val = 1 return new_val def task_action(self, event): [time_col, route_col, repeat_col, dont_schedule_col, train_name_col, train_description_col, edit_col, delete_col] = [0, 1, 2, 3, 4, 5, 6, 7] for row in reversed(range(len(self.model.data))): old_val = str(self.model.data[0][repeat_col]) if old_val == None: old_val = 0 new_val = self.new_task(old_val) self.model.data[row][repeat_col] = new_val self.save() self.completeTablePanel() def new_task(self, old_val): if old_val == "Once": new_val = "Repeat every 20 mins" elif old_val == "Repeat every 20 mins": new_val = "Repeat every 30 mins" elif old_val == "Repeat every 30 mins": new_val = "Repeat every Hour" elif old_val == "Repeat every Hour": new_val = "Repeat every 2 Hours" elif old_val == "Repeat every 2 Hours": new_val = "Once" else: return "Once" return new_val # def save_action(self, event): # self.save() # def save(self): [time_col, route_col, repeat_col, dont_schedule_col, train_name_col, train_description_col, edit_col, delete_col] = [0, 1, 2, 3, 4, 5, 6, 7] # print "save_action" # print "self.model.data", self.model.data self.clear_everything() # print "self.model.data after", self.model.data # print "apply action" for row in reversed(range(len(self.model.data))): # print "save row", row time_name = str(self.model.data[row][time_col]) route_name = str(self.model.data[row][route_col]) train_name = str(self.model.data[row][train_name_col]) train_description = str(self.model.data[row][train_description_col]) repeat_name = str(self.model.data[row][repeat_col]) # print "repeat_name", repeat_name dont_schedule_name = str(self.model.data[row][dont_schedule_col]) # if time_name != "" and route_name != "" and train_name_val != "": if train_name != "": # print "save schedule" self.save_schedule(row, time_name, route_name, repeat_name, dont_schedule_name, train_name, train_description) pass else: msg = "Cannot save row: " + str(row) + " train name, route or delay is not set" OptionDialog().displayMessage(msg,"") # self.completeTablePanel() if self.model.getRowCount() == 0: self.frame.dispatchEvent(WindowEvent(self.frame, WindowEvent.WINDOW_CLOSING)) def save_schedule(self, row, time_name, route_name, repeat_name, dont_schedule_name, train_name, train_description): print "save_schedule: train", train_name, "route_name", route_name, "time_name", time_name TrainManager=jmri.InstanceManager.getDefault(jmri.jmrit.operations.trains.TrainManager) train = TrainManager.newTrain(train_name) RouteManager = jmri.InstanceManager.getDefault(jmri.jmrit.operations.routes.RouteManager) route = RouteManager.getRouteByName(route_name) train.setRoute(route) train.setDescription(train_description) result = time_name.split(":") if len(result) == 2: day = "0" hour = result[0] minute = result[1] else: day = result[0] hour = result[1] minute = result[2] train.setDepartureTime(day, hour, minute) self.set_skip(train, dont_schedule_name) # do this first self.set_repeat(train, repeat_name) train.setName(train_name) # print "finished save schedule train.getName()", train.getName() def set_repeat(self, train, repeat): # print "in set_repeat" comment = train.getComment() #Null # if comment == None: comment = "" # repeat_current = MyTableModel4().find_between(comment, "[repeat-", "-repeat]") # empty string # print "repeat_currenr", repeat_current, "repeat", repeat # if repeat_current != repeat: # # self.delete_between(comment, "[repeat-", "-repeat]") # comment = "" # print "comment3a", comment comment = self.insert_between(comment, "[repeat-", "-repeat]", repeat) # print "comment3", comment train.setComment(comment) def set_skip(self, train, dont_schedule_name): comment = train.getComment() if comment == None: comment = "" if dont_schedule_name == "True": comment = "skip *" + comment train.setComment(comment) def delete_between(self, string, delim1, delim2): first, _, rest = string.partition(delim1) _, _, rest = rest.partition(delim2) cleaned_text = ' '.join([first.strip(), rest.strip()]) return cleaned_text def insert_between(self, string, delim1, delim2, value): first, _, rest = string.partition(delim1) _, _, rest = rest.partition(delim2) # print "string", string, "first.strip()", first.strip(), "rest.strip()", rest.strip() new_val = delim1 + str(value) + delim2 modified_text = new_val.join([first.strip(), rest.strip()]) # print "modified_text",modified_text return modified_text def clear_everything(self): TrainManager=jmri.InstanceManager.getDefault(jmri.jmrit.operations.trains.TrainManager) train_list = TrainManager.getTrainsByTimeList() for train in train_list: TrainManager.deregister(train) def directory(self): path = jmri.util.FileUtil.getUserFilesPath() + "dispatcher" + java.io.File.separator + "schedules" if not os.path.exists(path): os.makedirs(path) return path + java.io.File.separator def write_list(self, a_list, file): # store list in binary file so 'wb' mode #file = self.directory() + "blockDirections.txt" if self.logLevel > 0: print "block_info" , a_list if self.logLevel > 0: print "file" , file file = str(file) with open(file, 'wb') as fp: pass if self.logLevel > 0: print "V" with open(file, 'wb') as fp: if self.logLevel > 0: print "B" for items in a_list: if self.logLevel > 0: print "C", items i = 0 for item in items: if self.logLevel > 0: print "item", item fp.write('"%s"' %item) if i != 7: fp.write(",") i+=1 fp.write('\n') #fp.write('\n'.join(item)) #fp.write(items) # Read list to memory def read_list(self, file): file = str(file) if self.logLevel > 0: print "read list", file # for reading also binary mode is important #file = self.directory() + "blockDirections.txt" n_list = [] # try: with open(file, 'rb') as fp: for line in fp: if self.logLevel > 0: print "line" , line x = line[:-1] if self.logLevel > 0: print x y = x.split(",") #y = [item.replace('"','') for item in y] if self.logLevel > 0: print "y" , y n_list.append(y) return n_list class MyModelListener4(TableModelListener): def __init__(self, class_CreateAndShowGUI4, class_ResetButtonMaster): self.class_CreateAndShowGUI4 = class_CreateAndShowGUI4 self.class_ResetButtonMaster = class_ResetButtonMaster self.cancel = False self.logLevel = 0 self.i = 0 def tableChanged(self, e) : # print "tableChanged" self.i +=1 # if self.i % 2 == 0: return global trains_allocated global CreateAndShowGUI5_glb row = e.getFirstRow() column = e.getColumn() # print "column", column self.model = e.getSource() columnName = self.model.getColumnName(column) class_CreateAndShowGUI4 = self.class_CreateAndShowGUI4 class_ResetButtonMaster = self.class_ResetButtonMaster tablemodel = class_CreateAndShowGUI4.model [time_col, route_col, repeat_col, dont_schedule_col, train_name_col, train_description_col, edit_col, delete_col] = [0, 1, 2, 3, 4, 5, 6, 7] if column == time_col: # print "time col changed" pass elif column == edit_col: # sections if self.model.getValueAt(row, edit_col) == True: # print "starting edit" route_data = str(self.model.getValueAt(row, route_col)) scheduled_start = self.model.getValueAt(row, time_col) if route_data == "" or route_data is None or route_data == "None": OptionDialog().displayMessage("Cannot display route as route name has not been specified") else: if "CreateAndShowGUI5_glb" in globals(): if CreateAndShowGUI5_glb != None: CreateAndShowGUI5_glb.frame.dispose() CreateAndShowGUI5_glb = CreateAndShowGUI5(self, route_data, scheduled_start) # print "e" self.model.setValueAt(False, row, edit_col) elif column == delete_col: # print "delete col/row" title = "" msg = "delete row?" opt1 = "don't delete row" opt2 = "delete row" result = OptionDialog().customQuestionMessage2str(msg, title, opt1, opt2) if result == opt2: self.delete_row(row, class_CreateAndShowGUI4) class_CreateAndShowGUI4.save() # save everything when the table is changed # class_CreateAndShowGUI4.completeTablePanel() # don't need to refresh hence commented out def save_route(self, class_CreateAndShowGUI4): class_CreateAndShowGUI4.save() def delete_row(self, row, class_CreateAndShowGUI4): self.model.data.pop(row) class_CreateAndShowGUI4.save() class_CreateAndShowGUI4.completeTablePanel() def show_time_picker(self): # Show a simple JOptionPane input dialog for time selection selected_time = JOptionPane.showInputDialog(None, "Select a time (HH:mm):") return selected_time class ComboBoxCellRenderer4 (TableCellRenderer): def getTableCellRendererComponent(self, jtable, value, isSelected, hasFocus, row, column) : panel = self.createPanel(value) return panel def createPanel(self, s) : p = JPanel(BorderLayout()) p.add(JLabel(str(s), JLabel.LEFT), BorderLayout.WEST) icon = UIManager.getIcon("Table.descendingSortIcon"); p.add(JLabel(icon, JLabel.RIGHT), BorderLayout.EAST); p.setBorder(BorderFactory.createLineBorder(Color.blue)); return p; class MyTableModel4 (DefaultTableModel): columnNames = ["Time", "Route", "Repeat", " Don't Schedule", "Train Name", "Train Description", "Edit_Row", "Delete Row"] def __init__(self): # l1 = ["", "", False, "stop at end of route", 10, False, False] self.data = [] def remove_not_set_row(self): b = False for row in reversed(range(len(self.data))): # print "row", row if self.data[row][1] == "": self.data.pop(row) def add_row(self): # TrainManager=jmri.InstanceManager.getDefault(jmri.jmrit.operations.trains.TrainManager) # train_list = TrainManager.getTrainsByTimeList() [time_col, route_col, repeat_col, dont_schedule_col, train_name_col, train_description_col, edit_col, delete_col] = [0, 1, 2, 3, 4, 5, 6, 7] indices = [] for row in reversed(range(len(self.data))): # indices = [int(train.getName().split("Train",1)[1]) for train in train_list if train.getName().startswith("Train")] indices = [int(self.data[row][train_name_col].split("Train",1)[1]) for row in reversed(range(len(self.data))) if self.data[row][train_name_col].startswith("Train")] # print "indices", indices if indices == []: index = 1 else: index = max(indices) + 1 train_name = "Train" + str(index) # the train name in operations trains is unique train_description = "Select Train" # we put the roster name of the train in the description # print "adding row" self.data.append(["00:00", "", "Once", False, train_name, train_description, False, False]) # print "added row" # print self.data # print "added" def populate(self, items_to_put_in_dropdown): # print "in populate" for row in reversed(range(len(self.data))): self.data.pop(row) # print "cleared everything" # self.data = [] # append all trains to put in dropdown [time_col, route_col, repeat_col, dont_schedule_col, train_name_col, train_description_col, edit_col, delete_col] = [0, 1, 2, 3, 4, 5, 6, 7] for [train, train_description, time, comment, route] in items_to_put_in_dropdown: # print "train", train if "skip" in comment: skip = True else: skip = False # print "skip", skip train_present = False repeat = self.find_between(comment, "[repeat-", "-repeat]") if repeat == "": repeat = "Once" # print "append" self.data.append([time, route, repeat, skip, train, train_description, False, False]) # print "appended" # print "populated" # delete rows with no trains # for row in reversed(range(len(self.data))): # if self.data[row][time_col] == None or self.data[row][dont_schedule_col] == "": # self.data.pop(row) def find_between(self, s, first, last): try: start = s.index(first) + len(first) end = s.index(last, start) return s[start:end] except ValueError: return "" except IndexError: return "Index Error H" def getColumnCount(self) : return len(self.columnNames) def getRowCount(self) : return len(self.data) def getColumnName(self, col) : return self.columnNames[col] def getValueAt(self, row, col) : return self.data[row][col] # return 'fred' def getColumnClass(self, col) : return java.lang.Boolean.getClass(self.getValueAt(0,col)) # return java.lang.Boolean.getClass("fred") #only include if table editable def isCellEditable(self, row, col) : # Note that the data/cell address is constant, # no matter where the cell appears onscreen. # cell_value = self.getValueAt(row, col) return True # only include if data can change. def setValueAt(self, value, row, col) : # print "row1", row, "col", col, "value", value if col == 0: # print "row2", row, "col", col, "value", value if not self.isValidTimeFormat(value): return # print "row", row, "col", col, "value", value self.data[row][col] = value self.fireTableCellUpdated(row, col) # if (isValidValue(aValue)) { # data[rowIndex][columnIndex] = aValue; # fireTableCellUpdated(rowIndex, columnIndex); // Notify the table # } def isValidTimeFormat(self, input_string): import re pattern = r"^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$" # Matches HH.MM format my_match = re.match(pattern, input_string) is not None # print "m", re.match(pattern, input_string) is not None # print "my_match", re.match(pattern, input_string) return my_match