2009-06-04 54 views
0

我在一個非常複雜的基於Eclipse的應用程序中工作,並且在JSplitPane內部存在基於JTable的自定義組件的問題。我實際上可以訪問的應用程序的一部分是一個面板,在一個選項卡內,一個面板內,在實際應用程序中,所以有很多事情可能會出錯。JTable在點擊時選擇錯誤的單元格

我現在正在使用的具體問題是表單組件在點擊它時選擇了錯誤的單元格。如果我在第0行第0列中選擇一個單元格,則實際獲得選中的單元格位於第2行第0列,這比實際點擊低約20個像素。這隻會發生,如果表中的JSplitPane雖然:如果我只是將表本身添加到面板,單元格選擇是正確的。

對我來說,看起來是因爲表格在JSplitPane中,表格的邊界(或者包含表格的滾動窗格的視口)在某個地方大約有20個像素。另一個可以支持這個理論的問題是,滾動表格導致表格重新繪製:例如,當我向下滾動而不是滾動表格時,它實際上向上移動(繪製在表格上方的組件上)在滾動前大約20個像素。我能夠解決此問題,方法是向包含該表的滾動窗格添加

jscrollpane.getViewport().setScrollMode(JViewport.BACKINGSTORE_SCROLL_MODE); 

。由於涉及到所有的自定義組件,我實際上得不到一個顯示問題的小應用程序,但我擁有下一個最好的東西,這是一個顯示我擁有的佈局的應用程序(當然,它實際上並沒有相同的問題)。關於什麼可能會導致問題的任何想法?

//Test class showing layout of table/splitpane 
import javax.swing.*; 
import java.awt.*; 

public class SplitTest 
{ 
    private static JFrame frame; 

    private static JPanel buildTable() 
    { 
     JPanel tblPanel = new JPanel(); 
     tblPanel.setLayout(new BorderLayout()); 

     String[] cols = new String[]{"one", "two", "three", "four", "five", "six", "seven"}; 
     Object[][] data = new Object[30][7]; 
     for(int x = 0;x < data.length;x++) 
      for(int y = 0;y < data[x].length;y++) 
       data[x][y] = x + ", " + y; 

     JTable tbl = new JTable(data, cols); 

     JScrollPane scrollPane = new JScrollPane(tbl); 
     tblPanel.add(scrollPane, BorderLayout.CENTER); 

     return tblPanel; 
    } 

    private static JPanel buildTab() 
    { 
     JPanel pnl = new JPanel(); 
     pnl.setLayout(new BorderLayout()); 

     JPanel menuPnl = new JPanel(); 
     menuPnl.setLayout(new FlowLayout(FlowLayout.LEFT)); 
     menuPnl.add(new JLabel("label")); 
     menuPnl.add(new JComboBox(new String[]{"one", "two"})); 
     menuPnl.add(new JButton("Button")); 
     pnl.add(menuPnl, BorderLayout.NORTH); 

     JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT); 
     splitPane.setLeftComponent(buildTable()); 
     JPanel bottomPnl = new JPanel(); 
     bottomPnl.setPreferredSize(new Dimension(800, 200)); 
     bottomPnl.setBackground(Color.RED); 
     splitPane.setRightComponent(bottomPnl); 
     splitPane.setDividerLocation(.5); 
     pnl.add(splitPane, BorderLayout.CENTER); 

     return pnl; 
    } 

    private static JTabbedPane buildGUI() 
    { 
     JTabbedPane topLevelTabbedFrame = new JTabbedPane(); 
     topLevelTabbedFrame.addTab("Tab 1", buildTab()); 
     topLevelTabbedFrame.addTab("Tab 2", new JPanel()); 
     topLevelTabbedFrame.addTab("Tab 3", new JPanel()); 

     return topLevelTabbedFrame; 
    } 

    private static void createAndShowGUI() 
    { 
     frame = new JFrame("Split Test"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     frame.getContentPane().add(buildGUI(), BorderLayout.CENTER); 
//  frame.setSize(new Dimension(800, 600)); 

     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) throws Exception 
    { 
     SwingUtilities.invokeLater(new Runnable() 
       { 
        public void run() 
        { 
         createAndShowGUI(); 
        } 
     }); 
    } 
} 

回答

0

事實證明,問題是與爲了使組分初始化並添加到拆分窗格。所以最終的修正是延遲將表添加到拆分窗格,直到將拆分窗格實際添加到面板之後,而不是在將拆分窗格添加到面板之前將表添加到拆分窗格。做出這樣小的改變就解決了問題。

0

由於所涉及的所有自定義組件的,我不能真正得到一個小應用程序,顯示問題,但我有一個最好的事情,這是一個應用程序,顯示的佈局,我有(當然,它實際上並沒有相同的問題)。

我正要告訴你發表的代碼工作得很好,我讀了這個。

無論如何,它看起來問題在於您添加到混音中的所有自定義組件。對於JTable和JSplitPane單獨工作很好。

我會做什麼是一個直到它的工作原理刪除組件一個(可能我會工作時的代碼是一個類似於發佈並沒有什麼別的那裏)

或者你可以走了相反的路這更容易。從示例代碼開始,然後添加越來越多的組件直到它失敗。

您可以藉此機會重構並清理代碼並移動不需要的組件。甚至(爲什麼不)在過程中添加測試用例。

祝你好運。

+0

我一直在努力做到這一點 - 唯一的問題是,這不是我的代碼,我在另一個系統中工作,並且無法訪問我需要的所有東西(甚至找出發生了什麼事在這個自定義組件中,我不得不使用反編譯器)。我已經將它交給了拆分窗格 - 沒有它的情況下一切正常,但是一旦自定義表格位於拆分窗格中,它的位置就關閉了。 – 2009-06-04 19:10:58

0

您是否嘗試在另一個盒子上運行它以檢查其硬件是否相關。

可能與這個bug

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4763448

+0

我確實看到了這個錯誤,並且我嘗試了在我嘗試過的機器上重現錯誤,但它看起來並不像這個錯誤是這裏的罪魁禍首。我嘗試過不同的機器,並且每個機器都有相同的效果。 – 2009-06-05 14:08:31

相關問題