当存在jscrollpane时如何定位javaswing组件

hivapdat  于 2021-07-06  发布在  Java
关注(0)|答案(1)|浏览(394)

我对制作gui和javaswing还比较陌生,我正在尝试制作一个gui,它显示来自sql数据库的表。该表使用jscrollpane显示。一开始我以为我的其他组件(jlabel和jtextfield)没有被添加到内容窗格中,但实际上它们被隐藏在滚动窗格下面。缩小滚动窗格的尺寸后,现在会显示这些其他组件,但它们无法使用setbounds方法定位,并且始终显示在同一位置,以便最后添加的组件完全覆盖其他组件。除了代码之外,我还提供了一个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);

    }
}

ut6juiuv

ut6juiuv1#

为什么要在两个不同的地方创建swing组件?
不要在main()方法中创建组件。
标签、文本字段和表都应该在构造函数中创建并添加到框架中,与创建和添加滚动窗格/表的方式相同。
在下面的代码中:

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);

不应使用setbounds(…)语句。默认情况下,框架的内容窗格使用边框布局。布局管理器将根据布局管理器的规则设置组件的大小/位置。
如果在添加组件时未指定约束,则 BorderLayout.CENTER 已使用。但是,您只能将一个组件添加到中心,因此只有文本字段具有适当的大小/位置。标签被忽略。
因此,假设您将gui代码从main()方法移到构造函数中,正确的设计是执行以下操作:

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

add(top, BorderLayot.PAGE_START);

然后您还可以使用:

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

现在将在框架顶部显示标签和文本字段,在中心显示滚动窗格。然后,滚动条将随着帧大小的更改而自动调整。

相关问题