简体   繁体   English

有 JScrollPane 时如何 position Java swing 组件

[英]How to position Java swing components when there is a JScrollPane

I am new to making GUIs and Java Swing and I'm trying to make a GUI which displays a table from a SQL database.我是制作 GUI 和 Java Swing 的新手,我正在尝试制作一个显示来自 SQL 数据库的表格的 GUI。 The table is displayed using a JScrollPane.该表使用 JScrollPane 显示。 At first I thought that my other components (JLabel and JTextField) weren't being added to the content pane but they actually were they were just hidden underneath the ScrollPane.起初我以为我的其他组件(JLabel 和 JTextField)没有被添加到内容窗格中,但实际上它们只是隐藏在 ScrollPane 下。 After reducing the ScrollPane's dimensions, now these other components show up but they are unable to be positioned with the setBounds method and always appear in the same place so that the last component added covers up the other ones entirely.减小 ScrollPane 的尺寸后,现在这些其他组件会显示出来,但它们无法使用 setBounds 方法定位,并且始终出现在同一位置,因此最后添加的组件完全覆盖了其他组件。 As well as the code I've also included a screenshot of what the GUI looks like.除了代码之外,我还包含了 GUI 外观的屏幕截图。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;


import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;

public class LibraryAppGUI extends JFrame {
    String sql;
    String DB_PATH = LibraryAppGUI.class.getResource("LibraryManagement3.sqlite").getFile();
    
    private JTable table;
    private String columns[] = {"PatronFirstName", "PatronLastName"};
    private TableModelListener tableModelListener;
    
    public LibraryAppGUI () {
        DefaultTableModel model = new DefaultTableModel(columns, 0);
        table = new JTable(model);
        
        try{populateSQL(table);} catch(Exception e1) {e1.printStackTrace();}
        table.setCellSelectionEnabled(true);
        table.setPreferredScrollableViewportSize(new Dimension(600, 300));
        table.setFillsViewportHeight(false);
        
        
        JScrollPane scrollPane = new JScrollPane(table);
        scrollPane.setVisible(true);
        getContentPane().add(scrollPane, BorderLayout.PAGE_START);
    }
    

    
    public void createSQL() throws ClassNotFoundException, SQLException {
        Class.forName("org.sqlite.jdbc");
        Connection connection = DriverManager.getConnection("jdbc:sqlite:" + DB_PATH);
        PreparedStatement stmt = connection.prepareStatement("");
        
    }
    public void populateSQL(JTable table) throws ClassNotFoundException, SQLException {
        sql = "select PatronFirstName, PatronLastName\r\n" + 
                "FROM Patron\r\n";
        Class.forName("org.sqlite.JDBC");
        Connection connection = DriverManager.getConnection("jdbc:sqlite:" + DB_PATH);
        PreparedStatement stmt = connection.prepareStatement(sql);
        ResultSet res = stmt.executeQuery();
        
        while(res.next()) {
            Object[] row = new Object[columns.length];
            for (int i = 1; i <= columns.length; i++) {
                row[i-1] = res.getObject(i);
            }
            ((DefaultTableModel) table.getModel()).insertRow(res.getRow()-1, row);  
        }
        res.close();
        connection.close();
    }
    
    
    public static void main(String[] args) {
        LibraryAppGUI window = new LibraryAppGUI();
        //label to prompt user
        JLabel welcome = new JLabel("Welcome to the library. Choose your patron: ");
        welcome.setBounds(50,50, 100, 30);
        window.getContentPane().add(welcome);
        
        JTextField user = new JTextField("Enter the full name in this box.");
        user.setBounds(150,150,100,30);
        window.getContentPane().add(user);
        
        window.setDefaultCloseOperation(EXIT_ON_CLOSE);
        window.pack();
        window.setLocationRelativeTo(null);
        window.setVisible(true);
        
    }
} 

图形用户界面

Why do you create your Swing components in two different places?为什么要在两个不同的地方创建 Swing 组件?

  1. Don't create components in the main() method.不要在 main() 方法中创建组件。
  2. The label, text field and table should all created and added to the frame in the constructor, the same way you create and add the scrollpane/table. label、文本字段和表格都应在构造函数中创建并添加到框架中,与创建和添加滚动窗格/表格的方式相同。

In your code below:在下面的代码中:

JLabel welcome = new JLabel("Welcome to the library. Choose your patron: ");
welcome.setBounds(50,50, 100, 30);
window.getContentPane().add(welcome);

JTextField user = new JTextField("Enter the full name in this box.");
user.setBounds(150,150,100,30);
window.getContentPane().add(user);

The setBounds(...) statements should NOT be used.不应使用 setBounds(...) 语句。 By default the content pane of the frame uses a BorderLayout.默认情况下,框架的内容窗格使用 BorderLayout。 The layout manager will set the size/location of the components based on the rules of the layout manager.布局管理器将根据布局管理器的规则设置组件的大小/位置。

When you don't specify a constraint when you add the components, then the BorderLayout.CENTER is used.如果在添加组件时未指定约束,则使用BorderLayout.CENTER However you can only add one component to the CENTER, so only the text field is given the proper size/location.但是,您只能将一个组件添加到 CENTER,因此只有文本字段具有正确的大小/位置。 The label is ignored. label 被忽略。

So, assuming you move the GUI code from the main() method to the constructor, the proper design would be to do something like:因此,假设您将 GUI 代码从 main() 方法移动到构造函数,正确的设计是执行以下操作:

JPanel top = new JPanel();
top.add(welcome);
top.add(user);

add(top, BorderLayot.PAGE_START);

then you would also use:那么你也可以使用:

//getContentPane().add(scrollPane, BorderLayout.PAGE_START);
add(scrollPane, BorderLayout.CENTER);

This will now display the lable and text field at the top of the frame and the scrollpane in the center.现在这将在框架顶部显示标签和文本字段,并在中心显示滚动窗格。 The scrollbars will then automatically adjust as the frame size is changed.然后滚动条会随着帧大小的变化而自动调整。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM