class DialogPanel(Panel): manImage = None #image manImageSilent = None manLabel = None #label dialogText = None dialogTextScroller = None buttonsPanel = None def speak(self, text): self.dialogText.setText("") self.manLabel.setIcon(self.manImage) class Typer(threading.Thread): def __init__(thrd, text): threading.Thread.__init__(thrd) thrd.text = text def run(thrd): text = thrd.text for i in range(0, len(text)): if text[i] == '-': time.sleep(.05) pass self.dialogText.setText(self.dialogText.getText() + text[i]) time.sleep(.1) self.manLabel.setIcon(self.manImageSilent) Typer(text).start() def __init__(self, inconsolePanel): self.consolePanel = inconsolePanel Panel.__init__(self, "insets 0 0 0 0") self.speak( "My name is Captain danglewood! Help me find my lost crew in this hell pit of unix!!!" ) def initUI(self): self.manImage = ImageIcon('bin/gui/media/' + "danglewood.gif") self.manImageSilent = ImageIcon('bin/gui/media/' + "danglewood-silent.png") self.manLabel = JLabel(self.manImage) self.dialogText = JTextPane() self.dialogText.setEditable(False) self.dialogTextScroller = JScrollPane(self.dialogText) self.dialogText.setBackground(Color(0, 24, 0)) self.dialogText.setForeground(Color.WHITE) self.dialogText.setFont(Font("Arial", Font.BOLD, 15)) self.buttonsPanel = ButtonPanel(self.consolePanel, self) self.dialogText.setText("Welcome to BashED!!!") def addUI(self): self.add(self.buttonsPanel, "cell 0 0, pushy, growy") self.add(self.dialogTextScroller, "cell 1 0, push, grow") self.add(self.manLabel, "cell 2 0")
class ChatClient(JFrame): ## Constructor method, receives the variables from the ChatApp class as parameters def __init__(self, name, greeting, tn): '''Constructor, initialises base class & assigns variables ''' # Call to the super method to take care of the base class(es) super(ChatClient, self).__init__() # Assign the relevent variable names self.username=name self.greeting=greeting self.tn = tn self.no_users=[] # Initiate the Threaded function for receiving messages t1=Thread(target=self.recvFunction) # Set to daemon t1.daemon=True t1.start() #Call the main UI uI=self.clientUI() ## Main GUI building function def clientUI(self): '''ClientUI and Widget creation ''' # Colours foreground_colour = Color(30,57,68) background_colour = Color(247,246,242) window_background = Color(145,190,210) # Borders self.border2=BorderFactory.createLineBorder(foreground_colour,1, True) # Fonts self.font= Font("Ubuntu Light", Font.BOLD, 20) self.label_font= Font("Ubuntu Light", Font.BOLD, 17) self.label_2_font= Font( "Ubuntu Light",Font.BOLD, 12) self.btn_font=Font("Ubuntu Light", Font.BOLD, 15) # Set the layout parameters self.client_layout=GroupLayout(self.getContentPane()) self.getContentPane().setLayout(self.client_layout) self.getContentPane().setBackground(window_background) self.client_layout.setAutoCreateGaps(True) self.client_layout.setAutoCreateContainerGaps(True) self.setPreferredSize(Dimension(400, 450)) # Create widgets and assemble the GUI # Main display area self.main_content=JTextPane() self.main_content.setBackground(background_colour) #self.main_content.setForeground(foreground_colour) self.main_content.setEditable(False) # Message entry area self.message=JTextArea( 2,2, border=self.border2, font=self.label_font, keyPressed=self.returnKeyPress) self.message.requestFocusInWindow() self.message.setBackground(background_colour) self.message.setForeground(foreground_colour) self.message.setLineWrap(True) self.message.setWrapStyleWord(True) self.message.setBorder(BorderFactory.createEmptyBorder(3,3,3,3)) self.message.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0), self.returnKeyPress) # BUttons quit_btn=JButton("Quit!", actionPerformed=ChatApp().closeEvent, border=self.border2, font=self.btn_font) go_btn=JButton("Send", actionPerformed=self.grabText, border=self.border2, font=self.btn_font) quit_btn.setBackground(background_colour) go_btn.setBackground(background_colour) quit_btn.setForeground(foreground_colour) go_btn.setForeground(foreground_colour) # Make scrollable self.scroll_content=JScrollPane(self.main_content) self.scroll_content.setPreferredSize(Dimension(150,275)) self.scroll_content.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER) self.scroll_content.setViewportView(self.main_content) self.scroll_content.setBackground(Color.WHITE) self.scroll_message=JScrollPane(self.message) self.scroll_message.setPreferredSize(Dimension(150,20)) self.scroll_message.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS) # Test user label, still not updating after first round of messages self.user_label=JLabel(" Users online : %s "%(str(len(self.no_users))),JLabel.RIGHT, font=self.label_2_font) # Assemble the components # Horizontal layout self.client_layout.setHorizontalGroup(self.client_layout.createParallelGroup() .addComponent(self.scroll_content) .addGroup(self.client_layout.createParallelGroup(GroupLayout.Alignment.CENTER) .addComponent(self.scroll_message)) .addGroup(self.client_layout.createSequentialGroup() .addComponent(quit_btn) .addComponent(go_btn).addGap(20)) .addGroup(self.client_layout.createParallelGroup() .addComponent(self.user_label)) ) # Vertical layout self.client_layout.setVerticalGroup(self.client_layout.createSequentialGroup() .addGroup(self.client_layout.createParallelGroup() .addComponent(self.scroll_content)) .addComponent(self.scroll_message) .addGroup(self.client_layout.createParallelGroup() .addComponent(quit_btn) .addComponent(go_btn)) .addGroup(self.client_layout.createParallelGroup() .addComponent(self.user_label)) ) # Finalise the GUI self.client_layout.linkSize(SwingConstants.HORIZONTAL, [quit_btn,go_btn, self.user_label]) self.pack() self.message.requestFocusInWindow() self.setTitle(">>> Client %s <<<"%self.username) self.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) self.setLocationRelativeTo(None) self.setVisible(True) # Display the server greeting self.appendText('\n'+self.greeting+'\n') ## Function responsible for receiving and processing new messages def recvFunction(self): '''A function to control the receiving of data from the connection ''' # While the connection is available while self.tn: # Try to receive data using "<<<" as the delimiter try: message = self.tn.read_until('<<<') # If a message is received if message: garb, message=message.split('>>>') message, garb = message.split('<<<') message = ('\n'+message+'\n') # Call the append text function self.appendText(message) # Except if there is no data available except: #print('No message') pass ## Event driven function to retrieve and send data to the server def grabText(self, event): '''Function to repeatedly grab new messages entered into the text area and display them in the main text area. Resets the entry area ''' # Grab the text from the text area text=self.message.getText() # Don't allow an empty string through if text=='': return text=text.strip() # Call the append text function self.appendText('\nYou : '+text+'\n', self.username) # Reset the text to be empty and grab focus so that it is ready for new text input self.message.requestFocusInWindow() self.message.setText('') # Send the message to the server data=text.encode() self.tn.write(data+'\r\n') ## Function to handle appending of messages def appendText(self, message, user=None): '''This function takes care of appending any new messages to the content area ''' message_label=JTextArea(message,2,3, font=self.label_2_font) # If this is a message from the grab text function, create a new label, assign it's colours if user!=None: message_label.setBackground(Color(240,240,240)) message_label.setForeground(Color(129,129,129)) # Otherwise set the format for receive function (no user passed in) else: message_label.setBackground(Color(215,215,215)) message_label.setForeground(Color(40,153,153)) # Format and style options for the new message labels message_label.setEditable(False) message_label.setLineWrap(True) message_label.setWrapStyleWord(True) message_label.setBorder(BorderFactory.createLineBorder( Color(247,246,242),4)) # Sets the positioning of messages self.main_content.setCaretPosition(self.main_content.getDocument().getLength()) doc = self.main_content.getStyledDocument() attr=SimpleAttributeSet() self.main_content.insertComponent(message_label) # Essential for jtextarea to be able to stack message doc.insertString( self.main_content.getDocument().getLength(),'\n ', attr) # Not sure if needed self.main_content.repaint() ### This is a late edit so it isn't included in the documentation. Basically trying to dynamically update the number ### of users label at runtime. Works for incrementing the value but not decrementing it. print(message) # Only split the message if there are enough values to split (greeting messages differ in format to chat messages) try: user, text=message.split(' : ') except: return #print('Split values are %s %s'%(user, text)) user=str(user.strip()) #print(self.no_users) #print(user+' : '+text) # If the user already in the list, pass if user in self.no_users: if text == ('User %s amach sa teach !'%user): self.no_users.remove(user) print('User % removed'%user) else: #print('User %s not in list'%user) if str(user) == 'You': #print('User is equal to "You"') return self.no_users.append(user) print('User appended') self.number_users=len(self.no_users) #print('Length of user list is '+str(self.number_users)) self.user_label2=JLabel(" Users online : %s "%str(len(self.no_users)),JLabel.RIGHT, font=self.label_2_font) #print('Label created') #print('Attempt to replace label') self.client_layout.replace(self.user_label, self.user_label2) self.user_label = self.user_label2 self.user_label.repaint() self.user_label.revalidate() print('Label updated') ## Function to control return button press in message field def returnKeyPress(self,event): '''This function creates an object for return key press when inside the message entry area, creates an object of KeyAdapter and tests keycode for a match, responds with grab text callback ''' key_object=Key() key_value=key_object.keyPressed(event) if key_value == 10: self.grabText(event)
class InductionApplet(JApplet): def init(self): global exampleList self.thinFont = Font("Dialog", 0, 10) self.pane = self.getContentPane() self.examples = exampleList.keys() self.examples.sort() self.exampleSelector = JList(self.examples, valueChanged=self.valueChanged) self.exampleSelector.setSelectionMode(ListSelectionModel.SINGLE_SELECTION) self.exampleSelector.setLayoutOrientation(JList.VERTICAL) self.exampleSelector.setPreferredSize(Dimension(150,500)) self.exampleSelector.setBackground(Color(0.95, 0.95, 0.98)) self.exampleSelector.setFont(self.thinFont) self.centerPanel = JPanel(BorderLayout()) self.canvas = GraphCanvas() self.canvas.setApplet(self) self.buttonRow = JPanel(FlowLayout()) self.backButton = JButton("<", actionPerformed = self.backAction) self.backButton.setFont(self.thinFont) self.continueButton = JButton("continue >", actionPerformed=self.continueAction) self.continueButton.setFont(self.thinFont) self.scaleGroup = ButtonGroup() self.linearButton = JRadioButton("linear scale", actionPerformed=self.linearAction) self.linearButton.setSelected(True) self.linearButton.setFont(self.thinFont) self.logarithmicButton = JRadioButton("logarithmic scale", actionPerformed=self.logarithmicAction) self.logarithmicButton.setFont(self.thinFont) self.aboutButton = JButton("About...", actionPerformed=self.aboutAction) self.aboutButton.setFont(self.thinFont) self.scaleGroup.add(self.linearButton) self.scaleGroup.add(self.logarithmicButton) self.buttonRow.add(self.backButton) self.buttonRow.add(self.continueButton) self.buttonRow.add(JLabel(" "*5)) self.buttonRow.add(self.linearButton) self.buttonRow.add(self.logarithmicButton) self.buttonRow.add(JLabel(" "*20)); self.buttonRow.add(self.aboutButton) self.centerPanel.add(self.canvas, BorderLayout.CENTER) self.centerPanel.add(self.buttonRow, BorderLayout.PAGE_END) self.helpText = JTextPane() self.helpText.setBackground(Color(1.0, 1.0, 0.5)) self.helpText.setPreferredSize(Dimension(800,80)) self.helpText.setText(re_sub("[ \\n]+", " ", """ Please select one of the examples in the list on the left! """)) self.pane.add(self.exampleSelector, BorderLayout.LINE_START) self.pane.add(self.centerPanel, BorderLayout.CENTER) self.pane.add(self.helpText, BorderLayout.PAGE_END) self.graph = None self.simulation = None self.touched = "" self.selected = "" self.gfxDriver = None def start(self): self.gfxDriver = awtGfx.Driver(self.canvas) #self.gfxDriver.setAntialias(True) if self.gfxDriver.getSize()[0] < 200: # konqueror java bug work around self.gfxDriver.w = 650 self.gfxDriver.h = 380 self.graph = Graph.Cartesian(self.gfxDriver, 1, 0.0, 1000, 1.0, title="Results", xaxis="Rounds", yaxis="Success Rate") def stop(self): pass def destroy(self): pass def refresh(self): if self.graph != None: self.graph.redraw() def valueChanged(self, e): global exampleList newSelection = self.examples[self.exampleSelector.getSelectedIndex()] if newSelection != self.touched: self.touched = newSelection text = re_sub("[ \\n]+", " ", exampleList[self.touched][-1]) self.helpText.setText(text) if not e.getValueIsAdjusting() and newSelection != self.selected: self.selected = newSelection smallFontPen = copy.copy(Gfx.BLACK_PEN) smallFontPen.fontSize = Gfx.SMALL ex = exampleList[self.selected] myStyleFlags = self.graph.styleFlags if self.simulation != None: self.simulation.stop() self.gfxDriver.resizedGfx() # konqueror 3.5.5 java bug workaround self.graph = Graph.Cartesian(self.gfxDriver, 1, 0.0, ex[3], 1.0, title=ex[0], xaxis="Rounds", yaxis="Success Rate", styleFlags = myStyleFlags, axisPen = smallFontPen, captionPen = smallFontPen) self.zoomFrame = [(1, 0.0, ex[3], 1.0)] self.simulation = Simulation(self.graph, ex[1], ex[2], ex[3], ex[4]) RunAsThread(self.simulation.simulation).start() def determineCurrentZoomFrame(self): i = 0 for zf in self.zoomFrame: if self.graph.x2 <= zf[2]: break i += 1 return i def backAction(self, e): if self.simulation == None: return wasRunning = self.simulation.isRunning self.simulation.stop() if wasRunning or len(self.zoomFrame) <= 1: return zi = self.determineCurrentZoomFrame() if zi > 0 and zi < len(self.zoomFrame): x1, y1, x2, y2 = self.zoomFrame[zi-1] self.graph.adjustRange(x1, y1, x2, y2) def continueAction(self, e): if self.simulation == None: return wasRunning = self.simulation.isRunning self.simulation.stop() zi = self.determineCurrentZoomFrame() if zi == len(self.zoomFrame)-1: if wasRunning or self.simulation.world.round == self.zoomFrame[zi][2]: if self.graph.styleFlags & Graph.LOG_X == 0: self.simulation.rounds *= 2 else: self.simulation.rounds *= 10 self.zoomFrame.append((1, 0.0, self.simulation.rounds, 1.0)) self.graph.adjustRange(1, 0.0, self.simulation.rounds, 1.0) RunAsThread(self.simulation.simulation).start() else: x1, y1, x2, y2 = self.zoomFrame[zi+1] self.graph.adjustRange(x1, y1, x2, y2) def linearAction(self, e): if self.graph != None and (self.graph.styleFlags & Graph.LOG_X) != 0: if self.simulation != None: self.simulation.stop() self.graph.setStyle(self.graph.styleFlags & ~Graph.LOG_X, redraw=True) if self.simulation != None: RunAsThread(self.simulation.simulation).start() def logarithmicAction(self, e): if self.graph != None and (self.graph.styleFlags & Graph.LOG_X) == 0: if self.simulation != None: self.simulation.stop() self.graph.setStyle(self.graph.styleFlags | Graph.LOG_X, redraw=True) if self.simulation != None: RunAsThread(self.simulation.simulation).start() def aboutAction(self, e): aboutText = """Induction Applet v. 0.1 (c) 2007 University of Düsseldorf Authors: Gerhard Schurz, Eckhart Arnold """ aboutText = re_sub(" +", " ", aboutText) JOptionPane.showMessageDialog(self.getContentPane(), aboutText)