【问题标题】:Is it possible to use a JXBusyLabel as a cell rendered in a JTable?是否可以将 JXBusyLabel 用作在 JTable 中呈现的单元格?
【发布时间】:2011-05-19 22:35:11
【问题描述】:

我想在单元格中使用JXBusyLabel 来通知用户JXBusyLabel 所在行当前正在发生事件。 例如,双击一行打开它会触发JXBusyLabel 的anymation。

这有意义吗?

如果您想知道JXBusyLabel 是什么,请查看here

谢谢!

[EDIT] 基于@kleopatra 答案的解决方案

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();
                }
            }
        };
    }

}

【问题讨论】:

标签: java user-interface swingx


【解决方案1】:

根据您的具体用例,您不希望使用 JXBusyLabel 作为渲染组件(您不会获得动画,因为它是一个 渲染器),您只需要一个PainterHighlighter 配置有 BusyPainter,其 frame 属性由计时器控制。画家是否可见应该绑定到数据的某些属性,这些属性会触发荧光笔 HighlightPredicate 的开/关。

有关示例,请参阅 swingx 测试层次结构中的 PainterVisualCheck interactiveAnimatedBusyPainterHighlight,包渲染器。比如:

    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(); 
    }

编辑(回答扩展问题):

要仅针对特定条件激活忙碌的荧光笔,请实现自定义 HighlightPredicate 并设置它而不是 ALWAYS。菲列中的特定行:

    HighlightPredicate predicate = new HighlightPredicate() {

        @Override
        public boolean isHighlighted(Component renderer,
                ComponentAdapter adapter) {

            return 
               adapter.convertRowIndexToModel(adapter.row) == mySpecialRow;
        }

    };

【讨论】:

  • 酷,这工作:) 谢谢!还有一个问题,我如何指定它来影响表格中的特定单元格而不是整个列?我已经编辑了我的主要帖子以包含我用来完成这项工作的示例代码。顺便说一句,很抱歉我的反馈延迟:)
【解决方案2】:

是的,这是可能的。我也在我的桌子上用过这个。延迟加载看起来很酷。

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;
}

将新渲染器设置为 YourClass 的默认渲染器:

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

当然,您的表模型需要返回 YourClass 的实例。

【讨论】:

  • 可能,但缺少动画(至少 ;-)
  • 这很好,但如果没有动画,那就太可悲了JXBusyLabel ;(无论如何感谢@Stephan 的回答!:)
猜你喜欢
  • 2022-10-14
  • 2018-01-16
  • 1970-01-01
  • 2013-12-17
  • 2018-12-02
  • 2013-02-18
  • 1970-01-01
  • 1970-01-01
  • 2018-03-22
相关资源
最近更新 更多