Java 将加载循环添加到JTable

Java 将加载循环添加到JTable,java,swing,jtable,loading,Java,Swing,Jtable,Loading,我有一个从数据库加载数据的JTable。因为有时候数据太多,我想在Jtable中添加一个加载循环,通知用户数据正在加载。以下是我希望它是什么样子的图像: 这可能吗?如何在摇摆中完成 PS:我不想使用进度条,我只想要表格中的圆圈 更新:该表是GUI的一部分,我只想禁用或显示JTable内部的加载,并保持其他组件完好无损。1)至半透明、模态和未修饰的JDialog(阻止父级鼠标事件) 2) 到玻璃窗格(可阻止鼠标事件) 3) 到JViewport 编辑 如果您的SQL解释器支持分页,则拆分SQL结

我有一个从数据库加载数据的JTable。因为有时候数据太多,我想在Jtable中添加一个加载循环,通知用户数据正在加载。以下是我希望它是什么样子的图像:

这可能吗?如何在摇摆中完成

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

更新:该表是GUI的一部分,我只想禁用或显示JTable内部的加载,并保持其他组件完好无损。

1)至半透明、模态和未修饰的JDialog(阻止父级鼠标事件)

2) 到玻璃窗格(可阻止鼠标事件)

3) 到JViewport

编辑


如果您的
SQL解释器
支持
分页
,则拆分
SQL结果集
(5-20个),并使用
JProgressBar
而不是循环的
图像

我认为玻璃窗格足以完成此任务。它允许绘制窗口的内容。以下是示例(红色圆圈画在按钮上):

以下是基于

import java.awt.*;
导入java.awt.event.*;
导入java.beans.PropertyChangeEvent;
导入javax.swing.*;
导入javax.swing.plaf.LayerUI;
导入javax.swing.table.*;
公共类TableWaitLayerTest{
私有最终字符串[]columnNames={“字符串”、“整数”、“布尔值”};
私有最终对象[][]数据={
{“aaa”,12,正确},{“bbb”,5,错误},{“ccc”,9,错误},
};
私有最终DefaultTableModel=新的DefaultTableModel(数据、列名){
@重写公共类getColumnClass(int列){
返回getValueAt(0,列).getClass();
}
};
专用最终JTable表=新JTable(模型);
私有最终JButton startButton=新JButton();
私有最终WaitLayerUI layerUI=新的WaitLayerUI();
公共JComponent makeUI(){
setAction(新的抽象操作(“开始”){
@覆盖已执行的公共无效操作(ActionEvent e){
layerUI.start();
startButton.setEnabled(错误);
SwingWorker worker=新SwingWorker(){
@重写公共字符串doInBackground(){
int电流=0,长度为120;
while(当前正在使用JFC/Swing>创建GUI,并使用其他Swing功能)
//tap.java
类WaitLayerUI扩展了LayerUI实现ActionListener{
私有布尔运算错误;
痛风;
私人定时器;
私营企业;
私人国际货币基金组织;
私有int mFadeLimit=15;
@替代公共空白绘制(图形g、J组件c){
int w=c.getWidth();
int h=c.getHeight();
//绘制视图。
超级油漆(g,c);
如果(!运行错误){
返回;
}
Graphics2D g2=(Graphics2D)g.create();
浮动衰减=(浮动)mFadeCount/(浮动)mFadeLimit;
//把它涂成灰色。
复合urComposite=g2.getComposite();
g2.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_超过0.5f*衰减);
g2.fillRect(0,0,w,h);
g2.setComposite(urComposite);
//为等待指示器上漆。
int s=数学最小值(w,h)/5;
int cx=w/2;
int-cy=h/2;
g2.setRenderingHint(RenderingHints.KEY_抗锯齿,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.设定行程(
新BasicStroke(s/4,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
g2.setPaint(颜色为白色);
g2.旋转(数学PI*mAngle/180,cx,cy);
对于(int i=0;i<12;i++){
浮动刻度=(11.0f-(浮动)i)/11.0f;
g2.拉线(cx+s,cy,cx+s*2,cy);
g2.旋转(-Math.PI/6,cx,cy);
g2.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_超过,比例*衰减);
}
g2.dispose();
}
@覆盖已执行的公共无效操作(ActionEvent e){
如果(错误运行){
火属性更改(“勾号”,0,1);
裂口+=3;
如果(撕裂>=360){
mAngle=0;
}
如果(痛风){
如果(--mFadeCount==0){
错误运行=错误;
mTimer.stop();
}
}否则如果(mFadeCount@覆盖公共无效事件(AWTEvent e,jlaye通常它并不总是来自数据库。无论如何,我喜欢GlassPane方法!快捷方式是,基于@camickr的“如何显示部分GlassPane”?就像在我的示例中,我只想显示Jtable内部的加载,并保持其他组件的正常行为-1坚持使用不正确的JViewport。。(正如我在前面的回答中不止一次提到的:它在视图下方,在上面做任何事情都会被组件覆盖)谢谢。你是对的,但是mKorbel首先回答了,所以你得到了+1:)另一个图章到你的旅游visa@kleopatra我也这么认为。JLayer有很多有用的功能。
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();
    }
  }
}