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
    10

    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, 01:07 AM
  3. Issue
    By chaitu444 in forum New To Java
    Replies: 2
    Last Post: 11-06-2007, 08:49 PM
  4. jcheckbox issues need help. thanks.
    By carlos123 in forum New To Java
    Replies: 3
    Last Post: 11-05-2007, 11: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
  •