0

In swing application, I am using DefaultTableCellRenderer to flash the table cell when the cell time is equal to system time. I wrote if statement to compare cell time with hh:mm , If both time are equal, time cells backgroung will blink on the table rows. It is blinking 60 secs only still if statement is true, But i want to continue blinking same cell after false if statement.

I got the position value of blinking cell like (0,2) and (1,2). from this integer, how can i set continues blink after false if statement or Is there any other way? Thank you.

My Code is here :

I added table method and inner class.

  public void table() throws SQLException
    {
     Connection c=null;
    PreparedStatement pre;
    try 
    {
        Class.forName("com.mysql.jdbc.Driver");
        c=DriverManager.getConnection("jdbc:mysql://localhost:3306/telecaller_database", "root", "root");
        Statement st= c.createStatement();
        DateFormat df=new SimpleDateFormat(" dd/MM/yyyy");          
        Calendar cl=Calendar.getInstance();              
        Date dt1=cl.getTime();
        String str1=df.format(dt1);
        System.out.println("today date is "+str1);          
        pre=c.prepareStatement("Select name,phoneno,time from components where date=?");
        pre.setString(1,str1);          
        ArrayList<String> arl=new ArrayList<String>();
        ResultSet rs=pre.executeQuery();

        ResultSetMetaData md=rs.getMetaData();              
        System.out.println("result set data "+pre);

        int column=md.getColumnCount();

            System.out.println(column);

            for(int i=1;i<=column;i++)
            {
                columns.addElement(md.getColumnName(i));
            }               
                while(rs.next())
                {               
                    arl.add(rs.getString(1));
                    System.out.println(arl);
                    Vector row=new Vector(column);
                    for(int j=1;j<=column;j++)
                    {
                        row.addElement(rs.getString(j));
                    }
                    rows.addElement(row);                       
                }

                rs.close();
                st.close();             
    }   
    catch (ClassNotFoundException e)
    {           
        e.printStackTrace();
    }       
    final JTable table=new JTable(rows,columns);    
    Border bd2=BorderFactory.createLineBorder(Color.black,1);
    table.setBorder(bd2);       

    table.setDefaultRenderer(Object.class, (TableCellRenderer) new MyFlashingCellRenderer2());

    final long startTime = System.currentTimeMillis();      
     Thread thread = new Thread()
        {
            public void run()
            {                   
                while(true)
                {                  
                    long now = System.currentTimeMillis();
                    long second = (now -startTime) / 1000;
                   // System.out.println(second);

                    color = second / 2 * 2 ==  second ? Color.red : Color.yellow;
                    color1= second / 2 * 2 ==  second ? Color.green : Color.blue;
                   // System.out.println(second/2*2);

                    SwingUtilities.invokeLater(new Runnable()
                    {
                        public void run()
                        {
                            table.tableChanged(new TableModelEvent(table.getModel()));  
                            //table.setBackground(color1);                              
                        }
                    });
                    try
                    {
                        Thread.sleep(1000);
                    }
                    catch(InterruptedException e)
                    {
                        e.printStackTrace();  
                    }
                }
            }
        };

    thread.start();       
    JScrollPane scrollPane = new JScrollPane(table);
    scrollPane.setBounds(14,20,345,400);
    jp1.add(scrollPane);
    }

  public class MyFlashingCellRenderer extends DefaultTableCellRenderer          
  {
        public int cellr;
        public int cellc;  

    public Component getTableCellRendererComponent(JTable table, Object rows1, boolean isSelected, boolean hasFocus, int row, int column)
     {              
        JLabel label = (JLabel)super.getTableCellRendererComponent(table, rows1, isSelected, hasFocus, row, column);           
        String timeformat = " h:mm a";
        SimpleDateFormat obDateFormat = new SimpleDateFormat(timeformat);
        Calendar time = Calendar.getInstance();
        String time1=obDateFormat.format(time.getTime()).toString();
        //System.out.println("metod "+cellr+cellc);   

       if (time1.equals(rows1))
        {
           cellr=row;
           cellc=column;
           System.out.println("time  "+time1+" row "+rows1);                
           getTableCellRendererComponent2(table, rows1, isSelected, hasFocus, row, column);

        }           
        else if(!time1.equals(rows1))
        {               
           label.setBackground(null);              
        }           
        return label;               
    } 
    public Component getTableCellRendererComponent2(JTable table, Object rows1, boolean isSelected, 
                                                    boolean hasFocus, int x, int y)
    {
        JLabel label = (JLabel)super.getTableCellRendererComponent(table, rows1, isSelected, hasFocus, x, y);
        label.setBackground(color);
        System.out.println("outer method "+cellr+cellc);

        x=cellr; y=cellc;             // potition of blinking cell

        System.out.println("x and y  "+x+y);                                                                    
        return label;       
    }   
  }
151291
  • 3,308
  • 7
  • 48
  • 81
  • If you don't get a decent answer soon, consider creating and posting a [minimal example program](http://stackoverflow.com/help/mcve), one that does not need a database to demonstrate for us your problem. – Hovercraft Full Of Eels Mar 01 '14 at 12:29
  • can you re-word the question, its hard to understand what exactly your asking. Some general tips (after you determine issue) are to add () to the calculation of color and color1, try to to create new objects in loop like "new TableModelEvent(table.getModel())" if you can declare it outside the loop, since you have a lot going on here and it seems like it might be good code to make reusable I would put it in a separate thread class after you fix your issue and it will also make the code cleaner. (You might want to add condition later in the thread to stop it based on table property changes) –  Mar 01 '14 at 12:37
  • i have a table with three columns name, phoneno and time. when table time and system time is equal, time cell background will blink on the the table rows. it is blinking one minuts only still if statement is true. that means i comparing time `hh:mm` in if statement so it's blinking 60 secs only. after false if, how can continue blinking same cell, no other cells or row. – 151291 Mar 01 '14 at 13:14
  • 2
    this question hasn't something with JDBC (myslq & sql) but about Timer & JTable & XxxTableCellRenderer – mKorbel Mar 01 '14 at 13:40
  • please to re_read comment by @Hovercraft Full Of Eels – mKorbel Mar 01 '14 at 13:41
  • What happens if you declare the now value outside the while loop but you still instantiate it inside AND then you add 'second = second + 1000;' after the color1 instantiation? – Anto Mar 01 '14 at 14:09
  • Again, you will want to create a [minimal, compiable, runnable program](http://stackoverflow.com/help/mcve) that we can run unaltered, without need of a database, and that shows your problem for us. – Hovercraft Full Of Eels Mar 01 '14 at 15:37

2 Answers2

3

The code is indeed rather confusing. For example, it is not clear what the condition for the blinking should be. At the moment, it seems like the condition is that a particular cell displays the current time (as obtained from a calendar instance). However, making this decision in the CellRenderer is highly dubious. Instead, this decision should be made from outside, since it actually depends on the model data.

The implementation of the thread that controls the actual blinking is not very elegant. This could more easily be solved with a Swing Timer. (The thread only puts a task on the event queue, anyhow).

Additionally, changing the background of a table cell renderer component is fairly independent of the component itself.

However, I created a small example of how I would tackle this problem. I tried to mimic your original intention as far as possible: The sample creates a table that contains Strings of time (Calendar instances) that are a few seconds in the future, randomly permuted. It creates a timer that regularly checks whether any time limits has been exceeded. When the time has beed exceeded, the corresponding table cell starts to blink.

The blinking itself is handled by a special BlinkCellRenderer. Since this cell renderer only has to switch the background color of a cell, it just uses a delegate cell renderer which provides the actual cell renderer component, and sets the background color of this component according to the current blinking state. It also allows adding and removing cells that should currently be blinking.

Of course, this could be extended and implemented in a more sophisticated and versatile way, but maybe it serves as an inspiration, at least.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;

public class BlingBlingTable
{
    public static void main(String[] args) 
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(createMainPanel());
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private static JPanel createMainPanel()
    {
        JPanel mainPanel = new JPanel(new BorderLayout());

        final JTable table = createTable();

        TableCellRenderer delegate = new DefaultTableCellRenderer();
        final BlinkCellRenderer blinkCellRenderer = 
            new BlinkCellRenderer(table, delegate);
        table.setDefaultRenderer(Object.class, blinkCellRenderer);
        mainPanel.add(table, BorderLayout.CENTER);

        createBlinkChecker(table, blinkCellRenderer);

        final JToggleButton blinkButton = new JToggleButton("Random blink");
        blinkButton.addActionListener(new ActionListener() 
        {
            int r;
            int c;

            @Override
            public void actionPerformed(ActionEvent e)
            {
                if (blinkButton.isSelected())
                {
                    r = (int)(Math.random() * table.getRowCount());
                    c = (int)(Math.random() * table.getColumnCount());
                    blinkCellRenderer.addBlinkingCell(r, c);
                }
                else
                {
                    blinkCellRenderer.removeBlinkingCell(r, c);
                }
            }
        });
        mainPanel.add(blinkButton, BorderLayout.SOUTH);
        return mainPanel;
    }

    // Creates a table that contains strings that represent
    // points in time that are a few seconds in the future
    private static JTable createTable()
    {
        Vector<Vector<String>> rowDatas = new Vector<Vector<String>>();
        int rs = 3;
        int cs = 3;
        for (int r=0; r<rs; r++)
        {
            Vector<String> rowData = new Vector<String>();
            for (int c=0; c<cs; c++)
            {
                Calendar time = Calendar.getInstance();
                time.add(Calendar.SECOND, (c+(r * cs))*4);
                rowData.add(createTimeString(time));
            }
            Collections.shuffle(rowData);
            rowDatas.add(rowData);
        }
        Collections.shuffle(rowDatas);
        Vector<String> columnData = new Vector<String>();
        for (int c=0; c<3; c++)
        {
            columnData.add("Column "+c);
        }
        return new JTable(rowDatas, columnData);
    }

    // Creates a timer that regularly updates the blinking
    // state of all cells of the given table
    private static void createBlinkChecker(
        final JTable table, final BlinkCellRenderer blinkCellRenderer)
    {
        Timer timer = new Timer(500, new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                updateBlinkingState(table, blinkCellRenderer);
            }
        });
        timer.setInitialDelay(0);
        timer.start();
    }

    // Updates the blinking state of the specified cell
    // in the given table, using the #shouldBlink 
    // method below
    private static void updateBlinkingState(
        JTable table, BlinkCellRenderer blinkCellRenderer)
    {
        for (int r=0; r<table.getRowCount(); r++)
        {
            for (int c=0; c<table.getColumnCount(); c++)
            {
                if (shouldBlink(table, r, c))
                {
                    blinkCellRenderer.addBlinkingCell(r, c);
                }
                else
                {
                    blinkCellRenderer.removeBlinkingCell(r, c);
                }
            }
        }
    }

    // Returns whether the specified cell in the given 
    // table should currently blink
    private static boolean shouldBlink(JTable table, int r, int c)
    {
        Object value = table.getValueAt(r, c);
        Calendar cellTime = parseTime(String.valueOf(value));
        Calendar currentTime = Calendar.getInstance();
        cellTime.set(Calendar.YEAR, 
            currentTime.get(Calendar.YEAR));
        cellTime.set(Calendar.MONTH, 
            currentTime.get(Calendar.MONTH));
        cellTime.set(Calendar.DAY_OF_MONTH, 
            currentTime.get(Calendar.DAY_OF_MONTH));
        long difference = 
            currentTime.getTimeInMillis() - 
            cellTime.getTimeInMillis();

        // Blink for 10 seconds
        long blinkDurationInMS = 10000;
        return 
            difference >= 0 && 
            difference < blinkDurationInMS;
    }

    // The time format that will be used for creating
    // strings from calendar instances and for parsing
    private static final String TIME_FORMAT = " h:mm:ss a";
    private static final DateFormat DATE_FORMAT = 
        new SimpleDateFormat(TIME_FORMAT);

    // Creates a string containing the given time
    // in a particular format
    private static String createTimeString(Calendar time)
    {
        String timeString = DATE_FORMAT.format(time.getTime());
        return timeString;
    }

    // Parse the time from the given string
    private static Calendar parseTime(String timeString)
    {
        Calendar calendar = Calendar.getInstance();
        try
        {
            calendar.setTime(DATE_FORMAT.parse(timeString));
        }
        catch (ParseException e)
        {
            e.printStackTrace();
        }
        return calendar;
    }


    /**
     * A TableCellRenderer which can let particular cells of 
     * a JTable blink. That is, it switches the background
     * color at a regular interval and triggers a repaint
     * of the table. The cell renderer components whose 
     * background is switched are provided by a delegate
     * cell renderer
     */
    public static class BlinkCellRenderer extends DefaultTableCellRenderer          
    {
        /**
         * Serial UID
         */
        private static final long serialVersionUID = 6896646544236592534L;

        /**
         * Simple class storing the coordinates of a 
         * particular table cell
         */
        static class Cell
        {
            final int r;
            final int c;
            Cell(int r, int c)
            {
                this.r = r;
                this.c = c;
            }
            @Override
            public int hashCode()
            {
                return 31 * c + r;
            }
            @Override
            public boolean equals(Object object)
            {
                if (object instanceof Cell)
                {
                    Cell cell = (Cell)object;
                    return r == cell.r && c == cell.c; 
                }
                return false;
            }
        }

        /** 
         * The delegate cell renderer that provides the
         * cell renderer components
         */
        private final TableCellRenderer delegate;

        /**
         * The set of cells that are currently blinking
         */
        private final Set<Cell> blinkingCells = new HashSet<Cell>();

        /**
         * The current blinking state (that is, whether
         * the cells should be highlighted or not)
         */
        private boolean blinkingState = true;

        /**
         * Creates a BlinkCellRenderer that will let cells of
         * the given table blink. The cell renderer components
         * are provided by the given delegate
         * 
         * @param table The table
         * @param delegate The delegate
         */
        BlinkCellRenderer(final JTable table, TableCellRenderer delegate)
        {
            this.delegate = delegate;
            int delayMS = 250;
            Timer blinkingTimer = new Timer(delayMS, new ActionListener()
            {
                boolean timerBlinkingState = true;

                @Override
                public void actionPerformed(ActionEvent e)
                {
                    blinkingState = timerBlinkingState;
                    table.repaint();
                    timerBlinkingState = !timerBlinkingState;
                }
            });
            blinkingTimer.setInitialDelay(0);
            blinkingTimer.start();
        }

        /**
         * Add the cell with the given coordinates to the
         * set of cells that are currently blinking
         * 
         * @param r The row
         * @param c The column
         */
        void addBlinkingCell(int r, int c)
        {
            blinkingCells.add(new Cell(r, c));
        }

        /**
         * Remove the cell with the given coordinates from the
         * set of cells that are currently blinking
         * 
         * @param r The row
         * @param c The column
         */
        void removeBlinkingCell(int r, int c)
        {
            blinkingCells.remove(new Cell(r,c));
        }

        /**
         * Removes all blinking cells
         */
        void clearBlinkingCells()
        {
            blinkingCells.clear();
        }


        @Override
        public Component getTableCellRendererComponent(
            JTable table, Object value, boolean isSelected,
            boolean hasFocus, int row, int column)
        {
            Component component = 
                delegate.getTableCellRendererComponent(
                    table, value, isSelected, hasFocus, row, column);
            Cell cell = new Cell(row, column);
            if (blinkingState && blinkingCells.contains(cell))
            {
                component.setBackground(Color.RED);
            }
            else
            {
                component.setBackground(null);
            }

            return component;
        } 
    }


}

EDIT: Added a functionality to specify the duration for which the cells should keep blinking (blinkDurationInMS is the duration how long the cell will blink, in milliseconds)

Marco13
  • 53,703
  • 9
  • 80
  • 159
  • Thanks, i shorted as one cell, How can stop cell blinking after change time. – 151291 Mar 05 '14 at 14:05
  • You can call `blinkCellRenderer.removeBlinkingCell(r, c)` after a while. This could be controlled with another timer, or in the `updateBlinkingState` method. Currently, this call is commented out, but you could simply add this line, and modify the `shouldBlink` method so that it returns `true` when the current time is in the range (timeInCell, timeInCell+10seconds) – Marco13 Mar 05 '14 at 14:22
  • I enabled `blinkCellRenderer.removeBlinkingCell(r, c)` in `updateBlinkingstate` method but it is blinking one minutes only i changed `hh:mm:ss a` to `hh:mm a` how can change in `shouldBlink`? – 151291 Mar 05 '14 at 15:32
  • @NagarajRaju You have to describe the criterion that specifies whether a cell should be blinking or not, depending on *your* actual data. However, I edited the code a little: Now, there is a value `blinkDurationInMS` that allows specifying the blinking duration. For **your** data, you might have to adopt the computation of the difference between the current time and the time that is shown in the cell. – Marco13 Mar 05 '14 at 15:53
  • Thanks for the ideas. Repainting the entire table 4 times per second seems like overkill, though, especially if nothing is actively blinking. – Michael May 30 '22 at 11:37
  • @Michael A `repaint` is usually cheap. Swing will detect what has to be repainted. But one could think about 1. limiting the _number_ of calls and 2. limiting the _area_ that is marked as dirty (and has to be repainted) **iff** this turned out to be a bottleneck. (But it most likely won't, unless someone did something horribly wrong when implementing the cell renderer...) – Marco13 May 30 '22 at 19:30
0

Create another column of data to store in the TableModel that contains a Boolean value. The data should only be in the model, but the column should NOT be displayed in the JTable.

Then your logic can set the Boolean value to Boolean.TRUE whenever the times are the same. Once the value is true you never set it false. The renderer can now check the Boolean value to do the blinking for the cell and the blinking should continue fore ever.

camickr
  • 321,443
  • 19
  • 166
  • 288