在列标题中选择所有框的问题

时间:2015-12-09 17:46:30

标签: java jtable

我正在尝试在JTable的列标题中添加一个select all框。我一直在使用此问题中提供的答案作为指导:How can I put a control in the JTableHeader of a JTable?。当我尝试运行它时,我不断收到错误消息。你能看到这个问题吗?我已经确认所有课程都在运作。我认为这与该行有关:

table.getColumnModel().getColumn(0).setHeaderRenderer(new SelectAllHeader(table, 0));

但是,我真的很新,所以我很难看到我做错了什么。

package guit2;

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import java.awt.Component;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.DefaultCellEditor;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.UIManager;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;

public class Guit2 extends JFrame{

    //CONSTRUCTOR - for the form
    public Guit2()
    {

       DefaultTableModel model = new DefaultTableModel()
        {


           @Override
           public Class<?> getColumnClass(int column)
           {
               switch(column)
               {
               case 0: 
                   return Boolean.class;
               case 1:
                   return String.class;
               case 2: 
                   return String.class;
               case 3:
                   return String.class;
               case 4: 
                   return String.class;

               default:
                   return String.class;

               }
           }

       };

        final JTable table = new JTable();

        //The Form
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(200,200,800,300);       
        setTitle("Programming 1");
        getContentPane().setLayout(null);        
        //ADD SCROLLPANE
        JScrollPane scroll=new JScrollPane();
        scroll.setBounds(70,80,600,100);
        getContentPane().add(scroll);
        //The Table
        scroll.setViewportView(table);

       //Assign the model to table
       table.setModel(model);

       model.addColumn("Select");
       model.addColumn("Position");
       model.addColumn("Team");
       model.addColumn("Points");
       model.addColumn("Manager");

       //Set custom renderer to teams column
        table.getColumnModel().getColumn(1).setCellRenderer(new ButtonRenderer());;
        table.getColumnModel().getColumn(1).setCellEditor(new ButtonEditor(new JTextField()));

        table.getColumnModel().getColumn(0).setHeaderRenderer(new SelectAllHeader(table, 0));

       for(int i=0; i<=5;i++)
       {
           model.addRow(new Object[0]);
           model.setValueAt(false,i,0);
           model.setValueAt("Our Row" +(i+1), i, 1);
           model.setValueAt("Our Column 2", i, 2);
           model.setValueAt("Our Column 3", i, 3);
           model.setValueAt("Our Column 4", i, 4);          

       }

       //Obtain selected row
       JButton btn = new JButton("Get Selected");
       btn.addActionListener(new ActionListener() {

           @Override
           public void actionPerformed(ActionEvent arg0) {

               //Get selected row 
               for(int i=0; i<table.getRowCount(); i++)
               {
                   Boolean checked = Boolean.valueOf(table.getValueAt(i,0).toString());
                   String col = table.getValueAt(i, 1).toString();

                   //Display
                   if(checked)
                   {
                       JOptionPane.showMessageDialog(null, col);
                   }

                }
       }         
    }); 

       //ADD Button to form
       btn.setBounds(20,20,130,30);
       getContentPane().add(btn);      
    }

   public static void main(String[] args) 
    {

        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                //INITIALISE JFRAME FROM
                Guit2 form = new Guit2();
                form.setVisible(true);;   

            }
        });        
    }

}

//Button renderer class

class ButtonRenderer extends JButton implements TableCellRenderer
{
    //Constructir
    public ButtonRenderer(){
        setOpaque(true);
    }
    @Override
    public Component getTableCellRendererComponent(JTable table, Object obj, 
            boolean selected, boolean focused, int row, int col) {

            setText((obj==null) ? "":obj.toString());

        return this;
    }

}

//Button editor class

class ButtonEditor extends DefaultCellEditor
{
    protected JButton btn;
    private String lbl;
    private Boolean clicked;

    public ButtonEditor(JTextField txt){
        super(txt);

        btn=new JButton();
        btn.setOpaque(true);
        setClickCountToStart(1);

        //When button is clicked
        btn.addActionListener(new ActionListener(){

            @Override
            public void actionPerformed(ActionEvent e){             

                fireEditingStopped();
            }
        });
    }
    //Overide a couple of methods
    public Component getTableCellEditorComponent(JTable table, Object obj,
            boolean selected, int row, int col) {        

        //Set button text
        lbl=(obj==null) ? "":obj.toString();
        btn.setText(lbl);     
        clicked=true; 
        return btn;
    }
    //If button cell value changes (clicked)
    @Override
    public Object getCellEditorValue(){

        if(clicked)
        {
            JOptionPane.showMessageDialog(btn, lbl+" Clicked");
        }
        clicked = false;
      return new String(lbl);    
    }

