使用DefaultModel未显示Java JTable列标题

时间:2016-11-26 14:36:01

标签: java swing jtable jscrollpane layout-manager

就像标题所说的那样,听众的名字并没有出现。我尝试了很多选项,比如使用JScrollPane。和这个论坛上的许多指南,但没有帮助。我真的很想自己解决问题,但我已经尝试了一切并且没有选择。

import java.awt.Color;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import java.awt.Font;
import java.awt.ScrollPane;

import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.awt.event.ActionEvent;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.JScrollPane;
import javax.swing.JScrollBar;

public class Adminpage extends JPanel {
    private JFrame frame;
    static String ID[]={"name","Username","Password"};
    static DefaultTableModel model;
    private JTextField NametextField;
    private JTextField UsertextField;
    private JTextField PasstextField;
    private JTable table;
    private JScrollPane scroll;
    /**
     * Create the panel.
     */
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 497, 545);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);

        JLabel lblAdminstratorPortal = new JLabel("Adminstrator Portal");
        lblAdminstratorPortal.setFont(new Font("Tahoma", Font.BOLD, 20));
        lblAdminstratorPortal.setBounds(109, 26, 218, 25);
        frame.getContentPane().add(lblAdminstratorPortal);

        JButton btnNewButton = new JButton("Add Librarian");
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                //model= (DefaultTableModel)table.getModel();
                //model.addColumn("name");
                //model.addColumn("Username");
                //model.addColumn("Password");
                model.addRow(new Object[]{NametextField.getText(),UsertextField.getText(),PasstextField.getText()});

            }
        });
        btnNewButton.setBounds(10, 62, 108, 35);
        frame.getContentPane().add(btnNewButton);

        JButton btnDelete = new JButton("Delete");
        btnDelete.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {

            }
        });
        btnDelete.setBounds(130, 62, 108, 35);
        frame.getContentPane().add(btnDelete);

        JButton btnViewLibrarian = new JButton("View Librarian");
        btnViewLibrarian.setBounds(245, 62, 108, 35);
        frame.getContentPane().add(btnViewLibrarian);

        JButton btnLogout = new JButton("Logout");
        btnLogout.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                frame.dispose();
            }
        });
        btnLogout.setBounds(363, 62, 108, 35);
        frame.getContentPane().add(btnLogout);
        //model= (DefaultTableModel)table.getModel();

        JLabel lblName = new JLabel("Name");
        lblName.setBounds(21, 144, 60, 14);
        frame.getContentPane().add(lblName);

        JLabel lblUsername = new JLabel("Username");
        lblUsername.setBounds(21, 195, 60, 14);
        frame.getContentPane().add(lblUsername);

        JLabel lblPassword = new JLabel("Password");
        lblPassword.setBounds(21, 250, 60, 14);
        frame.getContentPane().add(lblPassword);

        NametextField = new JTextField();
        NametextField.setBounds(119, 141, 119, 20);
        frame.getContentPane().add(NametextField);
        NametextField.setColumns(10);

        UsertextField = new JTextField();
        UsertextField.setColumns(10);
        UsertextField.setBounds(119, 192, 119, 20);
        frame.getContentPane().add(UsertextField);

        PasstextField = new JTextField();
        PasstextField.setColumns(10);
        PasstextField.setBounds(119, 247, 119, 20);
        frame.getContentPane().add(PasstextField);


        table = new JTable();
        table.setBounds(10, 304, 461, 189);
        frame.getContentPane().add(table);


        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {

                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    public Adminpage() {
        database();
        setLayout(null);
        initialize();
        model= (DefaultTableModel)table.getModel();
        model.addColumn("name");
        model.addColumn("Username");
        model.addColumn("Password");






    }
    public void database(){
        try {
            Class.forName("sun.jdbc.odbc.JdbsOdbcDriver");
            Connection con = DriverManager.getConnection("jdbc:odbc:Games");
            Statement st = con.createStatement();
            String getquery = ("Select* from Games");
            ResultSet rs= st.executeQuery(getquery);
            while(rs.next()){
            System.out.println(rs.getString(2));
            }

        } catch (Exception e) {
            System.out.println(e.getMessage());

        }
    }
}

1 个答案:

答案 0 :(得分:3)

您将JTable直接添加到GUI。相反,是的,您需要将JTable嵌入到JScrollPane的视口中,然后将JScrollPane添加到GUI中。

例如:

    table = new JTable();
    JScrollPane scrollPane = new JScrollPane(table);
    // table.setBounds(10, 304, 461, 189);
    scrollPane.setBounds(10, 304, 461, 189);  // This is bad, but will leave for now
    // frame.getContentPane().add(table);
    frame.getContentPane().add(scrollPane);

此外,您通过使用空布局和绝对定位来伤害您的GUI,因为这会干扰组件完全正确展示自身的能力,以实现其自己的首选大小。更好的是学习和使用布局管理器。

例如,当我在我的平台上运行程序时,我看到:

enter image description here

请注意按钮如何不显示其全文,因为它们不允许达到其首选尺寸。

例如,将BoxLayout与一些嵌套的JPanels一起使用,一个使用GridLayout(1, 0, 5, 0)表示一行,列数可变,组件之间有5个点水平间隙,另一个嵌套JPanel使用GridBagLayout,用于放置JTextFields和JLabels和一些"包装" JPanels使用默认的FlowLayout来集中其中的组件......

import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;

