JTable调整第一次运行时不工作的列

时间:2015-07-11 09:45:50

标签: java swing resize jtable

我有一个方法如下:

public void displayTable() throws SQLException{

    table = new JTable(){
        private static final long serialVersionUID = 1L;

        @Override
            public boolean isCellEditable(int row, int column) {
               return false;
            }

    };

    stable = new JScrollPane (table);
    stable.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
    stable.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    panel1.add(stable);
    showTables();
}

showTables()就像这样:

public void showTables() throws SQLException{
    ResultSet showTablesResult = null;
    query = "abc";
    try {
        showTablesResult = stat.executeQuery("SHOW TABLES");
    } catch (SQLException e) {
        JOptionPane.showMessageDialog(null, "Error connecting to databse");
    }
    DefaultTableModel model = buildTableModel(showTablesResult);
    updateTable(model);     
}

updateTable():

public void updateTable(DefaultTableModel model){
    table.setModel(model);
    tweakColumns(table);
}

现在的问题是,当displayTable初始运行时,它会生成表格,但列数很小,并且不会按原样伸展。

当我按下一个运行showTables()的按钮时,列伸出。我不知道为什么这不起作用,因为displayTable()运行showTables()来生成它没有它?

此处的参考还有tweakColumns():

public static void tweakColumns(JTable table){
    Enumeration<TableColumn> columns = table.getColumnModel().getColumns();

    int required = 0;
    while(columns.hasMoreElements()){
        TableColumn column = columns.nextElement();
        int width = (int)table.getTableHeader().getDefaultRenderer()
                    .getTableCellRendererComponent(table, column.getIdentifier()
                            , false, false, -1, column.getModelIndex()).getPreferredSize().getWidth();
        required += width;
    }

    JViewport viewport = (JViewport)SwingUtilities.getAncestorOfClass(JViewport.class, table);
    int viewportWidth = viewport.getWidth();
    table.setAutoResizeMode(required<viewportWidth ? JTable.AUTO_RESIZE_ALL_COLUMNS : JTable.AUTO_RESIZE_OFF);
}

这是一个MCVE:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.URL;
import java.sql.SQLException;
import java.util.Enumeration;
import javax.imageio.ImageIO;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;


public class Main extends JFrame{

    private static final long serialVersionUID = 1L;
    private JPanel panel;
    private JLabel query = new JLabel("Showing All Tables");
    private JTable table;
    private JPanel panel1;
    private JScrollPane stable;
    private Component introLabel;
    private JPanel contentPane;
    private JTabbedPane tabbedPane;
    private JPanel server;

    public static void main(String[] args) throws InterruptedException {

            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        Main frame = new Main();
                        frame.setVisible(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
    }


    public Main() throws IOException, SQLException {

        setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 655, 470);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(1, 1));
        setContentPane(contentPane);

        tabbedPane = new JTabbedPane(JTabbedPane.TOP);
        contentPane.add(tabbedPane, BorderLayout.CENTER);

        setResizable(false);

        server = new JPanel();
        server.setLayout(new BorderLayout(0, 0));

        DbViewer();
    }

        /**
         * initial panel setup
         * @return 
         * @throws SQLException
         */
        public void DbViewer() throws SQLException{
            panel = new JPanel(new BorderLayout());
            introLabel = makeTextPanel("<html><center>You can use this to browse through the tables used in DEDServer. <br />Double click a Table Name to view it. You can copy a cells value by right clicking on it.<br />Press the home button at the bottom to go back and view all the tables.<br /><br />"+query.getText()+"</center></html>");
            panel.add(introLabel,BorderLayout.NORTH);
            tabbedPane.addTab("DB Viewer",panel);
            panel1 = new JPanel();
            panel1.setLayout(new BoxLayout(panel1, BoxLayout.PAGE_AXIS));
            panel.add(panel1,BorderLayout.CENTER);
            homeButton();
            displayTable();
        }


        /**
         * makes the home button
         */
        public void homeButton(){
            JButton button = new JButton(){
                private static final long serialVersionUID = 1L;
                    public Dimension getPreferredSize() {
                        return new Dimension(32,32);
                    };
                };
                  try {
                      URL url = new URL("http://png-2.findicons.com/files/icons/1264/clearblack/32/home.png");
                    Image img = ImageIO.read(url);
                    button.setIcon(new ImageIcon(img));
                  } catch (IOException ex) {
                  }
                button.setAlignmentX(Component.CENTER_ALIGNMENT);
                panel1.add(button);
                button.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent arg0) {
                        showTables();
                    }
             });
        }

        public void updateTable(DefaultTableModel model, JLabel query){
            table.setModel(model);
            tweakColumns(table);
            introLabel = makeTextPanel("<html><center>You can use this to browse through the tables used in DEDServer. <br />Double click a Table Name to view it. You can copy a cells value by right clicking on it.<br />Press the home button at the bottom to go back and view all the tables.<br /><font color='red'>"+query.getText()+"</font></center></html>");
            panel.removeAll();
            panel.add(introLabel,BorderLayout.NORTH);
            panel.add(panel1);
        }



        public void showTables(){
            String[] columnNames = {"TABLE NAME",
            "BLAH"};


            Object[][] data = {
            {"Table1", "PUBLIC"},
            {"Table2", "PUBLIC"}
            };

            DefaultTableModel model = new DefaultTableModel(data,columnNames);
            table.setModel(model);
            tweakColumns(table);
        }
        /**
         * makes the table and scrollpane at startup
         * @throws SQLException
         */
        public void displayTable() throws SQLException{

            table = new JTable(){
                private static final long serialVersionUID = 1L;

                @Override
                    public boolean isCellEditable(int row, int column) {
                       return false;
                    }

            };

            stable = new JScrollPane (table);
            stable.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
            stable.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
            table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
            panel1.add(stable);
            showTables();
        }


        /**
         * this resizes all the columns to make it clean
         * @param table
         */
        public static void tweakColumns(JTable table){
            Enumeration<TableColumn> columns = table.getColumnModel().getColumns();

            int required = 0;
            while(columns.hasMoreElements()){
                TableColumn column = columns.nextElement();
                int width = (int)table.getTableHeader().getDefaultRenderer()
                            .getTableCellRendererComponent(table, column.getIdentifier()
                                    , false, false, -1, column.getModelIndex()).getPreferredSize().getWidth();
                required += width;
            }

            JViewport viewport = (JViewport)SwingUtilities.getAncestorOfClass(JViewport.class, table);
            int viewportWidth = viewport.getWidth();
            table.setAutoResizeMode(required<viewportWidth ? JTable.AUTO_RESIZE_ALL_COLUMNS : JTable.AUTO_RESIZE_OFF);
        }


        public static Component makeTextPanel(String text) {
            JPanel panel = new JPanel(false);
            JLabel filler = new JLabel(text);
            filler.setHorizontalAlignment(JLabel.CENTER);

            panel.add(filler);
            return panel;
        }


}

运行它,你应该看到问题。为什么第一次运行时没有调整列的大小?

1 个答案:

答案 0 :(得分:1)

第一次在屏幕上显示表格后,必须调用tweakColumns(table)。对于此用途AncestorListener如下:

table.addAncestorListener(new AncestorListener(){
    @Override
    public void ancestorAdded(AncestorEvent event){
        tweakColumns(table);
    }

    @Override
    public void ancestorRemoved(AncestorEvent event){

    }

    @Override
    public void ancestorMoved(AncestorEvent event){

    }
})