我有一個從數據庫加載數據的JTable。由於有時數據太多,我想在Jtable中添加一個加載循環來通知用戶數據正在加載。下面是我怎麼想它是圖像:向JTable添加加載循環
這可能嗎?在Swing中怎麼做?
PS:我不想使用進度條,我只想要表格中的圓圈。
更新:該表是GUI的一部分,我只想禁用或顯示JTable內的加載並保持其他組件不變。
我有一個從數據庫加載數據的JTable。由於有時數據太多,我想在Jtable中添加一個加載循環來通知用戶數據正在加載。下面是我怎麼想它是圖像:向JTable添加加載循環
這可能嗎?在Swing中怎麼做?
PS:我不想使用進度條,我只想要表格中的圓圈。
更新:該表是GUI的一部分,我只想禁用或顯示JTable內的加載並保持其他組件不變。
1)至半透明&模態& un_decorated的JDialog(塊鼠標事件到母體)
2)至玻璃面板(可以阻止鼠標事件)
3)的JViewport
EDIT
如果您的SQL interpreter
支持Paginations
,則拆分SQL ResultSet
(5 - 20件)並使用JProgressBar
而不是cy cled Images
,
我認爲Glass Pane非常適合這項任務。它允許繪製窗口的內容。下面是tutorial的例子(紅色圓圈塗黑按鈕):
謝謝。你是對的,但mKorbel首先回答,所以你得到+1 :) – 2012-02-13 14:22:12
這裏的JLayer(Java 1.7.0)版本,基於How to Decorate Components with the JLayer Class (The Java Tutorials > Creating a GUI With JFC/Swing > Using Other Swing Features)
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();
}
}
}
其實它並不總是從數據庫。無論如何,我喜歡GlassPane的方法! – 2012-02-13 14:21:24
捷徑將是http://stackoverflow.com/q/8715807/714968,基於@ camickr的http://tips4java.wordpress.com/2008/11/07/disabled-glass-pane/ – mKorbel 2012-02-13 14:24:23
如何顯示部分GlassPane?就像在我的例子中,我只是想顯示Jtable中的加載,並保持其他組件的正常行爲 – 2012-02-13 15:14:39