    @Override
    public boolean stopCellEditing(){

       clicked=false;
       return super.stopCellEditing();
    }

    @Override
    protected void fireEditingStopped(){
        super.fireEditingStopped();
    }  

}

/**
 * A TableCellRenderer that selects all or none of a Boolean column.
 * 
 * @param targetColumn the Boolean column to manage
 * @see https://stackoverflow.com/a/7137801/230513
 */

class SelectAllHeader extends JToggleButton implements TableCellRenderer {

    private static final String ALL = "✓ Select all";
    private static final String NONE = "✓ Select none";
    private JTable table;
    private TableModel tableModel;
    private JTableHeader header;
    private TableColumnModel tcm;
    private int targetColumn;
    private int viewColumn;

    public SelectAllHeader(JTable table, int targetColumn) {
        super(ALL);
        this.table = table;
        this.tableModel = table.getModel();
        if (tableModel.getColumnClass(targetColumn) != Boolean.class) {
            throw new IllegalArgumentException("Boolean column required.");
        }
        this.targetColumn = targetColumn;
        this.header = table.getTableHeader();
        this.tcm = table.getColumnModel();
        this.applyUI();
        this.addItemListener(new ItemHandler());
        header.addMouseListener(new MouseHandler());
        tableModel.addTableModelListener(new ModelHandler());
    }

    @Override
    public Component getTableCellRendererComponent(
        JTable table, Object value, boolean isSelected,
        boolean hasFocus, int row, int column) {
        return this;
    }

    private class ItemHandler implements ItemListener {

        @Override
        public void itemStateChanged(ItemEvent e) {
            boolean state = e.getStateChange() == ItemEvent.SELECTED;
            setText((state) ? NONE : ALL);
            for (int r = 0; r < table.getRowCount(); r++) {
                table.setValueAt(state, r, viewColumn);
            }
        }
    }

    @Override
    public void updateUI() {
        super.updateUI();
        applyUI();
    }

    private void applyUI() {
        this.setFont(UIManager.getFont("TableHeader.font"));
        this.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
        this.setBackground(UIManager.getColor("TableHeader.background"));
        this.setForeground(UIManager.getColor("TableHeader.foreground"));
    }

    private class MouseHandler extends MouseAdapter {

        @Override
        public void mouseClicked(MouseEvent e) {
            viewColumn = header.columnAtPoint(e.getPoint());
            int modelColumn = tcm.getColumn(viewColumn).getModelIndex();
            if (modelColumn == targetColumn) {
                doClick();
            }
        }
    }

    private class ModelHandler implements TableModelListener {

        @Override
        public void tableChanged(TableModelEvent e) {
            if (needsToggle()) {
                doClick();
                header.repaint();
            }
        }
    }

    // Return true if this toggle needs to match the model.
    private boolean needsToggle() {
        boolean allTrue = true;
        boolean allFalse = true;
        for (int r = 0; r < tableModel.getRowCount(); r++) {
            boolean b = (Boolean) tableModel.getValueAt(r, targetColumn);
            allTrue &= b;
            allFalse &= !b;
        }
        return allTrue && !isSelected() || allFalse && isSelected();
    }
}

错误消息显示为:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at guit2.SelectAllHeader.needsToggle(Guit2.java:316)
    at guit2.SelectAllHeader.access$800(Guit2.java:229)
    at guit2.SelectAllHeader$ModelHandler.tableChanged(Guit2.java:304)
    at javax.swing.table.AbstractTableModel.fireTableChanged(AbstractTableModel.java:296)
    at javax.swing.table.AbstractTableModel.fireTableRowsInserted(AbstractTableModel.java:231)
    at javax.swing.table.DefaultTableModel.insertRow(DefaultTableModel.java:376)
    at javax.swing.table.DefaultTableModel.addRow(DefaultTableModel.java:350)
    at javax.swing.table.DefaultTableModel.addRow(DefaultTableModel.java:361)
    at guit2.Guit2.<init>(Guit2.java:93)
    at guit2.Guit2$3.run(Guit2.java:138)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:756)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:726)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
BUILD SUCCESSFUL (total time: 5 seconds)

0 个答案:

没有答案