如何在摇摆中的假if语句后连续闪烁表格单元格
Posted
技术标签:
【中文标题】如何在摇摆中的假if语句后连续闪烁表格单元格【英文标题】:how to blink table cell continuously after false if statement in swing 【发布时间】:2014-04-02 14:01:37 【问题描述】:在swing应用程序中,当单元格时间等于系统时间时,我使用DefaultTableCellRenderer
来刷新表格单元格。我写了 if 语句来比较单元格时间与 hh:mm
,如果两个时间相等,时间单元格背景将在表格行上闪烁。如果语句为真,它只会闪烁 60 秒,但我想在错误的 if 语句后继续闪烁 same cell。
我得到了闪烁单元格的位置值,例如 (0,2) 和 (1,2)。从这个整数中,我如何设置 false if 语句后继续闪烁,或者还有其他方法吗?谢谢。
我的代码在这里:
我添加了表格方法和内部类。
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;
【问题讨论】:
如果您没有很快得到合适的答案,请考虑创建并发布minimal example program,它不需要数据库来为我们展示您的问题。 你能重新提出这个问题吗,很难理解你到底在问什么。一些一般提示(确定问题后)是将 () 添加到颜色和 color1 的计算中,如果您可以在循环外声明它,请尝试在循环中创建新对象,如“new TableModelEvent(table.getModel())” ,因为你在这里有很多事情要做,而且看起来它可能是使可重用的好代码,我会在你解决你的问题后把它放在一个单独的线程类中,它也会使代码更干净。 (您可能希望稍后在线程中添加条件以根据表属性更改停止它) 我有一个包含三列名称、电话号码和时间的表格。当表格时间和系统时间相等时,表格行上的时间单元格背景会闪烁。只有当陈述为真时,它才会闪烁一分钟。这意味着我在 if 语句中比较时间hh:mm
,所以它只闪烁 60 秒。如果在 false 之后,如何继续闪烁相同的单元格,没有其他单元格或行。
这个问题与 JDBC (myslq & sql) 无关,而是关于 Timer & JTable & XxxTableCellRenderer
请重新阅读@Hovercraft Full Of Eels 的评论
【参考方案1】:
代码确实相当混乱。例如,不清楚闪烁的条件应该是什么。目前,条件似乎是特定单元格显示当前时间(从日历实例中获得)。然而,在CellRenderer
中做出这个决定是非常可疑的。相反,这个决定应该从外部做出,因为它实际上取决于模型数据。
控制实际闪烁的线程的实现不是很优雅。使用 Swing Timer
可以更轻松地解决这个问题。 (无论如何,线程只将任务放在事件队列中)。
此外,更改表格单元格渲染器组件的背景完全独立于组件本身。
但是,我创建了一个小示例来说明如何解决此问题。我试图尽可能地模仿您的初衷:该示例创建了一个表,其中包含未来几秒钟的时间字符串(日历实例),随机排列。它创建一个计时器,定期检查是否超过了任何时间限制。超过时间后,相应的表格单元格开始闪烁。
闪烁本身由特殊的BlinkCellRenderer
处理。由于这个单元格渲染器only 需要切换单元格的背景颜色,它只是使用了一个委托单元格渲染器,它提供了实际的单元格渲染器组件,并根据当前闪烁设置该组件的背景颜色状态。它还允许添加和删除当前应该闪烁的单元格。
当然,这可以以更复杂、更通用的方式进行扩展和实现,但至少可以作为一种灵感。
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;
编辑:添加了一个功能来指定单元格应保持闪烁的持续时间(blinkDurationInMS
是单元格闪烁的持续时间,以毫秒为单位)
【讨论】:
谢谢,我短为一个单元格,如何在更改时间后停止单元格闪烁。 您可以稍后拨打blinkCellRenderer.removeBlinkingCell(r, c)
。这可以通过另一个计时器或updateBlinkingState
方法来控制。目前,此调用已被注释掉,但您可以简单地添加此行,并修改shouldBlink
方法,使其在当前时间在范围内时返回true
(timeInCell,timeInCell+10 秒)
我在updateBlinkingstate
方法中启用了blinkCellRenderer.removeBlinkingCell(r, c)
,但它只闪烁一分钟我将hh:mm:ss a
更改为hh:mm a
shouldBlink
如何更改?
@NagarajRaju 您必须描述指定单元格是否应该闪烁的标准,具体取决于您的实际数据。但是,我稍微编辑了代码:现在,有一个值 blinkDurationInMS
允许指定闪烁持续时间。对于您的数据,您可能必须采用当前时间与单元格中显示的时间之间的差异计算。【参考方案2】:
创建另一列数据以存储在包含布尔值的 TableModel 中。数据只应在模型中,但列不应显示在 JTable 中。
然后,只要时间相同,您的逻辑就可以将布尔值设置为 Boolean.TRUE。一旦值为真,您就永远不会将其设置为假。渲染器现在可以检查布尔值以对单元格进行闪烁,并且闪烁应该永远持续下去。
【讨论】:
以上是关于如何在摇摆中的假if语句后连续闪烁表格单元格的主要内容,如果未能解决你的问题,请参考以下文章