Esempio n. 1
0
 def fillPanel(self, question):
     self.pnlQuestion.removeAll()
     if question.getKind() == 2:
         panel = TrueFalsePanel(question).getPanel()
     elif question.getKind() == 3:
         panel = MultipleChoicePanel(question).getPanel()
     scrollpanel = JScrollPane(panel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED)
     scrollpanel.setBorder(None)
     self.pnlQuestion.add(scrollpanel, BorderLayout.CENTER)
     self.pnlQuestion.updateUI()
Esempio n. 2
0
 def __fillQuestions(self):
   panel = JPanel()
   panel.setLayout(GridBagLayout())
   panel.setBorder(None)
   c = GridBagConstraints()
   c.gridx = 0
   c.gridy = 0
   c.weightx = 1.0
   c.fill = GridBagConstraints.HORIZONTAL
   c.anchor = GridBagConstraints.PAGE_START
   line = 0
   for question in self.test.getQuestions():
     c.gridy = line
     panel.add(question.getPanel().asJComponent(),c)
     line += 1
   scrollPanel = JScrollPane(panel)
   scrollPanel.setBorder(None)
   self.questionsContainer.setLayout(BorderLayout())
   self.questionsContainer.add(scrollPanel, BorderLayout.CENTER)
Esempio n. 3
0
    def _initUI(self):
        frame = JFrame('Simple popup',
                       defaultCloseOperation=JFrame.DISPOSE_ON_CLOSE,
                       size=(300, 300))
        frame.setLayout(BoxLayout(frame.contentPane, BoxLayout.PAGE_AXIS))

        # Call-back to close popup
        def closeDialog(event):
            frame.visible = False
            frame.dispose()

        # Instantiate components
        self.text_area = JTextArea()
        msgScroller = JScrollPane()
        msgScroller.setBorder(BorderFactory.createTitledBorder("Accounts"))
        msgScroller.setViewportView(self.text_area)
        self.close_button = JButton('Close', actionPerformed=closeDialog)

        # Add components to frame
        frame.add(msgScroller)
        frame.add(self.close_button)
        frame.visible = True
Esempio n. 4
0
    def registerExtenderCallbacks(self, callbacks):
        # smart xss feature (print conclusion and observation)
        # mark resulsts
        # add automatic check pages in the same domain

        self.tagPayloads = [
            "<b>test", "<b onmouseover=test()>test",
            "<img src=err onerror=test()>", "<script>test</script>"
            "", "<scr ipt>test</scr ipt>", "<SCRIPT>test;</SCRIPT>",
            "<scri<script>pt>test;</scr</script>ipt>",
            "<SCRI<script>PT>test;</SCR</script>IPT>",
            "<scri<scr<script>ipt>pt>test;</scr</sc</script>ript>ipt>",
            "<IMG \"\"\"><SCRIPT>test</SCRIPT>\">",
            "<IMG '''><SCRIPT>test</SCRIPT>'>", "<SCR%00IPT>test</SCR%00IPT>",
            "<IFRAME SRC='f' onerror=\"test\"></IFRAME>",
            "<IFRAME SRC='f' onerror='test'></IFRAME>",
            "<<SCRIPT>test//<</SCRIPT>", "<img src=\"1\" onerror=\"test\">",
            "<img src='1' onerror='test'",
            "<STYLE TYPE=\"text/javascript\">test;</STYLE>",
            "<<SCRIPT>test//<</SCRIPT>"
        ]
        self.attributePayloads = [
            "\"\"\"><SCRIPT>test", "'''><SCRIPT>test'",
            "\"><script>test</script>", "\"><script>test</script><\"",
            "'><script>test</script>", "'><script>test</script><'",
            "\";test;\"", "';test;'", ";test;", "\";test;//",
            "\"onmouseover=test ", "onerror=\"test\"", "onerror='test'",
            "onload=\"test\"", "onload='test'"
        ]
        self.xssKey = 'xssme'
        # keep a reference to our callbacks object
        self._callbacks = callbacks

        # obtain an extension helpers object
        self._helpers = callbacks.getHelpers()

        # set our extension name
        callbacks.setExtensionName("XSSor")

        self.affectedResponses = ArrayList()
        self._log = ArrayList()
        self._lock = Lock()

        # main split pane
        self._splitpane = JSplitPane(JSplitPane.HORIZONTAL_SPLIT)

        # table of log entries
        logTable = Table(self)
        scrollPane = JScrollPane(logTable)
        self._splitpane.setLeftComponent(scrollPane)

        # tabs with request/response viewers
        tabs = JTabbedPane()
        self._requestViewer = callbacks.createMessageEditor(self, False)
        self._responseViewer = callbacks.createMessageEditor(self, False)
        tabs.addTab("Request", self._requestViewer.getComponent())
        tabs.addTab("Response", self._responseViewer.getComponent())

        clearAPListBtn = JButton("Clear List",
                                 actionPerformed=self.clearAPList)
        clearAPListBtn.setBounds(10, 85, 120, 30)
        apListLabel = JLabel('Affected Pages List:')
        apListLabel.setBounds(10, 10, 140, 30)
        self.affectedModel = DefaultListModel()
        self.affectedList = JList(self.affectedModel)
        self.affectedList.addListSelectionListener(listSelectedChange(self))
        scrollAList = JScrollPane(self.affectedList)
        scrollAList.setVerticalScrollBarPolicy(
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
        scrollAList.setBounds(150, 10, 550, 200)
        scrollAList.setBorder(LineBorder(Color.BLACK))

        APtabs = JTabbedPane()
        self._requestAPViewer = callbacks.createMessageEditor(self, False)
        self._responseAPViewer = callbacks.createMessageEditor(self, False)
        APtabs.addTab("Request", self._requestAPViewer.getComponent())
        APtabs.addTab("Affeced Page Response",
                      self._responseAPViewer.getComponent())
        APtabs.setBounds(0, 250, 700, 350)
        APtabs.setSelectedIndex(1)

        self.APpnl = JPanel()
        self.APpnl.setBounds(0, 0, 1000, 1000)
        self.APpnl.setLayout(None)
        self.APpnl.add(scrollAList)
        self.APpnl.add(clearAPListBtn)
        self.APpnl.add(APtabs)
        self.APpnl.add(apListLabel)
        tabs.addTab("Affected Pages", self.APpnl)
        self.intercept = 0

        ## init conf panel
        startLabel = JLabel("Plugin status:")
        startLabel.setBounds(10, 10, 140, 30)

        payloadLabel = JLabel("Basic Payload:")
        payloadLabel.setBounds(10, 50, 140, 30)

        self.basicPayload = "<script>alert(1)</script>"
        self.basicPayloadTxt = JTextArea(self.basicPayload, 5, 30)
        self.basicPayloadTxt.setBounds(120, 50, 305, 30)

        self.bruteForceMode = JCheckBox("Brute Force Mode")
        self.bruteForceMode.setBounds(120, 80, 300, 30)
        self.bruteForceMode.addItemListener(handleBFModeChange(self))

        self.tagPayloadsCheck = JCheckBox("Tag paylods")
        self.tagPayloadsCheck.setBounds(120, 100, 300, 30)
        self.tagPayloadsCheck.setSelected(True)
        self.tagPayloadsCheck.setEnabled(False)
        self.tagPayloadsCheck.addItemListener(handleBFModeList(self))

        self.attributePayloadsCheck = JCheckBox("Attribute payloads")
        self.attributePayloadsCheck.setBounds(260, 100, 300, 30)
        self.attributePayloadsCheck.setSelected(True)
        self.attributePayloadsCheck.setEnabled(False)
        self.attributePayloadsCheck.addItemListener(handleBFModeList(self))

        payloadListLabel = JLabel("Payloads list (for BF mode):")
        payloadListLabel.setBounds(10, 130, 140, 30)

        self.payloadsModel = DefaultListModel()
        self.payloadsList = JList(self.payloadsModel)
        scrollPayloadsList = JScrollPane(self.payloadsList)
        scrollPayloadsList.setVerticalScrollBarPolicy(
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
        scrollPayloadsList.setBounds(120, 170, 300, 200)
        scrollPayloadsList.setBorder(LineBorder(
            Color.BLACK))  # add buttons to remove payloads and add

        for payload in self.tagPayloads:
            self.payloadsModel.addElement(payload)

        for payload in self.attributePayloads:
            self.payloadsModel.addElement(payload)

        self.startButton = JButton("XSSor is off",
                                   actionPerformed=self.startOrStop)
        self.startButton.setBounds(120, 10, 120, 30)
        self.startButton.setBackground(Color(255, 100, 91, 255))

        consoleTab = JTabbedPane()
        self.consoleLog = JTextArea("", 5, 30)
        scrollLog = JScrollPane(self.consoleLog)
        scrollLog.setVerticalScrollBarPolicy(
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
        scrollLog.setBounds(120, 170, 550, 200)
        scrollLog.setBorder(LineBorder(Color.BLACK))
        scrollLog.getVerticalScrollBar().addAdjustmentListener(
            autoScrollListener(self))
        consoleTab.addTab("Console", scrollLog)
        consoleTab.setBounds(0, 400, 500, 200)

        self.pnl = JPanel()
        self.pnl.setBounds(0, 0, 1000, 1000)
        self.pnl.setLayout(None)
        self.pnl.add(self.startButton)
        self.pnl.add(startLabel)
        self.pnl.add(payloadLabel)
        self.pnl.add(self.basicPayloadTxt)
        self.pnl.add(self.bruteForceMode)
        self.pnl.add(payloadListLabel)
        self.pnl.add(scrollPayloadsList)
        self.pnl.add(self.attributePayloadsCheck)
        self.pnl.add(self.tagPayloadsCheck)
        self.pnl.add(consoleTab)

        tabs.addTab("Configuration", self.pnl)
        tabs.setSelectedIndex(3)
        self._splitpane.setRightComponent(tabs)

        # customize our UI components
        callbacks.customizeUiComponent(self._splitpane)
        callbacks.customizeUiComponent(logTable)
        callbacks.customizeUiComponent(scrollPane)
        callbacks.customizeUiComponent(tabs)

        # add the custom tab to Burp's UI
        callbacks.addSuiteTab(self)

        # register ourselves as an HTTP listener
        callbacks.registerHttpListener(self)
        self._callbacks.registerContextMenuFactory(self)

        print "Thank you for installing XSSor v0.1 extension"
        print "Created by Barak Tawily"
        print "\nGithub:\nhttps://github.com/Quitten/XSSor"
        return
Esempio n. 5
0
    def draw(self):
        """ init the match/replace tab
        """
        #todo add an option to ignore large requests
        padding = 5
        labelWidth = 140
        labelHeight = 30
        editHeight = 110
        editWidth = 300
        buttonWidth = 120
        buttonHeight = 30
        column1X = 10
        column2X = column1X + labelWidth + padding
        column3X = column2X + editWidth + padding
        MRStrings = [
            "Headers (simple string):", "Headers (regex):",
            "Body (simple string):", "Body (regex):"
        ]
        row1Y = 10
        row2Y = row1Y + labelHeight + padding
        row3Y = row2Y + editHeight + padding
        row4Y = row3Y + editHeight + padding
        row5Y = row4Y + labelHeight + padding
        row6Y = row5Y + buttonHeight + padding

        MRTypeLabel = JLabel("Type:")
        MRTypeLabel.setBounds(column1X, row1Y, labelWidth, labelHeight)

        MContent = JLabel("Match:")
        MContent.setBounds(column1X, row2Y, labelWidth, labelHeight)

        RContent = JLabel("Replace:")
        RContent.setBounds(column1X, row3Y, labelWidth, labelHeight)

        MRLabelList = JLabel("Filter List:")
        MRLabelList.setBounds(column1X, row5Y, labelWidth, labelHeight)

        self._extender.MRType = JComboBox(MRStrings)
        self._extender.MRType.setBounds(column2X, row1Y, editWidth,
                                        labelHeight)

        self._extender.MText = JTextArea("", 5, 30)
        scrollMText = JScrollPane(self._extender.MText)
        scrollMText.setVerticalScrollBarPolicy(
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
        scrollMText.setBounds(column2X, row2Y, editWidth, editHeight)

        self._extender.RText = JTextArea("", 5, 30)
        scrollRText = JScrollPane(self._extender.RText)
        scrollRText.setVerticalScrollBarPolicy(
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
        scrollRText.setBounds(column2X, row3Y, editWidth, editHeight)

        # i couldn't figure out how to have a model that contained anythin other than a string
        # so i'll use 2 models, one with the data and one for the JList
        self._extender.badProgrammerMRModel = {}
        self._extender.MRModel = DefaultListModel()
        self._extender.MRList = JList(self._extender.MRModel)

        scrollMRList = JScrollPane(self._extender.MRList)
        scrollMRList.setVerticalScrollBarPolicy(
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
        scrollMRList.setBounds(column2X, row5Y, editWidth, editHeight)
        scrollMRList.setBorder(LineBorder(Color.BLACK))

        self._extender.MRAdd = JButton("Add filter",
                                       actionPerformed=self.addMRFilter)
        self._extender.MRAdd.setBounds(column2X, row4Y, buttonWidth,
                                       buttonHeight)
        self._extender.MRDel = JButton("Remove filter",
                                       actionPerformed=self.delMRFilter)
        self._extender.MRDel.setBounds(column3X, row5Y, buttonWidth,
                                       buttonHeight)
        self._extender.MRMod = JButton("Modify filter",
                                       actionPerformed=self.modMRFilter)
        self._extender.MRMod.setBounds(column3X,
                                       row5Y + buttonHeight + padding,
                                       buttonWidth, buttonHeight)

        self._extender.MRFeedback = JLabel("")
        self._extender.MRFeedback.setBounds(column1X, row6Y,
                                            column3X + buttonWidth,
                                            labelHeight)

        self._extender.MRPnl = JPanel()
        self._extender.MRPnl.setLayout(None)
        self._extender.MRPnl.setBounds(0, 0, 1000, 1000)
        self._extender.MRPnl.add(MRTypeLabel)
        self._extender.MRPnl.add(self._extender.MRType)
        self._extender.MRPnl.add(MContent)
        self._extender.MRPnl.add(scrollMText)
        self._extender.MRPnl.add(RContent)
        self._extender.MRPnl.add(scrollRText)
        self._extender.MRPnl.add(self._extender.MRAdd)
        self._extender.MRPnl.add(MRLabelList)
        self._extender.MRPnl.add(scrollMRList)
        self._extender.MRPnl.add(self._extender.MRDel)
        self._extender.MRPnl.add(self._extender.MRMod)
        self._extender.MRPnl.add(self._extender.MRFeedback)
Esempio n. 6
0
    def draw(self):
        """  init interception filters tab
        """
        self._extender.savedHeaders = [{"title": "Temporary headers", "headers": "Cookie: Insert=injected; cookie=or;\nHeader: here"}]
        # IFStrings has to contains : character
        IFStrings = ["Scope items only: (Content is not required)", 
                     "URL Contains (simple string): ",
                     "URL Contains (regex): ",
                     "URL Not Contains (simple string): ",
                     "URL Not Contains (regex): ",
                     "Only HTTP methods (newline separated): ",
                     "Ignore HTTP methods (newline separated): ",
                     "Ignore spider requests: (Content is not required)",
                     "Ignore proxy requests: (Content is not required)",
                     "Ignore target requests: (Content is not required)"]
        self._extender.IFType = JComboBox(IFStrings)
        self._extender.IFType.setBounds(80, 10, 430, 30)
       
        self._extender.IFModel = DefaultListModel()
        self._extender.IFList = JList(self._extender.IFModel)

        scrollIFList = JScrollPane(self._extender.IFList)
        scrollIFList.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
        scrollIFList.setBounds(80, 175, 300, 110)
        scrollIFList.setBorder(LineBorder(Color.BLACK))

        # Adding some default interception filters
        # self.IFModel.addElement("Scope items only: (Content is not required)") # commented for better first impression.
        self._extender.IFModel.addElement("URL Not Contains (regex): \\.js|\\.css|\\.png|\\.jpg|\\.svg|\\.jpeg|\\.gif|\\.woff|\\.map|\\.bmp|\\.ico$")
        self._extender.IFModel.addElement("Ignore spider requests: ")
        
        self._extender.IFText = JTextArea("", 5, 30)

        scrollIFText = JScrollPane(self._extender.IFText)
        scrollIFText.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
        scrollIFText.setBounds(80, 50, 300, 110)

        IFLType = JLabel("Type:")
        IFLType.setBounds(10, 10, 140, 30)

        IFLContent = JLabel("Content:")
        IFLContent.setBounds(10, 50, 140, 30)

        IFLabelList = JLabel("Filter List:")
        IFLabelList.setBounds(10, 165, 140, 30)

        self._extender.IFAdd = JButton("Add filter", actionPerformed=self.addIFFilter)
        self._extender.IFAdd.setBounds(390, 85, 120, 30)
        self._extender.IFDel = JButton("Remove filter", actionPerformed=self.delIFFilter)
        self._extender.IFDel.setBounds(390, 210, 120, 30)
        self._extender.IFMod = JButton("Modify filter", actionPerformed=self.modIFFilter)
        self._extender.IFMod.setBounds(390, 250, 120, 30)

        self._extender.filtersPnl = JPanel()
        self._extender.filtersPnl.setLayout(None)
        self._extender.filtersPnl.setBounds(0, 0, 1000, 1000)
        self._extender.filtersPnl.add(IFLType)
        self._extender.filtersPnl.add(self._extender.IFType)
        self._extender.filtersPnl.add(IFLContent)
        self._extender.filtersPnl.add(scrollIFText)
        self._extender.filtersPnl.add(self._extender.IFAdd)
        self._extender.filtersPnl.add(self._extender.IFDel)
        self._extender.filtersPnl.add(self._extender.IFMod)
        self._extender.filtersPnl.add(IFLabelList)
        self._extender.filtersPnl.add(scrollIFList)
Esempio n. 7
0
    def draw_unauthenticated(self):
        """ init enforcement detector tab
        """

        EDLType = JLabel("Type:")
        EDLType.setBounds(10, 10, 140, 30)

        EDLContent = JLabel("Content:")
        EDLContent.setBounds(10, 50, 140, 30)

        EDLabelList = JLabel("Filter List:")
        EDLabelList.setBounds(10, 165, 140, 30)

        EDStrings = [
            "Headers (simple string): (enforced message headers contains)",
            "Headers (regex): (enforced message headers contains)",
            "Body (simple string): (enforced message body contains)",
            "Body (regex): (enforced message body contains)",
            "Full response (simple string): (enforced message contains)",
            "Full response (regex): (enforced message contains)",
            "Full response length: (of enforced response)",
            "Status code equals: (numbers only)"
        ]
        self._extender.EDTypeUnauth = JComboBox(EDStrings)
        self._extender.EDTypeUnauth.setBounds(80, 10, 430, 30)

        self._extender.EDTextUnauth = JTextArea("", 5, 30)

        scrollEDTextUnauth = JScrollPane(self._extender.EDTextUnauth)
        scrollEDTextUnauth.setVerticalScrollBarPolicy(
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
        scrollEDTextUnauth.setBounds(80, 50, 300, 110)

        self._extender.EDModelUnauth = DefaultListModel()
        self._extender.EDListUnauth = JList(self._extender.EDModelUnauth)

        scrollEDListUnauth = JScrollPane(self._extender.EDListUnauth)
        scrollEDListUnauth.setVerticalScrollBarPolicy(
            JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED)
        scrollEDListUnauth.setBounds(80, 175, 300, 110)
        scrollEDListUnauth.setBorder(LineBorder(Color.BLACK))

        self._extender.EDAddUnauth = JButton(
            "Add filter", actionPerformed=self.addEDFilterUnauth)
        self._extender.EDAddUnauth.setBounds(390, 85, 120, 30)
        self._extender.EDDelUnauth = JButton(
            "Remove filter", actionPerformed=self.delEDFilterUnauth)
        self._extender.EDDelUnauth.setBounds(390, 210, 120, 30)
        self._extender.EDModUnauth = JButton(
            "Modify filter", actionPerformed=self.modEDFilterUnauth)
        self._extender.EDModUnauth.setBounds(390, 250, 120, 30)

        AndOrStrings = ["And", "Or"]
        self._extender.AndOrTypeUnauth = JComboBox(AndOrStrings)
        self._extender.AndOrTypeUnauth.setBounds(390, 170, 120, 30)

        self._extender.EDPnlUnauth = JPanel()
        self._extender.EDPnlUnauth.setLayout(None)
        self._extender.EDPnlUnauth.setBounds(0, 0, 1000, 1000)
        self._extender.EDPnlUnauth.add(EDLType)
        self._extender.EDPnlUnauth.add(self._extender.EDTypeUnauth)
        self._extender.EDPnlUnauth.add(EDLContent)
        self._extender.EDPnlUnauth.add(scrollEDTextUnauth)
        self._extender.EDPnlUnauth.add(self._extender.EDAddUnauth)
        self._extender.EDPnlUnauth.add(self._extender.AndOrTypeUnauth)
        self._extender.EDPnlUnauth.add(self._extender.EDDelUnauth)
        self._extender.EDPnlUnauth.add(self._extender.EDModUnauth)
        self._extender.EDPnlUnauth.add(EDLabelList)
        self._extender.EDPnlUnauth.add(scrollEDListUnauth)
Esempio n. 8
0
class StockGlance75():
#    print "StockGlance75"
    import java.awt.Color as Color
    import java.util.Vector as Vector
    import java.util.Arrays as Arrays
    import javax.swing.table.DefaultTableModel as DefaultTableModel
    import javax.swing.JTable as JTable
    
    
    book = None # AccountBook()
    table = None # StockGlance75.SGTable()
    tableModel = None  # StockGlance75.SGTableModel
    tablePanel = None # SGPanel()
    footerTable = None # StockGlance75.SGFooterTable
    footerModel = None # StockGlance75.SGFooterModel
#    scrollPane = None
    totalBalance = None # total of all Stock.Securities in all Accounts 
#    currencyTableCallback = None # currencyCallback(self)
#    allAccountsCallback = None # accountCallback(self)
#    refresher = None # CollapsibleRefresher()
    lightLightGray = Color(0xDCDCDC)
    rowCurrencies = Vector()   #  list of security names in the rows (like a row header)
    footer = Vector() # one row of footer data
    data = Vector() # the data retrieved from moneydance
    #  Per column metadata
    names = ["Symbol", "Stock", "Price", "Change", "Balance", "Day", "7 Day", "30 Day", "365 Day", "Accounts"]
    columnNames = Vector(Arrays.asList(names))
#    footerNames = ["", "", "", "", "Total", "", "", "", "", ""]
#    FooterNames = Vector(Arrays.asList(footerNames))
    
    columnTypes = ["Text", "Text", "Currency2", "Currency2", "Currency0", "Percent", "Percent", "Percent", "Percent", "Text"]

    #  Returns a short descriptive name of this view.
    def __str__(self):
        """ generated source for method toString """
        return "Stock Glance"

    # Returns a GUI component that provides a view of the info pane for the given data file.
    # w.s. must be called by Moneydance .. seems like this is how "book" gets set
#    @make_synchronized
#    def getGUIView(self, book): # replaced by createAndShowGUI(self):
#        print("getGUIView") 
#        if self.tablePanel == None:
#            self.book = book
#            self.tableModel = self.getTableModel(book)
#            print "table before",self.table
#            self.table = self.SGTable(self.tableModel)
#            self.scrollPane = JScrollPane(self.table)         
##            self.scrollPane = self.SGScrollPane(self.table)         
##            self.tablePanel = self.SGPanel(self.table)
##        return self.tablePanel
#        return self.scrollPane

    #  Sets the view as active or inactive. When not active, a view should not have any registered listeners
    #  with other parts of the program. This will be called when an view is added to the home page,
    #  or the home page is refreshed after not being visible for a while.
#    def setActive(self, active):
#        print 'setActive'
#        """ generated source for method setActive """
##        if self.book != None:
##            self.book.getCurrencies().removeCurrencyListener(self.currencyTableCallback)
##            #  At most one listener
##            self.book.removeAccountListener(self.allAccountsCallback)
##            if active:
##                self.book.getCurrencies().addCurrencyListener(self.currencyTableCallback)
##                self.book.addAccountListener(self.allAccountsCallback)

    #  Forces a refresh of the information in the view. For example, this is called after the preferences are updated.
    #  Like the other home page controls, we actually do this lazily to avoid repeatedly recalculating after stock
    #  price updates.
#    def refresh(self):
#        print("refresh")
#        self.refresher.enqueueRefresh()

    #  Actually recompute and redisplay table.
#    def actuallyRefresh(self):  # this function knocks out the TableRowSorter and messes with the Column Headers (i think)
#        print "actuallyRefresh"
## ?        synchronized (this) {
#        tableModel = self.getTableModel(self.book)
#        if self.table != None:
#            self.table.setModel(tableModel)
#            self.table.fixColumnHeaders()
#            self.fixTheRowSorter()
#        # ?        }
#        if self.tablePanel != None:
#            self.tablePanel.setVisible(True)
#            self.tablePanel.validate()

    #  Called when the view should clean up everything. For example, this is called when a file is closed and the GUI
    #  is reset. The view should disconnect from any resources that are associated with the currently opened data file.
#    def reset(self):
#        print "reset"
#        self.setActive(False)
#        if self.tablePanel != None:
#            self.tablePanel.removeAll()
#        self.tablePanel = None
#        self.table = None

    # 
    #  Implementation:
    #  pulls the data from moneydance into data Vector , returns an SGTableModel
    def getTableModel(self, book):
#        print "getTableModel book",book
        import java.util.Vector as Vector
        import java.util.Arrays as Arrays
        import java.util.Calendar as Calendar
        import com.infinitekind.moneydance.model.CurrencyType as CurrencyType
        import java.lang.Double as Double

        ct = book.getCurrencies()
        allCurrencies = ct.getAllCurrencies()
        data = Vector()
        today = Calendar.getInstance()
        balances = self.sumBalancesByCurrency(book) # HashMap<CurrencyType, Long>  contains no account info
        accounts = self.getCurrencyAccounts(book) # HashMap<CurrencyType, Accounts>
        self.totalBalance = 0.0
#        StockGlance75.totalBalance = 0.0
        for curr in allCurrencies:
            if not curr.getHideInUI() and curr.getCurrencyType() == CurrencyType.Type.SECURITY:
                price = self.priceOrNaN(curr, today, 0)
                price1 = self.priceOrNaN(curr, today, 1)
                price7 = self.priceOrNaN(curr, today, 7)
                price30 = self.priceOrNaN(curr, today, 30)
                price365 = self.priceOrNaN(curr, today, 365)
	      
                if not Double.isNaN(price) and (not Double.isNaN(price1) or not Double.isNaN(price7) or not Double.isNaN(price30) or not Double.isNaN(price365)):
		    entry = Vector(len(self.names))
                    bal = balances.get(curr)
                    balance = (0.0 if (bal == None) else curr.getDoubleValue(bal) * price)
# ?                    Double balance = (bal == null) ? 0.0 : curr.getDoubleValue(bal) * price;		        
                    self.totalBalance += balance
#                    StockGlance75.totalBalance += balance
                    entry.add(curr.getTickerSymbol())
                    entry.add(curr.getName())
                    entry.add(price)
                    entry.add(price - price1)
                    entry.add(balance)
                    entry.add((price - price1) / price1)
                    entry.add((price - price7) / price7)
                    entry.add((price - price30) / price30)
                    entry.add((price - price365) / price365)
                    entry.add(accounts.get(curr))
                    data.add(entry)
                    self.rowCurrencies.add(curr)
#                    StockGlance75.rowCurrencies.add(curr)
        self.data = data            
#        StockGlance75.data = data            
        return self.SGTableModel(self.data, self.columnNames, self.rowCurrencies)
#        return StockGlance75.SGTableModel(StockGlance75.data, self.columnNames, self.rowCurrencies)

    def getFooterModel(self):
#        print "getFooterModel "
        import java.util.Vector as Vector
        import java.util.Arrays as Arrays

        entry = Vector(len(self.names)) # its 10 columns
        entry.add("Total")
        entry.add(None)
        entry.add(None)
        entry.add(None)
#        entry.add(StockGlance75.totalBalance)
        entry.add(self.totalBalance)
        entry.add(None)
        entry.add(None)
        entry.add(None)
        entry.add(None)
        entry.add(None)
        self.footer.clear()
        self.footer.add(entry) # needs to be an list of lists (Vector of Vectors)
        return self.SGFooterModel(self.footer,self.columnNames)
#        StockGlance75.footer.clear()
#        StockGlance75.footer.add(entry) # needs to be an list of lists (Vector of Vectors)
#        return StockGlance75.SGFooterModel(StockGlance75.footer,StockGlance75.columnNames)


    def priceOrNaN(self, curr, date, delta):
        import java.lang.Double as Double
        try:
	    backDate = self.backDays(date, delta)
            if self.haveSnapshotWithinWeek(curr, backDate):
                return 1.0 / curr.adjustRateForSplitsInt(backDate, curr.getUserRateByDateInt(backDate))
            else:
                return Double.NaN
        except ZeroDivisionError as e: 
	              return Double.NaN
        except IndexError as e: 
                      return Double.NaN

    #  Return the date that is delta days before startDate
    def backDays(self, startDate, delta):
        import java.util.Calendar as Calendar     
        import com.infinitekind.util.DateUtil as DateUtil
        
        newDate = startDate.clone()
        newDate.add(Calendar.DAY_OF_MONTH, -delta)
        return DateUtil.convertCalToInt(newDate)

    #  MD function getRawRateByDateInt(int dt) returns last known value, even if wildly out of date.
    #  Return true if the snapshots contain a rate within a week before the date.
    def haveSnapshotWithinWeek(self, curr, date):
        import com.infinitekind.util.DateUtil as DateUtil
        snapshots = curr.getSnapshots()
        for snap in snapshots:
            if DateUtil.calculateDaysBetween(snap.getDateInt(), date) <= 7:
                #  within a week
                return True
        return snapshots.isEmpty()
        #  If no snapshots, use fixed rate; otherwise didn't find snapshot

    def sumBalancesByCurrency(self, book):
#        print "sumBalancesByCurrency "
        import java.util.HashMap as HashMap
        import com.infinitekind.moneydance.model.AccountUtil as AccountUtil
        import com.infinitekind.moneydance.model.AcctFilter as AcctFilter
        import com.infinitekind.moneydance.model.Account.AccountType as AccountType

        totals = HashMap() #  HashMap<CurrencyType, Long> 
        for acct in AccountUtil.allMatchesForSearch(book.getRootAccount(), AcctFilter.ACTIVE_ACCOUNTS_FILTER ): 
	    curr = acct.getCurrencyType()                                      
	    total = totals.get(curr) # this returns None if curr doesn't exist yet
	    if acct.getCurrentBalance() != 0 and acct.getAccountType() == AccountType.SECURITY: # we only want Securities with holdings
              pass
	    else:
	      continue # no sense slowing everything down with stuff we don't need 
	    
            total = (0L if (total == None) else total) + acct.getCurrentBalance()            
#?  java      total = ((total == null) ? 0L : total) + acct.getCurrentBalance();
            totals.put(curr, total)
        return totals

    def getCurrencyAccounts(self, book):
#        print "getCurrencyAccounts "
        import java.util.HashMap as HashMap
        import com.infinitekind.moneydance.model.AccountUtil as AccountUtil
        import com.infinitekind.moneydance.model.AcctFilter as AcctFilter
        import com.infinitekind.moneydance.model.Account.AccountType as AccountType
        
        accounts = HashMap()
        for acct in AccountUtil.allMatchesForSearch(book.getRootAccount(), AcctFilter.ACTIVE_ACCOUNTS_FILTER ): 
	    curr = acct.getCurrencyType()                                   
	    account = accounts.get(curr)# this returns None if curr doesn't exist yet
	    if acct.getCurrentBalance() != 0 and acct.getAccountType() == AccountType.SECURITY:
              pass
	    else:
	      continue # no sense slowing everything down with stuff we don't need  . only some BONDS left mixed in with the STOCK
	    if account == None:
	      account = str(acct.getParentAccount())
	    else:  
              account = account + ' : ' + str(acct.getParentAccount()) # concatinate two strings here
            accounts.put(curr,account)
        return accounts



    # 
    #  Private classes:
    # 
    #  CurrencyListener
##    class currencyCallback(CurrencyListener):
##        """ generated source for class currencyCallback """
##        thisSG = self.StockGlance()
##
##        def __init__(self, sg):
##            """ generated source for method __init__ """
##            super(currencyCallback, self).__init__()
##            self.thisSG = sg
##
##        def currencyTableModified(self, table):
##            """ generated source for method currencyTableModified """
##            self.thisSG.refresh()

    #  AccountListener
##    class accountCallback(AccountListener):
##        """ generated source for class accountCallback """
##        thisSG = StockGlance()
##
##        def __init__(self, sg):
##            """ generated source for method __init__ """
##            super(accountCallback, self).__init__()
##            self.thisSG = sg
##
##        def accountAdded(self, parentAccount, newAccount):
##            """ generated source for method accountAdded """
##            self.thisSG.refresh()
##
##        def accountBalanceChanged(self, newAccount):
##            """ generated source for method accountBalanceChanged """
##            self.thisSG.refresh()
##
##        def accountDeleted(self, parentAccount, newAccount):
##            """ generated source for method accountDeleted """
##            self.thisSG.refresh()
##
##        def accountModified(self, newAccount):
##            """ generated source for method accountModified """
##            self.thisSG.refresh()

    #  JPanel
#    class SGPanel(JPanel):
#        def __init__(self, table):
#            """ generated source for method __init__ """
#            super(JPanel, self).__init__()
#            print "SGPanel init "            
#            self.setLayout(BoxLayout(self, BoxLayout.PAGE_AXIS))
#            self.add(table.getTableHeader())
#            self.add(table)
#            self.add(table.getFooterTable())
#            self.setBorder(BorderFactory.createCompoundBorder(MoneydanceLAF.homePageBorder, BorderFactory.createEmptyBorder(0, 0, 0, 0)))


    #  SGTableModel
    class SGTableModel(DefaultTableModel):
#        print "SGTableModel "
        import java.awt.Color as Color
        import java.util.Vector as Vector
        import java.util.Arrays as Arrays
        import javax.swing.table.DefaultTableModel as DefaultTableModel

        rowCurrencies2 = Vector()

        def __init__(self, data, columnNames, rowCurrencies):
	    import javax.swing.table.DefaultTableModel as DefaultTableModel
            super(DefaultTableModel, self).__init__(data,columnNames)
            self.rowCurrencies2 = rowCurrencies

        def getRowCurrencies(self):
            return self.rowCurrencies2


    #  SGFooterModel
    class SGFooterModel(DefaultTableModel):      
#        print "SGFooterModel "
        import java.awt.Color as Color
        import java.util.Vector as Vector
        import java.util.Arrays as Arrays
        import javax.swing.table.DefaultTableModel as DefaultTableModel

        footer2 = Vector()
        columnNames2 = []

        def __init__(self, footer, columnNames):
	    import javax.swing.table.DefaultTableModel as DefaultTableModel
            super(DefaultTableModel, self).__init__(footer,columnNames)
            self.footer2 = footer
            self.columnNames2 = columnNames

        def getFooterVector(self):
            return self.footer2

	def isCellEditable(self, row, column):
            return False
	  

    #  SGFooterTable JTable
    
    class SGFooterTable(JTable):

#        print "SGFooterTable "

        def __init__(self, footerModel):
	    import javax.swing.JTable as JTable
            super(JTable, self).__init__(footerModel)

        def getDataModel(self):
	    global AAA 
            return AAA.footerModel
	  
	  
        #  Rendering depends on  column .. this footer only has one row
        def getCellRenderer(self, row, column):
#	    print "footer renderer",row,column
            import javax.swing.table.DefaultTableCellRenderer as DefaultTableCellRenderer
            import javax.swing.JLabel as JLabel
            global AAA 
            renderer = None
            if AAA.columnTypes[column]=="Text":
                renderer = DefaultTableCellRenderer()
                renderer.setHorizontalAlignment(JLabel.LEFT)
            elif AAA.columnTypes[column]=="Currency2" or AAA.columnTypes[column]=="Currency0":
	        rowCurrencies = self.getDataModel().getFooterVector() # only diff
	        curr = None
                if 0 <= row and row < len(rowCurrencies):
                    curr = AAA.rowCurrencies.get(row)
                else:
                    curr = self.book.getCurrencies().getBaseType() # Footer reports base currency
                renderer = AAA.CurrencyRenderer(curr, AAA.columnTypes[column] == "Currency0")
                renderer.setHorizontalAlignment(JLabel.RIGHT)
            elif AAA.columnTypes[column]=="Percent":
                renderer = AAA.PercentRenderer()
                renderer.setHorizontalAlignment(JLabel.RIGHT)
            else:
                renderer = DefaultTableCellRenderer()
            return renderer

	  
    class SGTable(JTable): # (JTable)
      
        def __init__(self, tableModel):
#            print "SGTable init"
            import javax.swing.JTable as JTable
            super(JTable, self).__init__(tableModel)
#            self.fixColumnHeaders()
            self.fixTheRowSorter();

        def getDataModel(self):
	    global AAA
            return AAA.tableModel

        def isCellEditable(self, row, column):
            return False

        #  Rendering depends on row (i.e. security's currency) as well as column
        def getCellRenderer(self, row, column):
	    import javax.swing.table.DefaultTableCellRenderer as DefaultTableCellRenderer
	    import javax.swing.JLabel as JLabel
	    global AAA 
            renderer = None
            if AAA.columnTypes[column]=="Text":
                renderer = DefaultTableCellRenderer()
                renderer.setHorizontalAlignment(JLabel.LEFT)
            elif AAA.columnTypes[column]=="Currency2" or AAA.columnTypes[column]=="Currency0":
	        rowCurrencies = self.getDataModel().getRowCurrencies()
	        curr = None
                if 0 <= row and row < len(rowCurrencies):
                    curr = AAA.rowCurrencies.get(row)
                else:
                    curr = self.book.getCurrencies().getBaseType() # Footer reports base currency
                renderer = AAA.CurrencyRenderer(curr, AAA.columnTypes[column] == "Currency0")
                renderer.setHorizontalAlignment(JLabel.RIGHT)
            elif AAA.columnTypes[column]=="Percent":
                renderer = AAA.PercentRenderer()
                renderer.setHorizontalAlignment(JLabel.RIGHT)
            else:
                renderer = DefaultTableCellRenderer()
            return renderer

        def columnMarginChanged(self, event):
            eventModel = event.getSource()
            thisModel = self.getColumnModel()
            columnCount = eventModel.getColumnCount()
            i = 0
            while i < columnCount:
                thisModel.getColumn(i).setWidth(eventModel.getColumn(i).getWidth())
                i += 1
            self.repaint()
            
        import java.util.Comparator as Comparator   
        class myComparator (Comparator): 
#	    print("Mycomparator")      # example of jython conditional operator.works like the java ? operator
	    def compare( self, str1 , str2): return 1 if str1 > str2 else 0 if str1 == str2 else -1                
      
#        def fixColumnHeaders(self):  # don't know what this was for
#            cm = self.getColumnModel()
#            i = 0
#            while i < cm.getColumnCount():
#	        col = cm.getColumn(i);
#                col.setHeaderRenderer(StockGlance75.HeaderRenderer())
#                i += 1
#            return
	        
        def fixTheRowSorter(self):    # for some reason everthing was being coverted to strings                                  
	    import javax.swing.table.TableRowSorter as TableRowSorter
	    sorter = TableRowSorter()           
	    self.setRowSorter(sorter)                               
	    sorter.setModel(self.getModel())                          
	    for i in range (0 , self.getColumnCount() ) :                   
                 sorter.setComparator(i,self.myComparator())    
            self.getRowSorter().toggleSortOrder(0) 
	  	  
#        @override ..JTable method . preformance pig	 
        def prepareRenderer(self, renderer, row, column):  # make Banded rows
	    global AAA 
            component = super(AAA.SGTable, self).prepareRenderer(renderer, row, column)
            if not self.isRowSelected(row):
              component.setBackground(self.getBackground() if row % 2 == 0 else AAA.lightLightGray)
            return component

        def getFooterTable(self):
            return self.footerTable

    # Render a currency with given number of fractional digits. NaN or null is an empty cell.
    # Negative values are red.
    import javax.swing.table.DefaultTableCellRenderer as DefaultTableCellRenderer
    class CurrencyRenderer(DefaultTableCellRenderer):
#        print "CurrencyRenderer "
        noDecimals = bool()
        relativeTo = None # CurrencyType()
        decimalSeparator = '.'
        noDecimalFormatter = None # NumberFormat()

        def __init__(self, currency, noDecimals):
	    import java.lang.Double as Double
	    import java.text.NumberFormat as NumberFormat
	    import javax.swing.table.DefaultTableCellRenderer as DefaultTableCellRenderer
	    import com.infinitekind.moneydance.model.CurrencyType as CurrencyType
            super(DefaultTableCellRenderer, self).__init__()
            self.noDecimals = noDecimals
            ct = currency.getTable()
            relativeToName = currency.getParameter(CurrencyType.TAG_RELATIVE_TO_CURR)
            if relativeToName != None:
                self.relativeTo = ct.getCurrencyByIDString(relativeToName)
            else:
                self.relativeTo = ct.getBaseType()
            self.noDecimalFormatter = NumberFormat.getNumberInstance()
            self.noDecimalFormatter.setMinimumFractionDigits(0)
            self.noDecimalFormatter.setMaximumFractionDigits(0)

        def isZero(self, value):
	    import java.lang.Math as Math
            return Math.abs(value) < 0.01

        def setValue(self, value):
	    import java.lang.Double as Double
	    import java.awt.Color as Color
            if value == None:
                self.setText("")
            elif Double.isNaN(float(value)):
                self.setText("")
            else:
                if self.isZero(float(value)):
                    value = 0.0
                if self.noDecimals:
		    # MD format functions can't print comma-separated values without a decimal point so
                    # we have to do it ourselves
                    scaledValue = float(value) * self.relativeTo.getUserRate();		  
                    self.setText(self.relativeTo.getPrefix() + " " + self.noDecimalFormatter.format(scaledValue) + self.relativeTo.getSuffix())
                else:
		    scaledValue = self.relativeTo.convertValue(self.relativeTo.getLongValue(float(value)))
                    self.setText(self.relativeTo.formatFancy(scaledValue, self.decimalSeparator))
                if float(value) < 0.0:
                    self.setForeground(Color.RED)
                else:
                    self.setForeground(Color.BLACK)
                    
    # Render a percentage with 2 digits after the decimal point. Conventions as CurrencyRenderer
    class PercentRenderer(DefaultTableCellRenderer):
#        print "PercentRenderer "
#        import java.lang.Double as Double
#        import java.lang.Math as Math
        decimalSeparator = '.'
        def __init__(self):
	    import javax.swing.table.DefaultTableCellRenderer as DefaultTableCellRenderer
            super(DefaultTableCellRenderer, self).__init__()

        def isZero(self, value):
	    import java.lang.Math as Math
            return Math.abs(value) < 0.0001

        def setValue(self, value):
	    import java.lang.Double as Double
	    import com.infinitekind.util.StringUtils as StringUtils
	    import java.awt.Color as Color
            if value == None:
                self.setText("")
            elif Double.isNaN(float(value)):
                setText("")
            else:
                if self.isZero(float(value)):
                    value = 0.0
                self.setText(StringUtils.formatPercentage(float(value), self.decimalSeparator) + "%")
                if float(value) < 0.0:
                    self.setForeground(Color.RED)
                else:
                    self.setForeground(Color.BLACK)

    class HeaderRenderer(DefaultTableCellRenderer):
#        print "HeaderRenderer "
        def __init__(self):
            super(DefaultTableCellRenderer, self).__init__()
            self.setForeground(Color.BLACK)
            self.setBackground(Color.lightGray)
            self.setHorizontalAlignment(JLabel.CENTER)
                        

#    def __init__(self): # init for StockGlance class
#        print "StockGlance init"
#        super(StockGlance, self).__init__()
                
#    @classmethod
    def createAndShowGUI(self):
#        print "creatAndShowGUI"
        from javax.swing import JScrollPane as JScrollPane
        import javax.swing.border.CompoundBorder as CompoundBorder
        import javax.swing.border.MatteBorder as MatteBorder
        import javax.swing.border.EmptyBorder as EmptyBorder
        import java.awt.Color as Color
        import javax.swing.JFrame as JFrame
        from javax.swing import WindowConstants as WindowConstants
        from java.awt import BorderLayout
        import javax.swing.JTable as JTable
        from java.awt import Dimension as Dimension
        
        root = moneydance.getRootAccount()
        self.book = root.getBook()

#        StockGlance75.tableModel = self.getTableModel(self.book)
#        StockGlance75.table = self.SGTable(StockGlance75.tableModel)
        self.tableModel = self.getTableModel(self.book)
        self.table = self.SGTable(self.tableModel)
        
        self.footerModel = self.getFooterModel()
        self.footerTable = self.SGFooterTable(self.footerModel)
#        StockGlance75.footerModel = self.getFooterModel()
#        StockGlance75.footerTable = self.SGFooterTable(StockGlance75.footerModel)
        
        self.scrollPane = JScrollPane(self.table, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED)
#        self.scrollPane = JScrollPane(StockGlance75.table, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED)
        self.scrollPane.setBorder(CompoundBorder(MatteBorder(0, 0, 1, 0, Color.gray), EmptyBorder(0, 0, 0, 0)))

        self.footerScrollPane = JScrollPane(self.footerTable, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED)
#        self.footerScrollPane = JScrollPane(StockGlance75.footerTable, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED)
        self.footerScrollPane.setBorder(CompoundBorder(MatteBorder(0, 0, 1, 0, Color.gray), EmptyBorder(0, 0, 0, 0)))
      
        frame_ = JFrame("StockGlance")
        frame_.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE) 
        frame_.add(self.scrollPane, BorderLayout.CENTER)
        
        self.table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF )
#        StockGlance75.table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF )
        
        self.footerTable.setColumnSelectionAllowed(False)
        self.footerTable.setRowSelectionAllowed(False)
        self.footerTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF )
#        StockGlance75.footerTable.setColumnSelectionAllowed(False)
#        StockGlance75.footerTable.setRowSelectionAllowed(False)
#        StockGlance75.footerTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF )
        

        frame_.add(self.footerScrollPane, BorderLayout.SOUTH)
        
        frame_.setSize(1170,1000)
        
        tcm = self.table.getColumnModel()
#        tcm = StockGlance75.table.getColumnModel()
        tcm.getColumn(0).setPreferredWidth(80)
        tcm.getColumn(1).setPreferredWidth(250)
        tcm.getColumn(2).setPreferredWidth(80)
        tcm.getColumn(3).setPreferredWidth(80)
        tcm.getColumn(4).setPreferredWidth(80)
        tcm.getColumn(5).setPreferredWidth(80)
        tcm.getColumn(6).setPreferredWidth(80)
        tcm.getColumn(7).setPreferredWidth(80)
        tcm.getColumn(8).setPreferredWidth(80)
        tcm.getColumn(9).setPreferredWidth(260)
        
        tcm = self.footerTable.getColumnModel()
#        tcm = StockGlance75.footerTable.getColumnModel()
        tcm.getColumn(0).setPreferredWidth(80)
        tcm.getColumn(1).setPreferredWidth(250)
        tcm.getColumn(2).setPreferredWidth(80)
        tcm.getColumn(3).setPreferredWidth(80)
        tcm.getColumn(4).setPreferredWidth(80)
        tcm.getColumn(5).setPreferredWidth(80)
        tcm.getColumn(6).setPreferredWidth(80)
        tcm.getColumn(7).setPreferredWidth(80)
        tcm.getColumn(8).setPreferredWidth(80)
        tcm.getColumn(9).setPreferredWidth(260)

        self.footerScrollPane.setPreferredSize(Dimension(10,30))# (width,height) width doesn't matter
 
        self.footerTableHeader = self.footerTable.getTableHeader()
#        self.footerTableHeader = StockGlance75.footerTable.getTableHeader()
        self.footerTableHeader.setEnabled(False) # may have worked
        self.footerTableHeader.setPreferredSize(Dimension(0,0)) # this worked no more footer Table header
        
        self.tableHeader = self.table.getTableHeader()
#        self.tableHeader = StockGlance75.table.getTableHeader()
        self.tableHeader.setReorderingAllowed(False) # no more drag and drop columns, it didn't work
                
#        frame_.pack()
        frame_.setVisible(True)