3

我在使用 Java Swing 时遇到了一些麻烦。我正在尝试制作一个顶部带有控制面板的框架,其中包含一些按钮。在此之下,我想要一个 JTable 来显示

我一直在尝试,但桌子没有显示。如果我删除顶部的 controlPanel,它有时会显示,有时不会。我在 JTable 的构造函数中使用的代码是在同一个应用程序中提供的,所以它不是网络错误

public ServerMainFrame(GuiController gc){
    this.gc = gc;
    initGUI();
}

private void initGUI() {
    System.out.println("initiating GUI");
    createFrame();
    addContentPanel();
    addControls();
    //openPopUpServerSettings();
    addSongTable();
}

private void createFrame()
{
    this.setTitle("AudioBuddy 0.1");
    this.setVisible(true);
    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setSize(800, 600);
    this.setResizable(false);
    this.setLocationRelativeTo(null);
}

private void addContentPanel()
{
    JPanel p = new JPanel();
    p.setLayout(new FlowLayout());
    p.setSize(new Dimension(800, 600));
    this.setContentPane(p);
}

private void addControls()
{
    JPanel controlPanel = new JPanel();
    controlPanel.setLayout(new FlowLayout());
    controlPanel.setBorder(BorderFactory.createLineBorder(Color.black));
    controlPanel.setSize(700,100);

    // Buttons
    JButton play = new JButton("Play");
    JButton pause = new JButton("Pause");
    JButton stop = new JButton ("Stop");
    JButton next = new JButton("Next");
    JButton prev = new JButton("Previous");     
    controlPanel.add(play);
    controlPanel.add(pause);
    controlPanel.add(stop);
    controlPanel.add(next);
    controlPanel.add(prev);

    // Currently playing
    JLabel playing = new JLabel("Currently playing:");
    controlPanel.add(playing);

    JLabel current = new JLabel("Johnny Cash - Mean as Hell");
    controlPanel.add(current);

    this.getContentPane().add(controlPanel);
}

private void addSongTable()
{
    JTable songTable = new JTable(Server.getSongTableModel());
    songTable.setVisible(true);
    JPanel tablePanel = new JPanel();
    tablePanel.setVisible(true);
    tablePanel.add(songTable);
    songTable.repaint();
    this.getContentPane().add(tablePanel);

    JButton btnMulticastList = new JButton("send list to clients");
    btnMulticastList.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            Server.MulticastPlaylist();
        }
    });

    getContentPane().add(btnMulticastList);
}
4

2 回答 2

5

如果您想在窗口顶部进行控件,并且表格占据了窗口的大部分,那么我建议您尝试使用BorderLayout而不是FlowLayout. 像这样创建它...

private void addContentPanel()
{
    JPanel p = new JPanel();
    p.setLayout(new BorderLayout());
    p.setSize(new Dimension(800, 600));
    this.setContentPane(p);
}

并通过在BorderLayout. 在这种情况下,控件应以最小尺寸添加到顶部...

this.getContentPane().add(controlPanel,BorderLayout.NORTH);

桌子应该在中间,填满剩余的窗口空间......

this.getContentPane().add(tablePanel,BorderLayout.CENTER);

就您而言,底部还有一个按钮...

getContentPane().add(btnMulticastList,BorderLayout.SOUTH);

对于您所追求的布局,BorderLayout更为合适。在这里使用的好处BorderLayout是组件应该自动调整到窗口的大小,并且您明确说明每个组件所在的位置,因此面板不应该出现

我还建议您找到调用getContentPane()所有方法的替代方法。也许考虑为主面板保留一个全局变量,像这样......

private mainPanel;

private void addContentPanel()
{
    mainPanel = new JPanel(new BorderLayout());
    mainPanel.setSize(new Dimension(800, 600));
    this.setContentPane(mainPanel);
}

然后,当您想要将add()组件添加到面板时,您可以直接引用面板。

最后,我还建议GridLayout您使用控件,因为它可以让您将所有按钮放入其中,并且它们的大小相同以保持一致性。像这样定义它以允许水平对齐的 5 个按钮...

JPanel controlPanel = new JPanel(new GridLayout(5,1));

然后您只需正常使用添加按钮controlPanel.add(button),它们将被添加到网格中的下一个插槽。

有关更多信息,请阅读有关GridLayoutBorderLayout的信息,或者仅查看 Java 教程以获取布局管理器的可视化指南,以了解您有哪些替代方案以及最适合您情况的替代方案。一般来说,我尽量避免使用FlowLayout,因为我发现LayoutManager在大多数情况下还有其他更合适的 s。

于 2012-11-12T12:51:03.707 回答
5

如果我删除顶部的 controlPanel,它有时会显示,有时不会。

  • 一切都隐藏在其中Server.getSongTableModel(),没有人知道不发布带有硬编码值返回的SSCCE

  • GUI在 Swing 中存在并发问题

  • XxxModel 在构建 GUI 时不断加载数据,然后异常导致描述的问题

我在 JTable 的构造函数中使用的代码是在同一个应用程序中提供的,所以它不是网络错误

  • 不知道你在说什么

  • 必须创建一个空的 GUI,请参阅InitialTread

  • 显示 GUI,然后开始将数据加载到JTable

  • 然后从SwingWorker或(描述网络问题)更好地启动Workers Thread(Backgroung Task) Runnable#Thread(便于捕获异常和处理单独的线程)

  • Swing GUI 的输出Runnable必须包装到invokeLater()

于 2012-11-12T12:49:21.183 回答