2015-04-17 137 views
0

当前正在开发一个项目,并且需要动态添加一个面板到一个滚动窗格或一个表格。该滚动窗格应该从空白处开始并添加面板。将JPanel动态添加到JTable或JScrollPane

GuiConstructor是我的窗户。

我的问题是,如果我不注释掉GuiConstructor中的setSize,窗口开始非常小。 其次,当我按下添加按钮,它不会添加面板。

public GuiConstructor(){ 
    super(APPLICATION_NAME); 
    setLayout(new BorderLayout()); 
    LoopControlWindow loopwin = new LoopControlWindow(connect); 
    add(loopwin , BorderLayout.NORTH); 
    pack(); 
    setLocationRelativeTo(null); 
    setResizable(false); 
    setVisible(true); 
    //this.setSize(500, 500); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 


} 


public class LoopControlWindow extends JPanel { 

IConnector connect; 

public LoopControlWindow(IConnector connect) { 
    super(new BorderLayout()); 
    this.connect = connect; 
    initPane(); 
} 

private void initPane() { 
    JPanel panel = new JPanel(new GridLayout(3,1)); 
    FolderSearchComp fsc = new FolderSearchComp(connect); 
    JScrollPane scrollPane = new JScrollPane(); 
    JButton button = new JButton("Add"); 

    button.addActionListener(new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      panel.add(new FolderSearchComp(connect)); 
      scrollPane.getViewport().setView(panel); 
     } 
    }); 



    scrollPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); 
    scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); 
    scrollPane.setViewportBorder(new LineBorder(Color.BLACK)); 


    add(scrollPane, BorderLayout.CENTER); 
    add(button, BorderLayout.SOUTH); 


} 

回答

2

这是典型的这种GUI应用程序风格。如果不使用setSize(),需要告诉布局管理器有多大才能使窗口初始化。执行此操作的方法是覆盖getPreferredSize()以返回默认大小。你的情况:

public LoopControlWindow extends JPanel { 
    private Dimension size; 

    public LoopControlWindow() { 
     Preferences prefs = Preferences.userNodeForPackge("your.java.package"); 
     size = new Dimension(prefs.getInt("width", 800), prefs.getInt("height", 600)); 
    } 
    public Dimension getPreferredSize() { 
     return size; 
    } 
} 

通过做这种方式,你可以存储的窗口尺寸用户的喜好,但也提供了合理的默认值开始。

你也应该确保这个JPanel是你的主面板,并且在BorderLayout.CENTER被添加到JFrame中以确保你的窗口被正确地绘制。所有其他面板应该在这个里面的某个地方。

一旦你有这个设置呼叫pack()将正常工作。

+0

加一,但是JFrame.pack()被指定用于完成这个......,在你的回答中错过 – mKorbel

+0

@mKorbel是的。谢谢。 – markbernard

+0

我没有得到usernodeforpacker方法,这是做什么的? –

0

对于第一个问题,您需要为初始JFrame()指定大小。一种方法是像你在做的那样调用setSize。另一个是重写getPreferredSize()以返回默认大小。另一个选择是找到用户监视器的大小,并将JFrame设置为该大小的百分比。这样可以确保您的窗口始终适合用户的屏幕。

int height = GraphicsEnvironment.getLocalGraphicsEnvironment() 
      .getDefaultScreenDevice().getDefaultConfiguration(). 
      getBounds().height; 
    height = (int) (height * .85); 
    int width = GraphicsEnvironment.getLocalGraphicsEnvironment() 
      .getDefaultScreenDevice().getDefaultConfiguration(). 
      getBounds().width; 
    width = (int) (width * .85); 
    frame.setSize(width, height); 

其次,您需要随时调用revalidate()和repaint(),以便在布局中添加或删除以查看更改。

button.addActionListener(new ActionListener() { 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     panel.add(new FolderSearchComp(connect)); 
     scrollPane.getViewport().setView(panel); 
     revalidate(); 
     repaint(); 
    } 
}); 

关于边界布局的一点说明。其中的组件不会调整您的JFrame。但是,无论放置在BorderLayout.CENTER中的组件是什么。随着JFrame的增长,该组件将会增长以填充所有额外的空间。它也将是JFrame窗口变小时收缩的组件。