向JTable添加加载循环

2023-12-10

我有一个从数据库加载数据的 JTable。因为有时数据太多,我想在Jtable内添加一个加载圆圈来通知用户数据正在加载。这是我希望的图像:

enter image description here

这可能吗?在 Swing 中如何实现呢?

PS:我不想使用进度条,我只想使用表格内的圆圈。

UPDATE:该表是 GUI 的一部分,我只想禁用或显示 JTable 内部的加载,并保持其他组件不变。


这里是JLayer(Java 1.7.0)版本,基于如何使用 JLayer 类装饰组件(Java 教程 > 使用 JFC/Swing 创建 GUI > 使用其他 Swing 功能)

import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import javax.swing.*;
import javax.swing.plaf.LayerUI;
import javax.swing.table.*;

public class TableWaitLayerTest {
  private final String[] columnNames = {"String", "Integer", "Boolean"};
  private final Object[][] data = {
    {"aaa", 12, true}, {"bbb", 5, false}, {"ccc", 9, false},
  };
  private final DefaultTableModel model = new DefaultTableModel(data, columnNames) {
    @Override public Class<?> getColumnClass(int column) {
      return getValueAt(0, column).getClass();
    }
  };
  private final JTable table = new JTable(model);
  private final JButton startButton = new JButton();
  private final WaitLayerUI layerUI = new WaitLayerUI();
  public JComponent makeUI() {
    startButton.setAction(new AbstractAction("start") {
      @Override public void actionPerformed(ActionEvent e) {
        layerUI.start();
        startButton.setEnabled(false);
        SwingWorker<String, Object[]> worker = new SwingWorker<String, Object[]>() {
          @Override public String doInBackground() {
            int current = 0, lengthOfTask = 120;
            while(current<lengthOfTask && !isCancelled()) {
              try {
                Thread.sleep(50);
              } catch(InterruptedException ie) {
                return "Interrupted";
              }
              publish(new Object[] {"aaa", current++, false});
            }
            return "Done";
          }
          @Override protected void process(java.util.List<Object[]> chunks) {
            for(Object[] array: chunks) {
              model.addRow(array);
            }
            table.scrollRectToVisible(
                table.getCellRect(model.getRowCount()-1, 0, true));
          }
          @Override public void done() {
            layerUI.stop();
            startButton.setEnabled(true);
            String text = null;
            if(isCancelled()) {
              text = "Cancelled";
            } else {
              try {
                text = get();
              } catch(Exception ex) {
                ex.printStackTrace();
                text = "Exception";
              }
            }
          }
        };
        worker.execute();
      }
    });
    JPanel p = new JPanel(new BorderLayout());
    p.add(new JButton("dummy"), BorderLayout.NORTH);
    p.add(new JLayer<JComponent>(new JScrollPane(table), layerUI));
    p.add(startButton, BorderLayout.SOUTH);
    return p;
  }
  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    JFrame f = new JFrame();
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.getContentPane().add(new TableWaitLayerTest().makeUI());
    f.setSize(320, 240);
    f.setLocationRelativeTo(null);
    f.setVisible(true);
  }
}

//http://docs.oracle.com/javase/tutorial/uiswing/misc/jlayer.html
//How to Decorate Components with the JLayer Class
//(The Java? Tutorials > Creating a GUI With JFC/Swing > Using Other Swing Features)
//TapTapTap.java
class WaitLayerUI extends LayerUI<JComponent> implements ActionListener {
  private boolean mIsRunning;
  private boolean mIsFadingOut;
  private Timer mTimer;

  private int mAngle;
  private int mFadeCount;
  private int mFadeLimit = 15;

  @Override public void paint (Graphics g, JComponent c) {
    int w = c.getWidth();
    int h = c.getHeight();

    // Paint the view.
    super.paint (g, c);

    if (!mIsRunning) {
      return;
    }

    Graphics2D g2 = (Graphics2D)g.create();

    float fade = (float)mFadeCount / (float)mFadeLimit;
    // Gray it out.
    Composite urComposite = g2.getComposite();
    g2.setComposite(AlphaComposite.getInstance(
                      AlphaComposite.SRC_OVER, .5f * fade));
    g2.fillRect(0, 0, w, h);
    g2.setComposite(urComposite);

    // Paint the wait indicator.
    int s = Math.min(w, h) / 5;
    int cx = w / 2;
    int cy = h / 2;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setStroke(
      new BasicStroke(s / 4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
    g2.setPaint(Color.white);
    g2.rotate(Math.PI * mAngle / 180, cx, cy);
    for (int i = 0; i < 12; i++) {
      float scale = (11.0f - (float)i) / 11.0f;
      g2.drawLine(cx + s, cy, cx + s * 2, cy);
      g2.rotate(-Math.PI / 6, cx, cy);
      g2.setComposite(AlphaComposite.getInstance(
                        AlphaComposite.SRC_OVER, scale * fade));
    }

    g2.dispose();
  }

  @Override public void actionPerformed(ActionEvent e) {
    if (mIsRunning) {
      firePropertyChange("tick", 0, 1);
      mAngle += 3;
      if (mAngle >= 360) {
        mAngle = 0;
      }
      if (mIsFadingOut) {
        if (--mFadeCount == 0) {
          mIsRunning = false;
          mTimer.stop();
        }
      } else if (mFadeCount < mFadeLimit) {
        mFadeCount++;
      }
    }
  }

  public void start() {
    if (mIsRunning) {
      return;
    }
    // Run a thread for animation.
    mIsRunning = true;
    mIsFadingOut = false;
    mFadeCount = 0;
    int fps = 24;
    int tick = 1000 / fps;
    mTimer = new Timer(tick, this);
    mTimer.start();
  }

  public void stop() {
    mIsFadingOut = true;
  }

  @Override public void applyPropertyChange(PropertyChangeEvent pce, JLayer l) {
    if ("tick".equals(pce.getPropertyName())) {
      l.repaint();
    }
  }

  @Override public void installUI(JComponent c) {
    super.installUI(c);
    ((JLayer)c).setLayerEventMask(
      AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK |
      AWTEvent.MOUSE_WHEEL_EVENT_MASK | AWTEvent.KEY_EVENT_MASK |
      AWTEvent.FOCUS_EVENT_MASK | AWTEvent.COMPONENT_EVENT_MASK);
  }
  @Override public void uninstallUI(JComponent c) {
    ((JLayer)c).setLayerEventMask(0);
    super.uninstallUI(c);
  }
  @Override public void eventDispatched(AWTEvent e, JLayer<? extends JComponent> l) {
    if(mIsRunning && e instanceof InputEvent) {
      ((InputEvent)e).consume();
    }
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

向JTable添加加载循环 的相关文章

随机推荐

  • 如何在Sed中查找[]内的文本?

    这与已经被问过的问题类似 但是 我正在寻找 Sed 的具体答案 我有类似以下内容的文字 一些示例文本 带有一些额外的文本 foo 我需要只抓取括号内的文本 到目前为止我的尝试都是徒劳的 我可以使用其他工具解析该行 但我似乎无法让 Sed 正
  • -std=c++11 和 -std=gnu++11 有什么区别?

    两者有什么区别 std c 11 and std gnu 11作为 gcc 和 clang 的编译参数 同样的问题与c99 and gnu99 我了解 C 和 C 标准 我感兴趣的是参数的差异 我在某处读到它与某些扩展有关 但我不清楚哪些扩
  • 托管 Flash 不会加载 swf 资源(xml、图像等)

    我首先尝试在我的unix机器上使用gtk2实现swf阅读器 成功了 我可以渲染简单的 swf 文件 现在 我尝试使用 xml 配置向 flash 文件添加配置 添加图像等 失败 无法通过 geturlnotify 这是我的代码 includ
  • 如何给一个命令指定多个名称?

    我有一个命令 bot command pass context True async def hellothere ctx await Bot say Hello format ctx message author 我想复制这个更短的命令
  • 按值获取所有数组键

    假设我有一个这样的数组 Array Start gt Array Item 1 gt Array 0 gt Item 1 1 Item 2 1 gt Array Item 2 1 1 gt x 1 gt Item 3 1 0 gt Item
  • 为什么 Oracle 存在长期问题?

    为什么 Oracle 存在长期问题 如果有人能告诉我在oracle中使用long数据类型有什么问题那就更好了 与存储有关的东西 我在一次采访中被问到这个问题 LONG 已经过时且已被弃用 并已被 CLOB 取代 LONG 有很多限制 并且很
  • 为什么 ggplot 在指定其他颜色时使用默认颜色?

    我试图让 ggplot2 将直方图的一行显示为与其余部分不同的颜色 在这方面我已经成功了 但是 当指定不同的颜色集时 ggplot 将使用默认颜色 我确信我的代码中有错误 但我无法确定它在哪里 数据和代码如下 创建数据 library gg
  • Matplotlib colorbar:如何手动设置间隔?

    我使用以下代码片段创建自定义颜色条 import pylab as pl import numpy as np a np array 0 10000 100000 400000 500000 pl figure figsize 9 1 5
  • 使用 PHP/Apache 限制对静态文件(html、css、img 等)的访问

    假设您的服务器上的目录中有大量 html css js img 等文件 通常 互联网上的任何用户都可以通过简单地输入完整的 URL 来访问这些文件 如下所示 http example com static files sub index h
  • 如何授予对 public_html 目录之外的文件的下载访问权限?

    出于安全目的 我将文件存储在 public html 文件夹之外 但是 我想以某种方式链接到特定文件 用户可以在其中下载这些文件之一 我正在使用 jquery 脚本 它允许我指定服务器 PATH 作为上传文件夹 并且它会在 public h
  • C# 访问修饰符部分,如 C++

    我需要写吗allC 中的访问修饰符 static class Node Node link Node link int data public void setlink Node next void display 我想使用访问修饰符部分
  • 如何在助手中访问小部件数据

    在我的前端助手中 我使用一个参数并将其提供给所有的 data widget 是否可以在帮助程序上下文中访问 data widget 我只找到了 self output 对象树 但我认为这不是一个高质量的解决方案 Thanks 编辑代码示例
  • 无法让 Twitter OAuth 回调身份验证在 Cocoa 应用程序中工作

    我正在使用 MGTwitterEngine 和 OAuthConsumer 框架 并且主要遵循以下说明使用OAuth消费者 为了使用 OAuth 并且不让用户处理基于 oob PIN 的身份验证 您需要启用对应用程序的回调 要在桌面 或 i
  • 如何识别窗口服务中的登录事件

    我有一个 Windows 服务 可以获取用户详细信息并将结果保存到日志文本文件中 而且 我的问题是当我注销系统并再次登录时 即无需重新启动机器 我还想将登录系统的时间节省到该日志文件中 如何在窗口服务中编写登录事件 请帮助评论 我使用了下面
  • 在 Tornado 中“超时”请求的正确方法

    我设法编写了一个相当愚蠢的错误 该错误将使我的一个请求处理程序运行非常慢的数据库查询 有趣的是 我注意到即使在围攻完成很久之后 Tornado 仍然在不断地处理请求 有时是 90 年代后 评论 gt 我不是 100 确定 Siege 的工作
  • 在另一个线程中创建 WPF 元素

    我可以在不同的线程上运行 2 个或更多 WPF 窗口 问题是现在我的应用程序分割在许多窗口中 我真正想要的是有一个主窗口包含一个网格 其中每个单元格都包含由不同线程管理的元素 是否可以创建一个由不是管理父窗口 包含窗口的线程管理的 UIEl
  • 按键升序对数组进行排序,并将“粘性”键指定为第一个

    我有一个多维数组 array array B gt array Banana Yello O gt array Orange Orange A gt array Apple Green S gt array Strawberry Red o
  • 在有内容的页面上触发文件下载

    我见过许多网站在包含现有 HTML 内容的页面上触发文件另存为对话框 他们如何做到这一点 我知道如何设置正确的标题 例如内容处置等 但是当我这样做时 页面的内容不会加载 并且立即触发文件下载 创建一个常规 HTML 页面 然后添加一个 ME
  • JavaScript:使值对数组形成值数组

    有没有一种优雅 实用的方法来转换这个数组 1 5 9 21 进入这个 1 5 5 9 9 21 我知道我可以forEach数组并收集值以创建一个新数组 有没有一种优雅的方式来做到这一点 lodash不使用forEach 您可以映射一个拼接数
  • 向JTable添加加载循环

    我有一个从数据库加载数据的 JTable 因为有时数据太多 我想在Jtable内添加一个加载圆圈来通知用户数据正在加载 这是我希望的图像 这可能吗 在 Swing 中如何实现呢 PS 我不想使用进度条 我只想使用表格内的圆圈 UPDATE