public class AdminPage2 extends JPanel {
    private static final long serialVersionUID = 1L;
    public static final String TITLE = "Administrator Portal";
    private static final Font TITLE_FONT = new Font("Tahoma", Font.BOLD, 20);
    private static final String[] COL_NAMES = {"Name", "User Name", "Password"};
    private int txtFieldCols = 20;
    private JTextField nameField = new JTextField(txtFieldCols);
    private JTextField userNameField = new JTextField(txtFieldCols);
    private JPasswordField passwordField = new JPasswordField(txtFieldCols);
    private DefaultTableModel tableModel = new DefaultTableModel(COL_NAMES, 0);
    private JTable table = new JTable(tableModel);
    private JScrollPane tableScrollPane = new JScrollPane(table);

    public AdminPage2() {
        JLabel titleLabel = new JLabel(TITLE, SwingConstants.CENTER);
        titleLabel.setFont(TITLE_FONT);
        JPanel titlePanel = new JPanel();
        titlePanel.add(titleLabel);

        JPanel buttonPanel = new JPanel(new GridLayout(1, 0, 5, 0));
        // of course you'd add ActionListeners or Actions to your buttons
        buttonPanel.add(new JButton("Add Library"));
        buttonPanel.add(new JButton("Delete"));
        buttonPanel.add(new JButton("View Library"));
        buttonPanel.add(new JButton("Logout"));

        JPanel textFieldPanel = new JPanel(new GridBagLayout());
        textFieldPanel.add(new JLabel("Name:"), createGbc(0, 0));
        textFieldPanel.add(nameField, createGbc(1, 0));
        textFieldPanel.add(new JLabel("User Name:"), createGbc(0, 1));
        textFieldPanel.add(userNameField, createGbc(1, 1));
        textFieldPanel.add(new JLabel("Password:"), createGbc(0, 2));
        textFieldPanel.add(passwordField, createGbc(1, 2));

        JPanel wrapTfPanel = new JPanel();
        wrapTfPanel.add(textFieldPanel);

        Dimension scrollPanePrefSz = tableScrollPane.getPreferredSize();
        int w = scrollPanePrefSz.width;
        int h = scrollPanePrefSz.height / 2;
         scrollPanePrefSz = new Dimension(w, h);
         tableScrollPane.setPreferredSize(scrollPanePrefSz);

        // put together main JPanel components
        int ebGap = 4;
        setBorder(BorderFactory.createEmptyBorder(ebGap, ebGap, ebGap, ebGap));
        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        add(Box.createVerticalStrut(5));
        add(titlePanel);
        add(Box.createVerticalStrut(5));
        add(buttonPanel);
        add(Box.createVerticalStrut(5));
        add(wrapTfPanel);
        add(Box.createVerticalStrut(5));
        add(tableScrollPane);
    }

    // create constraints to use when adding component to GridBagLayout
    private GridBagConstraints createGbc(int x, int y) {
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = x;
        gbc.gridy = y;
        gbc.gridwidth = 1;
        gbc.gridheight = 1;
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;
        gbc.anchor = x == 0 ? GridBagConstraints.WEST : GridBagConstraints.EAST;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        int in = 10;
        int leftIn = x == 0 ? 4 * in : in;
        gbc.insets = new Insets(in, leftIn, in, in);
        return gbc;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui() {
        AdminPage2 mainPanel = new AdminPage2();
        JFrame frame = new JFrame("Administrator Page");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

}

显示为:

enter image description here

关于你的问题:

  

但是新问题为什么给滚动窗格一个绑定而不是表格本身

JScrollPane 在其中包含 JTable,因此如果你使用null布局(你不应该这样做),并且你将这个包含JTable的JScrollPane添加到GUI ,你必须设置它的界限。 很多更好但是使用布局管理器,如上所述。它使以后修改GUI和现在调试更加容易。

  

以及为什么将滚动窗格添加到面板而不是表格中。

因为这就是JScrollPanes的工作方式。他们不会将滚动条添加到组件中,而是将组件本身嵌套在JScrollPane的视口中,这里是JTable。请阅读JScrollPane Tutorial(请参阅链接)以查看详细信息。

关于布局管理者权力的进一步说明。假设您要添加一个新的JLabel / JTextField组合,一个接受密码提示的组合,并说JTextField的名称是passwordHint。如果使用空布局和绝对定位,则必须设置新JLabel和JTextField的边界,但是您还必须更改以下所有组件的边界在它的右侧,并且必须手动重新设置GUI的大小。如果您的GUI非常复杂,这可能会导致错误和很多挫败感。

如果您使用上面的布局管理器,那么您需要做的就是在textFieldPanel JPanel创建代码中添加两行代码,如下所示,并带有明显的注释:

// original textFieldPanel creational code
JPanel textFieldPanel = new JPanel(new GridBagLayout());
textFieldPanel.add(new JLabel("Name:"), createGbc(0, 0));
textFieldPanel.add(nameField, createGbc(1, 0));
textFieldPanel.add(new JLabel("User Name:"), createGbc(0, 1));
textFieldPanel.add(userNameField, createGbc(1, 1));
textFieldPanel.add(new JLabel("Password:"), createGbc(0, 2));
textFieldPanel.add(passwordField, createGbc(1, 2));

// !! ****** these lines added ******
textFieldPanel.add(new JLabel("Password Hint:"), createGbc(0, 3));
textFieldPanel.add(passwordHint, createGbc(1, 3));

这样可以完美地放置新组件而不会对旧组件产生负面影响:

enter image description here