Can I use JXBusyLabel as a cell displayed in JTable?

I would like to use JXBusyLabel in a cell to notify the user that an event is currently happening for the row where JXBusyLabel is located. For example, double-clicking on a row to open it will cause anymation from JXBusyLabel .

It makes sense?

If you are interested in what JXBusyLabel , check here .

Thanks!

[EDIT] Solution based on @kleopatra answer :

 import java.awt.BorderLayout; 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.Timer; import javax.swing.table.DefaultTableModel; import org.jdesktop.swingx.JXTable; import org.jdesktop.swingx.decorator.AbstractHighlighter; import org.jdesktop.swingx.decorator.HighlightPredicate; import org.jdesktop.swingx.decorator.PainterHighlighter; import org.jdesktop.swingx.painter.BusyPainter; public class TableBusyLabelTest { private JFrame frame; private JXTable table; private JButton button; private BusyPainter busyPainter; private AbstractHighlighter highlighter; private Timer timer; private boolean on = false; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { TableBusyLabelTest window = new TableBusyLabelTest(); window.frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the application. */ public TableBusyLabelTest() { initialize(); } /** * Initialize the contents of the frame. */ private void initialize() { frame = new JFrame(); frame.setBounds(100, 100, 450, 300); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); busyPainter = new BusyPainter(15); timer = new Timer(100, getTimerActionListener()); highlighter = new PainterHighlighter(HighlightPredicate.NEVER, busyPainter); table = new JXTable(); table.setModel(getTableExampleModel()); // Tell which column will use the highlighter table.getColumnExt(0).addHighlighter(highlighter); button = new JButton("Start / Stop busy thing"); button.addActionListener(getButtonActionListener()); frame.getContentPane().add(table, BorderLayout.CENTER); frame.getContentPane().add(button, BorderLayout.SOUTH); } private DefaultTableModel getTableExampleModel() { return new DefaultTableModel(new Object[][] { { null, "Test1" }, { null, "Test2" }, }, new String[] { "busy", "Name" }); } private ActionListener getTimerActionListener() { return new ActionListener() { @Override public void actionPerformed(ActionEvent e) { int frame = busyPainter.getFrame(); frame = (frame + 1) % busyPainter.getPoints(); busyPainter.setFrame(frame); } }; } private ActionListener getButtonActionListener() { return new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (on) { on = false; } else { on = true; } // on a change that should toggle the busy-ness on/off if (on) { highlighter .setHighlightPredicate(HighlightPredicate.ALWAYS); timer.start(); } else { highlighter.setHighlightPredicate(HighlightPredicate.NEVER); timer.stop(); } } }; } } 
+4
source share
2 answers

Depending on your specific use case, you will not want to use JXBusyLabel as a rendering component (you will not get a view, since this is a visualization tool), all you need is a PainterHighlighter configured with BusyPainter, whose frame property is controlled by a timer. Regardless, the visible artist should be tied to some property of your data that triggers the HighlightPredicate on / off.

As an example, please refer to the interactive PainterVisualCheckAnimatedBusyPainterHighlight tool in the swingx test hierarchy, a package renderer. Sort of:

  BusyPainter painter = new BusyPainter(); ActionListener l = new ActionListener() { public void actionPerformed(ActionEvent e) { int frame = busyPainter.getFrame(); frame = (frame+1)%busyPainter.getPoints(); busyPainter.setFrame(frame); } }; Timer timer = new Timer(delay, l); AbstractHighlighter hl = new PainterHighlighter(HighlightPredicate.NEVER, painter); table.getColumnExt().addHighlighter(hl); // on a change that should toggle the busy-ness on/off if (on) { hl.setHighlightPredicate(HighlightPredicate.ALWAYS); timer.start(); } else { hl.setHighlightPredicate(HighlightPredicate.NEVER); timer.stop(); } 

Edit (answer to an extended question):

To activate the busy shortcut only for a specific condition, implement a custom HighlightPredicate and set it instead of ALWAYS. FI specific row in the column:

  HighlightPredicate predicate = new HighlightPredicate() { @Override public boolean isHighlighted(Component renderer, ComponentAdapter adapter) { return adapter.convertRowIndexToModel(adapter.row) == mySpecialRow; } }; 
+2
source

Yes it is possible. I used this in my desk as well. It looks very cool for lazy loading.

 private class YourCellRenderer implements TableCellRenderer { private final JLabel okLabel; private final JXBusyLabel busyLabel; public YourCellRenderer() { busyLabel = new JXBusyLabel(new Dimension(50, 50)); busyLabel.setHorizontalAlignment(JXLabel.CENTER); busyLabel.setBusy(true); okLabel = new JLabel(); } @Override public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column) { if (((YourClass)value).isBusy()) { return busyLabel; } else { okLabel.set(((YourClass)value).getText()); return okLabel; } return null; } 

Set the new renderer as the default renderer for YourClass:

 table.setDefaultRenderer(YourClass.class, new YourCellRenderer()); 

Your table model should return instances of YourClass, of course.

+1
source

All Articles