2013-01-04 66 views
3

我有一個jScrollPane和一個窗體上的按鈕。該按鈕將組件添加到jScrollPane。我使用帶中心對齊的FlowLayout來排列jScrollPane中的組件。jScrollPane無法添加組件

第一個組件沒有出現問題,並且完美對齊。當我再次點擊按鈕時,沒有任何事情發生。當我遵循調試器時,它顯示所有事情都像以前一樣精確地發生。

點擊按鈕當這樣被執行的代碼:

jScrollPane.getViewport().add(new Component()); 

這是我如何設置的FlowLayoutjScrollPaneViewport

jScrollPane.getViewport().setLayout(new FlowLayout(FlowLayout.CENTER)); 
+1

1)* 「按鈕添加到'jScrollPane'一個組成部分。」 * a)爲'jScrollPane'(注意是大寫的'J')二)爲什麼這樣做的按鈕點擊而不是在創建GUI時?這裏用什麼來改變現有的GUI? 2)在'jScrollPane.getViewport().add(new Component());'不要將基於AWT的組件添加到沒有正當理由的Swing GUI中。爲了測試添加一個'現實'的組件 - 一個默認的'JTree'帶有一些數據。 3)爲了更快得到更好的幫助,請發佈[SSCCE](http://sscce.org/)。 –

回答

5

你混合重物( AWT)組件與輕量級(Swing)組件,這是不明智的,因爲它們不會很好地一起玩。

JScrollPane包含JViewPort,您可以在其上添加子組件,即AKA視圖。

enter image description here

(從JavaDocs圖像)

所以通話jScrollPane.getViewport().setLayout(new FlowLayout(FlowLayout.CENTER));實際上是設置JViewPort的佈局管理器,這確實是不可取的。

你應該做的是創建你想要添加到滾動窗格的組件,設置它的佈局並將它的所有子組件添加到它,然後將其添加到滾動窗格。你可以在後面的階段將組件添加到「查看」如果你想要的,但是這取決於你...

// Declare "view" as a class variable... 
view = new JPanel(); // FlowLayout is the default layout manager 
// Add the components you need now to the "view" 
JScrollPane scrollPane = new JScrollPane(view); 

現在你可以添加新的組件,你所需要的視圖...

view.add(...); 

如果您不想保留對view的引用,您可以通過調用JViewport#getView來訪問它,這將返回組件由視圖端口管理。

JPanel view = (JPanel)scrollPane.getViewPort().getView(); 

工作實例

這工作得很好,我...

NB - 我加view.validate()我的代碼,你可能不會有,以後我添加了一個新的組件。 ..

public class TestScrollPane01 { 

    public static void main(String[] args) { 
     new TestScrollPane01(); 
    } 

    public TestScrollPane01() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (Exception ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new MainPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class MainPane extends JPanel { 

     private JScrollPane scrollPane; 
     private int count; 

     public MainPane() { 
      setLayout(new BorderLayout()); 
      scrollPane = new JScrollPane(new JPanel()); 
      ((JPanel)scrollPane.getViewport().getView()).add(new JLabel("First")); 
      add(scrollPane); 

      JButton add = new JButton("Add"); 
      add.addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        JPanel view = ((JPanel)scrollPane.getViewport().getView()); 
        view.add(new JLabel("Added " + (++count))); 
        view.validate(); 
       } 
      }); 

      add(add, BorderLayout.SOUTH); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

    } 

} 
+0

我按照你的建議設置了它。當我嘗試按下按鈕時,什麼也沒有發生。我使用'JPanel'作爲'view'實例化'JScrollPane',其餘部分完全按照您的建議完成。 代碼上按鈕事件: '((JPanel中)JScrollPane.getViewport()getView()。)添加(新的JComponent());' 代碼上實例化: 'JScrollPane的新= javax.swing.JScrollPane中(新的JPanel(新的FlowLayout(FlowLayout.CENTER)));' – Feanaro

+1

@Feanaro我已經添加了一個工作示例 – MadProgrammer

+0

非常感謝!這確實是'驗證()'的技巧。只有一個問題,當我看到'view'上的組件超出'view'時,我無法滾動。我錯誤地設置了'JScrollPane'嗎? – Feanaro