Results 1 to 3 of 3
  1. #1
    ram_76uk is offline Member
    Join Date
    Jul 2008
    Posts
    2
    Rep Power
    0

    Question Issue with Jcheckbox on JTableheader

    Hello ,

    I have used below code to add checkboxes on Jtableheader.In my table i can resize column width(resize).I feel that is the problem.


    XML Code:
    package com.ibm.report;
     
    import java.awt.event.ItemListener;
    import java.awt.event.MouseListener;
    import java.awt.event.MouseEvent;
    import java.awt.Component;
     
    import javax.swing.JCheckBox;
    import javax.swing.JTable;
    import javax.swing.UIManager;
    //import javax.swing.ImageIcon;
    import javax.swing.table.JTableHeader;
    import javax.swing.table.TableCellRenderer;
    import javax.swing.table.TableColumnModel;
     
     
    /**
      * Add a JCheckBox to the Renderer
      * @author Jan-Friedrich Mutter (jmutter@bigfoot.de)
      */
    public class CheckBoxHeader extends JCheckBox implements TableCellRenderer, MouseListener {
     
      /**
        * the Renderer Component.
        * @see #getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
        */
      protected CheckBoxHeader rendererComponent;
     
      /** To which (JTable-) columns does this Checkbox belong ? */
      protected int column;
     
      /**
        * remembers, if mousePressed() was called before.
        * Workaround, because dozens of mouseevents occurs after one
        * mouseclick.
        */
      protected boolean mousePressed = false;
     
      /**
        * @param itemListener will be notified when Checkbox will be checked/unchecked
        */
      public CheckBoxHeader(ItemListener itemListener) {
    	  
        rendererComponent = this;
        rendererComponent.addItemListener(itemListener);
        
      }
     
      /** @return this */
      //pasted from javax.swing.table.TableColumn.createDefaultHeaderRenderer()
      //with some slight modifications.
      //implements TableCellRenderer
      public Component getTableCellRendererComponent(
          JTable table, Object value,boolean isSelected, boolean hasFocus, int row, int column) {
     
        if (table != null) {
          JTableHeader header = table.getTableHeader();
          if (header != null) {
            rendererComponent.setForeground(header.getForeground());
            rendererComponent.setBackground(header.getBackground());
            rendererComponent.setFont(header.getFont());
     
            header.addMouseListener(rendererComponent);
          }
        }
     
        setColumn(column);
        rendererComponent.setText((value == null) ? "" : value.toString());
    		setBorder(UIManager.getBorder("TableHeader.cellBorder"));
     
        return rendererComponent;
      }
     
      /** @param column to which the CheckBox belongs to */
      protected void setColumn(int column) {
        this.column = column;
      }
     
      /** @return the column to which the CheckBox belongs to */
      public int getColumn() {
        return column;
      }
     
      /**************** Implementation of MouseListener ******************/
     
      /**
        * Calls doClick(), because the CheckBox doesn't receive any
        * mouseevents itself. (because it is in a CellRendererPane).
        */
      protected void handleClickEvent(MouseEvent e) {
        // Workaround: dozens of mouseevents occur for only one mouse click.
        // First MousePressedEvents, then MouseReleasedEvents, (then
        // MouseClickedEvents).
        // The boolean flag 'mousePressed' is set to make sure
        // that the action is performed only once.
        if (mousePressed) {
          mousePressed=false;
     
          JTableHeader header = (JTableHeader)(e.getSource());
          JTable tableView = header.getTable();
          TableColumnModel columnModel = tableView.getColumnModel();
          
          int viewColumn = columnModel.getColumnIndexAtX(e.getX());
          int column = tableView.convertColumnIndexToModel(viewColumn);
     
          if (viewColumn == this.column && e.getClickCount() == 1 && column != -1) {
            doClick();
          }
        }
      }
     
      public void mouseClicked(MouseEvent e) {
        handleClickEvent(e);
        //Header doesn't repaint itself properly
        ((JTableHeader)e.getSource()).repaint();
      }
     
      public void mousePressed(MouseEvent e) {
        mousePressed = true;
      }
     
      public void mouseReleased(MouseEvent e) {
        //works - problem: works even if column is dragged or resized ...
        //handleClickEvent(e);
        //properly repainting by the Header
      }
     
      public void mouseEntered(MouseEvent e) {
      }
     
      public void mouseExited(MouseEvent e) {
      }
    }

    This code is working fine as long as i am not resizing the column width.Even if i resize the column width slowly for few times ,its working fine.But if i resize bit faster many times i am seeing below error message.



    Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
    at java.awt.AWTEventMulticaster.mouseReleased(AWTEven tMulticaster.java:263)
    at java.awt.AWTEventMulticaster.mouseReleased(AWTEven tMulticaster.java:263)
    at java.awt.AWTEventMulticaster.mouseReleased(AWTEven tMulticaster.java:263)
    at java.awt.AWTEventMulticaster.mouseReleased(AWTEven tMulticaster.java:263)
    at java.awt.AWTEventMulticaster.mouseReleased(AWTEven tMulticaster.java:263)
    at java.awt.AWTEventMulticaster.mouseReleased(AWTEven tMulticaster.java:263)
    at java.awt.AWTEventMulticaster.mouseReleased(AWTEven tMulticaster.java:263)
    at java.awt.AWTEventMulticaster.mouseReleased(AWTEven tMulticaster.java:263)
    at java.awt.AWTEventMulticaster.mouseReleased(AWTEven tMulticaster.java:263)
    at java.awt.AWTEventMulticaster.mouseReleased(AWTEven tMulticaster.java:263)
    at java.awt.AWTEventMulticaster.mouseReleased(AWTEven tMulticaster.java:263)


    Could you please let me know how to avoid this ,if you come accross such problem please.

    Thanks in advance...

  2. #2
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    8

    Default

    See comments for why this happens, how to avoid it and, better yet, how to do it properly in swing/java.
    Java Code:
    import java.awt.event.ItemListener;
    import java.awt.event.MouseListener;
    import java.awt.event.MouseEvent;
    import java.awt.Component;
     
    import javax.swing.JCheckBox;
    import javax.swing.JTable;
    import javax.swing.UIManager;
    //import javax.swing.ImageIcon;
    import javax.swing.table.JTableHeader;
    import javax.swing.table.TableCellRenderer;
    import javax.swing.table.TableColumnModel;
    
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.table.*; 
     
    /**
      * Add a JCheckBox to the Renderer
      * @author Jan-Friedrich Mutter (jmutter@bigfoot.de)
      */
    public class CBH extends JCheckBox implements TableCellRenderer, MouseListener {
     
      /**
        * the Renderer Component.
        * @see #getTableCellRendererComponent(JTable table, Object value,
        *             boolean isSelected, boolean hasFocus, int row, int column)
        */
      protected CBH rendererComponent;
     
      /** To which (JTable-) columns does this Checkbox belong ? */
      protected int column;
     
      /**
        * remembers, if mousePressed() was called before.
        * Workaround, because dozens of mouseevents occurs after one
        * mouseclick.
        */
      protected boolean mousePressed = false;
     
      /**
        * @param itemListener will be notified when Checkbox will be 
    
    checked/unchecked
        */
      public CBH(ItemListener itemListener) {
    	  
        rendererComponent = this;
        rendererComponent.addItemListener(itemListener);
        
      }
     
      /** @return this */
      //pasted from javax.swing.table.TableColumn.createDefaultHeaderRenderer()
      //with some slight modifications.
      //implements TableCellRenderer
      public Component getTableCellRendererComponent(JTable table, Object value,
                   boolean isSelected, boolean hasFocus, int row, int column) {
     
        if (table != null) {
          JTableHeader header = table.getTableHeader();
          if (header != null) {
            rendererComponent.setForeground(header.getForeground());
            rendererComponent.setBackground(header.getBackground());
            rendererComponent.setFont(header.getFont());
     
                // We only need one listener on the header
                // this adds another every time this renderer
                // is fetched to render a column header which
                // can eventually lead to StackOverflowError.
                header.addMouseListener(rendererComponent);
          }
        }
     
        setColumn(column);
        rendererComponent.setText((value == null) ? "" : value.toString());
    		setBorder(UIManager.getBorder("TableHeader.cellBorder"));
     
        return rendererComponent;
      }
     
      /** @param column to which the CheckBox belongs to */
      protected void setColumn(int column) {
        this.column = column;
      }
     
      /** @return the column to which the CheckBox belongs to */
      public int getColumn() {
        return column;
      }
     
      /**************** Implementation of MouseListener ******************/
     
      /**
        * Calls doClick(), because the CheckBox doesn't receive any
        * mouseevents itself. (because it is in a CellRendererPane).
        * The way to get the JCheckBox to work is to create and
        * install an editor that looks, ie, is configured just like
        * this renderer.
        */
      protected void handleClickEvent(MouseEvent e) {
        // Workaround: dozens of mouseevents occur for only one mouse click.
        // First MousePressedEvents, then MouseReleasedEvents, (then
        // MouseClickedEvents).
        // The boolean flag 'mousePressed' is set to make sure
        // that the action is performed only once.
        if (mousePressed) {
          mousePressed=false;
     
          JTableHeader header = (JTableHeader)(e.getSource());
          JTable tableView = header.getTable();
          TableColumnModel columnModel = tableView.getColumnModel();
          
          int viewColumn = columnModel.getColumnIndexAtX(e.getX());
          int column = tableView.convertColumnIndexToModel(viewColumn);
     
          if (viewColumn == this.column && e.getClickCount() == 1 && column != -1) {
            doClick();
          }
        }
      }
     
      public void mouseClicked(MouseEvent e) {
        handleClickEvent(e);
        //Header doesn't repaint itself properly
        // If I comment out the line
        // [i]header.addMouseListener(rendererComponent);[/i]
        // in the [i]getTableCellRendererComponent[/i]
        // method above the header seems to repaint
        // itself okay for mouseDrags/moving/resizing.
        ((JTableHeader)e.getSource()).repaint();
      }
     
      public void mousePressed(MouseEvent e) {
        mousePressed = true;
        // How many MouseListeners are being notified for this event?
        JTableHeader header = (JTableHeader)e.getSource();
        MouseListener[] mls = header.getListeners(MouseListener.class);
        System.out.printf("TableHeader has %d MouseListeners added to it%n",
                           mls.length);
      }
     
      public void mouseReleased(MouseEvent e) {
        //works - problem: works even if column is dragged or resized ...
        //handleClickEvent(e);
        //properly repainting by the Header
      }
     
      public void mouseEntered(MouseEvent e) {
      }
     
      public void mouseExited(MouseEvent e) {
      }
    
        public static void main(String[] args) {
            JTable table = new JTable(getTableModel());
            TableColumnModel model = table.getColumnModel();
            for(int i = 0; i < 2; i++) {
                TableColumn col = model.getColumn(i);
                col.setHeaderRenderer(new CBH(il));
                // an option
                //col.setPreferredWidth(25);
                //col.setResizable(false);
            }
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.add(new JScrollPane(table));
            f.setSize(400,400);
            f.setLocation(200,200);
            f.setVisible(true);
        }
        
        private static AbstractTableModel getTableModel() {
            return new AbstractTableModel() {
                public int getRowCount() { return 10; }
    
                public int getColumnCount() { return 4; }
    
                public Object getValueAt(int row, int col) {
                    return String.valueOf((row+1)) + (col+1);
                }
            };
        }
    
        private static ItemListener il = new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
                System.out.println("itemListener");
            }
        };
    }

  3. #3
    ram_76uk is offline Member
    Join Date
    Jul 2008
    Posts
    2
    Rep Power
    0

    Thumbs up

    Hi Thanks for your valuable suggestions.I have modified the code as per your suggestions,now functionality is working great as per client requirements.

    Only thing i did was i restricted in code to add mouse listener as below in getTableCellRendererComponent(...).If we add action listener only once to table header , i am able check/uncheck checkbox only in the first column of the table.So i have added for all the columns by checking table columns length.

    XML Code:
    MouseListener[] mls = (MouseListener[])header.getListeners(MouseListener.class);
    if(mls.length < table.getColumnCount()){
                 header.addMouseListener(rendererComponent);
    }

Similar Threads

  1. Compile Issue
    By CrazyShells Slam in forum New To Java
    Replies: 4
    Last Post: 05-14-2008, 08:51 PM
  2. Can we add JCheckBox array into JTextArea?
    By nancyhung in forum AWT / Swing
    Replies: 1
    Last Post: 02-17-2008, 12:07 AM
  3. Issue
    By chaitu444 in forum New To Java
    Replies: 2
    Last Post: 11-06-2007, 07:49 PM
  4. jcheckbox issues need help. thanks.
    By carlos123 in forum New To Java
    Replies: 3
    Last Post: 11-05-2007, 10:37 PM
  5. Replies: 1
    Last Post: 08-08-2007, 01:25 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •