簡體   English   中英

有 JScrollPane 時如何 position Java swing 組件

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

我是制作 GUI 和 Java Swing 的新手,我正在嘗試制作一個顯示來自 SQL 數據庫的表格的 GUI。 該表使用 JScrollPane 顯示。 起初我以為我的其他組件(JLabel 和 JTextField)沒有被添加到內容窗格中,但實際上它們只是隱藏在 ScrollPane 下。 減小 ScrollPane 的尺寸后,現在這些其他組件會顯示出來,但它們無法使用 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);
        
    }
} 

圖形用戶界面

為什么要在兩個不同的地方創建 Swing 組件?

  1. 不要在 main() 方法中創建組件。
  2. label、文本字段和表格都應在構造函數中創建並添加到框架中,與創建和添加滾動窗格/表格的方式相同。

在下面的代碼中:

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。 布局管理器將根據布局管理器的規則設置組件的大小/位置。

如果在添加組件時未指定約束,則使用BorderLayout.CENTER 但是,您只能將一個組件添加到 CENTER,因此只有文本字段具有正確的大小/位置。 label 被忽略。

因此,假設您將 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);

現在這將在框架頂部顯示標簽和文本字段,並在中心顯示滾動窗格。 然后滾動條會隨着幀大小的變化而自動調整。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM