简体   繁体   English

Java JTable列标题未使用DefaultModel显示

[英]Java JTable column header not showing using DefaultModel

Like the title said, the hearder name is just not showing up. 就像标题所说的那样,听众的名字没有出现。 i tried many options like using a JScrollPane. 我尝试了很多选择,例如使用JScrollPane。 and fallowed many guide on this forum but no help. 并在此论坛上提供了许多指南,但没有帮助。 I really wanted to get resolve problem by myself but i have tried everything and out of option. 我真的很想自己解决问题,但我已经尝试了一切,并且选择不了。

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

        }
    }
}

You're adding the JTable directly to the GUI. 您正在将JTable直接添加到GUI。 Instead, yes you need to embed the JTable into the viewport of a JScrollPane and then add the JScrollPane to the GUI. 相反,是的,您需要将JTable嵌入到JScrollPane的视口中,然后将JScrollPane添加到GUI。

For example: 例如:

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

Also, you're harming your GUI by using null layouts and absolute positioning, as this can interfere with a component's ability to show itself fully and correctly, to achieve its own preferred size. 另外,使用空布局和绝对定位会损害GUI,因为这可能会干扰组件完全正确显示其自身的能力,以实现其自己的首选大小。 Much better is to learn and use the layout managers. 学习和使用布局管理器会更好。

For instance, when I run your program on my platform, I see: 例如,当我在平台上运行您的程序时,我看到:

在此处输入图片说明

Note how the buttons do not show their full texts due to their not being allowed to achieve their preferred sizes. 请注意,由于不允许按钮实现其首选大小,它们如何不显示其全文。

For example, using BoxLayout with some nested JPanels, one using GridLayout(1, 0, 5, 0) for one row, variable number of columns, and a 5 point horizontal gap between components, and another nested JPanel using GridBagLayout, for placement of JTextFields and JLabels, and some "wrapper" JPanels using default FlowLayout to center components within them... 例如,将BoxLayout与一些嵌套的JPanel一起使用,其中一个对一行使用GridLayout(1, 0, 5, 0) 1,0,5,0 GridLayout(1, 0, 5, 0) ,行数可变,组件之间的水平间距为5点,而另一对JPanel则使用GridBagLayout进行嵌套JTextFields和JLabels,以及一些使用默认FlowLayout将组件居中的“包装” JPanel。

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

}

Which displays as: 显示为:

在此处输入图片说明

Regarding your questions: 关于您的问题:

but new question why give the scrollpane a bound instead of the table itself 但是新的问题是为什么要给滚动窗格一个绑定而不是表格本身

The JScrollPane holds the JTable within it, and so if you use null layouts (which you shouldn't), and you're adding this JTable-containing JScrollPane to the GUI, you must set its bounds. JScrollPane将JTable 保留在其中,因此,如果您使用空布局(不应这样做),并且要将此包含JTable的JScrollPane添加到GUI,则必须设置其边界。 Much better though is to use layout managers as I've outlined above. 好得多,虽然是使用布局管理器,因为我先前提到。 It makes it much easier to modify the GUI later and to debug it now. 这使得以后修改GUI和现在对其进行调试变得容易得多。

and why adding the scrollpane into the panel instead of the table. 以及为什么将滚动窗格添加到面板而不是表中。

Because that's how JScrollPanes work. 因为这就是JScrollPanes的工作方式。 They don't add scrollbars to a component but rather nest the component itself, here the JTable, within the JScrollPane's viewport. 他们没有向组件添加滚动条,而是在JScrollPane的视口中嵌套了组件本身(这里是JTable)。 Please read the JScrollPane Tutorial (see link) to see the details on this. 请阅读JScrollPane教程 (请参阅链接)以了解有关此内容的详细信息。


A further note on the power of layout managers. 关于布局管理器功能的进一步说明。 Say you want to add a new JLabel / JTextField combination, one that accepts a password hint, and say the JTextField's name is passwordHint . 假设您要添加一个新的JLabel / JTextField组合,该组合接受一个密码提示,并说该JTextField的名称为passwordHint If you were using null layouts and absolute positioning, you'd have to set the bounds of your new JLabel and JTextField, but you'd also have to change the bounds of all components below and to the right of it, and would have to re-set the size of the GUI manually. 如果使用空布局和绝对定位,则必须设置新的JLabel和JTextField的边界,但是还必须更改其下方和右侧的所有组件的边界,并且必须手动重新设置GUI的大小。 If your GUI is very complex, this can lead to bugs and a lot of frustration. 如果您的GUI非常复杂,则可能会导致错误和很多挫败感。

If you used the layout managers above however, all you'd need to do would be to add two lines of code to the textFieldPanel JPanel creational code as shown below with the obvious comments: 但是,如果您使用了上面的布局管理器,那么您要做的就是将两行代码添加到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));

This results in a perfect placement of the new components without adversely affecting the old: 这样可以完美放置新组件,而不会对旧组件产生不利影响:

在此处输入图片说明

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

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